Tandem's MCP server is a standard Model Context Protocol stdio server. It isn't Claude-specific: any MCP-aware client — editor, agent framework, or an orchestrator you wrote yourself — spawns it, calls canvas_connect with a canvas code, and starts working the same board a human is looking at in the browser. It also starts the Tandem server on your machine if nothing is running yet.
Several agents can connect to the same canvas at once. Every claim, completion and note is broadcast over a WebSocket to every browser and every other agent on that code.
Pick whichever fits your setup — the one-liner is the easiest and works for almost everyone.
Registers the MCP server with Claude Code at user scope (so it's available in every project), downloads this platform's Tandem binary into ~/.tandem/bin, starts it, and opens the board.
npx -y @jaximus/tandem-mcp setup
Binaries for macOS, Linux and Windows (amd64 + arm64) are on the releases page; the package is @jaximus/tandem-mcp on npm.
These snippets all use the npx form. Swap to tandem-mcp if you installed globally.
One command, user scope. setup runs exactly this for you; run it by hand if you'd rather not.
claude mcp add --scope user tandem -- npx -y @jaximus/tandem-mcp
Or, per project, in .mcp.json:
{
"mcpServers": {
"tandem": {
"command": "npx",
"args": ["-y", "@jaximus/tandem-mcp"]
}
}
}Open the board (tandem-mcp open), click New canvas, and copy its 8-character code — or run npx @jaximus/tandem-mcp init --write inside a repo to create one and pin it to that project. Then tell your agent the code. It calls canvas_connect once; from then on every tool operates on that canvas, with no id to pass around.
The same package is the launcher. Run with no arguments it is the MCP server; with a subcommand it manages the local Tandem process.
Eighteen intent-level tools, advertised by default. Every one operates on whatever canvas the session connected to — the session handle from canvas_connect carries the binding, so there is never an id to pass around.
The older ~40-tool CRUD surface (documents, notes, roadmap items, raw actions, agents, each with a batch variant) is still callable and is advertised behind TANDEM_FULL_TOOLS=1.
Because the board is the shared artifact, you can split work across sessions instead of stuffing everything into one prompt. Each session connects to the same canvas code; their claims and results land on the same board in real time, and you can watch (or steer) from the browser.
Connects as role: "planner", reads context_get, and turns a vague ask into an epic of named tickets with epic_propose. Nothing is claimable yet.
One click on the board approves the epic and every ticket under it. The planner, parked on queue_wait, wakes up with the ready queue.
The planner spawns a subagent per task and pastes it the task's handoff block. Each worker connects as an executor, task_claims its own ticket (the loser of a race takes another), reports task_progress, and task_completes with the commit.
Reject a ticket mid-batch and the reason lands on the proposer's next task_get. Amend the plan and in-flight sessions pick it up on their next pull. You don't stop the fleet to steer it.
The MCP server is intentionally thin: it holds a canvas token and forwards tool calls to the Tandem HTTP API on 127.0.0.1:7891. If you'd rather skip it and talk to the API directly from your runtime, the same endpoints live under /api/canvas/*. The MCP layer exists so MCP-aware clients get a zero-config experience; it isn't required.
Source lives in apps/mcp-gateway/ — small enough to fork.
# health + config of the local server
curl -s http://127.0.0.1:7891/healthz
curl -s http://127.0.0.1:7891/api/config # {"auth":"none","local":true,"version":"0.1.1"}