MCP Server Cards: auditing the new discovery layer
MCP finally has a pre-connection discovery story. This week the text of SEP-2127 — MCP Server Cards — was marked Final in its pull request branch, and the design looks nothing like the January draft. The .well-known guessing game for cards is out. A protocol-agnostic AI Catalog is in.
The Model Context Protocol has had a strange blind spot since launch: a client cannot learn anything about a remote server without connecting to it. Name, version, supported transports, required headers — all of it sits behind a full initialization handshake. SEP-1649, opened in October 2025, framed the problem precisely: to obtain even basic metadata, clients must complete an entire handshake, which blocks registry crawling, domain-level indexing, and IDE autoconfiguration.
Its successor, SEP-2127, has been in review since January 21, 2026. On September 8 a working-group lead asked whether it was ready to merge, and the SEP text in the PR branch now reads Status: Final, Type: Extensions Track. As of publication the PR is still open — but the shape of MCP discovery is settled enough to audit. This post walks the final design, what changed during eight months of review, and what it does and does not solve for autonomous agents.
The gap: you cannot ask a server anything until you connect
MCP already has two partial answers to "how do I find a server." The MCP Registry solves publication: a centralized index with a server.json schema covering both remote endpoints and locally installable packages. And the server/discover RPC, added to the draft spec, solves live introspection — but only after you already know where to connect and can reach the endpoint.
Neither answers the domain-level question: given example.com, what MCP servers does it operate, where do they live, and what do I need to connect? That is the question a shopping agent asks before it spends money, the question an IDE asks when a user pastes a domain, and the question a crawler asks when building an ecosystem-wide index. Server Cards exist to answer it out-of-band: public, cacheable, indexable metadata that requires no protocol exchange at all.
The design pivot: from well-known cards to catalog-first
The January draft looked the way you would expect: serve a card at /.well-known/mcp-server-card, with a per-server variant for origins hosting multiple servers. Rich schema, CORS rules, IANA registration of the URI suffix. Conventional and self-contained.
The final design threw most of that out. In the merged-candidate text, a Server Card can be hosted at any unreserved URI — MCP reserves only one recommended location, GET <streamable-http-url>/server-card, adjacent to the transport endpoint itself. Domain-level discovery moves to a separate, protocol-agnostic document: the AI Catalog, published at /.well-known/ai-catalog.json, which links to or embeds the cards. Two media types make the layers explicit: application/ai-catalog+json for the catalog, application/mcp-server-card+json for the card.
The rationale is a hosting reality the first draft ignored. The SEP's own example: a restaurant uses one SaaS platform for MCP-powered reservations and another for MCP-powered job listings. Neither server runs on the restaurant's domain, and the restaurant cannot publish files under either vendor's .well-known path. With the catalog model, restaurant-a.com advertises both cards in its own catalog, and each SaaS platform hosts the cards for every tenant it serves. Cards on any domain, discovery anchored to the identity domain.
The working group also documented what it rejected. DNS TXT records — the approach we audited for x402 discovery — were ruled out because they only work at domain granularity, not for path- or port-based servers. Link-header discovery was ruled out because it requires an HTTP request to the endpoint first, which defeats the purpose of pre-connection discovery.
What a Server Card actually contains
The normative spec no longer lives in the SEP. Following the precedent set by MCP Apps, SEP-2127 is a chartering document; the wire format lives in the experimental-ext-server-card repository, where a TypeScript file, schema.ts, is the single source of truth and the JSON Schema is generated from it. The extension identifier is io.modelcontextprotocol/server-card.
A card describes exactly three things: identity, transport, and protocol versions. A minimal but realistic card:
{
"$schema": "https://static.modelcontextprotocol.io/schemas/v1/server-card.schema.json",
"name": "com.example/weather",
"version": "1.4.0",
"description": "Forecasts and historical weather data",
"title": "Example Weather",
"remotes": [
{
"type": "streamable-http",
"url": "https://example.com/mcp",
"supportedProtocolVersions": ["2026-07-28"],
"headers": [
{ "name": "X-API-Key", "isRequired": true, "isSecret": true }
]
}
]
}
The schema details reward a close read. name is reverse-DNS with exactly one forward slash separating namespace from server name — the same identity convention as the Registry. version should be semver and explicitly rejects ranges (^1.2.3, 1.x). $schema must point at the /v1/ schema URL; breaking revisions publish a new vN family rather than date-versioned schemas. Remote URLs support {curly_brace} template variables, and both URL variables and headers are described as typed inputs — with description, isRequired, isSecret, format, default, and choices — so a client can prompt a user for an API key or a region without vendor-specific configuration UI.
One small field carries a lot of security thinking: the optional repository.id, the hosting service's stable repo identifier. Because a deleted-and-recreated repository gets a new ID, registries can use it to detect repository resurrection attacks — someone re-registering an abandoned name to ship a malicious server under established identity.
The catalog flow
Discovery starts at the domain. A client fetches https://{domain}/.well-known/ai-catalog.json, filters entries by the Server Card media type, then either follows each entry's url or reads the card inline from data:
{
"specVersion": "1.0",
"entries": [
{
"identifier": "urn:air:example.com:mcp:weather",
"type": "application/mcp-server-card+json",
"url": "https://example.com/mcp/server-card"
}
]
}
Catalog identifiers use a domain-anchored URN format, urn:air:{publisher}:{namespace}:{name}. Entries deliberately do not repeat the card's human-readable fields — title, description, and version live in the card only, so the two documents cannot drift apart.
The AI Catalog itself is not an MCP artifact. It is a typed, nestable container for heterogeneous AI metadata, developed in a working repository currently maintained under the Linux Foundation, with contributors from multiple protocol communities. The stated plan is for the A2A and MCP steering committees to vote on adopting it as a shared standard. If that lands, the same .well-known document that advertises a domain's MCP servers will advertise its A2A Agent Cards — one discovery root for the whole agentic surface of a domain.
What cards deliberately leave out
The most consequential design decision is negative: Server Cards do not enumerate tools, resources, or prompts. The reasoning is that MCP servers are dynamic — the primitives a server exposes vary by authenticated user, session, configuration, and feature flags. A static manifest cannot represent that surface honestly, and a card that lists tools invites clients to make trust decisions against stale or falsified data. Runtime listing via tools/list with the logged-in identity remains the only source of truth. Capabilities and negotiated extension support are excluded on the same grounds, and the spec is explicit that _meta may not be used to smuggle them in.
server/discover wherever the two disagree.
This restraint is the right call, and it is worth noting how it interacts with the 2026-07-28 spec release. That release formalized the extensions framework (SEP-2133) that makes Server Cards shippable as an optional, independently versioned extension at all — no core protocol changes, full backward compatibility, and the extension maintainers can iterate without waiting for a spec release train.
Status, governance, implementations
The Server Card Working Group was chartered on March 26, 2026, led by David Soria Parra (Anthropic) and Sam Morrow Drums (GitHub), with Tadas Antanavicius as a member. Its charter draws clean boundaries: the Registry WG owns server.json and the catalog/registry problem; the Server Card format covers remote connectivity only and should stay compatible with Registry metadata where the concepts overlap. The MCP roadmap update published August 22, 2026 lists the group's .well-known conventions work as an active track toward the next spec release.
Reference implementations already exist: an experimental Python SDK implementation covering server-side card construction, client-side fetch and validation, and Pydantic models; a Go SDK server-side implementation; and a demonstration of card-driven discovery and installation in the Goose client. That is exactly the working group's stated success criteria — SDK availability plus real clients and servers with reach — being assembled before the merge rather than after.
Audit notes: where the design is thin
Four things stand out after reading the schema, the discovery spec, and the review thread.
No integrity mechanism
Cards and catalogs are plain JSON over HTTPS. There is no signature, no hash, no way to bind a card to the key of the operator it claims to describe. The spec's mitigation is the advisory rule: a compromised card "primarily affects discoverability rather than connection security." That holds for connection metadata. It holds less well for the discovery decision itself — a tampered catalog can steer an agent to a lookalike endpoint that speaks perfectly valid MCP. Compare NANDA's AgentFacts, which signs agent metadata precisely because unsigned discovery is a phishing surface. For agents that pay for what they discover, transport security alone is a thin guarantee.
A hard dependency on an unratified external spec
Domain-level discovery — the headline use case — is delegated entirely to the AI Catalog, which lives in a temporary repository and still awaits adoption votes by the MCP and A2A steering committees. The SEP hedges well: cards can be iterated independently as long as catalog entries can point to them. But until the catalog is ratified, "fetch /.well-known/ai-catalog.json" is a convention two committees could still reshape.
The well-known path excludes hosted tenants — partially solved
Review raised that small businesses on hosted website platforms cannot write to .well-known paths at all. The catalog model helps — cards can live on the SaaS vendor's domain — but the discovery root still assumes the identity domain can serve a well-known file. A restaurant on a fully managed website builder still depends on that builder shipping catalog support.
Consistency is SHOULD-level
A card SHOULD match the server's runtime serverInfo and server/discover values, and clients SHOULD verify. Nothing enforces it. Drift between static metadata and live behavior is the known failure mode of every manifest system; here it is handled by convention, and the ecosystem's crawlers and registries will need their own revalidation cadence.
What it means for LLM4Agents
Discovery is the layer just above payments in our stack, and this proposal touches both sides of what we run.
As an operator, we expose MCP tools for the gateway — model listing, balance queries, usage reporting. Today an agent finds those tools because we documented them. Under this design, publishing a Server Card at the reserved <endpoint>/server-card location plus an ai-catalog.json at our domain root makes the same surface machine-discoverable: an IDE pointed at our domain can autoconfigure the gateway's MCP connection, headers and protocol versions included. The typed headers inputs map cleanly onto API-key provisioning. This is cheap, additive, and indexable by every registry crawler that adopts the flow.
As infrastructure for paying agents, the calculus is sharper. An agent that discovers a service pre-connection and then pays it per call via x402 is making a spend decision partly on discovery metadata — exactly the data this spec declares advisory and leaves unsigned. The same lesson we drew from the x402 well-known discovery audit applies here: discovery layers tell you where to look, and must never be allowed to tell you whom to trust. Our position in the middle of the payment flow is the natural place to enforce that separation — verified endpoint pinning for payment-bearing tools, card claims cross-checked against live serverInfo before any funds move.
Strategically, the AI Catalog is the piece to watch. If MCP and A2A converge on one .well-known discovery root, the fragmented discovery landscape — MCP Registry, A2A cards, x402 discovery, vendor directories — gets a shared anchor. A platform that already speaks both the payment and tool layers should be present in that document from day one.
Staying on the frontier
Concrete steps, in order:
- Publish now. Ship a v1 Server Card at the reserved location on our MCP endpoint and an
/.well-known/ai-catalog.jsonreferencing it, validated against the extension repo's generatedschema.json. The format is Final in all but merge status; early publication costs nothing and gets us indexed first. - Implement verified discovery in the agent-facing SDK. Fetch card, connect, compare
name/version/transport against runtime values, and hard-fail the payment path on mismatch. Make the advisory rule an enforced rule wherever money follows discovery. - Track the merge and the Tier-1 SDK train. When the Python and Go SDK implementations land in releases, replace any hand-rolled card handling with official types.
- Watch the AI Catalog adoption votes. If
urn:airidentifiers become the cross-protocol convention, align our agent and service identifiers with the same domain-anchored scheme rather than inventing another namespace. - Push on signatures. The unsigned-metadata gap is the opening for the identity layer we already track — signed cards, or catalog entries bound to onchain agent identity, would close the discovery-phishing hole. That argument belongs in the working group's thread now, not after the first incident.
Build agents that discover and pay
One gateway, 345+ models, stablecoin billing per call — infrastructure for agents that find their own services.
Register your agent