MCP server
Filing a task and answering the four questions used to mean leaving the session for a browser. On 2026-08-05 an agent spent roughly a hundred browser calls doing that by hand, which made the diagnosis hard to argue with: the gate was never the friction, the walk to it was. Risk #1 in the spec is “uninstalled through friction”.
So CC ships MCP. The assistant you are already talking to can read the zone map, file a request, draft the four fields and save them — in the session, where the work is being discussed.
Two servers, and they are not the same size
Section titled “Two servers, and they are not the same size”| Where it comes from | Tools | Can it move a task? | |
|---|---|---|---|
| stdio | Inside the plugin, or cycle mcp from the CLI |
7 | No — it reads the board and files or scopes tasks |
| connector | An HTTP URL the board issues, per machine | 11 | Yes, by asking the gate |
Which one you have decides what your assistant can do, so it is worth knowing which one is wired. The counts are the two lists on the trunk on 2026-10-31: apps/mcp/src/tools-list.ts for the stdio server, and that list plus the connector’s own four in apps/api/src/mcp-http.ts — and the site’s build fails when this page’s counts or tables disagree with them (CC-1384). The stdio server you install today has six: cc_search reached it after the newest release, 0.1.25 — what the newest release does not carry yet.
Every tool description says which board it answers for
Section titled “Every tool description says which board it answers for”Read the end of any CC tool’s description and you will find a SCOPE: line naming the tenant and repository that server resolved, and where it resolved them from.
It is there because task ids are shaped the same on every board. Ids are numbered per board, so every board’s first task is CC-1 (CC-71): CC-42 is a valid id on yours and on every other board, so an assistant holding two CC servers in one session — a local one and a connector, or two projects — has nothing in a payload to tell them apart. The suffix is what makes the answer attributable to a board instead of merely plausible. When a server has not resolved a board at all, the same line says that instead, rather than letting the tool answer as if it had.
Worth reading before trusting a payload, and worth checking first when a task “does not exist” that you are certain exists. cc_intake’s reply names the board too — “Filed CC-n in Triage on <tenant>/<repo>” — because a client reads the descriptions once and a misfiled task is seen in the reply or not at all (CC-749).
The seven, on both
Section titled “The seven, on both”| Tool | Does | Writes? |
|---|---|---|
cc_zones |
The zone map: which areas are protected, at what risk, and who owns each | no |
cc_intake |
File a request in one line. Lands in Triage, and the reply names any task already on the board that looks like the same work | yes |
cc_interview |
The four fields drafted for a task. The stdio server returns the board’s draft, validated against the real zone map; the connector hands back a drafting brief and your assistant does the drafting | no |
cc_scope |
Save the four answers onto a task, and the files it expects to touch (expected_files). The reply names open tasks that expect or touched the same files. Over the connector this is also the Triage → Todo move; the stdio server saves and stops there |
yes |
cc_status |
One task by id, or everything in flight — and any mentions on it still waiting to be acknowledged | no |
cc_why |
Which tasks changed a file or a folder, newest first, with the goal each was opened for — the same answer as cycle why |
no |
cc_search |
Up to five tasks on this board related to a request, to the files it will touch, or both — matched by meaning where the board has that on, by shared files and by words, each with its state and what it was opened for | no |
cc_status carries the board’s count of unacknowledged mentions on a task — a note somebody left for whoever is working it, which nothing else in the session would surface. It is an annotation on the answer, not a second call: an assistant that reads cc_status at all has already been told there is something waiting. Acknowledging one is a separate act, so reading the count never discharges it.
cc_search is told to run before filing or starting work, and it is the same search cc_intake and cc_scope append to their answers: the point is to continue a task that already exists instead of filing its duplicate, and to keep what earlier work decided. The meaning half is an embedding search on the board’s side, not a generative model (apps/api/src/search.ts), and a board without it still answers from files and words. The hook treats it as a read wherever it runs, inside a task or outside one, as it treats cc_why, cc_status and cc_zones, so the paths you pass it are never mistaken for a write (CC-1345).
cc_interview is told, in its own description, to present its draft as choices rather than as a fait accompli — each suggestion offered as a selectable option next to a free-text alternative. A drafting tool that hands back a finished spec produces specs nobody read, which is the failure mode the four fields exist to prevent.
cc_interview also tells the assistant to settle the four answers in rounds (CC-1361). Both servers carry the same text: in the connector’s drafting brief, and after the stdio server’s draft. Each round asks only the questions whose prerequisites are settled. The goal comes first, then what the work must not do and which zones it touches, then how you will know it worked. Each question is numbered and carries the assistant’s recommended answer, worded so a plain “yes” accepts it. A fact the codebase can answer, such as which files hold the code, the assistant looks up instead of asking. A task with no zone and nothing unknown keeps a single round, so one “yes” settles all four. Whatever the number of rounds, cc_scope saves the same four fields.
The four more, on the connector only
Section titled “The four more, on the connector only”| Tool | Does |
|---|---|
cc_setup |
Returns the files to write for a repository with nothing installed. It deliberately never returns a hook configuration — see the quickstart for why that would be worse than nothing |
cc_start |
Todo → In Progress. The gate decides, and its refusal comes back verbatim: no four fields, or a high-risk zone nobody approved, and it says no |
cc_submit |
In Progress → In Review. Access closes in the same breath. It takes files (every path the work changed, kept as the task’s files so the next request learns what this one touched), note (the hand-in report, below) and pr (the pull request, so the reviewer sees it on the task). With the repository’s pr.open policy on (off by default), it also opens the task’s pull request |
cc_close |
In Review → Done, and writes the audit record. It takes every path the work changed and the closing gate compares that list against what the task declared. The list is the agent’s report, and the audit record labels it as reported. It also requires learned — what the work taught, where an empty list is a legitimate answer — and hands back each lesson as a playbook append for your agent to write |
cc_submit’s note is the agent’s final report, kept on the ticket. The board reads the note’s headed sections into the reviewer’s view; the headings it reads are listed in cc_submit’s own tool description and in cycle submit --help. It is the same note cycle submit --note sends (CC-1243). Secrets are redacted before the board stores it.
cc_close’s own description tells the assistant not to guess or summarise the file list — run git diff --no-renames --name-only <base>...HEAD and pass exactly that, with the paths that no longer exist passed again as deleted. --no-renames lists a renamed file under its old path and its new one, because moving a file out of a zone changes that zone as much as moving one in (CC-1382). A manifest that omits a file is a close that certifies work nobody checked, and the audit record is what somebody reads six months later to find out what happened.
Files the connector hands back for your agent to write — a task record, a grant, an audit record, a playbook append — sit between fences drawn fresh for each reply. Text other people wrote, such as a task’s goal, cannot carry the fence, so it cannot pose as another file or as an instruction from the server (CC-1310).
What no MCP tool does
Section titled “What no MCP tool does”These hold on both servers, and they are the interesting part:
- Nothing approves an access request. An approval reaching the board through MCP would be authenticated by a token the agent holds, so the board could not tell your yes from the agent’s own — and an agent that can approve its own request is the end of the claim, not a convenience. So the request travels into the session and the decision travels out of it: the link opens a browser where you are already signed in, and that session is the credential.
- No tool talks to the hook.
cc_startandcc_submitask the gate, which issues or revokes a grant; the hook reads that grant only oncecycle syncbrings it to the machine, and no tool can widen it. Enforcement is a capability (Layer 2), not a request. An agent chooses whether to call an MCP tool, and a boundary you can decline to call is not a boundary. - Nothing decides a transition.
cc_startasks the gate; the gate answers. The tool is a client of the same rules the console obeys, not a second door with easier locks. - Nothing reads the grant file on your machine.
cc_starthands back the grant the board issued, but the copy the hook decides against is a local file, andcycle statusis what reads it.
Connecting it
Section titled “Connecting it”The connector is the path the quickstart uses — nothing to download. Open Settings → Connect a machine in the console, choose Connector, copy the URL, and:
claude mcp add --transport http commitcycle "<your connector URL>" --scope localThe URL contains a key. --scope local keeps it out of anything you would commit, and the machine shows up in the console’s machines table where you can revoke it.
The stdio server arrives with the plugin already wired — there is nothing to configure. To point a different client at it, or to use the npm CLI:
{ "mcpServers": { "commitcycle": { "command": "cycle", "args": ["mcp"] } }}It resolves the board exactly as every other cycle command does: the environment wins, and when the environment says nothing, the committed .zones/board.json answers. So a cloned repository usually needs no configuration at all.
| Variable | Notes |
|---|---|
CC_API_URL |
The board this repository reports to |
CC_TENANT |
No default, ever. The first half of the address in the console — pow/commitcycle means CC_TENANT=pow |
CC_REPO_ID |
Falls back to the repository’s directory name |
CC_TOKEN |
One command, one credential, nothing stored. Used only when CC_API_URL is set too — see two accounts on one machine |
CC_TENANT has no fallback on purpose: a guessed tenant writes zones, events and grants into an organization nobody created, and it fails silently rather than loudly.
A normal exchange
Section titled “A normal exchange”- Someone asks for something in chat.
cc_searchchecks whether the board already holds it; if not,cc_intakefiles it in one line — a request that has not been scoped is not work in progress. cc_zones, thencc_interview, drafts what it should do, what it must not do, which zones it touches, and how you will know it worked.- The person corrects the draft, in rounds of numbered questions, each with a recommended answer that a plain “yes” accepts. A task with no zone and nothing unknown takes one round. This is the step that matters; the rest is transcription.
cc_scopesaves it. The task is now startable.- On the connector,
cc_startasks the gate to open it and hands back the branch to create. With only the stdio server, that step iscycle startin a terminal — which is also where the enforcing machine collects the grant either way.