feat: add mcp:// discovery URI resolution (draft-serra-mcp-discovery-uri)#952
Open
vincenzopalazzo wants to merge 1 commit into
Open
feat: add mcp:// discovery URI resolution (draft-serra-mcp-discovery-uri)#952vincenzopalazzo wants to merge 1 commit into
vincenzopalazzo wants to merge 1 commit into
Conversation
…uri)
Implements the client-side resolver for IETF draft-serra-mcp-discovery-uri:
resolve an mcp://host[:port][/path] URI to a working MCP server endpoint.
Resolution chain:
1. (optional fast-mode) DNS TXT _mcp.{host} for endpoint hint,
_mcp-key.{host} for JWK public key used to verify manifest signatures
2. (authoritative) GET https://{host}/.well-known/mcp-server manifest
3. (fallback) direct handshake probe at https://{host}/mcp
Security posture: HTTPS-only; endpoint host must equal-or-be-subdomain of
discovery host; detached JWS signature verified against DNS-published JWK;
fail-closed when a manifest claims a signature we cannot verify.
Feature-gated behind 'discovery' (DNS+HTTP resolver) and 'discovery-jws'
(adds JWS signature verification via jsonwebtoken).
Co-Authored-By: goose <goose@aaif.ai>
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.
Summary
Implements the client-side resolver for IETF draft-serra-mcp-discovery-uri: resolve an
mcp://host[:port][/path]URI to a working MCP server endpoint.This was originally submitted as a goose core PR (aaif-goose/goose#9660) but @DOsinga correctly identified that the resolver is generic plumbing with nothing goose-specific — it belongs here in rmcp.
Resolution chain:
_mcp.{host}for endpoint hint,_mcp-key.{host}for JWK public key used to verify manifest signaturesGET https://{host}/.well-known/mcp-servermanifesthttps://{host}/mcpSecurity posture: HTTPS-only; endpoint host must equal-or-be-subdomain of discovery host; detached JWS signature verified against DNS-published JWK; fail-closed when a manifest claims a signature we cannot verify.
Feature-gated behind
discovery(DNS + HTTP resolver) anddiscovery-jws(adds JWS signature verification viajsonwebtoken).cc @alexhancock
Review Notes
#[ignore]d — they need real TLS infrastructure to test HTTPS resolution against a live serverbuilder_tokio()requiressystem-configfeature;txt_datais a field not a method)#[non_exhaustive]per rmcp'sexhaustive_structs/exhaustive_enumsclippy lintscargo clippy -D warningsclean,cargo fmtappliedDecision Log
Hardest decision: Marking the 3 E2E tests (
e2e_well_known_manifest_resolution,e2e_direct_fallback_resolution,e2e_no_server_found) as#[ignore]rather than trying to set up a self-signed TLS server in unit tests. The resolver always buildshttps://URLs frommcp://URIs (correct per spec), but spinning up a TLS-enabled axum server with self-signed certs in a unit test adds significant complexity for marginal coverage — the resolution logic is fully exercised by the 32 mock-based tests. The E2E tests are left in place for manual/integration testing.Alternatives rejected:
http://for127.0.0.1/localhostwould violate the spec's HTTPS-only requirement and create a security hole.Least confident about: The JWS canonicalization in
jws.rs— it's a JCS-style approximation (recursive key sort + compact serialization) that covers typical manifests but does not implement full RFC 8785 number/unicode normalization. A mismatch fails closed (rejects a valid signature), never the reverse, but a reviewer with crypto expertise should confirm this is acceptable for the draft stage.Test plan
cargo test -p rmcp --features "discovery,discovery-jws" --lib discovery— 32 tests pass, 3 ignoredcargo clippy -p rmcp --features "discovery,discovery-jws" -- -D warnings— cleancargo fmt --check— clean