Add Server Cards example (SEP-2127)
Closed
DS
5mo ago+1917+1917+0123456789012345678901234567890123456789-0-0-0123456789
Summary
Adds a self-contained example package under examples/server-card/ demonstrating
MCP Server Cards (SEP-2127)
in Python: clients consuming and validating a card, and servers generating and
publishing one. It ports the TypeScript source of truth in
experimental-ext-server-card
and follows mcp.types conventions, so the mcp_server_card/ library could later
be lifted into mcp/experimental/server_card/ largely unchanged.
A Server Card is a static metadata document (typically at
https://<host>/.well-known/mcp/server-card) describing a remote server's
identity, transport endpoints, and supported protocol versions, so a client can
discover and connect to it before initialization.
Layout
| Path | Purpose |
|---|---|
mcp_server_card/types.py | Pydantic port of the ServerCard / Server schema (camelCase wire format, reuses Icon) |
mcp_server_card/schema.json | Bundled JSON Schema (from the experimental repo) |
mcp_server_card/validation.py | JSON Schema validation + semantic guards (e.g. rejects version ranges) → typed models |
mcp_server_card/client.py | fetch_server_card / load_server_card / well_known_url |
mcp_server_card/server.py | build_server_card / write_server_card / mount_server_card / add_server_card_route |
mcp_server_card/cli.py | mcp-server-card — validate / fetch / schema |
examples/, tests/ | Runnable client + server flows, round-trip + conformance tests |
Design
- One type port, two consumers.
types.pyis the only place the schema is expressed;Iconis reused frommcp.types(already in the core spec). - Clients validate in two layers via
parse_server_card/parse_server: JSON Schema (authoritative structure) + Pydantic constraints and semantic guards JSON Schema can't express. Failures raiseServerCardValidationErrorcarrying every problem at once. - Servers build a card once (incl.
server_card_from_implementation(...)to derive identity from anMCPServer), then eitherwrite_server_card(...)a static file or serve it from the.well-knownpath on a Starlette app /MCPServer.
Validation
pytest: 10 passing (round-trip, discriminated transport/argument unions, camelCase serialization, invalid-card rejection).- Cross-checked against the conformance fixtures in
experimental-ext-server-card/examples/— all valid cards parse, all invalid ones are rejected. - End-to-end verified:
serve_card.py serveexposes the card over HTTP andconsume_card.pyfetches + validates it; bare-Starlettemount_server_cardalso verified. ruffclean; package builds and installs withuv(bundledschema.jsonships in the wheel;mcp-server-cardentry point works).
Open questions
- Well-known path: uses
/.well-known/mcp/server-cardper the experimental repo README;schema.tscomment saysmcp-server-card(no subpath) — worth reconciling upstream. Parameterized everywhere. - Schema distribution:
schema.jsonis bundled for offline validation; a real SDK integration would track the version published atstatic.modelcontextprotocol.io.