Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

MCP server discovery: where each document belongs

Four different documents describe an MCP server to a client that has not connected yet. They are easy to confuse, they live in different places, and only two of them are settled standards. This page says which is which.

DocumentWhere it goesStatus
Registry manifest (server.json)Anywhere. /.well-known/mcp.json by conventionOfficial schema, unofficial path
Server Card<streamable-http-url>/server-cardExperimental extension, SEP-2127 under review
AI Catalog/.well-known/ai-catalog.jsonStandards-track, site-wide
Protected-resource metadata/.well-known/oauth-protected-resourceRatified, RFC 9728

None of them replaces the others. A registry manifest tells a package manager how to install a server. A Server Card tells a client how to connect to a remote one. An AI Catalog tells a crawler which servers a domain runs at all. The RFC 9728 document tells a client how to authenticate once it has arrived.

What is /.well-known/mcp.json?

A convention, not a standard. No MCP specification defines that path.

It is still worth serving, because scanners, directories and agent-readiness tools probe for it, and a server that answers is easier to find than one that does not. Just do not treat it as compliance with anything.

The body is the MCP registry’s server.json, and that part is official. The schema is published and versioned, currently at https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json, and it requires name, description and version. It carries installation metadata: npm, PyPI, NuGet, OCI and MCPB packages, runtime hints, arguments and environment variables.

So the file is an official document at an unofficial address.

What is a Server Card?

A static document describing one remote server: its identity, its transport endpoints, and the protocol versions it speaks. Enough for a client to connect, and nothing more.

Its reserved location is not a .well-known path. It is the streamable-HTTP URL with /server-card appended:

GET https://mcp.example.com/server-card

A server hosted at https://example.com/mcp therefore serves its card at https://example.com/mcp/server-card. The path namespacing comes free, and one host can run several servers without collision.

The extension’s own discovery notes considered a .well-known URI and rejected it, on the grounds that .well-known is for site-wide metadata while a single server’s card is application-level. A card can live at any unreserved URI; the /server-card suffix is only the predictable default.

Four fields are required: $schema, name, description and version. name must be reverse-DNS with exactly one slash, and description is capped at 100 characters. remotes, repository, title, icons and websiteUrl are optional.

Cards deliberately do not list tools, resources or prompts. Those stay runtime listings, because a static file cannot keep up with them.

Serve the card as application/mcp-server-card+json, with Access-Control-Allow-Origin: * so browser clients can read it, an ETag, and Cache-Control: public, max-age=3600. Honour If-None-Match with a 304.

Read the status before you build on it

The schema lives in modelcontextprotocol/experimental-ext-server-card, which describes itself as “not an accepted or official MCP extension”. SEP-2127 is under review, and the repository is meant to be lifted into the main specification if the proposal is accepted.

There is a wrinkle worth knowing before you validate anything. The schema pins $schema by regex to exactly https://static.modelcontextprotocol.io/schemas/v1/server-card.schema.json, and that URL returned 404 when we checked it on 2026-08-23. A conforming card has to cite a schema that nobody can currently resolve.

A card is advisory, not authoritative

A client reads the card before it connects, so nothing in it has been verified at the point of reading. The specification is explicit that clients must not treat card contents as authoritative for security or access-control decisions, and should prefer the live connection wherever the two disagree.

That makes accuracy a security property rather than a matter of tidiness. A card that claims more transports or more protocol versions than the server actually serves can steer a client into a weaker configuration before it observes the real server/discover response. Keep the card’s supportedProtocolVersions equal to what the server will really accept. If you reject older revisions, do not list them.

What is the AI Catalog?

The document that answers “which MCP servers does this domain run?”. It lives at /.well-known/ai-catalog.json, and unlike the two above, being site-wide is exactly why a .well-known path is right for it.

Each entry points at a Server Card, either by URL or inline:

{
  "specVersion": "1.0",
  "entries": [
    {
      "identifier": "urn:air:example.com:mcp:weather",
      "type": "application/mcp-server-card+json",
      "url": "https://example.com/mcp/server-card"
    }
  ]
}

The AI Catalog is how a client learns a card’s address, which is why cards are allowed to live anywhere. It may also point at servers on other domains, so an organisation can advertise a server that somebody else operates for it.

What about protected-resource metadata?

/.well-known/oauth-protected-resource is the one document here that is a ratified standard, and it answers a different question from the other three: not “where is the server” but “how do I authenticate to it”. It has to be same-origin with the endpoint it describes.

See authentication for how we score it and how to add it. There is also /.well-known/owners.json, which proves who controls a domain rather than describing a server.

What we serve

VerifyMCP runs a remote MCP server, so these are our four real addresses:

URLDocument
verifymcp.io/.well-known/mcp.jsonRegistry manifest, on the brand domain, so the service can be found from the name people know
mcp.verifymcp.io/.well-known/mcp.jsonThe same manifest, same-origin with the endpoint
mcp.verifymcp.io/server-cardServer Card
mcp.verifymcp.io/.well-known/oauth-protected-resourceRFC 9728 metadata

We serve the manifest twice on purpose. The copy on the brand domain is a pointer, and a pointer you can only fetch once you already know the address is not doing its job. The copy on the service origin is for consumers that expect a discovery document to share an origin with the endpoint it describes.

Both are generated from one file, so they cannot drift apart. The card reads its name and version from that same file, which is what keeps it honest against the running server: our test suite fails if the card’s protocol versions stop matching what server/discover reports.

Where to start

Serve the registry manifest first. It is the most widely read of the four, the schema is stable, and it is what gets you listed.

Add protected-resource metadata next if your server does anything that needs authorising, because that one is a real standard and we score it.

Add a Server Card when you want clients to be able to connect without reading your documentation first, and accept that the format may still move.

Written by Stuart Blackler · Last reviewed 24 August 2026.