Specs that everyone
can work from.

Everyone writes specs — PMs, designers, engineers, AI agents. Same format. Same output. Every time.

password-resetfeature_spec · 8 blocks
✓ validated
user_story
What the user needs to accomplish

As a user, I can reset my password by entering my email address.

acceptance_criteria
Must pass before shipping
Email validates format
Link expires after 24h
Success on unknown email
Previous tokens invalidated
error_case
What happens when things go wrong

User enters an email that isn't registered.

respond with200 OK — { success: true }
whyavoid exposing registered emails
+ 5 more blocks · api_endpoint · data_model · auth_rule · screen_spec · test_spec

Why specs fail

Prose specs get misread.
By developers, clients, and AI agents.

Prose is ambiguous — every reader interprets it differently
Decisions live in Slack — the doc is always stale
No formal sign-off — a call isn't approval
AI agents guess from context, not from structure

With SPEC-R

Typed blocks — unambiguous by definition
Every change tracked — always in sync
Stakeholders approve blocks, not paragraphs
AI reads the exact validated spec via MCP

The spec format

What a real spec looks like

The usual way

specs.notion.so · password-reset

“Password reset feature. User enters email, gets a link, clicks it, resets password. Should expire — 24hrs maybe? Need to handle if email doesn't exist (just show success I think?). Invalidate old tokens probably. Dev can figure out the API. Sarah approved this on the call last Tuesday.”

Edited 3 weeks ago · Sarah M.unversioned

With SPEC-R

user_story

As a user, I can reset my password by entering my email address.

acceptance_criteria
Email validates format before submit
Reset link expires after 24 hours
Success message shown regardless of email existence
Previous tokens invalidated on new request
api_endpoint
methodPOST
route/api/auth/reset-password
bodyResetPasswordDto
returns{ success: boolean }
authnone
data_model
PasswordResetToken
tokenuuid, unique
emailstring
expires_atdatetime
used_atdatetime?

Deterministic Blocks

AI writes in blocks.
Every time.

password-reset · feature_spec · 8 blocks

user_story

What the user needs to do, and why

As a user, I can reset my password by entering my email address, so I can regain access to my account.

Output constrained to valid schemas — parseable, diffable, executable.

25+
typed block types

For developers

Your IDE, your specs, one config.

Add SPEC-R to Claude Code in 5 minutes.

list_specs
get_spec
publish_spec
update_implementation
{
  "mcpServers": {
    "spec-r": {
      "command": "npx",
      "args": [
        "@spec-r/mcp-server"
      ],
      "env": {
        "SPEC_R_API_KEY": "sk-...",
        "SPEC_R_PROJECT_ID": "proj_..."
      }
    }
  }
}

The full cycle

Write. Review. Iterate. Lock.

draft01
acceptance_criteria
Email validates before submit
Reset link expires after 24h
more criteria...

Partial drafts are fine — structure is the point.

in review02
acceptance_criteria
Email validates before submit
Reset link expires after 24h
Sarah M. · PM

24h from creation or from last click?

Share via link. Comments per block.

revised03
acceptance_criteria
Email validates before submit
Link expires 24h from creation, not last click
Success shown on unknown email

Update and re-submit.

✓ validated04
acceptance_criteria
Email validates before submit
Link expires 24h from creation
Success on unknown email
Previous tokens invalidated
read by Claude Code via MCP

Locked. Your agent reads this.

Good specs ship.
Start here.

Free to start — bring your own AI key and wire to Claude Code in 5 minutes.