diff --git a/docs/discovery.md b/docs/discovery.md index 6768df6..7faffd9 100644 --- a/docs/discovery.md +++ b/docs/discovery.md @@ -150,6 +150,25 @@ A Server Card includes: For the full Server Card specification, see [SEP-2127: MCP Server Cards](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2127). +### Consistency with Runtime Behavior + +A Server Card is fetched _before_ the client connects, so its contents are unverified when +read. A Server Card SHOULD accurately reflect the server's runtime behavior: the values a +client observes once connected — the `serverInfo` (`name`, `version`) and `supportedVersions` +from [`server/discover`](https://modelcontextprotocol.io/specification/draft/server/discover), +the transport served at each `remotes[]` endpoint, and descriptive fields (`title`, +`description`, `icons`) — SHOULD NOT contradict the equivalent values declared in the Server +Card. + +As with the deliberately omitted primitives (tools, resources, prompts), a static manifest +can drift from runtime, so even the fields a Server Card does declare are advisory rather +than binding. Accordingly: + +- Clients MUST NOT treat Server Card contents as authoritative for security or + access-control decisions. +- Clients SHOULD verify a Server Card's claims against the live connection, preferring the + runtime values where the two disagree. + ### Server Card Location The Catalog is the discovery entrypoint, and every Catalog Entry already carries the @@ -233,6 +252,17 @@ information such as: - Internal network topology or private endpoints - Proprietary business logic +### Server Card Accuracy + +A Server Card is consumed before the client connects, so an inaccurate one — stale or +deliberately crafted — is a mild confusion or downgrade vector: one that overstates +transport or protocol-version support, or misrepresents the server's identity, can steer a +client toward a weaker configuration or the wrong server before it observes the actual +`server/discover` response. This makes the consistency requirement partly a security +property, not merely a matter of correctness. The normative protections live in +[Consistency with Runtime Behavior](#consistency-with-runtime-behavior): clients do not +treat a Server Card as authoritative and reconcile it against the live connection. + ### CORS Requirements Discovery endpoints MUST include appropriate CORS headers to allow browser-based clients: diff --git a/schema.json b/schema.json index ea100c5..781fc9f 100644 --- a/schema.json +++ b/schema.json @@ -527,7 +527,7 @@ "type": "object" }, "ServerCard": { - "description": "A static metadata document describing a remote MCP server, suitable for\npre-connection discovery. A Server Card MAY be hosted at any unreserved URI;\nMCP reserves `GET /server-card` as the recommended\nlocation. Clients learn a card's URL from an MCP/AI Catalog rather than\nguessing it.\n\nServer Cards intentionally describe only what is needed to discover and\nconnect to a remote server: identity, transport, and protocol versions.\nThey do not enumerate primitives (tools, resources, prompts) — those remain\nsubject to runtime listing via the protocol's standard list operations.\n\nThe companion {@link Server} shape is a strict superset that adds local\npackage metadata for use cases like the MCP Registry's `server.json`.", + "description": "A static metadata document describing a remote MCP server, suitable for\npre-connection discovery. A Server Card MAY be hosted at any unreserved URI;\nMCP reserves `GET /server-card` as the recommended\nlocation. Clients learn a card's URL from an MCP/AI Catalog rather than\nguessing it.\n\nServer Cards intentionally describe only what is needed to discover and\nconnect to a remote server: identity, transport, and protocol versions.\nThey do not enumerate primitives (tools, resources, prompts) — those remain\nsubject to runtime listing via the protocol's standard list operations.\n\nThe fields a Server Card does declare (identity, transport, protocol\nversions) are advisory, not authoritative: they SHOULD be consistent with\nthe server's `server/discover` response, and clients MUST NOT treat them as\nauthoritative for security decisions. See \"Consistency with Runtime\nBehavior\" in docs/discovery.md for the normative requirement.\n\nThe companion {@link Server} shape is a strict superset that adds local\npackage metadata for use cases like the MCP Registry's `server.json`.", "properties": { "$schema": { "description": "The Server Card JSON Schema URI that this document conforms to. Required.\n\nMust be a `/v1/` URL under `static.modelcontextprotocol.io/schemas/`,\nnaming a Server Card / `server.json` schema (e.g.,\n`https://static.modelcontextprotocol.io/schemas/v1/server-card.schema.json`\nor `https://static.modelcontextprotocol.io/schemas/v1/server.schema.json`).\nSchema URLs are versioned by the `vN` segment rather than by date so that\nminor, additive revisions of the v1 shape don't bump every published\ndocument's `$schema` URL.", diff --git a/schema.ts b/schema.ts index 32eccca..a8211d8 100644 --- a/schema.ts +++ b/schema.ts @@ -21,6 +21,12 @@ * They do not enumerate primitives (tools, resources, prompts) — those remain * subject to runtime listing via the protocol's standard list operations. * + * The fields a Server Card does declare (identity, transport, protocol + * versions) are advisory, not authoritative: they SHOULD be consistent with + * the server's `server/discover` response, and clients MUST NOT treat them as + * authoritative for security decisions. See "Consistency with Runtime + * Behavior" in docs/discovery.md for the normative requirement. + * * The companion {@link Server} shape is a strict superset that adds local * package metadata for use cases like the MCP Registry's `server.json`. *