Add experimental Server Cards support (SEP-2127)
Closes https://github.com/modelcontextprotocol/experimental-ext-server-card/issues/16
Summary
Experimental SDK support for MCP Server Cards (SEP-2127) and AI Catalog discovery, opt-in under mcp.{shared,server,client}.experimental. As an experimental extension, these APIs may change without notice.
Takes over #2696 (thanks @dsp-ant — the original two commits are preserved with authorship), rebased cleanly onto current main. #2696 was stacked on the Tasks (SEP-1686) work, since removed from main (#2714).
Opening as a draft for maintainer review — per the extension repo's contribution rules, AI-assisted changes are not self-merged.
What it does
A server builds a Server Card from its own identity, serves it from a Starlette app, and advertises it through an AI Catalog. A client discovers a host's catalog, then fetches and validates the cards it references. Cards describe identity and remote (HTTP) transport only — locally-runnable package metadata stays in the MCP Registry's server.json.
Conformance to the current schemas
$schemais pinned tohttps://static.modelcontextprotocol.io/schemas/v1/server-card.schema.json; a card pointing at the registry'sserver.schema.jsonis rejected. A document that omits$schemais defaulted to the v1 URL rather than rejected.- AI Catalog entries use the serialized
typefield, requirespecVersion, and accept optionaldisplayName.server_card_entry()emits the minimal MCP shape (identifier,type, andurl) so human-readable fields cannot drift from the referenced card. - Media type — serving and catalog entries use
application/mcp-server-card+json; the client recognizes only this type and skips catalog entries declaring anything else. - Catalog identifiers are
urn:air:{publisher}:mcp:{name}— the card name's reverse-DNS namespace turned back into the publisher's forward-DNS domain (com.example/weather→urn:air:example.com:mcp:weather). - Discovery uses the AI Catalog at
/.well-known/ai-catalog.json. Discovery responses carry the CORS headers the spec requires (MUST),Cache-Control(SHOULD), strong SHA-256 ETags, andIf-None-Matchhandling for conditional requests. versionaccepts exact versions only; ranges and wildcards (^1.2.3,~1.2.3,>=1.2.3,1.x,1 || 2,1 - 2) are rejected.- Unsettled AI Catalog metadata remains available but is documented as unstable pending the outcome of Agent-Card/ai-catalog#77.
Verification
./scripts/test— full coverage suite andstrict-no-coverpre-commit run --all-files— formatting, lint, pyright, markdownlint, lock consistency, and README snippets- Focused Server Card and AI Catalog tests cover URL and inline discovery, entry filtering, relative URLs, CORS on both
200and304, ETags, validation, and client/server helpers
🤖 The implementation and cleanup were AI-assisted and human-directed.