Documentation
Write structured spec blocks, validate them with your team, then execute with Claude Code via MCP — without re-explaining anything. Context that doesn't drift.
Getting Started
Three ways to use SPEC-R:
Web app
Write & validate: block editor, AI generation, public review links, version history
MCP server
Execute: Claude Code reads your validated specs in real-time from the IDE
REST API
Integrate: programmatic spec management for CI/CD and external tooling
Create an account
Sign up at https://spec-r.app
/signup
Create a project
Define your tech stack, conventions, and business context — every spec you create will inherit it automatically.
Write, validate, then build
Generate blocks from text, screenshots, or templates. Share via public link for client or stakeholder review. Mark as approved — then your agent builds from the validated spec, not from memory.
Connect your IDE
Add the MCP server and your agent reads specs in real-time while you code. See the MCP Setup section below.
MCP Server Setup
Connect SPEC-R to Claude Code (or any MCP-compatible IDE). Your agent can list specs, read blocks, create specs, and update implementation progress — directly from the IDE.
Get your API key
Go to Settings → API Keys and generate a key. Copy it — it's shown only once.
Add to your .mcp.json
{
"mcpServers": {
"spec-r": {
"command": "npx",
"args": ["@spec-r/mcp-server"],
"env": {
"SPECR_API_KEY": "specr_xxxxx",
"SPECR_BASE_URL": "https://spec-r.app
",
"SPECR_PROJECT_ID": "your-project-uuid"
}
}
}
}Find your project UUID in the URL bar when viewing a project.
Try it
list_specsget_specpublish_specupdate_implementation_statusBring Your Own AI
SPEC-R never charges for AI tokens. You bring your own key — AI calls go directly to Anthropic or OpenAI, not through SPEC-R's servers.
Option 1 — Anthropic / OpenAI key
Go to Settings → AI Providers and add your API key. All web AI features use it.
Option 2 — Claude Max via MCP
If you have Claude Max, the AI runs entirely on your machine via Claude Code. SPEC-R only handles spec storage. Zero AI cost on our side.
API Authentication
All /api/v1/* endpoints require a Bearer token.
Authorization: Bearer specr_xxxxxBase URL: https://spec-r.app
Generate keys in Settings → API Keys.
Specs API
List specs
GET /api/v1/projects/:projectId/specsCreate a spec
{
"title": "Feature Name",
"type": "feature",
"status": "draft",
"blocks": [
{
"type": "heading",
"content": { "text": "Title", "level": 1 },
"position": 0
}
]
}Get a spec
GET /api/v1/specs/:specId # JSON (default)
GET /api/v1/specs/:specId?format=markdown # Markdown
GET /api/v1/specs/:specId?format=agent # Agent-optimizedUpdate / Delete
PUT /api/v1/specs/:specId { "title": "New Title", "status": "review" }
DELETE /api/v1/specs/:specIdBlocks API
List blocks
GET /api/v1/specs/:specId/blocksAdd a block
{
"type": "user_story",
"content": {
"id": "US-001",
"actor": "user",
"action": "reset my password",
"goal": "regain access to my account",
"priority": "HIGH",
"acceptanceCriteria": ["Email sent within 30s", "Link expires after 1h"]
}
}Update / Delete
PUT /api/v1/specs/:specId/blocks/:blockId { "content": { ... } }
DELETE /api/v1/specs/:specId/blocks/:blockIdPublish (Upsert)
Matches by title within the project. Creates if not found, replaces all blocks if found. Ideal for agent workflows.
{
"projectId": "uuid",
"spec": { "title": "Auth Feature", "type": "feature", "status": "draft" },
"blocks": [
{ "type": "heading", "content": { "text": "Auth Feature", "level": 1 }, "position": 0 },
{ "type": "user_story", "content": { "id": "US-001", "actor": "user", "action": "..." }, "position": 1 }
]
}{ "success": true, "specId": "uuid", "action": "created", "blocksCount": 2 }MCP Tools Reference
All tools available via @spec-r/mcp-server:
Read tools
list_specsList all specs in a projectprojectId?get_specGet full spec with blocksspecId, format?search_specsSearch specs and blocks by keywordquery, projectId?get_project_contextGet tech stack and conventionsprojectId?get_data_modelsGet all project data modelsprojectId?Write tools
publish_specCreate or update a spec (upsert by title)title, type, blockscreate_specCreate an empty spectitle, typeadd_blockAdd a block to a specspecId, type, contentupdate_blockUpdate a block's contentspecId, blockId, contentupdate_specUpdate spec title or statusspecId, title?, status?Tracking tools
update_implementation_statusMark an implementation step done, blocked, or in progressspecId, stepIndex, status, commitSha?Block Types
The core of SPEC-R. Each block is a typed, structured unit — not prose. An AI agent reading a spec gets field names, routes, schemas, and priorities. No guessing. The same block your client reviewed in the browser is the one your agent reads via MCP.
Every block has a type and a typed content object. Fields marked ? are optional.
Requirements
What to build and whyuser_storyThe unit of implementation{
"id": "US-001",
"actor": "authenticated user",
"action": "reset my password via email",
"goal": "regain access without contacting support",
"priority": "HIGH", // LOW | MEDIUM | HIGH | CRITICAL
"acceptanceCriteria": [
"Email sent within 30s of request",
"Link expires after 1 hour",
"Old password invalidated on use"
],
"storyPoints": 3, // optional
"status": "todo" // todo | in_progress | done
}acceptance_criteriaVerifiable checklist{
"criteria": [
{ "id": "AC-1", "description": "Returns 401 for unauthenticated requests", "verified": false },
{ "id": "AC-2", "description": "Rate limited to 5 requests/minute", "verified": true }
]
}business_rule{
"id": "BR-01",
"name": "Free tier limit",
"description": "Max 3 projects",
"trigger": "project creation",
"conditions": ["plan === 'free'"],
"actions": ["block + show upgrade"]
}persona{
"name": "Alex",
"role": "Senior developer",
"goals": [
"Ship with AI agents",
"No ambiguous specs"
],
"frustrations": [
"Confluence docs lie"
]
}Technical
How to build it — precise enough for an agentapi_endpointRoute contract{
"method": "POST",
"path": "/api/v1/specs/:specId/blocks",
"description": "Add a block to a spec",
"auth": true,
"requestSchema": {
"type": "object",
"required": ["type", "content"],
"properties": {
"type": { "type": "string" },
"content": { "type": "object" },
"position": { "type": "number" }
}
},
"responseSchema": { "id": "uuid", "specId": "uuid", "type": "string" }
}data_modelSchema definition{
"entityName": "Specification",
"description": "A spec document containing typed blocks",
"fields": [
{ "name": "id", "type": "uuid", "required": true, "description": "Primary key" },
{ "name": "projectId", "type": "uuid", "required": true, "description": "FK → projects" },
{ "name": "title", "type": "string", "required": true },
{ "name": "status", "type": "enum", "required": true, "enum": ["draft","review","approved","locked"] },
{ "name": "publicToken", "type": "string", "required": false, "description": "For public sharing" }
],
"relations": [{ "type": "hasMany", "entity": "SpecBlock", "foreignKey": "specId" }]
}implementation_plan{
"steps": [
{
"order": 1,
"title": "DB migration",
"description": "Add plan_tier to users",
"files": ["schema/auth.ts"]
},
{
"order": 2,
"title": "Webhook handler",
"description": "Handle Polar events",
"files": ["api/webhooks/polar"]
}
]
}component_spec{
"name": "SpecEditor",
"filePath": "app/.../spec-editor.tsx",
"description": "Block-based editor",
"props": [
{ "name": "specId", "type": "string" },
{ "name": "readOnly","type": "boolean" }
],
"states": ["loading", "editing", "saving"]
}PRD
Stakeholder-facing blocksproblem_statement{
"problem": "Specs get out of sync with code",
"impact": "Agents hallucinate implementations",
"audience": "Dev teams using AI"
}solution_overview{
"solution": "Typed spec blocks readable by agents via MCP",
"successMetrics": [
"10% fewer agent errors",
"Spec-to-PR time < 2h"
]
}scope_boundary{
"inScope": ["Block editor", "MCP server", "API"],
"outOfScope": ["Real-time collab"],
"deferredItems": ["Linear sync"]
}Agent-Ready
Implementation-level blocksfile_structureentries[]: path, action, descriptionarchitecture_decisioncontext, decision, consequences[]environment_configvariables[], services?test_specframework?, cases[]: name, typescreen_specroute?, states[], components[]enum_definitionvalues[]: key, label, color?external_dependencyname, version, purpose, docsUrl?dtoname, fields[], direction: req|resspec_linkspecId, relationTypeStructure blocks
Not specific to SPEC-R — standard document primitivesheadingtextcodediagramimageQuestions or issues? hello@spec-r.com