🤖 Drafted by Claude Code (an AI coding agent) on behalf of @tadasant. The substance was reviewed by a human before filing.
Summary
The Server Card spec describes what a card declares (identity, transport, supported protocol versions) but states no requirement that those declarations match the server's actual runtime behavior. A Server Card is fetched before the initialize handshake, so a stale or incorrect card can claim a name, version, transport, or protocol-version set that contradicts what a client observes once it connects. There is currently no normative text saying the card must not lie, nor that clients must not treat it as authoritative.
This carries over a review point @a-akimov raised on SEP-2127 (PR #2127, comment on L345):
I believe it's a very important point that the MCP Server Card SHOULD (MUST?) mirror the actual behaviour of the MCP server (card content should not contradict what a client would receive when doing actual initialization). Should we have a section explicitly mentioning this requirement somewhere in the main part of this SEP? Not only mentioning at the end in the Backward Compatibility one.
It survives the SEP-2127 → Extensions Track charter refactor (#15 / modelcontextprotocol#2893): #2893 deletes the detailed normative content from the SEP and makes this repo the source of truth, but its deletion-audit translates the schema, server.json, endpoint mechanics, and the five security sub-sections — and never carries a card-vs-runtime consistency requirement to anywhere. It is currently homeless in both the SEP and this repo.
Current state
schema.ts already encodes half of the relevant threat model — the half about fields the card deliberately omits. Primitives are excluded precisely because a static manifest can drift from runtime (schema.ts#L16-L19):
* Server Cards intentionally describe only what is needed to discover and
* connect to a remote server: identity, transport, and protocol versions.
* They do not enumerate primitives (tools, resources, prompts) — those remain
* subject to runtime listing via the protocol's standard list operations.
SEP-2127 states the security reasoning behind that exclusion explicitly — "the actual primitives at runtime may differ due to auth scoping, feature flags, configuration, or other dynamic factors."
But neither schema.ts nor docs/discovery.md states the complementary requirement for the fields the card does declare — name, version, remotes[].type / url, supportedProtocolVersions, and the descriptive title / description / icons. Nothing says those must be consistent with what a client receives at initialize, and nothing tells clients not to rely on them as authoritative.
This is distinct from the existing open issues:
Proposed resolution
Add an explicit normative subsection — most naturally in docs/discovery.md's "MCP Server Cards" / Security Considerations area, with a short pointer comment in schema.ts — roughly:
- A Server Card SHOULD accurately reflect the server's actual behavior. The values a client receives from the server in any
DiscoverResultResponse SHOULD NOT contradict equivalent values in the Server Card.
- Clients MUST NOT treat Server Card contents as authoritative for security or access-control decisions, and SHOULD verify card claims against the live connection after connecting — the same posture the spec already takes toward primitives, generalized to the declared fields.
- Note the security angle for the Security Considerations section: a card that overstates transport/protocol support (or otherwise misrepresents the server) is a mild confusion/downgrade vector, so this consistency requirement is partly a security property, not just a correctness one.
Derived from @a-akimov's review of SEP-2127 (PR #2127); carried into this repo because #2893 moves the normative source of truth here.
Summary
The Server Card spec describes what a card declares (identity, transport, supported protocol versions) but states no requirement that those declarations match the server's actual runtime behavior. A Server Card is fetched before the
initializehandshake, so a stale or incorrect card can claim aname,version, transport, or protocol-version set that contradicts what a client observes once it connects. There is currently no normative text saying the card must not lie, nor that clients must not treat it as authoritative.This carries over a review point @a-akimov raised on SEP-2127 (PR #2127, comment on L345):
It survives the SEP-2127 → Extensions Track charter refactor (#15 / modelcontextprotocol#2893): #2893 deletes the detailed normative content from the SEP and makes this repo the source of truth, but its deletion-audit translates the schema,
server.json, endpoint mechanics, and the five security sub-sections — and never carries a card-vs-runtime consistency requirement to anywhere. It is currently homeless in both the SEP and this repo.Current state
schema.tsalready encodes half of the relevant threat model — the half about fields the card deliberately omits. Primitives are excluded precisely because a static manifest can drift from runtime (schema.ts#L16-L19):SEP-2127 states the security reasoning behind that exclusion explicitly — "the actual primitives at runtime may differ due to auth scoping, feature flags, configuration, or other dynamic factors."
But neither
schema.tsnordocs/discovery.mdstates the complementary requirement for the fields the card does declare —name,version,remotes[].type/url,supportedProtocolVersions, and the descriptivetitle/description/icons. Nothing says those must be consistent with what a client receives atinitialize, and nothing tells clients not to rely on them as authoritative.This is distinct from the existing open issues:
discovery.mdaligned with the schema on the primitives the card omits. This issue is about the truthfulness of the fields the card includes.Proposed resolution
Add an explicit normative subsection — most naturally in
docs/discovery.md's "MCP Server Cards" / Security Considerations area, with a short pointer comment inschema.ts— roughly:DiscoverResultResponseSHOULD NOT contradict equivalent values in the Server Card.Derived from @a-akimov's review of SEP-2127 (PR #2127); carried into this repo because #2893 moves the normative source of truth here.