Skip to content

feat: add mark3labs/mcp-go adapter; harden DPoP htu and RFC 9728 PRM#12

Merged
muralx merged 2 commits into
mainfrom
feat/mark3labs-adapter-and-dpop-hardening
Jun 16, 2026
Merged

feat: add mark3labs/mcp-go adapter; harden DPoP htu and RFC 9728 PRM#12
muralx merged 2 commits into
mainfrom
feat/mark3labs-adapter-and-dpop-hardening

Conversation

@muralx

@muralx muralx commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a new mark3labs adapter module for mark3labs/mcp-go, and tightens DPoP proof verification and RFC 9728 Protected Resource Metadata handling across core and the net/http adapter.

Added

  • mark3labs module — adapter for mark3labs/mcp-go. Wraps
    *authplanehttp.Adapter so consumers get bearer + DPoP auth, RFC 9728 PRM,
    and HTTPContextFunc integration for the mark3labs HTTP server.
    HTTPContextFunc accepts WithForwardedContextKeys(...) and
    WithContextForwarding(fn) to propagate request IDs / tracing spans onto the
    per-tool-call MCP context. See mark3labs/docs/user-guide.md.
  • core/resource/verifier: (*VerifiedClaims).RequireScopes(...) plural helper
    with enriched insufficient-scope errors (names every missing scope plus the
    scopes the token carries, for verbatim use in the WWW-Authenticate
    error_description).
  • core/resource/verifier: NewDPoPContext(...) factory and
    ErrMultipleDpopProofs sentinel — the canonical RFC 9449 §4.3 deps: bump github.com/modelcontextprotocol/go-sdk from 1.4.1 to 1.6.0 in /mcp in the gomod-all group #1 enforcement
    boundary, mapped to a DPoP error="invalid_dpop_proof" 401 challenge (§7.1).
  • core/resource: Resource.PRMURL() and typed Resource.PRMConfig() for
    RFC 9728 metadata, the latter for feeding third-party PRM-serving handlers
    without going through the dynamic PRMResponse map.

Fixed

  • DPoP htu binding compares EscapedPath() (encoded %2F is no longer
    treated as /), strips explicit default ports (:80/:443, RFC 9110 §7.2),
    and collapses an empty path to / on both sides — so bare-origin and
    default-port resources stop spuriously rejecting valid proofs (RFC 9449 §4.3,
    RFC 3986 §6.2.2.2).

Breaking changes (pre-1.0)

See CHANGELOG.md for the full list and migration details.

Testing

go vet, go build, golangci-lint, and the full test suite (incl. the RFC
conformance harness) pass across all modules; per-module coverage floors met.

Add a new `mark3labs` module adapting mark3labs/mcp-go (bearer + DPoP auth,
RFC 9728 PRM, HTTPContextFunc forwarding), and tighten DPoP proof
verification and Protected Resource Metadata handling across core and the
net/http adapter.

- DPoP htu binding: compare EscapedPath (encoded %2F is not /), strip
  default ports and collapse empty paths on both sides (RFC 9110 §7.2,
  RFC 9449 §4.3), and pin scheme/authority to the configured resource URI
  instead of the proxy-controlled Host header and r.TLS.
- Reject requests carrying more than one DPoP header via NewDPoPContext /
  ErrMultipleDpopProofs (RFC 9449 §4.3 #1, §7.1).
- VerifiedClaims.RequireScopes plural helper with enriched
  insufficient-scope errors.
- Resource.PRMURL() and typed Resource.PRMConfig() for RFC 9728 metadata.
- NewAdapterFromClientAndResource constructors return (*Adapter, error)
  instead of panicking on a nil client.

Includes BREAKING (pre-1.0) changes to DPoPContext and the net/http htu
reconstruction; see CHANGELOG for migration steps.
@muralx
muralx requested a review from a team as a code owner June 10, 2026 08:46
The mark3labs adapter module (own go.mod, own mark3labs/vX.Y.Z publish
path) was missing from the per-release-tag automation. Extend it
everywhere the other modules appear:

- release.yml: derive the mark3labs tag; include mark3labs in the
  vet/lint, require-bump, test, tag-creation, atomic-push, and summary
  steps. mark3labs wraps the http adapter, so it also gets a require-http
  bump (after the core-require loop, so the core hash is already stable).
- cut-release.yml: extend the pre-cut "tag already exists" guard to the
  mark3labs tag.

@RobertoIskandarani RobertoIskandarani left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@muralx
muralx merged commit b5bd34c into main Jun 16, 2026
9 checks passed
@muralx
muralx deleted the feat/mark3labs-adapter-and-dpop-hardening branch June 16, 2026 15:52
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.

2 participants