Estas guías de corrección están escritas en inglés.
MCP (Model Context Protocol)
Esta comprobación representa el 3% de la puntuación.
How to create a Model Context Protocol configuration: the missing file, server metadata, tools, resources, and CORS.
An MCP server is only useful to an agent that knows the URL. Without discovery, somebody has to paste it in by hand, which means your server is reachable by people who already know about you and nobody else.
/.well-known/mcp.json carrying a tools[] array, and recommended publishing one. That path was never part of the MCP specification and that array was never part of a card. If you followed the old advice, the legacy manifest section says what to do with the file.The check looks in four places, in order, and the first hit wins:
- an entry in
/.well-known/ai-catalog.json /.well-known/mcp/server-card.json, the Cloudflare and Mintlify convention<endpoint>/server-card, what the draft extension recommends/.well-known/mcp.json, legacy, reported and never recommended
No MCP server discoverable
Nothing at any of the four. If you run no MCP server this is nothing to fix and the check reports it as such. If you do run one, agents have to be told its URL by a person.
GET /.well-known/mcp/server-card.json
Content-Type: application/mcp-server-card+json
{
"$schema": "https://modelcontextprotocol.io/schemas/draft/server-card.schema.json",
"name": "com.example/docs",
"version": "1.0.0",
"description": "Search and read the Example documentation.",
"websiteUrl": "https://example.com",
"remotes": [
{
"type": "streamable-http",
"url": "https://example.com/mcp",
"supportedProtocolVersions": ["2026-07-28"]
}
]
}Then reference it from /.well-known/ai-catalog.json so one file names everything you offer.
/.well-known/mcp.json is served
A folk convention that predates server cards, and one this audit used to recommend. It is reported rather than scored: serving it is not an error, and it is not discovery either, because no client looks there.
Publish a server card first. Once a card exists, remove the manifest rather than keeping both: two files describing one server is two places to update and one place to forget.
The manifest has no name
Your /.well-known/mcp.json is missing name, so anything reading it has a server with no identity. Add the field if you intend to keep the file working while clients migrate.
com.example/docs. Writing the same name here means the manifest and the card agree while both exist, and nothing has to be renamed when the manifest goes away.The manifest has no description
The description is the one line that decides whether a client connects at all. Without it, whoever is looking at your server sees a name and a URL and has to try it to find out what it does.
Say what the server is for in a sentence, in the terms a caller would use: "Search and read the Example documentation", not "MCP server".
Some tools have no description
Part of your tools array carries a description and part does not. A tool with no description is one an agent will not choose, because choosing is exactly what it reads the description for.
The undescribed tools are usually the ones added last, after the file stopped being reviewed. That is also the argument for the live tools/list call: a description written next to the handler is written once and cannot fall behind.
No tool has a description
Every entry in tools is a bare name. An agent picking between search and query has nothing to pick on, so it either guesses or calls both.
{
"name": "search_docs",
"description": "Search the documentation and return matching sections with their URLs.",
"inputSchema": {
"type": "object",
"properties": { "query": { "type": "string" } },
"required": ["query"]
}
}Write the description for the caller, not for the changelog: what it does, what it returns, and when to reach for it rather than a neighbouring tool.
The tools array is empty
"tools": [] is a server that declares it can do nothing. It is almost always a placeholder that shipped, or a generator that ran before the tools were registered.
If the server does have tools, list them. If it does not — a resources-only server is legitimate — drop the empty array rather than publishing a claim you do not mean.
No tools array
The manifest describes a server without saying what can be called on it. For a file whose only purpose is to be read statically, that leaves nothing to read.
tools array — see a tools array in the card. The two files disagree on this because they answer different questions: the manifest was a static catalogue, the card is a pointer to a live server you call tools/list on.No resources array
Resources are the data an MCP server exposes for reading, as opposed to the tools it exposes for calling: files, records, documents addressed by URI. Your manifest lists none.
Plenty of servers are genuinely tools-only, and this is reported rather than treated as an error. If yours does expose readable data, list it — a resource an agent cannot see is one it will try to reach through a tool call instead.
No protocol version
Nothing in the manifest says which revision of MCP the server speaks, so a client cannot tell whether its own revision will work before connecting.
{
"protocolVersion": "2026-07-28"
}2026-07-28 is the current revision. The server card spells this as supportedProtocolVersions, an array, because a server usually speaks more than one — see no supportedProtocolVersions.
The card is not valid JSON
Served and unparseable. Check for a trailing comma, and check the response is not an HTML error page returned with a 200.
A required field is missing
A server card declares four things: $schema, name, version and description. The description is the one most often left out and the one an agent reads to decide whether to connect at all.
A name that is not in reverse-DNS form
Names are reverse-DNS so that a registry listing a thousand servers has no collisions: com.example/docs, io.github.owner/server. A bare word like docs is not globally unambiguous, and half the servers in the world would like to be called it.
A tools array in the card
The schema deliberately omits it. Tool lists come from a live tools/list call, and a static copy in a cached file drifts from the server the first time you ship a change.
A card is a pointer, not an inventory: it says where the server is and what it speaks, and the server says what it can do.
No remotes declared
The card describes a server and does not say where it is. Declare at least one:
"remotes": [
{
"type": "streamable-http",
"url": "https://example.com/mcp",
"supportedProtocolVersions": ["2026-07-28"]
}
]An unrecognised transport
Two are defined: streamable-http and sse. SSE is the legacy transport; new servers use streamable-http. Anything else is skipped by a client that validates.
A remote with no url
Every remote needs an absolute https:// URL. A relative path cannot be resolved by a client that found the card through a catalog on another origin.
No supportedProtocolVersions
Without it a client has to connect and negotiate to find out whether it can talk to you at all. Declaring the revisions you speak, newest first, turns that into a decision made before the connection.
An unrecognised revision
MCP revisions are dates. A semantic version, or a date that was never released, will not match anything a client knows. The released revisions are 2026-07-28, 2025-11-25, 2025-06-18, 2025-03-26 and 2024-11-05.
Only pre-2025-06 revisions supported
Clients on newer revisions may not negotiate down. 2026-07-28 removed sessions and initialize, made MCP-Protocol-Version mandatory on every POST, and added server/discover, so the gap between old and current is a different handshake rather than a few extra fields.
No CORS on the card
Browser-based agents fetch the card cross-origin and are refused without it. The extension recommends both of these:
Access-Control-Allow-Origin: * Cache-Control: public, max-age=3600
The card is a public document, so the permissive origin costs nothing. If the header is missing here it is usually missing everywhere; the HTTP Headers guide covers setting it once, at the edge.
The catalog declares no version
The card was found through /.well-known/ai-catalog.json and that catalog carries no specVersion, so a consumer cannot tell which revision of the catalog shape to expect. See the AI Catalog guide.
An incomplete catalog entry
An entry needs an identifier, a type, and either a url or an inline data object. Missing one, it is listed and unusable.
An unrecognised entry type
Three types are defined: application/mcp-server-card+json, application/a2a-agent-card+json and application/ai-catalog+json. An entry outside them is skipped.