Protocol Discovery · Essential · High impact
MCP server card
Since MCP 2026-07-28, agents discover tool servers through a published declaration.
- Essential
- High impact
- Draft standard
| Property | Value |
|---|---|
| Check id | mcp-card |
| Dimension | Protocol Discovery (25%) |
| Tier | Essential — pool 80 pts |
| Weight inside tier | 2 |
| Impact | High |
| Maturity | Draft — A published specification that is not yet ratified. |
| Conditional | No |
| Publishing skill | mcp-server-card |
| Standards | MCP 2026-07-28 |
What the scanner requests
-
/.well-known/mcp/server-card.json -
/.well-known/mcp.json -
/mcp.json
What is measured
The scanner GETs /.well-known/mcp/server-card.json first, then /.well-known/mcp.json and /mcp.json, and validates the first 200 response as JSON. It then requests the remote URLs of the first card that offers a transport, on the scanned origin only and up to a published cap, with one plain GET and no credentials. It passes when the document is a usable MCP Server Card - a reverse-DNS name containing exactly one slash, a version, a description, and at least one usable remotes entry giving a transport type (streamable-http or sse), a url and the supported protocol versions - and at least one remote on the scanned origin answered. A remote answers with a 2xx; a streamable-http remote also answers with 405 or 406, the refusal a running server gives a plain GET; and any remote answers with a 401 whose WWW-Authenticate challenge names resource_metadata, as MCP authorization requires. A bare 401 is not counted, because any authorization wall returns one. A remote is not usable when the card itself marks it status declared - a promise is not a transport - or when it is on the scanned origin, the scan requested it, and it answered anything else. It partially passes when the card is usable but no remote on the scanned origin answered: every remote is on another origin, was not requested, or did not answer, and the detail says which. It also partially passes when the JSON parses and carries name, version and description but no usable remotes entry. A $schema property is accepted when present but is deliberately NOT required: the schema URLs published for this extension do not resolve, and a check that demands a dead URL cannot be satisfied.
Reproduce it yourself
You do not have to take our word for any of this. Run the same measurement against your own domain:
DOMAIN=https://your-domain.example
for p in /.well-known/mcp/server-card.json /.well-known/mcp.json /mcp.json; do printf '%s -> ' "$p"; curl -sS "$DOMAIN$p" | jq -c '{name,version,description,remotes}' 2>/dev/null || echo "missing or not JSON"; done
The fix
This is the artifact to ship. It is the complete change, not a description of one.
{
"name": "com.example/weather",
"version": "1.0.0",
"description": "Live weather and forecast data for partner agents.",
"title": "Example Weather",
"websiteUrl": "https://your-domain.example/developers",
"remotes": [
{
"type": "streamable-http",
"url": "https://your-domain.example/mcp",
"supportedProtocolVersions": ["2026-07-28"]
}
]
}
Standards referenced
-
MCP 2026-07-28
Related checks
| Check | Tier | Impact | Same skill |
|---|---|---|---|
openapi — OpenAPI definition | Essential | High | — |
oauth-discovery — OAuth discovery documents | Essential | High | — |
api-catalog — API catalog | Recommended | Medium | — |
agent-skills — Agent Skills declaration | Recommended | Medium | — |
a2a-card — A2A agent card | Recommended | Medium | — |
a2a-signed — Cryptographically signed agent card | Emerging | Medium | — |
auth-md — /auth.md agent authentication guide | Emerging | Medium | — |
webmcp — WebMCP browser tool declaration | Emerging | Medium | — |