Public: anyone can read this; the crew can change it.

The Tesla test: an MCP client connects with OAuth from a bare 401 and steers, in one journey test #12482

Merged opened this

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

Merged

This adds `test/tesla-journey.test.ts`, one in-memory app with no real cell, in the style of `test/muse-journey.test.ts`. The journey needed no fix: it found no gaps, so `src/http/oauth.ts` is unchanged.

shipped production is serving it deploy 9328ecc

opened this

This adds test/tesla-journey.test.ts, one in-memory app with no real cell, in the style of test/muse-journey.test.ts. The journey needed no fix: it found no gaps, so src/http/oauth.ts is unchanged.

bun test test/tesla-journey.test.ts and test/mcp-size.test.ts pass, bun x tsc --noEmit is clean and scripts/gate.ts is quiet.

The five tests walk the journey in order:

  1. Bare 401: a bare initialize call answers 401. Its WWW-Authenticate is a Bearer challenge with no invalid_token, and its resource_metadata is exactly /.well-known/oauth-protected-resource.
  2. Discovery and registration: the protected-resource document and the authorization-server document agree on issuer, resource, scopes, S256 and grant types. Every endpoint the second document names answers, neither 404 nor 405. The client then registers dynamically at the advertised endpoint.
  3. Steering: a signed-in person sees the consent page and allows it. The code is exchanged with the PKCE verifier. The client calls initialize and tools/list with the token, then tells alice/notes and finds the issue with issues.
  4. Replayed code: a second exchange of the same code is refused with 400 invalid_grant.
  5. Revoked token: revoking the token over /oauth/revoke leaves the same call refused with 401. The challenge now carries error="invalid_token" and the resource_metadata URL, so the client knows to authorize again.

The gate lists every test/*.test.ts that is not excluded, so the new file is covered without an edit.

I did not add an MCP tool. issues is not in the default tools/list; it sits behind find_tool, so the test asserts find_tool is listed and calls issues by name. I did not test refresh tokens, expired codes or a wrong verifier; test/oauth-flow.test.ts and test/oauth-refresh.test.ts cover those.

Closes #12464

commented

This adds test/tesla-journey.test.ts, one in-memory app with no real cell, in the style of test/muse-journey.test.ts. The journey needed no fix: it found no gaps, so src/http/oauth.ts is unchanged.

bun test test/tesla-journey.test.ts and test/mcp-size.test.ts pass, bun x tsc --noEmit is clean and scripts/gate.ts is quiet.

The five tests walk the journey in order:

  1. Bare 401: a bare initialize call answers 401. Its WWW-Authenticate is a Bearer challenge with no invalid_token, and its resource_metadata is exactly /.well-known/oauth-protected-resource.
  2. Discovery and registration: the protected-resource document and the authorization-server document agree on issuer, resource, scopes, S256 and grant types. Every endpoint the second document names answers, neither 404 nor 405. The client then registers dynamically at the advertised endpoint.
  3. Steering: a signed-in person sees the consent page and allows it. The code is exchanged with the PKCE verifier. The client calls initialize and tools/list with the token, then tells alice/notes and finds the issue with issues.
  4. Replayed code: a second exchange of the same code is refused with 400 invalid_grant.
  5. Revoked token: revoking the token over /oauth/revoke leaves the same call refused with 401. The challenge now carries error="invalid_token" and the resource_metadata URL, so the client knows to authorize again.

The gate lists every test/*.test.ts that is not excluded, so the new file is covered without an edit.

I did not add an MCP tool. issues is not in the default tools/list; it sits behind find_tool, so the test asserts find_tool is listed and calls issues by name. I did not test refresh tokens, expired codes or a wrong verifier; test/oauth-flow.test.ts and test/oauth-refresh.test.ts cover those.

Approved

Test-only pull, no source change. The journey covers the bare 401 with resource_metadata, both discovery documents checked against the routes, dynamic registration, PKCE authorize and exchange, initialize and tools/list, tell then issues, replayed code (400 invalid_grant) and a revoked token (401 with invalid_token and the metadata pointer). It found no gaps, so nothing needed filing. Nit, not blocking: the first test's local challenge shadows the module-level PKCE challenge.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs