Skip to content

Commit 0bb9ee7

Browse files
committed
Build send_discover params via DiscoverRequest; gate preconnect cancel-suppression by method
- send_discover: construct params through types.DiscoverRequest/RequestParams instead of a hand-rolled dict (same wire shape; routing stays raw because the probe's _meta version is per-call, not session state). - _preconnect_stamp: only suppress cancel_on_abandon for initialize and server/discover, so lowlevel ClientSession callers that skip the handshake keep the courtesy cancel on timed-out/abandoned requests. - send_discover docstring: drop the nonexistent ProbeNotRecognized entry; fold the transport-4xx case into the MCPError Raises line. - migration.md: note the MCP_PROTOCOL_VERSION header constant move to mcp.shared.inbound.MCP_PROTOCOL_VERSION_HEADER.
1 parent 20a564e commit 0bb9ee7

2 files changed

Lines changed: 20 additions & 13 deletions

File tree

docs/migration.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,8 @@ Note: `sse_client` retains its `headers`, `timeout`, `sse_read_timeout`, and `au
163163

164164
The transport no longer holds per-connection protocol state; era-dependent headers (e.g. `MCP-Protocol-Version`) are now supplied per-message by the session. If you were reading `transport.protocol_version` to learn the negotiated version, read `session.protocol_version` (or `client.protocol_version` on the high-level `Client`) instead.
165165

166+
The `MCP_PROTOCOL_VERSION` header-name constant has moved: import `MCP_PROTOCOL_VERSION_HEADER` from `mcp.shared.inbound` instead of `MCP_PROTOCOL_VERSION` from `mcp.client.streamable_http`.
167+
166168
### `terminate_windows_process` removed
167169

168170
The deprecated `mcp.os.win32.utilities.terminate_windows_process` function has been

src/mcp/client/session.py

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,10 @@
5252

5353

5454
def _preconnect_stamp(data: dict[str, Any], opts: CallOptions) -> None:
55-
# Only initialize/discover go out before connect; both forbid cancellation.
56-
opts["cancel_on_abandon"] = False
55+
# initialize/discover forbid cancellation; other pre-handshake requests (lowlevel
56+
# ClientSession callers may skip the handshake entirely) keep the courtesy cancel.
57+
if data["method"] in ("initialize", "server/discover"):
58+
opts["cancel_on_abandon"] = False
5759

5860

5961
def _make_handshake_stamp(protocol_version: str) -> Callable[[dict[str, Any], CallOptions], None]:
@@ -402,25 +404,28 @@ async def send_discover(self, version: str) -> dict[str, Any]:
402404
the connect-time auto-negotiation policy.
403405
404406
Raises:
405-
MCPError: The server returned a JSON-RPC error.
406-
ProbeNotRecognized: The transport bounced the request at its own
407-
layer (HTTP 4xx without a JSON-RPC error body).
407+
MCPError: The server returned a JSON-RPC error, or the transport
408+
bounced the request at its own layer (a bare HTTP 4xx is
409+
synthesized into a JSON-RPC error by the transport).
408410
"""
409411
client_info = self._client_info.model_dump(by_alias=True, mode="json", exclude_none=True)
410412
capabilities = self._build_capabilities().model_dump(by_alias=True, mode="json", exclude_none=True)
411-
params = {
412-
"_meta": {
413-
PROTOCOL_VERSION_META_KEY: version,
414-
CLIENT_INFO_META_KEY: client_info,
415-
CLIENT_CAPABILITIES_META_KEY: capabilities,
416-
}
417-
}
413+
request = types.DiscoverRequest(
414+
params=types.RequestParams(
415+
_meta={
416+
PROTOCOL_VERSION_META_KEY: version,
417+
CLIENT_INFO_META_KEY: client_info,
418+
CLIENT_CAPABILITIES_META_KEY: capabilities,
419+
}
420+
)
421+
)
422+
data = request.model_dump(by_alias=True, mode="json", exclude_none=True)
418423
opts: CallOptions = {
419424
"timeout": DISCOVER_TIMEOUT_SECONDS,
420425
"cancel_on_abandon": False,
421426
"headers": {MCP_PROTOCOL_VERSION_HEADER: version},
422427
}
423-
return await self._dispatcher.send_raw_request("server/discover", params, opts)
428+
return await self._dispatcher.send_raw_request(data["method"], data.get("params"), opts)
424429

425430
async def discover(self) -> types.DiscoverResult:
426431
"""Probe `server/discover` and adopt the result.

0 commit comments

Comments
 (0)