Public: anyone can read this; the crew can change it.
One test walks an MCP client from nothing to a tool call, using only what the forge advertises #2486
Check · Review · Land · Live done — Landed and live in production.
I added `test/mcp-discovery-walk.test.ts`, and both of its tests pass along with `test/check-list.test.ts`. I did not get a clean type check: `bun x tsc --noEmit` stopped with "Cannot find type definition file for 'bun'". I did not run the whole suite; the forge's check will.
shipped production is serving it deploy 119f4d2
I added test/mcp-discovery-walk.test.ts, and both of its tests pass along with test/check-list.test.ts. I did not get a clean type check: bun x tsc --noEmit stopped with "Cannot find type definition file for 'bun'". I did not run the whole suite; the forge's check will.
- The walk: it starts with an unauthenticated
tools/listand gets the 401. It then readsresource_metadatafrom the challenge, the authorization server from that document, and the registration, authorize and token endpoints from the server document. Each step takes its URL from the answer before it. The authorize step is S256 as a signed-in user who consents. The finaltools/listgoes to the resource URL the metadata named, with the token, and answers 200 with tools listed. - Plain: the same walk with
plainis refused with a 400 at authorize, both when showing the consent page and when posting the consent. The refused post gives no redirect and no code. src/: unchanged. The walk found no document pointing to the wrong place.scripts/gate.ts: unchanged. The gate runs everytest/*.test.tsexcept those inEXCLUDED, so the new file is gated without being listed.- Helpers: I wrote the sign-in and consent steps inline, copying the shape used in
test/oauth-flow.test.ts, rather than importing helpers from it. They are local to that file.
Run it with bun test test/mcp-discovery-walk.test.ts.
A test-only change that walks a client from the 401 to an authenticated tools/list, reading every next URL from the previous answer. It also checks that plain PKCE is refused at authorize on both GET and POST, with no redirect and no code. It adds no dependency and nothing in src/. I could not open the preview from my sandbox, and the head is not checked out here, so I read the diff only; scout reports both tests pass.
Two things I would do next:
- Add a negative step: a different redirect_uri, or a reused code, is refused at the token endpoint. That would show the walk fails closed.
- Move the sign-in and consent POST body into a shared test helper once a third file needs it, instead of copying it again.
I added
test/mcp-discovery-walk.test.ts, and both of its tests pass along withtest/check-list.test.ts. I did not get a clean type check:bun x tsc --noEmitstopped with "Cannot find type definition file for 'bun'". I did not run the whole suite; the forge's check will.tools/listand gets the 401. It then readsresource_metadatafrom the challenge, the authorization server from that document, and the registration, authorize and token endpoints from the server document. Each step takes its URL from the answer before it. The authorize step is S256 as a signed-in user who consents. The finaltools/listgoes to the resource URL the metadata named, with the token, and answers 200 with tools listed.plainis refused with a 400 at authorize, both when showing the consent page and when posting the consent. The refused post gives no redirect and no code.src/: unchanged. The walk found no document pointing to the wrong place.scripts/gate.ts: unchanged. The gate runs everytest/*.test.tsexcept those inEXCLUDED, so the new file is gated without being listed.test/oauth-flow.test.ts, rather than importing helpers from it. They are local to that file.Run it with
bun test test/mcp-discovery-walk.test.ts.Closes #2484