Skip to content

Commit d1258af

Browse files
committed
Keep migration.md scoped to v1.x breakage
The server-identity section described 2026-07-28 behavior only: server/discover does not exist in v1.x, so no v1 code path reaches it. The migration guide covers exactly what breaks when v1.x code moves to v2; the identity stamp and the Implementation|None client surface are documented on the low-level server, middleware, and client pages instead. The era-neutral accessors section keeps its corrected server_info type without the removed cross-reference. No-Verification-Needed: docs-only edit
1 parent fb9b64c commit d1258af

2 files changed

Lines changed: 2 additions & 36 deletions

File tree

docs/migration.md

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -468,40 +468,6 @@ now a plain `dict[str, Any]`: pass a dict when constructing params
468468
and read extras with dictionary access (`params.meta["traceparent"]`) instead of
469469
attribute access. The JSON wire format is unchanged.
470470

471-
### Server identity moved from the `server/discover` result body to result `_meta`
472-
473-
The 2026-07-28 draft changed how identity travels
474-
([spec #3002](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/3002)):
475-
`serverInfo` is no longer a field of the `server/discover` result. Servers now
476-
report who they are by stamping `io.modelcontextprotocol/serverInfo` into the
477-
`_meta` of every 2026-era result, and the request-side `clientInfo` `_meta` key
478-
became optional (`protocolVersion` and `clientCapabilities` remain required).
479-
480-
What changed in the SDK:
481-
482-
- `DiscoverResult` no longer has a `server_info` field. Read or write identity
483-
through result `_meta`; the key is exported as `mcp_types.SERVER_INFO_META_KEY`.
484-
- Servers stamp `serverInfo` into every 2026-era result's `_meta`, built from
485-
the constructor identity fields (`name`, `version`, `title`, and so on). A
486-
`serverInfo` value your handler already set in `_meta` is never overwritten.
487-
Handshake-era responses are unchanged, and notifications and error responses
488-
are never stamped. A middleware that answers a request itself (without
489-
`call_next`) owns its result envelope, stamp included; a server that must
490-
not identify itself can strip the key the same way, with a middleware that
491-
removes it from the results it passes along.
492-
- `client.server_info` and `session.server_info` are `Implementation | None`
493-
on 2026-era connections: identity is optional on the wire, so a server that
494-
does not stamp it reads as `None`. Handshake-era connections still always
495-
have it. A pinned `Client(target, mode="2026-07-28")` without
496-
`prior_discover=` now reports `None` instead of an `Implementation` with
497-
empty strings. The stamp is display-only in the spec, so a malformed value
498-
from a misbehaving server also reads as `None` rather than failing the call.
499-
- Requests that omit `clientInfo` are now accepted. On the server,
500-
`ctx.session.client_params` is `None` for such requests; capability checks
501-
should use `ctx.session.client_capabilities` (or `ctx.client_capabilities`
502-
in `MCPServer` handlers), which is recorded whether or not the client
503-
identified itself.
504-
505471
### `SUPPORTED_PROTOCOL_VERSIONS` deprecated; `LATEST_PROTOCOL_VERSION` changed meaning
506472

507473
`SUPPORTED_PROTOCOL_VERSIONS` is deprecated — it's now the union of `HANDSHAKE_PROTOCOL_VERSIONS` (initialize-handshake versions) and `MODERN_PROTOCOL_VERSIONS` (per-request-envelope versions). If you were using it to mean "versions the initialize handshake accepts", switch to `HANDSHAKE_PROTOCOL_VERSIONS`. Named scalars derived from these tuples are now exported alongside them — `LATEST_HANDSHAKE_VERSION`, `LATEST_MODERN_VERSION`, `OLDEST_SUPPORTED_VERSION` — so prefer those over indexing the tuples directly. All of these live in `mcp_types.version` (previously `mcp.shared.version`): `from mcp_types.version import HANDSHAKE_PROTOCOL_VERSIONS`.
@@ -1532,7 +1498,7 @@ version = session.protocol_version
15321498

15331499
The raw handshake result is also retained: `session.initialize_result` is set after `initialize()` (≤2025-11-25 servers — including `stateless_http=True` servers, which still answer `initialize`); `session.discover_result` is set after `discover()` (2026-07-28+ servers). At most one is non-`None`.
15341500

1535-
On the high-level `Client`, `client.server_capabilities` and `client.protocol_version` are non-nullable inside the context manager. `client.instructions` remains `str | None` since the server may omit it, and `client.server_info` is `Implementation | None`: on 2026-era connections identity is optional wire metadata, so a server that does not report it reads as `None` (see [Server identity moved to result `_meta`](#server-identity-moved-from-the-serverdiscover-result-body-to-result-_meta)). (The lowlevel `ClientSession` still lets you call methods before any handshake, as in v1; `Client` always connects on enter — by default it probes `server/discover` and falls back to the initialize handshake.)
1501+
On the high-level `Client`, `client.server_capabilities` and `client.protocol_version` are non-nullable inside the context manager. `client.instructions` remains `str | None` since the server may omit it, and `client.server_info` is `Implementation | None`: on 2026-era connections identity is optional wire metadata, so a server that does not report it reads as `None`. (The lowlevel `ClientSession` still lets you call methods before any handshake, as in v1; `Client` always connects on enter — by default it probes `server/discover` and falls back to the initialize handshake.)
15361502

15371503
### `cursor` parameter removed from `ClientSession` list methods
15381504

docs/whats-new.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ At 2026-07-28 the standalone HTTP GET stream and `resources/subscribe` are repla
197197

198198
### The rest, quickly
199199

200-
* **Identity is optional, per-message metadata.** The request-side `clientInfo` `_meta` key is optional (the required pair is `protocolVersion` + `clientCapabilities`), and `serverInfo` moved out of the `server/discover` result body: servers stamp it into every 2026-era result's `_meta` instead (since `2.0.0b3`; [spec #3002](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/3002)). The SDK always stamps; `client.server_info` is `None` when a server does not identify itself (for example, a middleware stripped the key). The **[Migration Guide](migration.md#server-identity-moved-from-the-serverdiscover-result-body-to-result-_meta)** has the details.
200+
* **Identity is optional, per-message metadata.** The request-side `clientInfo` `_meta` key is optional (the required pair is `protocolVersion` + `clientCapabilities`), and `serverInfo` moved out of the `server/discover` result body: servers stamp it into every 2026-era result's `_meta` instead (since `2.0.0b3`; [spec #3002](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/3002)). The SDK always stamps; `client.server_info` is `None` when a server does not identify itself (for example, a middleware stripped the key). **[The low-level Server](advanced/low-level-server.md)** shows the stamp on the wire.
201201
* **Requests are routable without parsing bodies.** Modern HTTP requests carry `Mcp-Method` (and, for the three tool-ish calls, `Mcp-Name`); a tool input-schema property annotated with `x-mcp-header` is mirrored into an `Mcp-Param-*` header and cross-checked by the server ([SEP-2243](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2243)). Gateways and rate limiters can route on headers alone; the **[Migration Guide](migration.md#servers-validate-mcp-param-headers-against-the-request-body-sep-2243)** has the rules.
202202
* **Results carry cache hints.** List and read results declare `ttlMs` and `cacheScope` ([SEP-2549](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2549)); you set them per method with `cache_hints=`, and `Client` honors them with a built-in response cache. A server that sends no hints (every pre-2026 server) sees identical, uncached traffic. **[Caching hints](client/caching.md)**.
203203
* **Extensions are first class.** Servers and clients declare optional capability bundles under reverse-DNS identifiers ([SEP-2133](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2133)); the built-in `Apps` extension (MCP Apps) is the reference. **[Extensions](advanced/extensions.md)** and **[MCP Apps](advanced/apps.md)**.

0 commit comments

Comments
 (0)