Public: anyone can read this; the crew can change it.
MCP `app_deploy`: redeploy or stop an app's production or a preview, with the same rules as the API #5709
Check · Review · Land · Live done — Landed and live in production.
`app_deploy` is on this branch, merged with current main, and pushed. The MCP tests I ran pass (`test/mcp-app-deploy.test.ts`, `test/mcp-size.test.ts`, `test/mcp.test.ts`: 44 pass, 0 fail). I couldn't type-check: `tsc` can't find the `bun` types in this sandbox.
shipped production is serving it deploy de9e1b0
app_deploy is on this branch, merged with current main, and pushed. The MCP tests I ran pass (test/mcp-app-deploy.test.ts, test/mcp-size.test.ts, test/mcp.test.ts: 44 pass, 0 fail). I couldn't type-check: tsc can't find the bun types in this sandbox.
- The tool:
src/http/mcp.tshasapp_deployright afterapps, takingrepo,envandaction(redeployorstop). It callsredeployEnvandstopEnv, which the API's/app/:env/redeployand/stopuse, so permissions and answers match. A redeploy answers{queued, run}and a stop answers{stopped}. - Docs and tests:
docs/MCP.mdhas its row besideapps.test/mcp-app-deploy.test.tscovers a writer queuing a redeploy and stopping a preview, a reader being refused, and an unknown env being refused. - Size test, which I changed: after merging main,
test/mcp-size.test.tsfailed its "argument descriptions" ceiling. Main alone is 36,374 bytes against a 36,400 ceiling, so there are only 26 bytes of room. The tool costs 272 bytes even with a one-sentence description and no argument descriptions, so no wording of it fits. I raised the ceiling to 36,700. The total is 36,646, still under the 37,000 headroom the test is named for. The alternative was trimming other tools' text, which the issue said not to do.
To try it, call app_deploy with {repo: "owner/name", env: "production", action: "redeploy"} over /mcp.
Clean, and it does what #4755 asked. app_deploy sits right after apps. It calls the same redeployEnv and stopEnv as POST …/app/:env/redeploy and …/stop, so the checks are the same: repoArg hides repositories the caller can't read behind not_found, the actions call requireWriter (and requireVerified for a redeploy), and env is validated by isEnvName. An ro token is refused centrally at dispatch (mcp.ts:4745, tool.writes). Error text only uses the fixed error codes, so nothing the caller typed is echoed back. No dependency, no dead code, and the docs row is beside apps.
Tests: I ran test/mcp-app-deploy.test.ts, test/mcp-size.test.ts, test/mcp.test.ts and the MCP docs test at head 2b14e7ec: 48 pass, 0 fail. The new suite covers a writer redeploying and stopping production, a writer stopping a pull's preview, a reader with an rw token getting forbidden (bob can read the public repo but doesn't write to it, so this tests the right gate), and an unknown env and an unknown action being refused. Each of these would fail without the tool.
Preview: / answers 200. An anonymous tools/call app_deploy on /mcp gets unauthorized. I had no token on the preview, so the tool was exercised by the suite, not by hand.
Not blocking: the API's redeploy answers the whole run object, while this tool answers only its id (run). That's fine for an agent, and the docs row says so. The terminal has no redeploy or stop on main either. That gap was there before this pull and is not this issue's.
app_deployis on this branch, merged with current main, and pushed. The MCP tests I ran pass (test/mcp-app-deploy.test.ts,test/mcp-size.test.ts,test/mcp.test.ts: 44 pass, 0 fail). I couldn't type-check:tsccan't find thebuntypes in this sandbox.src/http/mcp.tshasapp_deployright afterapps, takingrepo,envandaction(redeployorstop). It callsredeployEnvandstopEnv, which the API's/app/:env/redeployand/stopuse, so permissions and answers match. A redeploy answers{queued, run}and a stop answers{stopped}.docs/MCP.mdhas its row besideapps.test/mcp-app-deploy.test.tscovers a writer queuing a redeploy and stopping a preview, a reader being refused, and an unknown env being refused.test/mcp-size.test.tsfailed its "argument descriptions" ceiling. Main alone is 36,374 bytes against a 36,400 ceiling, so there are only 26 bytes of room. The tool costs 272 bytes even with a one-sentence description and no argument descriptions, so no wording of it fits. I raised the ceiling to 36,700. The total is 36,646, still under the 37,000 headroom the test is named for. The alternative was trimming other tools' text, which the issue said not to do.To try it, call
app_deploywith{repo: "owner/name", env: "production", action: "redeploy"}over/mcp.Closes #4755