Skip to content

fix(auth): add issuer to pre-registration context - #423

Open
logiscapedev wants to merge 1 commit into
modelcontextprotocol:mainfrom
logiscapedev:fix/pre-registration-issuer
Open

fix(auth): add issuer to pre-registration context#423
logiscapedev wants to merge 1 commit into
modelcontextprotocol:mainfrom
logiscapedev:fix/pre-registration-issuer

Conversation

@logiscapedev

@logiscapedev logiscapedev commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Fixes #422

What

auth/pre-registration hands the client under test context: { client_id, client_secret } with
no indication of which authorization server issued the credentials. The 2026-07-28 spec's
Authorization Server Binding
section says clients using pre-registered credentials MUST associate them with the issuing
authorization server, keyed by its issuer identifier. A client that takes the strict reading of
that MUST — refusing to present credentials it cannot bind — never makes a token request, and the
scenario's pre-registration-auth check fails ("Client did not make a token request"). The
scenario predates the rule (#120, Jan 2026, before SEP-2352) and was never updated.

This PR additively supplies the mock AS's issuer in the scenario context:

context: {
  client_id: PRE_REGISTERED_CLIENT_ID,
  client_secret: PRE_REGISTERED_CLIENT_SECRET,
  issuer: this.authServer.getUrl()
}

The emitted value equals the issuer the mock AS publishes in its metadata (the scenario sets
neither metadataIssuer nor routePrefix, so createAuthServer resolves the published issuer to
exactly this URL — pinned by a new self-test). Alongside:

  • src/schemas/context.ts — the auth/pre-registration variant of
    ClientConformanceContextSchema gains issuer: z.string().
  • examples/clients/typescript/everything-client.tsrunPreRegistration demonstrates the
    intended use via the provider's existing SEP-2352 helper: provider.bindIssuer(ctx.issuer).

This is the discovery half of what #285/#286 already settled behaviorally: #285 concluded issuer
keying isn't protocol-observable and #286 tests the enforcement side via
auth/authorization-server-migration — indeed #286 shipped bindIssuer() in this repo's own
example client precisely to key credentials by issuer, yet this scenario gave a client nothing to
key by. Real-world pre-registration always tells the operator which AS issued the credentials; the
scenario now does too. Strict clients become testable; warn-and-proceed clients are provably
unaffected (verified against the TypeScript SDK).

Self-test (prove it passes and fails)

New test in src/scenarios/client/auth/index.test.ts: the scenario's emitted context parses
against ClientConformanceContextSchema and its issuer equals the issuer the mock AS serves
at /.well-known/oauth-authorization-server — the property a binding client depends on. The
strict-refusal red case is demonstrated with a real SDK below.

npm test 484/484, npm run check clean.

Real-SDK evidence (per CONTRIBUTING)

Strict client (PHP SDK, logiscape/mcp-sdk-php v2 main, draft track = mandatory issuer
binding, no legacy opt-out):

  • Before (unpatched main): 2/3 — pre-registration-auth FAILURE "Client did not make a token
    request"; the client refuses: "Pre-registered client credentials have no issuer binding…"
  • After (one-line change in its conformance client to pass issuer from context): 14/14.

Warn-path regression (official TypeScript SDK, current main, via the sdk-runner): passes
before and after — its conformance client's non-strict context parsing strips the new key, so
behavior is byte-identical.

This repo's example client: auth/pre-registration 14/14 before and after; full --suite auth 235/235 before and after (no delta in sibling scenarios).

🤖 Generated with Claude Code

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

@pkg-pr-new

pkg-pr-new Bot commented Jul 29, 2026

Copy link
Copy Markdown

Open in StackBlitz

npx https://pkg.pr.new/@modelcontextprotocol/conformance@423

commit: bd07d9a

@logiscapedev logiscapedev changed the title fix(auth): add issuer to pre-registration context Fixes #422 fix(auth): add issuer to pre-registration context Jul 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

auth/pre-registration: scenario context omits the issuer, so a client implementing the 2026-07-28 spec's Authorization Server Binding cannot pass

1 participant