MCP setup
The same work loop the spec CLI drives is available
as an MCP server, so an MCP-capable agent (Claude Code, Codex, OpenCode, Cursor, Claude Desktop) can
claim, report, and complete tasks with structured tools instead of shell commands. The
server is mounted at https://api.specstrand.com/mcp.
1. Mint a token
The MCP server authenticates with a personal access token. Generate a quickstart token in the web app under Settings → MCP. It is shown once and is task-scoped (it can claim and work your tasks; it cannot push repos or manage other tokens). Copy it before you leave the page.
2. Connect your agent
Claude Code: register the server once, with your token in place of the placeholder:
claude mcp add --transport http --scope user specstrand \
https://api.specstrand.com/mcp \
--header "Authorization: Bearer <your-token>"Codex: add this to ~/.codex/config.toml:
[mcp_servers.specstrand]
url = "https://api.specstrand.com/mcp"
bearer_token_env_var = "SPEC_TOKEN"Codex reads the token from the SPEC_TOKEN variable in the shell that launches
it, the same variable the spec CLI uses.
Fallback: to hold the token in the file instead, replace that line with http_headers = { Authorization = "Bearer <your-token>" }.
OpenCode: add this to opencode.json in your project root, or to ~/.config/opencode/opencode.json for every project:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"specstrand": {
"type": "remote",
"url": "https://api.specstrand.com/mcp",
"oauth": false,
"headers": { "Authorization": "Bearer {env:SPEC_TOKEN}" }
}
}
}OpenCode replaces {env:SPEC_TOKEN} with the SPEC_TOKEN variable from the shell that launches it, so the token stays out of the file. "oauth": false stops OpenCode from trying an OAuth sign-in, because the token
already authenticates.
Fallback: to hold the token in the file instead, write "Authorization": "Bearer <your-token>" in headers.
Cursor or Claude Desktop: add this to your client's MCP config (e.g. mcp.json):
{
"mcpServers": {
"specstrand": {
"url": "https://api.specstrand.com/mcp",
"headers": { "Authorization": "Bearer <your-token>" }
}
}
}Protocol versions: the server speaks MCP 2026-07-28 (stateless requests
with server/discover) and 2025-11-25 (the initialize handshake; 2025-06-18 clients also work) on the same
URL. Your client picks the version; there is nothing to
configure.
Then give your agent its first job. A new account comes with a Getting started graph; paste this into the agent once it is connected:
Work the Getting started graph in SpecStrand: call project.work with project getting-started and follow each task until there is nothing to claim.3. Drive the loop
Graphs come first. An agent starts multi-plan work with graph.list and graph.get, calls graph.create when no graph fits, and creates
plans into it with plan.create and its graph argument
(graph.add moves an existing plan in). A plan created or updated outside
every graph returns a plan_not_in_graph warning with the exact follow-up call.
On connect, the server sends an instruction that tells the agent to route multi-step,
project-like work through SpecStrand. A 2025-11-25 client receives it in the initialize result and a 2026-07-28 client in the server/discover result; the text is the same. It opens with a short head
that fits the 2048 characters some clients keep, and detail follows. This is the head,
verbatim, so what you read here is exactly what your agent was told:
Work like this:
- Start with a graph:
graph.list, thengraph.geton the one that fits, orgraph.create; create plans into it (plan.createwithgraph) orgraph.addthem.- Run the loop:
project.workclaims the next ready task; do it,task.reportas you go,task.complete(ortask.fail), then callproject.workagain until "no claimable task".- Learn capabilities from these instructions, the tool descriptions and
spec help, never from SpecStrand source or raw /v1 calls. Each claim's instruction pack carries the reporting and friction rules.- Have a shell? Prefer the
specCLI for all of this: the same loop plus every verb (install:curl -fsSL https://specstrand.com/install.sh | sh, thenspec auth loginand have the human approve its code in the browser;spec helplists every verb). Need something no tool here does? Check MCP resourcespecstrand://cli: with a shell, run that verb; with no shell, give the human the exact command. Fileidea.createonly when neither surface has it.- A user's "queue" is a graph queue (ordered plan graphs;
project.workwithgraph_queue), not a task queue. Supervising a graph drain for someone? Delegate each task to a worker agent that runs the full loop, and read skillspecstrand:basefirst.Gates: a gate is a graph decision node that blocks its downstream plans until answered, and it is answered by the human in the UI (Approve, Reject or Rework). A drain that stops at a waiting gate means a decision is pending: stop and tell the human.
Exempt: general questions, quick lookups, and small one-offs.
The same instruction also carries a short conduct note, and the detailed rules reach the
agent where they apply. Every claimed task's instruction pack carries the reporting
protocol (the approach on claim, milestones, one report per gate run, each PR or
artifact, a verdict before completing) and asks the agent to file friction it meets
with idea.create. The specstrand:base skill teaches the agent to
learn capabilities from the served help rather than the SpecStrand source, defines a
graph queue, and holds the rules for an agent that supervises others: delegate each
task to a worker that runs the full loop, and keep worker prompts minimal.
4. Make agents use it from the first message
The initialize instruction only surfaces after the agent's first tool call. To drive
from the very first message and across clients, paste a short rule into your project's AGENTS.md or CLAUDE.md:
## SpecStrand
This project is connected to SpecStrand over MCP. Route multi-step or
project-like work through it by default:
- Start with a graph: graph.list / graph.get first; graph.create when none
fits; then create plans into it (plan.create with graph) or graph.add them.
- Capture first: a concrete unit of work -> a plan + tasks (plan.create,
task.create); a rough thought -> idea.create.
- Drive the loop: project.work claims the next ready task; do it, then
task.report, task.complete (or task.fail), and call project.work again
until "no claimable task".
- Gates: a gate is a graph decision node that blocks its downstream plans
until a human answers it. A drain that pauses at a waiting gate means a
decision is pending; stop and say so.
- Exempt: general questions, quick lookups, and small one-offs.
Capture freely; confirm before starting an autonomous multi-task drain.Prefer a shell-driven agent? The spec CLI exposes the
same loop over REST; see the getting-started guide.
Some operations exist only in the CLI, such as editing a gate, moving a plan, linking
documents, reading skills, and codebase graphs. Archiving, reading a document, releasing
a task and removing a plan from a graph have MCP tools (archive, document.get, task.release, graph.remove) for
agents with no shell. The server lists the CLI-only operations, each with its exact
verb, as the MCP resource specstrand://cli. The list is generated from the
CLI help and the MCP tool list, so it stays current. When a tool call asks for one of
them, the error names the CLI verb. An agent with a shell runs that verb; an agent with no
shell gives you the exact command. It files an idea only when neither the CLI nor a tool
can do the job.