Agent Swarm

Self-hosted multi-agent orchestration API whose MCP endpoint hands tasks, memory and schedules to agents

Official · Desplega Labs TypeScript Local · Streamable HTTP AI and MLKnowledge and memoryCommunication

72 popularity score ★ 1.0k ↓ 3.2k/wk

Connect your client

Local (once it is running)

Add in one click

Opens the app, which asks before it adds the server.

Or add it by command or config

Claude CodeTerminal
claude mcp add --transport http agent-swarm http://localhost:3013/mcp
Cursor~/.cursor/mcp.json
{
  "mcpServers": {
    "agent-swarm": {
      "url": "http://localhost:3013/mcp"
    }
  }
}
VS Code.vscode/mcp.json
{
  "servers": {
    "agent-swarm": {
      "type": "http",
      "url": "http://localhost:3013/mcp"
    }
  }
}
Codex~/.codex/config.toml
[mcp_servers.agent-swarm]
url = "http://localhost:3013/mcp"
Gemini CLITerminal
gemini mcp add --scope user --transport http agent-swarm http://localhost:3013/mcp

Settings 4

AGENT_SWARM_API_KEY secret Required: API key clients must send as a Bearer token; can also be given with --key (legacy name API_KEY).
PORT Optional: Port for the API and MCP server, also set with --port. Default 3013.
DATABASE_PATH Optional: SQLite file path, also set with --db. Default ./agent-swarm-db.sqlite.
CAPABILITIES Optional: Comma list of tool groups to expose; replaces the default list of 16 groups.

What it does

Agent Swarm, from Desplega Labs, is a self-hosted system where a lead agent breaks work into tasks and hands them to worker agents like Claude Code or Codex. Each worker normally runs in its own Docker container. The npm package's `agent-swarm api` command starts one HTTP process that serves the REST API and the MCP endpoint together, keeping state in a SQLite file (./agent-swarm-db.sqlite unless you pass --db).

Agents use the MCP endpoint to take part in the swarm. They join, poll for work, claim it and report back, and they can pass tasks to one another. Memories can be stored and searched. Schedules can be cron or one-off, and workflows can pause until a person approves a step. Skills, per-agent MCP servers, key-value state, pages and small apps are handled through tools as well. Once the integrations are set up, agents can also read and post in Slack or send WhatsApp messages.

The tool count is large. MCP.md at the current release lists 170 tools in 22 groups, and the CAPABILITIES setting picks which groups an agent sees. Sixteen are on by default. The six others stay hidden until you name them: prompt-templates, agentmail, kapso, chat-sdk, swarm-x and messaging. Note that setting CAPABILITIES replaces the default list instead of adding to it. It only hides MCP tools, too, because most REST routes are not gated.

The quickest way in is now the one-line installer from agent-swarm.dev. It runs onboarding with the full preset, a lead plus ten workers in Docker Compose, and unless you pass --no-tunnel it puts the API on a public localtunnel address.

What it needs

RuntimeNode.jsDocker
Runs onmacOS, Windows, Linux
Anthropic, OpenAI or another harness providerPaid planWorkers need a credential for the chosen harness, such as an Anthropic or OpenAI key. The API process alone does not.
Also
  • Docker Compose v2 (or Podman) for the full stack with workers
  • Bun for the onboard and controller commands and the installer, which installs it when missing
  • About 4 vCPU, 8 GB RAM and 40 GB free disk for the reference deployment

Start the server with `npx @desplega.ai/agent-swarm api`, giving an API key you choose with --key or AGENT_SWARM_API_KEY. Clients then connect to http://localhost:3013/mcp and send that key as a Bearer token plus the ID of an agent registered on the swarm in X-Agent-ID. For the whole system, `curl -fsSL https://agent-swarm.dev/install.sh | bash` checks for Docker and Compose v2, adds Bun if it is missing and starts the full preset. Add `bash -s -- --no-tunnel` to keep the API off the public internet.

Limits

  • Limit Speaks MCP only over streamable HTTP at /mcp, with no stdio mode, so the API process must already be running when a client connects
  • Limit Its MCP registry entries give 3000 as the default port, but the CLI listens on 3013 unless PORT or --port says otherwise
  • Limit The installer opens a public tunnel by default; pass --no-tunnel or set AGENT_SWARM_TUNNEL=0 to keep the API local
  • Limit The tunnel URL is random and changes whenever the tunnel restarts, including after a reboot
  • Read only db-query accepts read-only SQL only and rejects queries on credential tables
  • Not covered script-run supports only fsMode "none", so scripts get no filesystem access
  • Limit Several client subcommands fall back to the API key 123123 when neither --api-key nor AGENT_SWARM_API_KEY is set
  • Early release The README warns that the repository changes every day
  • Limit Database retention runs as a dry run by default

It speaks MCP only over streamable HTTP at /mcp; there is no stdio mode, so the API process must be started and kept running before a client connects. Its MCP registry entry gives 3000 as the default port, but the CLI code at v1.173.0 defaults to 3013 (or PORT). The db-query tool is read-only and refuses queries on credential tables. script-run supports only fsMode "none" in this version. The README warns the repository changes daily, and the docs note that database retention defaults to dry-run.

Who it suits

Suits teams that want to run their own fleet of coding agents with shared tasks, memory and schedules on their own machines or cluster, and that are ready to operate a Docker or Kubernetes stack. It is a coordination layer for agents. Someone who only wants one assistant to remember notes or post to Slack will find a dedicated server smaller and simpler to set up. Because the tools can create tasks, change config, post messages and run inline TypeScript, it fits setups where every connecting agent is trusted. Anyone using the installer on a machine that should stay private should pass --no-tunnel.

Tools 36 of 170

9 only read, 24 change things, 3 can delete or overwrite. A ? marks an optional parameter.

join-swarm changes
Registers the calling agent in the swarm, with optional profile detailsrequestedId?: stringlead?: booleanname: stringdescription?: stringrole?: stringcapabilities?: array
poll-task
Checks for a new or offered task for the calling agent
get-swarm
Lists the agents in the swarma?: stringincludeFull?: boolean
get-tasks
Lists tasks with filters, sorted by priority and recencystatus?: enummineOnly?: booleanunassigned?: booleanofferedToMe?: booleanreadyOnly?: booleantaskType?: stringtags?: arraysearch?: stringscheduleId?: stringworkflowRunId?: stringkey?: anykeyPrefix?: anyincludeHeartbeat?: booleanlimit?: numberincludeFull?: boolean
send-task changes
Assigns a task to an agent, adds it to the pool, or offers itagentId?: stringroutingReason?: enumroutingNote?: stringtask: stringkey?: anyofferMode?: booleantaskType?: stringtags?: arrayrequiredCapabilities?: arrayleadOnly?: booleanpriority?: numberdependsOn?: arrayparentTaskId?: stringdir?: stringvcsRepo?: stringmodel?: stringmodelTier?: enumallowCustomModel?: booleaneffort?: enumprofile?: string
get-task-details
Shows a task's output, failure reason and logtaskId: string
store-progress changes
Records progress on a task and can mark it done or failedtaskId?: stringprogress?: stringstatus?: enumoutput?: stringfailureReason?: stringattachments?: arraycitations?: arraylearning?: anypersistMemory?: booleanforce?: boolean
cancel-task changes
Cancels a pending or running task (lead or creator only)taskId: stringreason?: string
steer-task changes
Sends a message to a task that is already runningtaskId: stringmessage: stringmode?: enumonUnsupported?: enum
task-action changes
Creates, claims, releases, accepts or rejects pool tasksaction: enumtask?: stringkey?: anytaskType?: stringtags?: arraypriority?: numberdependsOn?: arraytaskId?: stringreason?: stringdir?: stringmodel?: stringmodelTier?: enumallowCustomModel?: booleaneffort?: enumprofile?: stringrequiredCapabilities?: arrayleadOnly?: boolean
db-query
Runs a read-only SQL query on the swarm's SQLite databasesql?: stringquery?: stringparams?: array
get-oauth-access-token
Returns a current OAuth access token for a connected trackerprovider?: stringauthorizationId?: stringminValiditySeconds?: number
manage-user deletes
Creates, edits, deletes or lists user profilesaction: enumuserId?: stringname?: stringemail?: stringrole?: stringnotes?: stringidentities?: arrayemailAliases?: arraypreferredChannel?: stringtimezone?: stringdailyBudgetUsd?: numberstatus?: enummetadata?: objectcomms?: object
credential-bindings changes
Lead-only management of credential bindings for scriptsaction: enumid?: stringconfigKey?: stringallowedHosts?: arrayheaderTemplate?: stringqueryTemplate?: stringscope?: enumscopeId?: anyauthKind?: enumoauthAuthorizationId?: stringpresetId?: stringprovider?: stringlabel?: stringclientId?: stringclientSecret?: stringauthorizeUrl?: stringtokenUrl?: stringuserinfoUrl?: stringrevocationUrl?: stringscopes?: array
script-run changes
Runs a saved script or inline TypeScriptname?: anysource?: stringargs?: anyintent?: stringscope?: anyfsMode?: anyexecutor?: anyidempotencyKey?: string
script-upsert changes
Saves or updates a reusable scriptname: anysource: stringdescription?: stringintent?: stringscope?: anyfsMode?: anyexecutor?: any
extension-install changes
Installs an extension as an inactive drafttemplate?: stringmanifest?: anyfiles?: objectpriority?: numberconfig?: object
extension-enable changes
Turns on an installed extensionid: string
update-profile changes
Edits an agent's name, role and capabilitiesagentId?: stringname?: stringdescription?: stringrole?: stringcapabilities?: arrayclaudeMd?: stringsoulMd?: stringidentityMd?: stringsetupScript?: stringtoolsMd?: stringheartbeatMd?: stringavatar?: anyslackIcon?: any
context-history
Shows version history of an agent's context filesagentId?: stringfield?: enumlimit?: number
defer-task changes
Completes a task now and books a later wake-uptaskId: stringdelayMs?: numberrunAt?: stringwakeOn?: objectsummary: stringoutput?: stringnote: stringchecks?: array
memory-search
Searches stored memories in natural languagequery: stringintent?: stringscope?: enumlimit?: numbersource?: enumkeyPrefix?: string
memory-store changes
Saves a learning as a searchable memorycontent: stringname?: stringscope?: enumtags?: anytaskId?: stringintent?: stringkey?: string
memory-delete deletes
Deletes a memory by ID (swarm-wide ones by the lead only)memoryId: string
inject-learning changes
Lets the lead push a learning into a worker's memoryagentId: stringlearning: stringcategory: enum
request-human-input changes
Opens an approval or question request for a persontitle: stringquestions: arraytimeoutSeconds?: numberdetached?: boolean
create_page changes
Stores an HTML or JSON page and returns links to itkey?: anytitle: stringslug?: stringbody: stringcontentType: enumauthMode?: enumpassword?: stringdescription?: stringneedsCredentials?: arraytheme?: stringthemeTokens?: anydesignVersion?: number
app-upsert changes
Creates or updates a schema-backed appname: stringdescription?: stringdefinition: anyappId?: stringmigration?: anyforceElementBreak?: any
slack-read
Reads messages from a Slack thread or channelinboxMessageId?: stringtaskId?: stringchannelId?: stringthreadTs?: stringlimit?: numberincludeFiles?: boolean
slack-post changes
Posts a message to a Slack channel or threadchannelId: stringmessage: stringblocks?: arraythreadTs?: string
slack-upload-file changes
Uploads a file to SlackinboxMessageId?: stringtaskId?: stringchannelId?: stringthreadTs?: stringfilePath?: stringcontent?: stringfilename?: stringinitialComment?: string
slack-delete deletes
Deletes a Slack message the bot itself posted (lead only)channelId: stringmessageTs: string
register-agentmail-inbox changes
Routes an AgentMail inbox's mail to the agent (off by default)action: enuminboxId?: stringinboxEmail?: string
chat-post changes
Lead-only post to a Telegram, Slack, Discord or Teams chat (off by default)adapter: anythreadId?: stringchannelId?: stringtext: stringattachments?: array
swarm_x changes
Calls an external command route such as Composio (off by default)target?: anymethod: anypath: stringbody?: anyquery?: objectheaders?: objectbaseUrl?: stringuseOrgKey?: booleanraw?: boolean
post-message changes
Posts to an internal channel between agents (off by default)channel?: stringcontent: stringreplyTo?: stringmentions?: array

Similar servers