Repository navigation
feat(server): add protected resource metadata discovery scenario - #572
Open
JosephDoUrden wants to merge 1 commit into
Open
JosephDoUrden wants to merge 1 commit into
JosephDoUrden wants to merge 1 commit into
Conversation
Add auth/protected-resource-metadata, a server scenario that probes an MCP endpoint without a token and grades the Protected Resource Metadata it publishes (RFC 9728): the 401 challenge, discovery via resource_metadata or the well-known URIs, the 200 application/json response, the resource field and a non-empty authorization_servers list, plus a SHOULD-level scope check that is SKIPPED at 2025-06-18, where the spec says nothing about scope in the challenge. A 2xx to the unauthenticated probe reports every check untestable. The fetch and parse logic lives in a standalone helper under src/scenarios/server/auth/prm.ts so other server auth scenarios can reuse it. Every request is bounded to 10 s, headers and body, so a server that holds a stream open fails with a reason naming the timeout instead of hanging the suite. Discovery candidates are fetched once per URL, and the challenge parser survives a token68 challenge and an unquoted resource_metadata value. The scenario starts in the pending suite because the everything-server does not run with authorization enabled; an auth-enabled fixture with one break mode per check backs the vitest cases. Closes modelcontextprotocol#565
commit: |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
closes #565
adds
auth/protected-resource-metadata, a server scenario. the harness plays a client with no token. one unauthenticated post, then metadata discovery in client order:resource_metadatafrom the challenge, the path well-known url, the root one.six checks come out of that.
server-auth-401: 401 plus aWWW-Authenticateheader.server-prm-discovery: the metadata can be found; at 2025-06-18 the challenge url is required, from 2025-11-25 a well-known document on its own is fine.server-prm-response: 200,application/json, json object body (rfc 9728 §3.2).server-prm-resource:resourceidentifies the server (§3.3); at the root well-known url the origin is accepted too, same as the ts sdk.server-prm-authorization-servers: non-empty array of urls.server-www-authenticate-scope:scopein the challenge, warning only; skipped at 2025-06-18, the should first appears in 2025-11-25.a 2xx to the probe means the server has no auth. every check then reports "not testable" per #248, never skipped.
every request is bounded to 10 s, headers and body. a server that holds the sse stream open, or never ends the json body, fails the checks it blocks with a reason naming the timeout. the suite does not hang. two tests cover it with a mock server.
the fetch and parse logic sits in
src/scenarios/server/auth/prm.ts. the challenge parser handles multiple challenges, quoted pairs, a token68 challenge before the bearer one, and an unquotedresource_metadatavalue, which shows up in the wild. a url named by two sources is fetched once.fixture:
examples/servers/typescript/auth-prm-server.ts, port 3013.PRM_BREAKpicks one defect per check. unknown values exit with the allowed list. readme has the table. 25 vitest cases.against the real ts sdk (
typescript-sdk/examples/oauth/server.ts): 5/5 plus the scope warning at 2025-11-25 and 2026-07-28, scope skipped at 2025-06-18. note--urlmust match the server's own resource exactly.localhostagainst a server that names127.0.0.1failsserver-prm-resource, which is what rfc 9728 §3.3 asks for.starts in the pending suite. the everything-servers do not run with auth on. targeted run:
npm start -- server --scenario auth/protected-resource-metadata --url http://localhost:3013/mcpon the dpop stack (#395, #527, #528, #529): those branches also add
src/scenarios/server/auth/spec-references.ts, so there is an add/add conflict on that one file. the three rfc 9728 entries are identical. happy to rebase whichever lands second. the helper here was written in parallel, not extracted from #529.spec refs point at the dated 2025-11-25 pages, each anchor checked.