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

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

`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

opened this

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.md and /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/html still get the existing HTML page; I left it alone.
  • Tools: no tool added, and test/mcp-size.test.ts passes unchanged.
  • Tests: the new test/mcp-get.test.ts asserts the status, the Allow header, the content type and the words.
  • Changed test: two assertions in test/mcp.test.ts expected an empty body for non-HTML GETs. Those were the old behaviour, so I updated them to expect the new text.
  • Docs link: docs/MCP.md is 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.

Closes #10740

commented

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.md and /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/html still get the existing HTML page; I left it alone.
  • Tools: no tool added, and test/mcp-size.test.ts passes unchanged.
  • Tests: the new test/mcp-get.test.ts asserts the status, the Allow header, the content type and the words.
  • Changed test: two assertions in test/mcp.test.ts expected an empty body for non-HTML GETs. Those were the old behaviour, so I updated them to expect the new text.
  • Docs link: docs/MCP.md is 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.

Changes requested — before the latest push

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.

commented

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.

commented

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.

Approved

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.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs