MCP overview
What the IntentDocs MCP server gives a coding agent, and the rules it builds by.
The IntentDocs MCP server lets a coding agent read your story map and report back to it. The agent gets each story's acceptance criteria, plan and design references. It then records its tests, results and pull requests against that story. You don't paste specs into prompts, and the map shows what was built.
Two servers
IntentDocs runs two MCP servers. Most people use the hosted one.
| Hosted | Local | |
|---|---|---|
| Address | https://www.intentdocs.com/api/mcp | Started on your machine by npx intentdocs mcp |
| Transport | Streamable HTTP | stdio |
| Auth | A bearer token (intent_cli_...) or OAuth | The login saved by intentdocs login, and the project linked in .intent/config.json |
| Tools | 41, always on | 15, filtered by --mode |
| Story lifecycle | start_story, save_tests, report_criteria, complete_story, build runs, PR linking | mark_in_progress, report_criteria, mark_done |
| Resources | One card resource for clients that render it, and two prompts | Six read-only intentdocs://project/... resources |
| Projects | Every project the token can reach, chosen by project_id | The one project in .intent/config.json |
Everything on this page describes the hosted server unless it says otherwise. The two tool sets are different. See Tools & resources for both.
A third address, https://www.intentdocs.com/api/mcp/chatgpt, serves the ChatGPT plugin. It is the same server with a smaller tool set and no build loop. See Cursor & remote setup.
Start with list_projects
The server tells every client to call list_projects first. It returns each project's id, name, description, has_synced, and vision_status with vision_progress (for example "3/5"). The older fields constitution_status and constitution_progress carry the same values.
Every other tool takes a project_id. If you have more than one project and haven't said which, the agent is told to ask you. It is told not to try each project in turn.
The server also tells the agent which workspace its token reads from, for example "Personal workspace — only you can see what's here." The agent is asked to name that workspace in its first answer, so you know where it is reading from. list_projects repeats the sentence in a second text block.
If you already know the project, get_session_context returns a compact summary in one call: the vision state, story counts, the story in progress or the next one, blockers and sync state.
The vision gate
A project's vision is five questions, keyed users, problem, switch, first and proof. Stories need it.
list_projectsshowsvision_status:missing,draftorcomplete.- If it isn't
complete,get_visionreturns each question, its current answer and the keys stillunanswered. set_visionsaves answers. You can save any subset and come back later.- Once all five are answered,
create_storiesandimport_prdwork.
Until then, both refuse with error: "constitution_required", the progress, the unanswered keys and next_call: "get_constitution". Passing force: true skips the gate. The schema marks that as not recommended.
get_constitution and set_constitution are aliases of get_vision and set_vision. Same schema, same result.
The story lifecycle
Build one story at a time:
start_storyclaims the story and sets it toin_progress. It returns the criteria, plan and design references, so the agent doesn't needget_storyas well.- The agent builds the feature in your codebase.
save_testssaves each test it writes and links it to the criteria it proves. Passfileandfull_nameexactly as your test runner reports them, so CI results reach the story. You can also name tests insidereport_criteria.report_criteriarecordspass,failorblockedfor each criterion.complete_storymarks the storydone. It refuses while anymustcriterion is failing or unreported, unless you passforce: true.- A person approves the story in the IntentDocs app. Agents can't set
approved, and they can't setready_for_deveither.update_storiesrefuses both.
If a must criterion keeps failing, the agent calls raise_blocker with the decision it needs from you, then stops work on that story.
report_criteriaon a story that is stilltodomoves it toin_progressand claims it for the calling session. Reporting results counts as starting work.
The project's build gate
Each project has a build gate: what a person must do before an agent builds a story. It is set in the workspace's plan settings, and new projects start at Spec + plan. start_story checks it before it changes anything:
- Nothing. Any story can be started.
- Spec. A person must mark the story ready for dev first.
- Spec + plan. An approver must approve the story's plan, saved with
save_plan. If they requested changes, the nextsave_planmust answer each one.
A refused start says what is waiting, for example that the plan is waiting for review. A story in an approved build run is not held at this gate, because approving the run approves its stories.
One story per session
Several agents can build the same project at once. Each story is claimed by the agent session that started it.
- The hosted server issues an
Mcp-Session-Idwhen a client connects. The client sends it back on later requests, and that id is the session. - A session holds one story at a time. Starting a second is refused. Call
complete_storyfirst, or callstart_storyagain withrelease_current: trueto put the first story back. It staysin_progress, unclaimed. - A story another live session is building is refused, with who holds it and when they were last heard from.
- Any call from a session keeps its claim alive. After 2 hours with no call, the claim goes stale, and another session's
start_storytakes the story over. The response tells the new session to check the branch and any open pull request for work left behind. The takeover is recorded in the project's activity. start_storywarns when another live session's plan changes the same files.
If a client doesn't send the session id back, its claims are recorded under its token and client name. Two sessions sharing one token then can't be told apart, so the one-story limit only applies to real session ids.
get_story shows a story's claim: who holds it, the client, when it was claimed and last seen, and whether its state is held or stalled.
Build runs
A build run is a batch of stories a person approves for agents to build. Runs have keys like R-7.
When you ask an agent to build a run, it calls next_in_run instead of start_story. next_in_run starts the next story in the run and returns what start_story returns, plus the run key and the story's position. The agent builds the story, saves tests, reports criteria, calls complete_story with the pull request, then calls next_in_run again.
next_in_run tells the agent to stop when the run is:
draft(not approved yet),paused,cancelledorstoppedcomplete, with every story builtfull, with as many stories being built as the run allows at oncewaiting, because the remaining stories depend on unbuilt stories, or other sessions hold them
A story isn't handed out until the stories it depends on are built. When a story in the run is blocked, the run either skips it or stops, depending on how the person set it up. A session that already holds one of the run's stories is given that story again.
get_run reads a whole run in one call: its state and settings, and each story in build order with its criteria, status, who is building it and its pull request.
Pull requests
Pass the pull request URL to complete_story as pr_url, or call link_pr at any time. The PR number then shows on the story card.
When GitHub is connected, IntentDocs adds a footer to the PR description: "Spec → Code via intentdocs.com", with a link back to the story. A PR that already has the footer is left alone. If IntentDocs can't stamp the PR, the response gives the agent the exact footer line to end the PR body with. The link is saved either way.
get_story returns a suggested_branch built from the story key and title. Use the key in branch names, commits and PR titles.
Naming stories and criteria
Story keys. Each story has a key like PB-42: the project's prefix and the story's number. Any tool that takes project_id and story_id accepts the key in story_id, in any case. Keys with a prefix the project has retired still work. A key from another project never resolves.
Most story tools also accept a full UUID or a UUID prefix. get_story also accepts a build-sequence reference like #5. The criteria tools (report_criteria, add_criteria, update_criterion, replace_criteria and preview_criteria_replacement) accept a key or a full UUID only.
Criterion ids. In report_criteria, criterion_id can be the full id or a prefix of at least 4 characters, such as the first 8. If any id names no criterion on the story, names more than one, or appears twice in the same report, the whole report is refused and nothing is saved. The refusal lists the valid ids.
Concurrent edits
update_stories, report_criteria, replace_criteria, update_criterion and save_plan take an optional expected_version. Read it from get_story, list_stories or start_story. If the story changed since, the write is refused with error: "VERSION_CONFLICT" and the current version. Re-read the story and retry. Use it with save_plan especially, because a person may have edited the plan.
Analytics
No tool asks for analytics fields. Usage is counted from the connection: the client name your agent sends when it connects, and the session it keeps. Older clients that still send context, llm_model or conversation_id are not refused; the values are ignored.
Speccing an idea in chat
Chat assistants that start from an app idea follow Spec my idea. That page, the server instructions and the Spec my idea prompt are one text.
Where to next
- Spec my idea, the steps a chat assistant follows from an app idea
- Claude Code setup
- Cursor & remote setup, including Claude, Grok Bot, ChatGPT, and the other clients on the tokens page
- Tools & resources, every tool and its parameters
- Example workflows