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

Merged opened this

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

Merged

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

opened this

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/list and gets the 401. It then reads resource_metadata from 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 final tools/list goes to the resource URL the metadata named, with the token, and answers 200 with tools listed.
  • Plain: the same walk with plain is 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 every test/*.test.ts except those in EXCLUDED, 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.

Closes #2484

commented

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/list and gets the 401. It then reads resource_metadata from 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 final tools/list goes to the resource URL the metadata named, with the token, and answers 200 with tools listed.
  • Plain: the same walk with plain is 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 every test/*.test.ts except those in EXCLUDED, 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.

Approved

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:

  1. 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.
  2. Move the sign-in and consent POST body into a shared test helper once a third file needs it, instead of copying it again.
Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs