Add Server Cards example (SEP-2127)

Closed
DS
5mo ago
+1917-0

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

PathPurpose
mcp_server_card/types.pyPydantic port of the ServerCard / Server schema (camelCase wire format, reuses Icon)
mcp_server_card/schema.jsonBundled JSON Schema (from the experimental repo)
mcp_server_card/validation.pyJSON Schema validation + semantic guards (e.g. rejects version ranges) → typed models
mcp_server_card/client.pyfetch_server_card / load_server_card / well_known_url
mcp_server_card/server.pybuild_server_card / write_server_card / mount_server_card / add_server_card_route
mcp_server_card/cli.pymcp-server-card — validate / fetch / schema
examples/, tests/Runnable client + server flows, round-trip + conformance tests

Design

  • One type port, two consumers. types.py is the only place the schema is expressed; Icon is reused from mcp.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 raise ServerCardValidationError carrying every problem at once.
  • Servers build a card once (incl. server_card_from_implementation(...) to derive identity from an MCPServer), then either write_server_card(...) a static file or serve it from the .well-known path 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 serve exposes the card over HTTP and consume_card.py fetches + validates it; bare-Starlette mount_server_card also verified.
  • ruff clean; package builds and installs with uv (bundled schema.json ships in the wheel; mcp-server-card entry point works).

Open questions

  • Well-known path: uses /.well-known/mcp/server-card per the experimental repo README; schema.ts comment says mcp-server-card (no subpath) — worth reconciling upstream. Parameterized everywhere.
  • Schema distribution: schema.json is bundled for offline validation; a real SDK integration would track the version published at static.modelcontextprotocol.io.