Skip to content

Let an agent run Thermite over MCP

Control has an MCP server, so an AI agent such as Claude Code can watch rigs and campaigns, start runs, steer them and check rigs for you. You give the agent a token of its own, whose role decides what it may do. The decisions that matter stay yours.

  • Control’s address, as the agent’s computer reaches it: http://127.0.0.1:8800 on the computer that runs the local stack, or your control’s address, such as https://control.example.com.
  • A token for the agent (step 1).
  • To start runs: a contract file, and the thermite command line where the agent works, to turn the contract into a command (step 3). Run npx thermite in the folder you built it in (see the command line). The command line has no option to name a Git access, so start campaigns on private repositories from the dashboard’s New campaign page.
TokenGive it toIt may
OperatorAn agent that runs campaigns for youRead everything; start, pause and resume runs, give them rules (redirect) and restart their lanes (reset_workers, Restart the lanes on the dashboard); export; run rig checks; send champions to other rigs; message a run’s agents and advisors, keep a message in force and remove one from force; change a run’s experiment queue and remove its rules; search Thermite’s knowledge base and let a campaign read another’s folder; read control’s own log, providers, MCP servers and how rigs were set up; add rigs on a cluster, set a cluster’s slots, stop, start and restart a cluster’s rigs and move them onto control’s images; give a rig’s agents a model; start and end RunPod test pods, which costs money
AgentAn agent that only coordinates runsRead; start, pause and resume runs, give them rules (redirect) and restart their lanes (reset_workers); export; run rig checks; send champions to other rigs. Not the experiment queue’s commands, the knowledge base, control’s log, providers, how rigs were set up, or RunPod. While you fully reset a rig, issue_command refuses it for that rig
ReaderAn agent that only watchesRead, including control’s log, providers and how rigs were set up (without each step’s details). Not the knowledge base

The reader’s token reads control’s log, providers and how rigs were set up, and the agent’s token doesn’t: they describe control itself, not the campaigns, and are for whoever runs control.

Give the agent the token with the least it needs: it acts with that token’s rights, and nothing more. Don’t give an agent the owner’s token. The owner’s token also approves and declines promotions over MCP, retires rigs, works on the whole REST API and signs in to the dashboard.

Some things no token can do over MCP: approving a goal the review panel passed, ending a campaign as not possible, changing a rig’s settings (apart from its agents’ model), accepting a rig’s key and wiping a rig. Adding, changing or deleting an MCP server is for the owner’s token alone. A model is never the last word on what counts as a result; see Why agents never judge. Approving and declining promotions is the owner’s alone.

On the local stack, an operator’s token is ready in .dev/secrets/control-operator-token, unless you replaced it with one of your own. For an agent’s or a reader’s token, see Make and change tokens.

The MCP server is at /mcp on control, for example http://127.0.0.1:8800/mcp or https://control.example.com/mcp. It uses MCP’s streamable HTTP transport, with the token in an Authorization: Bearer header.

Claude Code, with the server named thermite-control (any name works; Claude Code shows the tools under it). Run it in your Thermite folder, where the token file is:

Terminal window
claude mcp add --transport http thermite-control http://127.0.0.1:8800/mcp \
--header "Authorization: Bearer $(cat .dev/secrets/control-operator-token)"

Claude Code keeps the server and its token for the folder you run it in: that is its local scope, the default. Add --scope user to have the tools in every folder.

Any other MCP client: add an HTTP (streamable HTTP) server with the address above and the header Authorization: Bearer <token>. A client you write yourself must send Accept: application/json, text/event-stream with each request, or the server answers 406.

To check the connection, ask the agent to list Thermite’s rigs. It calls the list_rigs tool, and its answer names your rigs, such as local-1, with whether each is live and what it runs. A wrong token gets 401 and no tools.

The MCP tools reference lists every tool, its inputs, its answers and which tokens may call it. In short:

  • Look: list_rigs, get_run (a run’s champions and attempts, and in journal all its agents’ field notes and research notes, oldest first), run_queue (a run’s experiment queue, its rules and your messages), recent_events, leaderboard, rig_reports, list_commands and command_status.
  • Search past research, with the operator’s or the owner’s token: kb_folders lists the folders of Thermite’s knowledge base, one for each campaign, with what each holds and which campaigns read it; kb_search finds their items by words, such as experiments with their results, attempts with their verdicts, field notes, sources, claims, findings and reports.
  • Act: issue_command sends a signed command to a rig, of a kind the token allows (who may issue each kind), and propagate_champion sends a champion to another rig.
  • Let a campaign read another’s folder, with the operator’s or the owner’s token: kb_grant and kb_revoke, as Can read from does on a campaign’s page.
  • Set rigs up, with the operator’s or the owner’s token: add_cluster_rig, set_cluster_slots, cluster_rig, update_rig_images and set_rig_model, with the same checks as the dashboard’s pages. Retiring a rig is the owner’s.
  • Debug, with any token but the agent’s: control_log, providers and rig_setup.

A command is queued, not done at once. issue_command returns the command’s id. The agent then calls command_status until the status is delivered, failed or rejected with the rig’s reason, or expired. delivered means the rig applied the command; a rig check’s result comes later, in the rig’s events.

To start another run of a campaign that control keeps (one saved on the New campaign page, or one assigned before), the agent calls start_run, the twin of the campaign page’s Start a run: for example {"campaign": "sort-speed", "rig": "rig-1", "queue_from": {"rig": "rig-1", "run": "sort-speed-1"}}. It takes the panel’s fields, past research by the ids kb_search gives included, and answers with the new run and its command id, or with the panel’s refusal in words. The operator’s token may call it; only the owner’s changes a rig’s GPU split or starts a stopped pod on RunPod. Start a run from a script or an agent maps each field.

To start a campaign from a contract, the agent needs an assign_campaign payload. npx thermite assign … --print builds one from a contract, and the agent passes it to issue_command; see Start a campaign from the command line. A payload can also carry past research that an operator’s or the owner’s token found with kb_search (see assign_campaign):

  • queue: experiments to start with, such as another run’s untried ones or past experiments from the knowledge base. thermite assign … --queue-from <run> --print puts a past run’s untried ones there for you; it reads them from control, so it needs --control and the owner’s --token-file. Over MCP, control takes a copied experiment’s words from its own record of it, when it has one and the experiment comes from a run of the new run’s campaign or of one whose folder that campaign may read, and ends its details with what became of it there, such as In sort-speed-1 (sort-speed) it was tried: …, as Start a run does. Any other keeps the caller’s words, with the author copied;
  • briefing: findings, claims, notes and reports, as [{"text": "…", "from": {"campaign": "…", "run": "…", "kind": "…", "ref": "…"}}]. Every agent’s brief shows them as background. Over MCP, control replaces each item’s text with the knowledge base’s own words for that item, and leaves out an item it can’t find or one from a folder the run’s campaign may not read.

A run without agents takes neither: the rig refuses such a command. Use past research in a new run shows the whole path.

The pages for each task give the payloads the agent sends:

Control writes each tool call it runs, reads included, to its audit log, as an mcp:<tool> entry with the call’s arguments. Each token has its own name there. An operator acts for you, so its name starts with owner::

TokenName in the audit log and on commands
Operatorowner:operator
Agentagent:mcp
Readerreader:mcp
Ownerowner:mcp

A tool call that control refuses has a second entry, refused, with the tool’s name and the reason. Open Audit log in the dashboard’s sidebar to see them. Commands shows who issued each command in its By column.