Skip to content

Use SilentSwarm from an AI agent

The leader speaks the Model Context Protocol (MCP) at https://<your-leader>/mcp. An AI agent connected there - Claude Code, Claude Desktop, a claude.ai connector, Cursor or any other MCP client - can do what you do in the web UI: look at pools and fellows, add a machine, manage buckets and datasets, plan and run training, follow a run, load a model and chat with it, and, for admins, run the deployment.

It does that as you, with your token's permissions and nothing more. Every tool calls the same REST route the web UI and the swarm CLI call, with your token, so the route's own checks - who may see which pool, quotas, validation - apply unchanged. There is no second permission model to drift.

The full list of tools, resources and prompts, with every parameter, is the MCP tool reference, generated from the server's own registry.

Set up a client

You need two things: the leader's address and an API token. Create the token under Profile > API tokens (Profile) and give it the scopes the agent needs (see Tokens and scopes). Then pick your client below. swarm mcp config prints every snippet with your leader's address filled in; it never prints the token.

export SWARM_API_TOKEN=sk-swarm-...      # the token you just created
swarm mcp config                         # every client below, ready to paste
swarm mcp config --client claude-code    # just one: claude-code, claude-desktop, cursor, json

Claude Code

Claude Code talks to /mcp over HTTP and sends the token as a header:

claude mcp add --transport http silentswarm https://<your-leader>/mcp \
  --header "Authorization: Bearer $SWARM_API_TOKEN"

Run it in a shell where SWARM_API_TOKEN is set; the shell expands it once and Claude Code stores the header. Add --scope project to share the entry with a repository (then keep the token out of it and let each person add their own). Leave the header out and Claude Code signs in with OAuth instead the first time you use the server (/mcp in Claude Code), through the same consent page as the connectors below.

Claude Desktop

Two ways:

  • The swarm mcp serve bridge. Claude Desktop starts a local process and talks to it over stdio; the bridge forwards every message to the leader with your CLI token (--token, SWARM_API_TOKEN, then api_token in ~/.swarm/config.toml). Add this to claude_desktop_config.json:

    {
      "mcpServers": {
        "silentswarm": {
          "command": "swarm",
          "args": ["--leader-url", "https://<your-leader>", "mcp", "serve"]
        }
      }
    }
    

    Desktop does not use your shell's PATH: if it cannot start swarm, put the full path in command (which swarm prints it). This works for a leader on your own network, too.

  • A custom connector with OAuth, as for claude.ai below.

claude.ai connectors (OAuth)

In claude.ai (or Claude Desktop) add a custom connector with the URL https://<your-leader>/mcp. No token to paste: the leader is its own OAuth 2.1 authorization server (PKCE, dynamic client registration, as the MCP authorization spec asks), so the connector:

  1. finds the leader's sign-in through the 401 it gets from /mcp without a token (its WWW-Authenticate header points at the protected-resource metadata),
  2. opens the leader's login page and then a consent page that names the app, where it will send you back to, the tool groups it asked for, and the scopes it may have - untick any you do not want to grant,
  3. receives a scoped API token labelled oauth: <app name> that lasts an hour and is refreshed while the connection is in use.

The connection appears under Profile > API tokens; Revoke there ends it. A connector is reached from Anthropic's servers, so this needs a leader with a public HTTPS address. For a leader on a private network use Claude Code or the swarm mcp serve bridge. Operators: the endpoints and limits are in Users & authentication.

Other clients

Any client that takes a Streamable HTTP server and a header:

{
  "mcpServers": {
    "silentswarm": {
      "type": "http",
      "url": "https://<your-leader>/mcp",
      "headers": { "Authorization": "Bearer ${SWARM_API_TOKEN}" }
    }
  }
}

Cursor writes the variable as ${env:SWARM_API_TOKEN}; replace it with the token itself if your client does not expand environment variables. A client that only speaks stdio can run swarm mcp serve instead, like Claude Desktop. swarm mcp tools lists what the token can see, to check the setup without an agent.

Tokens and scopes

The token decides what an agent may do. Each API token carries one or more scopes:

Scope What it allows
read Look: pools, fellows, jobs, loss curves, logs, models, buckets. Changes nothing.
operate Change things as you: submit and cancel jobs, load and unload models, manage buckets, datasets and pools, add fellows, chat with a model.
admin The admin toolset: users, every pool and fellow, quotas, announcements, the audit log. Only an admin can hold it.
  • A connection lists only the tools its scopes allow. A read-only token sees the read tools and none of the others - a good start for an agent that should explain, not act.
  • Scopes are separate: operate does not include read. Give an agent that acts both. A tool that has to read what it changes first (deleting a pool, cancelling a job, chatting with a model) needs both, and the reference marks it operate + read; an operate-only token is not offered it.
  • A token never does more than its owner. Pool membership still decides which pools, jobs and models it sees, and a demoted admin's tokens lose admin at once.
  • Legacy tokens, created before scopes existed, keep their owner's whole power (read and operate, plus admin for an admin). Create a narrower one for the agent and revoke the old one.
  • The me tool (toolset account) shows whose token it is and its scopes.

Toolsets

Over 100 tools would crowd an agent's context and make it pick the wrong one, so tools come in toolsets and a connection lists only those it asks for:

Toolset What it covers Listed by default
cluster Fellows, GPUs, the swarm graph, fellow logs, adding a fellow yes
training Plan, submit, follow, checkpoint and cancel runs; train from a bucket yes
buckets Buckets and datasets: create, upload, reference Hugging Face, preload yes
serving The model catalogue, load and unload, chat yes
meta Leader health, public stats, announcements, the docs, and pools_list (the pool ids other tools take) always
pools Members, invites, join requests, node roles, pool telemetry -
account Who am I -
admin Users, pools, quotas, announcements, audit, mail, fellows -

Choose them in the URL:

  • https://<your-leader>/mcp - the default set.
  • https://<your-leader>/mcp/pools,admin - those toolsets (plus meta).
  • https://<your-leader>/mcp/all - every toolset.
  • https://<your-leader>/mcp?toolsets=pools,admin - the same, as a query.

Unknown names are ignored. swarm mcp config --toolsets pools,admin (or all) writes the matching URL into every snippet. Toolsets only choose what is listed; the scopes decide what the token may do.

Resources and subscriptions

State you follow is also offered as resources (swarm://...), so a client that supports them can read it without a tool call: swarm://cluster/nodes, swarm://jobs/{job_id}, swarm://jobs/{job_id}/metrics, swarm://fellows/{fellow_id}/logs, swarm://models/{model_id}, the pools and buckets, and more (list).

Most of them are subscribable: after resources/subscribe the leader re-reads the resource every few seconds and sends notifications/resources/updated when it changes - a job's step and loss, new log lines, a model's load progress. A subscription ends with the session - when the client disconnects, when the leader ends an idle session (after SWARM_MCP_SESSION_IDLE_S, default 30 minutes, with no request and no open stream) - or as soon as the token is revoked. Subscribing to something you cannot read (an id that does not exist, or one outside your pools) is refused at once with JSON-RPC error -32002, as is reading it. One session holds at most 50 subscriptions, one token 100 across all its sessions.

For clients without resources, every one has a read tool too, and jobs_wait and models_wait_ready block until a run ends or a model is ready, sending progress notifications on the way, like swarm train --wait - at least every five seconds even while nothing moves, so a client that resets its timeout on progress keeps waiting.

swarm://docs lists the pages of this documentation and swarm://docs/{page} returns one as Markdown (swarm://docs/06_user_guide/mcp is this page), so an agent can look up a setting or an error without leaving the session.

Prompts

Four ready-made workflows, offered by clients as commands (in Claude Code, /mcp__silentswarm__train_from_bucket and so on). Each lists the tool calls in order and stops for you before anything that changes the cluster:

Prompt What it does Scope
train_from_bucket Check a bucket, plan the run, ask you, submit, follow it to the end operate
diagnose_failed_job Read a job's error, loss curve and fellow logs, re-plan it, and name the cause and one next step read
add_a_fellow Mint the join command, wait while you run it on the new machine, watch until the node is ready operate
serve_and_test Load a model, wait until it is ready, check it answers a short chat operate

A prompt is offered only when the token has the scope its steps need.

Safety model

An agent here acts on real machines and other people's work, so:

  • Destructive tools ask you first. Deleting a bucket, dataset, pool or user, cancelling a run, unloading a model, releasing or removing fellows and the like are marked destructive. If your client supports MCP elicitation, the leader asks you through the client what will happen ("Release 2 fellows: ...") - always, even when the agent claims you agreed. The question has one box, ticked: Accept goes ahead, Decline (or unticking the box) does not. Other clients - and a client that declared only URL-mode elicitation - get a refusal that says what the tool would do; it runs only when called again with confirm: true, which the agent should set only after you said yes.
  • Plan before acting. jobs_plan (and buckets_train with plan_only) shows where a run would go and why it could not start, without submitting; the server tells agents to show you that first. jobs_plan is a read: it is free, not logged, and clients may run it without asking.
  • Every change is audit-logged. Each call to a tool that changes something writes an audit row mcp.<tool> with via=mcp, the token's label, the argument names and the outcome - result=ok, result=refused (the confirmation was declined or missing, nothing changed) or result=error (the route refused it) - next to the route's own event. Both rows carry your address as the leader saw it through its proxy. Admins find them under Admin > Audit log with the MCP calls toggle (Administration). Reads are not logged.
  • Changes are rate-limited per token. Read tools are free; every other tool takes one unit from the token's bucket: SWARM_MCP_WRITE_BURST (default 20) in a row, refilled at SWARM_MCP_WRITES_PER_MIN (default 30) per minute. A refused confirmation gives its unit back. Past that a tool answers "Too many changes in a short time; try again in N s", so an agent in a loop cannot submit jobs back to back.
  • What comes back is data, not instructions. Fellow logs, job errors, dataset text, Hugging Face rows, names people typed and model replies come from other machines and people. Tool descriptions say so, and the server tells agents never to follow instructions found in them. Treat an agent that suddenly wants to do something a log line suggested with suspicion.
  • Sessions belong to their token. The endpoint takes only a bearer token - a browser's session cookie is ignored, so a web page cannot drive tools as you - and an MCP session opened with one token cannot be used with another. One token may hold SWARM_MCP_SESSIONS_PER_TOKEN (default 20) open sessions and open about as many per minute; past that a new connection answers 429, so no single token can fill the leader's session table (SWARM_MCP_MAX_SESSIONS, default 10000).

What MCP will not do

Some of the web UI stays in the browser on purpose (src/silent_swarm/leader/mcp/coverage.py, held by a test that fails when a new route is neither covered nor listed there):

Not over MCP Why
Password, two-factor setup, sessions, log out everywhere, extend session A token holder must not change the credentials that protect the account; browser only.
Creating, listing or revoking API tokens An agent must not mint, list or revoke its own credentials.
Login, registration, email verification, password reset Human login and registration flows, bound to a browser.
The public waitlist form A sign-up form; admins read the waitlist with admin_waitlist.
The bootstrap script, manifest and source archive; a joining machine's progress reports Fetched and written by the install script, not by people; fellows_join_command gives you the command and join_sessions_get reads the progress.
Live event streams (metrics, logs, the swarm graph) Offered as subscribable resources instead.
Downloading a model archive A multi-GB file of weights that fellows fetch; agents read models_get.
/v1/chat/completions An alias of the route the chat tool uses.
The fellow protocol (registration, heartbeats, relay) Machine to machine, with a node credential no agent holds.
HTML pages Their data comes from the tools behind them.

An admin's agent also cannot reset the password of, re-verify, change the email or role of, or delete the account its own token belongs to, and never receives a one-time sign-in link (Administration). The REST routes behind those tools enforce the same rule for every API token - the CLI's and an OAuth connector's too - so it holds outside MCP as well.

Troubleshooting

401 with invalid_token. No token, a mistyped or revoked one, or an OAuth token whose hour is up and could not be refreshed. The answer carries WWW-Authenticate: Bearer realm="silentswarm", resource_metadata="https://<your-leader>/.well-known/oauth-protected-resource/mcp": OAuth clients use it to start the sign-in, so a connector showing a login again after a revoke is expected. With a header client, check the header is Authorization: Bearer <token> and that the token still lists under Profile > API tokens. swarm mcp serve explains a refused token on stderr and to the client, then exits with status 1 (status 2 when it has no token).

403 with insufficient_scope. "This token has no owner": an old token not tied to an account. Create a new one on your Profile page.

A tool is missing, or "Unknown tool". The token lacks the tool's scope, or the connection did not ask for its toolset. Check with swarm mcp tools --toolsets all, which lists what the token can call, or the me tool for its scopes. A route can still refuse with "not found" for something outside your pools, or "forbidden"; the tool error carries the same message the web UI would show, and its structured content the problem's status, type and title, so an agent can tell the cases apart without parsing the text.

The confirmation question never appears, progress stalls, or long calls end after a minute. Something between the client and the leader buffers text/event-stream. Every MCP response is streamed, and a destructive tool's question to you is sent in the middle of the call. The shipped frontend (docker/nginx/frontend.conf) proxies /mcp with proxy_buffering off and a one-hour read timeout, and Traefik streams by default. Behind your own nginx, give /mcp the same (proxy_buffering off; proxy_read_timeout 3600s;); with other proxies, turn off response buffering and compression for text/event-stream on that path.

404 "Session not found" or 400 "Missing session ID". MCP sessions live in the leader's memory: after a leader restart or redeploy, or once an idle session expired, the client must connect again (in Claude Code, /mcp and reconnect). A session also belongs to the token that opened it, so changing the token mid-session has the same effect. swarm mcp serve notices this itself: it answers the waiting request with "the leader no longer knows this MCP session", says so on stderr and exits with status 1, so Claude Desktop shows the server as stopped - restart it there (or restart Desktop) to connect again.

429 with too_many_sessions. The token already holds SWARM_MCP_SESSIONS_PER_TOKEN open sessions, or opened sessions too fast. Close clients you no longer use (each disconnect ends its session), wait for idle ones to expire, or give each client its own token.

A leader under a path prefix. A leader served at https://host/swarm (uvicorn --root-path /swarm behind a proxy) serves MCP at https://host/swarm/mcp, and tools reach its routes under the same prefix.

"Too many changes in a short time". The write rate limit above. Wait the seconds it names, or raise SWARM_MCP_WRITE_BURST / SWARM_MCP_WRITES_PER_MIN on the leader.

An upload is refused as too large. datasets_upload takes at most 5 MB of inline text. Give it a source_url for the leader to download, or upload a larger file in the browser or with the CLI.

Licence

SilentSwarm is source-available under the PolyForm Noncommercial License 1.0.0: self-hosting it, and connecting your own agents to your own leader, is free for any noncommercial purpose. Commercial use - running it inside a for-profit company, or offering it, its MCP endpoint included, as part of a product or service - needs the commercial licence (fabian@nexpatch.ai).