Repository navigation
fix(sep-1932): serve the draft (2026-07-28) wire from the DPoP fixtures; name a protocol-version rejection once - #1
Open
figitaki wants to merge 2 commits into
Conversation
The CLI defaults to DRAFT_PROTOCOL_VERSION, whose probe is `server/discover` with a per-request `_meta` envelope. The compliant and broken fixtures are built on the pinned SDK 1.x StreamableHTTPServerTransport, which only speaks the initialize/session lifecycle and answers that probe with 400 / -32000. AcceptsValidProof then fails before any DPoP check runs and 23 further checks go not-testable: 2/26 at the default, 27/27 at 2025-11-25. Add a minimal stateless dispatcher (sep-1932-draft-wire.ts), following the pattern everything-server.ts already uses on the same SDK: `_meta`/header validation, then server/discover, ping, tools/list and tools/call for the echo tool, with resultType and the SEP-2549 hints on results. Route draft-wire requests there in both fixtures; authentication is unchanged and still runs first. The reject-all fixture needs nothing. Add two unit tests at DRAFT_PROTOCOL_VERSION so the stateless path is covered: testContext() defaults to LATEST_SPEC_VERSION, which is why this was only reachable by hand. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…Proof When the positive probe is refused with a non-401 JSON-RPC error, the request never reached the proof: SDKs that predate the stateless wire answer server/discover with -32000, a draft-aware server with -32022. Say so in the AcceptsValidProof failure, with the server's error and a pointer to --spec-version, instead of "Expected 2xx, got 400" followed by 24 not-testable rows. A 401 is reported exactly as before; that is a real DPoP result. UNSUPPORTED_PROTOCOL_VERSION is the existing constant from spec-types/draft. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
figitaki
marked this pull request as ready for review
October 19, 2026 19:19
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.
Fixes modelcontextprotocol#566. Follow-up to the SEP-1932 thread (modelcontextprotocol/modelcontextprotocol#1932): the
sep-1932-compliant-serverfixture failsauth/dpop-server-validationat the CLI's default spec version.Two commits that stand alone. If you would rather fix the fixtures by moving them to the TS SDK 2.x packages, as @nbarbettini suggested, drop the first commit and keep the second: the once-only diagnostic is useful either way.
Problem
The CLI defaults to
DRAFT_PROTOCOL_VERSION(2026-07-28), whose probe isserver/discoverwith a per-request_metaenvelope. The DPoP fixtures are built on the pinned@modelcontextprotocol/sdk1.29StreamableHTTPServerTransport, which only speaks the initialize/session lifecycle and answers that probe with HTTP 400 / JSON-RPC-32000("Unsupported protocol version: 2026-07-28 …").AcceptsValidProoftherefore fails before any DPoP check runs, 23 further checks go not-testable, andReportsDpopErrorCodewarns: 2/26 at the default, 27/27 with--spec-version 2025-11-25 --force.The unit tests did not see it because
testContext()defaults toLATEST_SPEC_VERSION(2025-11-25), so only theinitializepath was exercised.Change
Three parts, no SDK bump.
examples/servers/typescript/sep-1932-draft-wire.ts(new): a minimal stateless dispatcher for the fixtures, following the patterneverything-server.tsalready uses on the same SDK:_meta/header validation (-32020,-32602,-32022as in the everything-server), thenserver/discover,ping,tools/list, andtools/callfor the echo tool, withresultTypeand the SEP-2549 hints stamped on results. Authentication stays in the fixture and runs before dispatch.sep-1932-compliant-server.ts,sep-1932-broken-server.ts: route draft-wire requests to that dispatcher; everything else still goes through the SDK transport. The reject-all fixture needs no change. The echo tool is defined once per fixture and shared by both paths.src/scenarios/server/auth/dpop.ts: when the positive probe is refused with a non-401 JSON-RPC error,AcceptsValidProofnow says so once, with the server's error and a pointer to--spec-version, instead of a bare "Expected 2xx, got 400" followed by 24 not-testable rows. A 401 is still reported as before: that is a real DPoP result.UNSUPPORTED_PROTOCOL_VERSIONis the existing constant fromspec-types/draft.Plus two unit tests at
DRAFT_PROTOCOL_VERSION(compliant passes with no failures or warnings; broken gets its 2xx baseline and fails the negatives), so the stateless path is covered.Verification
npm run lint,npm run typecheck,npm run build: clean.npx vitest run: all passing, including the two new cases.DPOP_ISSUER_JWK,DPOP_ISSUERandDPOP_AUDIENCE=http://localhost:3010/mcp; CLI with the matchingDPOP_ISSUER_PRIVATE_JWKandDPOP_ISSUER; scenarioauth/dpop-server-validation):2026-07-28(default)2025-11-25 --force2026-07-282026-07-28Pre-existing and untouched:
examples/servers/typescript/no-dns-rebinding-protection.tshas twotscerrors on the base branch;npm run lintdoes not runtscon examples, so CI is unaffected.Notes for review
nbarbettini:feat/1932-server-dpop-discovery), since the fixtures and the scenario only exist there. It should rebase cleanly onto feat(sep-1932): DPoP error codes (stacked on #527) modelcontextprotocol/conformance#528/feat(sep-1932): tighten the Bearer-downgrade probe (stacked on #395) modelcontextprotocol/conformance#527/Server Auth: DPoP Proof Validation (SEP-1932) modelcontextprotocol/conformance#395 as they move.🤖 Generated with Claude Code