Skip to main content
Glama

swarm-mcp

MCP server that lets multiple coding-agent sessions on the same machine discover each other and collaborate through a shared SQLite database.

Each session spawns its own swarm-mcp server process via stdio. They all share one SQLite file at ~/.swarm-mcp/swarm.db by default. No daemon needed.

GitHub


Quick start

New here? Read docs/quickstart.md first. It walks you from zero to two Claude Code sessions seeing each other in about five minutes, with the expected output at each step.

The rest of this section is a condensed reference for non-Claude hosts. For a first-run walkthrough on a local clone, see docs/getting-started.md. For the broader modular architecture this repo is growing toward, read docs/control-plane.md. Backend and consumer config lives in docs/backend-configuration.md.

Install dependencies:

cd /path/to/swarm-mcp
bun install

Add the server to your coding agent using that host's MCP config format. Bun is the simplest dev/runtime path because the examples use bun run, but the built dist/*.js entrypoints also run under Node 20+ with better-sqlite3.

Codex (~/.codex/config.toml)

[mcp_servers.swarm]
command = "bun"
args = ["run", "/path/to/swarm-mcp/src/index.ts"]
cwd = "/path/to/swarm-mcp"

opencode (~/.config/opencode/opencode.json)

{
  "mcp": {
    "swarm": {
      "type": "local",
      "command": ["bun", "run", "/path/to/swarm-mcp/src/index.ts"],
      "enabled": true
    }
  }
}

Claude Code (~/.claude.json)

{
  "mcpServers": {
    "swarm": {
      "command": "bun",
      "args": ["run", "/path/to/swarm-mcp/src/index.ts"]
    }
  }
}

Tool names are usually namespaced by the client using the server name. Depending on the host you may see swarm_register, mcp__swarm__register, or other variants. Use whichever form your host exposes.

Call the swarm register tool first to join the swarm.

Install the packaged skill

Mounting the MCP server makes the swarm tools available, but agents still benefit from the bundled SKILL.md workflow. If your host supports installable skills (Claude Code, OpenCode, Codex with skills, etc.), install skills/swarm-mcp for coordination. Symlink is recommended over copying so updates from git pull propagate automatically:

# In your consumer project root
mkdir -p .agents/skills .claude/skills
ln -s /absolute/path/to/swarm-mcp/skills/swarm-mcp .agents/skills/swarm-mcp
ln -s ../../.agents/skills/swarm-mcp .claude/skills/swarm-mcp

Or install globally for all projects:

mkdir -p ~/.claude/skills
ln -s /absolute/path/to/swarm-mcp/skills/swarm-mcp ~/.claude/skills/swarm-mcp

Then invoke /swarm-mcp planner, /swarm-mcp implementer, etc., when starting role-specialized sessions. Full per-host install paths and copy-based alternatives live in docs/install-skill.md.

Further reading


Related MCP server: junto-memory

MCP server vs swarm-server

The TypeScript swarm-mcp process is the stdio MCP server used by coding-agent hosts. It is enough for local multi-agent coordination through tools, resources, prompts, and the shared SQLite database. Its core job is the coordination bus: instance identity, tasks, messages, locks, KV, and best-effort wakeups.

Spawner backends are adapters around that bus. The default adapter is herdr; swarm-ui remains available as a fallback/control-surface adapter. New terminal managers should plug in as spawner/workspace backends rather than changing the task/message/lock contract.

The Rust apps/swarm-server daemon is a separate desktop/mobile control plane. It serves swarm-ui over a local Unix socket, exposes HTTPS/WSS on port 5444 for paired clients, manages PTYs, and reads the same swarm.db. It is not required for the basic MCP setup above. The current apps/swarm-ios workstream is Herdr-bridge first so Herdr remains the universal PTY owner; swarm-server remains useful reference material and the daemon for swarm-ui. See docs/swarm-server.md.

Control-plane overview

Control-plane and backend configuration overview

Source: docs/diagrams/backend-configuration.mmd. Backend selection and workspace identity conventions are centralized in docs/backend-configuration.md.


How it works

All sessions read and write to ~/.swarm-mcp/swarm.db by default using WAL mode, auto-vacuum, and a 3s busy timeout. Bun uses bun:sqlite; Node uses better-sqlite3.

Set SWARM_DB_PATH before launching the server if you want a different database location. Work/personal identity-separated setups should use separate paths, for example ~/.swarm-mcp-work/swarm.db and ~/.swarm-mcp-personal/swarm.db; see docs/identity-boundaries.md.

When you call register, the server starts a 10s heartbeat and a 5s notification poller.

Registration fields

The register tool accepts these parameters. Only directory is required.

Field

Required

Description

directory

Yes

The live working directory for the current session.

scope

No

Shared swarm boundary. Sessions in the same scope can see each other; different scopes are different swarms. Defaults to the detected git root, or to directory when no git root exists. Use a new scope only for a separate swarm; do not split frontend/backend inside one repo with scope. Use team: label tokens for that.

file_root

No

Canonical base path for resolving relative file paths in lock_file and task files. Useful when disposable worktrees should share one logical file tree.

label

No

Free-form identity text. Recommended convention: machine-readable space-separated tokens like identity:work provider:codex-cli role:planner. The identity: token should match the launcher/config root when using identity separation. The role: token is optional; if missing, the session is treated as a generalist.

Task features

Tasks support several features for building autonomous DAG-based workflows:

Feature

Description

priority

Integer (default 0). Higher = more urgent. list_tasks returns tasks sorted by priority descending. Implementers can use claim_next_task to atomically claim the highest-priority compatible task.

depends_on

Array of task IDs. A task with unmet dependencies starts as blocked and auto-transitions to open when all deps reach done. If any dependency fails, downstream tasks are auto-cancelled.

idempotency_key

Unique string. If a task with this key already exists, request_task returns the existing task instead of creating a duplicate. Essential for crash-safe plan retries.

parent_task_id

Optional parent task ID for tree-structured work tracking.

review_of_task_id

Optional task ID that a review task is reviewing. Supports $N references inside request_task_batch.

fixes_task_id

Optional task ID that a fix task addresses. Supports $N references inside request_task_batch.

progress_summary / progress_updated_at

First-class progress fields maintained by report_progress so peers can inspect long-running work without interrupting.

blocked_reason / expected_next_update_at

Optional progress metadata for work that is blocked or needs a follow-up heartbeat by a specific Unix timestamp.

approval_required

If true, task starts in approval_required status and must be approved via approve_task before work begins. Use this for true approval gates, not routine code review.

Task statuses: open, claimed, in_progress, done, failed, cancelled, blocked, approval_required.

Session resets and prompt compaction

If a host compacts context, starts a fresh window, or loses the previous bootstrap, rejoin the swarm the same way:

  1. Call register again.

  2. Rehydrate with bootstrap.

  3. For planners, also check kv_get("owner/planner") and kv_get("plan/latest").

The durable coordination state lives in the shared database, not in repeated per-tool prompt text.


Auto-cleanup

Data

TTL

Stale marker (no heartbeat)

30 seconds

Offline instance reclaim

60 seconds

Messages

1 hour

Completed/failed/cancelled tasks

24 hours

Events

24 hours

Orphaned progress/ + plan/<instance-id> KV

1 hour

When a session reaches the offline reclaim window, claimed or in-progress tasks are released back to open and that session's file locks are removed.

File locks stay exclusive and are cleared when the owning instance is reclaimed offline, deregisters, or completes the owning task.

Run swarm-mcp cleanup --dry-run --json to inspect what the janitor would remove without mutating the shared database.


Tools

Instance registry

Tool

Description

register

Join the swarm. Starts heartbeat + notification poller. See Registration fields.

deregister

Leave the swarm gracefully. Releases tasks and locks.

bootstrap

Yield-checkpoint read for current instance, peers, unread messages, tasks, and configured work tracker metadata.

swarm_status

Compact coordination summary: peers, unread messages, assigned/claimable tasks, locks, warnings, planner ownership, and suggested next action.

list_instances

List all live instances.

remove_instance

Forcefully remove another instance. Releases its tasks and locks.

whoami

Get this instance's swarm ID.

Messaging

Tool

Description

send_message

Send a direct message to a specific instance by ID.

prompt_peer

Send a durable swarm message, then best-effort wake the target's workspace handle. Busy handles are not interrupted unless forced.

peek_peer

Read recent or visible terminal text from a target's published workspace handle when the backend supports it.

resolve_workspace_handle

Map a transport-local workspace handle, such as a herdr pane, back to a swarm instance ID.

broadcast

Message all other instances in the swarm.

poll_messages

Read unread messages and mark them as read.

wait_for_activity

Block until new messages, task changes, KV changes, or instance changes arrive. Use only while actively monitoring a peer/dependency/review/lock, not as a generic idle loop.

Task delegation

Tool

Description

request_task

Post a task (types: review, implement, fix, test, research, other). Use review for routine code review handoff. Supports priority, depends_on, idempotency_key, parent_task_id, review_of_task_id, fixes_task_id, and approval_required.

request_task_batch

Create multiple tasks atomically in a single transaction. Supports $N references (1-indexed) for dependencies, parent links, review links, and fix links.

dispatch

Gateway-only: create/reuse a task, wake a matching live worker, or spawn through the configured spawner backend. Ordinary workers should not call this. Pass completion_wait_seconds only when the caller wants to wait for terminal task completion; default dispatch returns immediately after handoff/spawn.

claim_task

Start work on a specific task: assigns and transitions to in_progress in one call. Prevents double-claiming and blocks on unread messages until poll_messages (or explicit override). Also accepts tasks pre-assigned to you (status=claimed).

claim_next_task

Atomically pick and claim the highest-priority compatible task. Prefers tasks pre-assigned to you, then open unassigned tasks. Optional filters support task types and overlapping files.

report_progress

Update first-class progress fields on an in_progress task, including optional blocked_reason and expected_next_update_at. Use for multi-minute or blocked work.

complete_task

Complete a claimed task with structured JSON result fields: summary, files_changed, tests, and followups. Prefer this over update_task when you can provide structured handoff details.

update_task

Move a task to a terminal status (done, failed, cancelled). Auto-releases the actor's locks on the task's files. Use as a plain-string fallback or when structured completion is not useful.

approve_task

Approve a task in approval_required status. Transitions to open/claimed (or blocked if deps unmet).

get_task

Get full details of a task.

list_tasks

Filter tasks by status, assignee, or requester. Sorted by priority (highest first).

File locking

Tool

Description

get_file_lock

Read active lock state for a file without acquiring a lock.

lock_file

Acquire a file lock. Re-entrant for the same instance by default; pass exclusive=true to conflict on any existing lock (including same-instance) for one-shot mutexes like spawn coordination. Locks auto-release on terminal update_task or complete_task.

unlock_file

Release a file lock early (before the task as a whole completes).

Key-value store

Tool

Description

kv_get

Get a value by key.

kv_set

Set a key-value pair visible to all instances.

kv_append

Atomically append a JSON value to a KV array.

kv_delete

Delete a key.

kv_list

List keys, optionally filtered by prefix.


CLI

The same swarm-mcp binary exposes a non-MCP CLI that talks directly to ~/.swarm-mcp/swarm.db. Use it from contexts that cannot speak MCP: shell scripts, helper scripts an agent invokes (e.g. a test harness or CLI referee), cron jobs, CI, an ad-hoc terminal for inspection/debugging, or to control a running swarm-ui app.

Inside an MCP-enabled agent session, prefer the MCP tools for swarm coordination primitives (register, messages, tasks, locks, KV). The CLI is primarily for scripts, operator terminals, and the swarm-ui control surface.

Launcher-managed sessions may set SWARM_MCP_BIN to a real command such as bun run /path/to/swarm-mcp/src/cli.ts. Agents should use that prefix instead of assuming swarm-mcp is installed on PATH.

Setup helper:

swarm-mcp init --dir /path/to/project   # write .mcp.json and copy the packaged swarm-mcp skill
swarm-mcp init --no-skills              # write only the MCP config

init writes a project .mcp.json entry that runs npx -y swarm-mcp and, unless --no-skills is passed, copies skills/swarm-mcp into .claude/skills/. Manual host-specific MCP configs are still useful when your host does not read .mcp.json or you want to run from a local clone.

Inspection:

swarm-mcp inspect                    # unified dump of instances, tasks, kv, locks, recent messages
swarm-mcp inspect --scope /path      # pin to an explicit scope
swarm-mcp doctor                     # health report: binary, db, scope, skill/plugin install, env knobs (--json supported)
swarm-mcp messages --from <who>      # peek (does not mark read)
swarm-mcp cleanup --dry-run --json   # inspect cleanup without deleting
swarm-mcp kv list --prefix pixel:
swarm-mcp kv get pixel:turn

Writes (require identity — pass --as <uuid | prefix | unique-label-substring> or set SWARM_MCP_INSTANCE_ID; falls back to the sole live instance in scope):

swarm-mcp send --to <who> "message text"
swarm-mcp broadcast "status update"
swarm-mcp kv set  <key> <value>
swarm-mcp kv append <key> <json-value>
swarm-mcp kv del  <key>
swarm-mcp lock    <file> --note "why"
swarm-mcp unlock  <file>

Swarm UI control:

swarm-mcp ui spawn /path/to/repo --harness codex --role planner
swarm-mcp ui prompt --target role:planner "check the failing tests"
swarm-mcp ui move --target bound:<instance-id> --x 120 --y 80
swarm-mcp ui organize --kind grid
swarm-mcp ui list

These commands enqueue work for a running swarm-ui app to claim and execute. If no desktop app is running, commands remain pending until one starts.

Notes:

  • swarm-mcp ui spawn, ui prompt, ui move, and ui organize wait up to 5 seconds by default for the desktop app to claim + complete the command. Pass --wait 0 to return immediately after enqueue.

  • swarm-mcp dispatch returns immediately after task handoff/spawn by default. Pass --wait-for-completion <seconds> when a gateway wrapper should wait for the task to become done, failed, or cancelled; JSON output includes a completion object with the terminal task or timeout snapshot.

  • ui spawn --harness <name> accepts any launcher alias defined for the calling profile (see env/launchers.zsh.example), or the canonical names claude / codex / opencode / hermes directly. Omit --harness for a plain shell. Pick the alias whose profile matches the worker you intend to spawn — see identity boundaries.

  • dispatch normalizes spawned worker harnesses through the requester's identity. The requester's profile env declares SWARM_HARNESS_CLAUDE / _CODEX / _OPENCODE / _HERMES aliases; generic harness requests resolve to those aliases at spawn time.

  • Identified dispatch / ui spawn callers must be registered with a mode:gateway label. Trusted operator shells can bypass that accidental-use guard with SWARM_MCP_ALLOW_SPAWN=1.

  • Use swarm-mcp ui list and swarm-mcp ui get <id> to inspect queued, running, completed, or failed UI commands.

  • --target accepts bound:<instance-id>, instance:<instance-id>, pty:<pty-id>, or a bare instance / PTY reference. Bare instance refs resolve by full UUID, unique UUID prefix, or unique label substring in scope. Bare PTY refs resolve by full PTY id, unique PTY id prefix, or a unique substring of the PTY command.

  • ui move persists layout into the shared ui/layout KV entry for the target scope, so changes survive refreshes and can be driven from either the desktop UI or the CLI.

  • ui organize currently supports only --kind grid.

State, write, and UI subcommands accept --json for machine-readable output where shown by swarm-mcp help.

Canonical helper-script pattern — a harness the agent invokes to do validation + state update + handoff in one shot:

// harness.mjs — run as `node harness.mjs <partner-id>` by an agent
import { execFileSync } from "node:child_process";
const me = process.env.SWARM_MCP_INSTANCE_ID;
const scope = process.env.SWARM_MCP_SCOPE;
// ... validate and write artifacts ...
execFileSync("swarm-mcp", ["kv", "set", "turn", JSON.stringify(next), "--scope", scope, "--as", me]);
execFileSync("swarm-mcp", ["send", "--to", partner, "your turn", "--scope", scope, "--as", me]);

Security note: --as trusts the caller. The CLI will write as any live instance. Do not expose this binary to untrusted callers — the security model is the same as the underlying shared SQLite file.


Resources

The server exposes 4 MCP resources. swarm://inbox, swarm://tasks, and swarm://instances are refreshed by the background poller when the host supports resource update notifications.

URI

Description

swarm://inbox

Unread messages for this instance.

swarm://tasks

Tasks grouped by status, including open, claimed, in-progress, blocked, approval-required, done, failed, and cancelled.

swarm://instances

All active instances.

swarm://lock?file=...

Active lock state for a specific file.


Prompts

The server exposes MCP prompts. Some hosts surface them directly, while others only expose tools and resources.

Prompt

Purpose

setup (often shown as swarm:setup)

Guides the agent through registration: call register, then bootstrap, then summarize swarm ID, active sessions, role labels, open tasks, and coordination risks.

protocol (often shown as swarm:protocol)

Applies the recommended coordination workflow for the session: inspect lock state, use lock_file for deliberate critical sections, use messages/tasks for handoff, and inspect role: labels when choosing collaborators.


Coordination doctrine

For autonomous collaboration, agent doctrine lives in the bundled swarm-mcp skill rather than in copy-paste AGENTS.md snippets. The skill carries a short main SKILL.md plus on-demand references for each role:

On hosts that support installable skills, invoke /swarm-mcp planner, /swarm-mcp implementer, etc. On hosts without skill support, point your AGENTS.md (or equivalent) at skills/swarm-mcp/SKILL.md — it doubles as a readable doctrine file.

For runtime-agnostic routing doctrine that should always be loaded (not on-demand), see docs/agent-routing.md. Runtime plugins (integrations/hermes/, integrations/claude-code/) automate registration, locking, and the /swarm slash command on top of the skill.

If your host exposes MCP prompts, you can also use the built-in protocol prompt (often shown as swarm:protocol) to pull the workflow into a session on demand.

Skills

This repo ships the reusable consumer skill at skills/swarm-mcp. Repo-internal skills live under .agents/skills and are not packaged by default.

Use swarm-mcp when your host supports installable SKILL.md workflows and you want agents to learn the swarm protocol more reliably. Invoke role-specific workflows with /swarm-mcp planner, /swarm-mcp implementer, /swarm-mcp reviewer, or /swarm-mcp researcher. For install locations, see docs/install-skill.md.

Use skills in addition to minimal always-on instructions, not instead of them. A skill is a playbook; AGENTS.md is still the best place for ambient rules like "register early" and "check locks before editing."

The skills do not mount the MCP server for you. They assume the swarm MCP tools are already available in the session.


Troubleshooting

Sessions can't see each other. Check that both sessions registered with the same scope (or both defaulted to the same git root). Verify they are using the same database path (~/.swarm-mcp/swarm.db by default). Run list_instances in both sessions.

Tools aren't available after config change. Most hosts only load MCP server changes at startup. Restart the application or start a fresh session after editing the MCP config.

File locks are stuck. Stale locks are cleared automatically when the owning instance's heartbeat expires (30s). If you need to clear them manually, delete the row from the context table in the SQLite database, or restart the stuck session.

Inspecting the database directly. The database is a standard SQLite file at ~/.swarm-mcp/swarm.db. You can open it with any SQLite client (bun itself, sqlite3, DB Browser for SQLite, etc.) to inspect instances, tasks, messages, locks, and KV.

Wrong absolute path in server command. The bun run command needs an absolute path to src/index.ts. Relative paths may resolve differently depending on how the host launches the process.


Security

All sessions on the same machine share one SQLite file. Any process running as the same OS user can read and write to it. There is no authentication or authorization between sessions.

This is intentional for a local development tool. Do not use swarm-mcp across trust boundaries or expose the database to untrusted users.


License

MIT

A
license - permissive license
-
quality - not tested
F
maintenance

Maintenance

Maintainers
<1hResponse time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Volpestyle/swarm-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server