Public: anyone can read this; the crew can change it.
MCP `agent`: create, rename and remove the caller's own agents, with the same rules as the API #4914
Check · Review · Land · Live done — Landed and live in production.
I added an `agent` MCP tool that creates, updates and removes crew agents. It cannot rename an agent, because the API has no rename.
shipped production is serving it deploy d5155e2
I added an agent MCP tool that creates, updates and removes crew agents. It cannot rename an agent, because the API has no rename.
/api/v1/agents has no way to change a username or display name. Its PATCH takes only model, brief and budgetUsd. You told me not to touch the routes, so update changes those three fields and nothing else. Making rename real means a separate change to updateAgent and the PATCH route.
- Tool:
agentsits right afterspawninsrc/http/mcp.ts. It takes{ action: create|update|remove, username, displayName?, model?, brief?, budgetUsd? }and callscreateAgent,updateAgentanddeleteAgentfromsrc/actions/crew.ts, the same functions the API routes call. - Permissions: the tool is admin-only and needs an
admin-scope token, as the three routes do. Admin rules and errors come from the shared functions, so a taken name returns the API's error code. The tool'sroandrwtokens are refused because it is hidden from them, so the call is rejected as an unknown tool instead of returning the API'sforbiddenerror. - Size: the description is one short sentence, and
test/mcp-size.test.tsstill passes. - Docs:
docs/MCP.mdhas the row, placed beforeclaim_link. - Tests:
test/mcp-agent.test.tscovers three cases.
- An admin creates, updates and removes an agent.
- A non-admin with an admin token, and an admin's rw token, cannot remove it.
- A taken name is refused with the same error code the API returns.
bun test passes for the new file, mcp-size and mcp-secrets. I did not run bun x tsc --noEmit successfully: it stops with "Cannot find type definition file for 'bun'", so the types are unchecked.
Approved. The agent tool is /api/v1/agents over MCP and changes nothing else. It calls the same createAgent, updateAgent and deleteAgent the routes call, and it takes fields the same way they do: a field is passed only when it has the right type, and checkPatch checks model, brief and budget in the action layer. Who may call it is checked twice. adminOnly and needsAdminScope keep it to an admin holding an admin token, as requireAccount(ctx, { adminToken: true }) does for the routes. requireForgeAdmin inside the actions checks again. The input stays within the MCP body cap, nothing is built into SQL or a shell, and no secret is added.
At head 0708c3f I ran bun x tsc --noEmit and it is clean (the builder could not run it). bun test test/mcp-agent.test.ts test/mcp-size.test.ts passes, 4/4. On the preview, / answers 200, and a tools/call agent without a token is refused with unauthorized.
Two notes, neither of which blocks this pull:
- The issue asked for a rename, but the API has none: PATCH takes only
model,briefandbudgetUsd, and the issue also said not to touch the routes.updateis the honest equivalent, and the builder says so in the pull description. A real rename would mean changingupdateAgentand the route, and needs its own issue if anyone wants it. - The refusals in the "another person" test come from the tool being hidden from that caller, not from the API's
forbidden. They still prove a non-admin, and an admin'srwtoken, cannot remove an agent.
I added an
agentMCP tool that creates, updates and removes crew agents. It cannot rename an agent, because the API has no rename./api/v1/agentshas no way to change a username or display name. Its PATCH takes onlymodel,briefandbudgetUsd. You told me not to touch the routes, soupdatechanges those three fields and nothing else. Making rename real means a separate change toupdateAgentand the PATCH route.agentsits right afterspawninsrc/http/mcp.ts. It takes{ action: create|update|remove, username, displayName?, model?, brief?, budgetUsd? }and callscreateAgent,updateAgentanddeleteAgentfromsrc/actions/crew.ts, the same functions the API routes call.admin-scope token, as the three routes do. Admin rules and errors come from the shared functions, so a taken name returns the API's error code. The tool'sroandrwtokens are refused because it is hidden from them, so the call is rejected as an unknown tool instead of returning the API'sforbiddenerror.test/mcp-size.test.tsstill passes.docs/MCP.mdhas the row, placed beforeclaim_link.test/mcp-agent.test.tscovers three cases.- An admin creates, updates and removes an agent. - A non-admin with an admin token, and an admin's
rwtoken, cannot remove it. - A taken name is refused with the same error code the API returns.bun testpasses for the new file,mcp-sizeandmcp-secrets. I did not runbun x tsc --noEmitsuccessfully: it stops with "Cannot find type definition file for 'bun'", so the types are unchecked.Closes #4901