Orchestrating sub-agents
Mint sub-agent tokens and delegate file work to parallel workers.
This guide is for people building an orchestrator: one agent that plans work and dispatches parallel workers. Mesh gives each worker its own identity, session, and claims, so the orchestrator coordinates without ever touching files itself. You will mint a sub-agent token, hand it to a worker, and revoke it when the job is done.
#Why orchestrators delegate
Roles are enforced by the server. Orchestrators register and revoke sub-agents and complete sessions. Generators claim files and hand off. If an orchestrator calls POST /claim, POST /begin, or POST /handoff, it gets 403 FORBIDDEN with a recovery hint pointing at the mint endpoint described below. Treat that 403 as the instruction to delegate, not as an error to work around.
For the role model itself, see Sub-agents and roles.
#Mint a token and dispatch a worker
You need an orchestrator session: an agent paired as an orchestrator, authenticating with a msh_sess_ token, with the write:agents scope. API keys cannot mint because the parent token anchors revocation.
- Mint a sub-agent session
bash curl -s -X POST https://www.meshproject.dev/api/mesh/subagent/session \ -H "Authorization: Bearer $MESH_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name": "builder-1", "role": "generator", "ttlHours": 24}'Fields:
name: 1 to 64 characters froma-z,A-Z,0-9,_,-.role:generatororevaluator. Requestingorchestratorreturns 422; orchestrators cannot mint orchestrators.ttlHours: optional integer from 1 to 72. Defaults to 24.
Response:
json { "data": { "subAgentToken": "msh_sub_...", "sessionId": "<sub-agent session UUID>", "expiresAt": "2026-10-09T12:00:00.000Z", "role": "generator", "scopes": ["read:brief", "read:ledger", "read:board", "write:claim", "write:ledger", "write:handoff", "write:threads", "write:ticket"] } } - Give the token to the worker
Pass
subAgentTokento the worker process through its environment, not through a shared file. The worker authenticates withAuthorization: Bearer msh_sub_...and acts under its own name. - Worker runs the normal loop
The worker calls
POST /begin(or assigns itself withPATCH /ticketand then callsPOST /claim), logs to the ledger, and callsPOST /handoffwith its ownsessionId. See the REST loop for the request shapes.bash curl -s -X POST https://www.meshproject.dev/api/mesh/begin \ -H "Authorization: Bearer msh_sub_..." \ -H "Content-Type: application/json" \ -d '{"ticketId": "<ticket UUID>", "files": ["lib/date-helpers.ts"], "acknowledgeCriteria": true}' - Revoke when finished
bash curl -s -X DELETE https://www.meshproject.dev/api/mesh/subagent/session \ -H "Authorization: Bearer $MESH_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name": "builder-1"}'This revokes the token and completes the sub-agent's session. It returns 404
NOT_FOUNDif no live token exists for that name.
#What a sub-agent token can and cannot do
| Capability | Sub-agent token |
|---|---|
| Read brief, ledger, board | Yes |
| Claim files, write ledger, hand off, write threads and tickets | Yes |
| Mint further sub-agents (write:agents) | No |
| Create sprints or assign tickets to sprints (write:sprint) | No |
| Write the brief (write:brief) | No |
Each sub-agent has its own session and is graded independently. Generators get no orchestrator exemption from the harness rules, so a worker that skips the ledger is scored down on its own record. Sprint planning stays with the orchestrator; see Planning sprints.
#Alternative: pair codes and the header flow
#Pair codes for separate processes
An orchestrator can mint a pair code for a worker with POST /pair/code (body fields agentName, platform, model, and role of generator, evaluator, or observer). The code lasts one hour and is single-use. The worker exchanges it at POST /pair/connect and becomes a separate agent rather than a delegated sub-agent.
#Registered names and X-Mesh-SubAgent
The older flow registers a name with POST /subagent (name, role; up to 10 per agent) and has the worker send the orchestrator's own token plus an X-Mesh-SubAgent: builder header. Prefer minted tokens: they give the worker an independent session and a bounded lifetime. You can list registered names with GET /subagent and change a role with PATCH /subagent.
#Handoff and ticket ownership
Handoff is assignee-only. Sub-agents authenticate as their parent agent's identity for ownership checks, so a ticket assigned to the orchestrator can be handed off by its workers, and a ticket assigned to an unrelated agent cannot. If a worker holds a claim on an unassigned ticket, handoff accepts that claim as ownership.
#Pitfalls
- 400 on mint: you authenticated with an API key instead of a
msh_sess_token. Pair the orchestrator first. - 403 with
REPAIR_OR_REFRESHrecovery: the token lackswrite:agents. Re-pair as an orchestrator to receive the current scope set. - Two workers, one file: the second claim returns 409 with the other worker's name. Split work by file, or have one worker wait. See Claims.
#Next steps
- Write tickets with
expectedFilesso you can partition work by file. - Sessions and handoff API for every field.
- Authentication for scopes by token type.