feat(server): add request-time OAuth scope challenges (#1624)
Some checks failed
Conformance Tests / client-conformance (push) Has been cancelled
Conformance Tests / server-conformance (push) Has been cancelled
Deploy Docs / deploy-docs (push) Has been cancelled
Examples / examples (build + e2e) (push) Has been cancelled
/ build (push) Has been cancelled
/ test (20) (push) Has been cancelled
/ test (22) (push) Has been cancelled
/ test (24) (push) Has been cancelled
/ test-e2e (20) (push) Has been cancelled
/ test-e2e (22) (push) Has been cancelled
/ test-e2e (24) (push) Has been cancelled
/ test-runtimes (bun, 1.x) (push) Has been cancelled
/ test-runtimes (deno, v2.x) (push) Has been cancelled
Publish Any Commit / pkg-publish (push) Has been cancelled
Release / Version (push) Has been cancelled
Release / Publish (push) Has been cancelled

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Sam Morrow 2026-09-16 18:51:56 +02:00 • committed by GitHub
commit 6032170087
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -0,0 +1,22 @@
---
'@modelcontextprotocol/server': minor
'@modelcontextprotocol/node': minor
---
Add request-time OAuth scope challenges for tools, resources, resource templates,
and prompts. Each primitive's `scopeChallenge` callback receives the parsed
request and verified authentication info, then either continues or returns the
exact scope set for an `insufficient_scope` response. `requireScopes` provides a
small helper for static all-of checks.
`createMcpHandler` and Streamable HTTP transports return HTTP 403 with an
`insufficient_scope` challenge before handler execution or SSE setup. The
preflight is active whenever a registered primitive carries a `scopeChallenge`
callback — there is no handler- or transport-level configuration. The
challenge's `WWW-Authenticate` header is built by the same formatter as the
bearer-auth 401/403 answers, and its `resource_metadata` parameter is derived
from the verified `AuthInfo`: `requireBearerAuth` / `verifyBearerToken` now
stamp their configured `resourceMetadataUrl` onto the `AuthInfo` they return
(new optional `AuthInfo.resourceMetadataUrl` field), with a fallback to the
well-known location for an HTTP(S) RFC 8707 `resource` identifier; the
parameter is omitted when neither is available.