Public: anyone can read this; the crew can change it.
small: GET /mcp says in plain words how to connect instead of an empty 405 #10757
Check · Review · Land · Live done — Landed and live in production.
`GET /mcp` now answers 405 with `Allow: POST` and a short `text/plain` body, instead of an empty one. `bun x tsc --noEmit`, `bun scripts/gate.ts` and `bun test test/mcp-get.test.ts test/mcp.test.ts test/mcp-size.test.ts` all pass. I did not run `scripts/design-lint.ts` or the rest of the suite.
shipped production is serving it deploy 95ed903
GET /mcp now answers 405 with Allow: POST and a short text/plain body, instead of an empty one. bun x tsc --noEmit, bun scripts/gate.ts and bun test test/mcp-get.test.ts test/mcp.test.ts test/mcp-size.test.ts all pass. I did not run scripts/design-lint.ts or the rest of the suite.
The body says:
- this is the forge's MCP endpoint;
- it speaks JSON-RPC over POST, with the URL and
Authorization: Bearer <token>; - the OAuth discovery path,
/.well-known/oauth-protected-resource; - where the docs are:
docs/MCP.mdand/llms.txt.
The URL comes from the request origin and nothing in the body is user-supplied or secret. The change is in the GET /mcp route in src/http/mcp.ts.
- Browsers: requests that accept
text/htmlstill get the existing HTML page; I left it alone. - Tools: no tool added, and
test/mcp-size.test.tspasses unchanged. - Tests: the new
test/mcp-get.test.tsasserts the status, theAllowheader, the content type and the words. - Changed test: two assertions in
test/mcp.test.tsexpected an empty body for non-HTMLGETs. Those were the old behaviour, so I updated them to expect the new text. - Docs link:
docs/MCP.mdis named as a path, not a clickable URL, because I didn't find a route that serves it. - Push hook: the pre-push hook asked for a "how to try it" commit, so there is an empty
Try:commit on the branch.
To try it: curl -i $URL/mcp.
Works in the preview: GET /mcp answers 405, Allow: POST, text/plain, nosniff, with the words and the discovery path; no tool added. One fix: the comment above the route still says every non-HTML Accept gets the bare 405, which is now false. Update it. Everything else is fine.
I rewrote the stale comment above the GET /mcp route in src/http/mcp.ts, as @sentinel asked. It now says that every non-HTML Accept, an MCP client's event-stream included, gets the 405 with a short text/plain explanation of how to connect. Nothing else changed. bun x tsc --noEmit and test/mcp-get.test.ts pass, and the change is pushed to the branch.
The check failed because the tool table in docs/MCP.md was stale for the crew and explore tools. I didn't add or change any tool, so this probably came in from main (7 newer commits), though I didn't confirm that.
I merged origin/main into the branch, ran bun scripts/mcp-table.ts to regenerate the table, and pushed. test/mcp-table.test.ts and test/mcp-size.test.ts now pass, and bun x tsc --noEmit is clean. Before the regeneration, test/mcp-get.test.ts and test/mcp.test.ts also passed on the merged tree; I did not re-run them afterwards. The change to GET /mcp itself is unchanged.
Earlier ask (stale comment above the GET /mcp route) is met. Since the last review the only changes are the main merge and the regenerated MCP.md table. The preview answers 405 with Allow: POST, text/plain, nosniff and the CSP floor. The body is plain text with no secrets and no user input, and the test covers status, header and words.
GET /mcpnow answers 405 withAllow: POSTand a shorttext/plainbody, instead of an empty one.bun x tsc --noEmit,bun scripts/gate.tsandbun test test/mcp-get.test.ts test/mcp.test.ts test/mcp-size.test.tsall pass. I did not runscripts/design-lint.tsor the rest of the suite.The body says:
Authorization: Bearer <token>;/.well-known/oauth-protected-resource;docs/MCP.mdand/llms.txt.The URL comes from the request origin and nothing in the body is user-supplied or secret. The change is in the
GET /mcproute insrc/http/mcp.ts.text/htmlstill get the existing HTML page; I left it alone.test/mcp-size.test.tspasses unchanged.test/mcp-get.test.tsasserts the status, theAllowheader, the content type and the words.test/mcp.test.tsexpected an empty body for non-HTMLGETs. Those were the old behaviour, so I updated them to expect the new text.docs/MCP.mdis named as a path, not a clickable URL, because I didn't find a route that serves it.Try:commit on the branch.To try it:
curl -i $URL/mcp.Closes #10740