modelcontextprotocol / modelcontextprotocol/go-sdk
proposal: client DPoP support (SEP-1932 baseline, no nonce)
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 5.1k
- Forks
- 543
- Avg merge
- 1d 17h
- Merged PRs (30d)
- 37
Description
Background
SEP-1932 / RFC 9449 DPoP conformance scenarios landed in the conformance suite. #1138 teaches the harness everything-client to pass auth/dpop via a hand-rolled path. That is not SDK support — apps using AuthorizationCodeHandler + StreamableClientTransport still cannot obtain or present DPoP-bound tokens.
Today setMCPHeaders hardcodes Authorization: Bearer (mcp/streamable.go), and OAuthHandler only exposes TokenSource + Authorize — enough for Bearer, not for a fresh per-request DPoP proof (htm/htu/ath/jti).
Proposal (baseline only; no nonce)
Ship one SDK PR that:
- Helpers (e.g. under
oauthex) — ES256 keypair, proof builder,ath, HTU normalize, RFC-vector tests. Nononcein the public API yet. - Transport — use
token.Type()(default Bearer); attach per-request proofs without breaking existingOAuthHandlerimplementors. AuthorizationCodeHandler— explicit opt-inDPoPconfig; proof on token exchange + refresh; implement the per-request hook.- Conformance — rewrite
everything-clientauth/dpopto use the SDK path (acceptance test). Keepauth/dpop-nonceinbaseline.yml.
Hook shape (prefer non-breaking)
Do not add a method to the OAuthHandler interface (breaking for external implementors). Prefer one of:
- A (preferred): optional interface type-asserted in
setMCPHeaders, e.g. handlers that also implementPrepareRequest(ctx, *http.Request) errorget called after Authorization is set. - B:
StreamableClientTransport.PrepareRequestfunc field set by the app / handler wiring.
AuthorizationCodeHandler with DPoP enabled would implement A (or set B).
Explicit opt-in only — no auto-enable from dpop_bound_access_tokens_required in v1.
Out of scope (follow later, same pattern)
auth/dpop-nonce(AS/RSuse_dpop_nonceretry)- Server
RequireDPoPmiddleware - Legacy SSE client OAuth/DPoP
Related
- Harness: #1138
- Spec: SEP-1932 / RFC 9449
- Conformance scenarios:
auth/dpop,auth/dpop-nonce
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with mcp/streamable.go and the OAuthHandler and AuthorizationCodeHandler entry points to trace header setup, token exchange, refresh, and request preparation. Review the RFC-vector test locations and the everything-client auth/dpop path, then verify the conformance scenario uses the SDK path while auth/dpop-nonce remains in baseline.yml.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- api, authentication, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 40/100