MCP: Swarm for agents
Everything you can do with swarm claim and swarm res an agent can do itself, through an MCP server that swarm setup registers with Claude Code. The point is that a session can take a task, get its own worktree, hold the dev server it starts, and hand everything back — without you typing a command.
How it's registered
swarm setup (or swarm install) adds a stdio server named swarm to mcpServers in ~/.claude/settings.json, pointing at the swarm-mcp binary from the same install as the CLI. swarm doctor reports "MCP server registered" when it is there; swarm uninstall removes it.
Claude Code starts the server with the session's working directory as its cwd, and every tool resolves the project from that directory — so tools act on the repo the agent is sitting in, including from inside a claimed worktree. The server starts the daemon if it is not running.
The owner name on claims and resources made through MCP defaults to agent; set SWARM_OWNER in the environment Claude Code runs in to change it, or pass owner explicitly.
Other agents
swarm install registers the same stdio server with Codex CLI (~/.codex/config.toml, [mcp_servers.swarm]) and Gemini CLI (~/.gemini/settings.json, mcpServers.swarm) when their config directories exist — never created, existing entries untouched, swarm uninstall removes exactly the Swarm entry. Those agents then get every swarm_* tool too: coordination is two-way for them, not just observation. swarm doctor says which CLIs got it.
Tools
All tools return a one-line summary followed by the JSON result. Refusals come back as tool errors starting with REFUSED:, with the same messages the CLI prints.
swarm_status
Inputs: none.
Returns the project's claims, live sessions (projectId, agent, state, last) and held resources. Call it before claiming to see what is taken.
swarm_claim
| Input | Type | Meaning |
|---|---|---|
task |
string | task id, e.g. login-form |
owner |
string, optional | defaults to SWARM_OWNER or agent |
Returns task, owner, worktree, branch (task/<task>) and expiresAt (45 minutes out). Fails closed if another owner holds the task. The agent must cd into worktree before editing.
swarm_renew
| Input | Type |
|---|---|
task |
string |
Extends the lease by 45 minutes from now. Use it during long work so the reaper does not reclaim the task.
swarm_release
| Input | Type | Meaning |
|---|---|---|
task |
string | |
force |
boolean, optional | discard uncommitted or unpushed work |
Removes the worktree and releases the claim. Refuses while the worktree is dirty or has unpushed commits unless force is true. Commit and push first.
swarm_reap
Inputs: none. Releases expired claims in this project, keeping (as orphaned) any whose worktree still holds work. Returns the list of { task, action }.
swarm_acquire_resource
| Input | Type | Meaning |
|---|---|---|
name |
string | singleton name, e.g. dev-server or port:3000 |
owner |
string, optional | defaults to SWARM_OWNER or agent |
pid |
number, optional | track this process; released automatically when it dies |
port |
number, optional | the port it occupies; protected from other agents' kills |
leaseMinutes |
number, optional | lease for holdings without a pid (default 60) |
Returns the resource record. Fails closed while another owner holds the name; the same owner refreshes.
swarm_release_resource
| Input | Type | Meaning |
|---|---|---|
name |
string | |
owner |
string, optional | defaults to SWARM_OWNER |
force |
boolean, optional | release even if someone else holds it |
swarm_resources
Inputs: none. Lists resources held in this project plus machine-global ones.
swarm_next_task
Inputs: { all?: boolean }. The first task in the repo's task source that is unclaimed, not done, and whose dependencies are done — what to pick up next. all: true lists every ready task. Fails with a hint when the repo has no [tasks] source.
swarm_gate_run
Inputs: { task: string, gates?: string[] }. Runs the gates the repo defines as commands (.swarm.toml [gates.<name>] cmd) inside the task's held worktree and records the verdicts — exit 0 is a pass, the rubric is the command, the evidence is the output tail (the last lines are returned on a fail). Defaults to the required gates that have a command. Use it instead of swarm_gate_record whenever a gate has a command: the record then says exactly what ran.
swarm_context
No inputs. What Swarm told you at session start, current as of now — what you hold (task, worktree, lease left), the latest handoff, gate status, held resources, rule modes — plus answers to your questions and questions still open. Call it after a long stretch, when resuming, or when unsure what you hold.
swarm_ask
Inputs: { question: string, options?: string[] }. Park a question only a human can answer. It appears on the dashboard (with a notification); the answer comes back as [swarm] context on a later tool call — or on stdin for a spawned run — and can be polled with swarm_inbox. Ask once, then carry on with what doesn't depend on it or stop and say you're waiting.
swarm_inbox
No inputs. Answers to your swarm_ask questions you haven't received yet.
swarm_dispatch
Inputs: { tasks?: string[], ready?: boolean, max?: number }. Hands ready tasks to autonomous runs — a claim + worktree + claude -p each, [dispatch] max_parallel at a time, the rest queued. The outcome of each run is derived from gates and PRs when it ends, never from the agent. For a lead session that wants to fan work out; follow progress with swarm_status or the Board.
swarm_pr_open
Inputs: { task: string, title?: string, body?: string, draft?: boolean }. Pushes the task's worktree branch and opens a PR / MR through the locally logged-in gh / glab, with the title and body drafted from the task, the latest handoff, the gates and the changed files (override either). Refuses uncommitted changes — commit first. The natural last step of a task, after swarm_handoff and the gates.
swarm_search
Inputs: { query: string, kind?: "handoff" | "incident" | "gate" | "session", all_projects?: boolean, limit?: number }. Full-text search over Swarm's memory for this repo — handoffs, incidents (commands the rules stopped, and why), gate runs, and what past sessions last said. Not the codebase. Words are AND-ed, the last is a prefix, quote a phrase, kind: / task: filter inline. Ask it before redoing work, or when a rule blocks you and you want to see how it was handled before.
An agent's flow
A session asked to "implement the login form" might do this:
swarm_status—login-formis free;paymentsis held by another session. (Orswarm_next_task, when the repo has a task source.)swarm_claim { task: "login-form" }— gets/Users/you/.swarm/worktrees/my-app/login-formon branchtask/login-form.cdinto the worktree. From here theshared_treerule cannot fire: no other session shares this checkout.- Start the dev server and
swarm_acquire_resource { name: "dev-server", port: 3000, pid: 48213 }. Nowlsof -ti:3000 | xargs killfrom any other session is asked about or denied. - Work. If it runs long,
swarm_renew { task: "login-form" }. - Commit, push, open a PR. It appears in the PRs view.
- Stop the server (the resource holding dies with the pid) and
swarm_release { task: "login-form" }.
Telling agents to do this is a matter of a few lines in your CLAUDE.md, for example: Before editing, call swarm_status and swarm_claim a task; work only inside the returned worktree; release when pushed. Swarm enforces the fail-closed parts regardless of whether the agent remembers the prose.
Seeing it on the dashboard
Claims and resources taken over MCP show on the Board exactly like ones taken from the CLI, owned by agent (or your SWARM_OWNER). Tool calls to swarm_* also appear in the session's tool histogram.
Source: docs/guide/08-mcp.md · v0.7.0.