Bug Description
When McpClientOptions.ProtocolVersion is explicitly set, the client requires the server to respond with that exact version. If the server responds with a different but supported version (e.g., negotiating down), the client throws McpException: Server protocol version mismatch.
This violates proper MCP protocol negotiation, where the server may respond with any version it supports — which may be lower than the version the client requested.
Reproduction
Set McpClientOptions.ProtocolVersion = "DRAFT-2026-v1" and connect to a server that responds with "2025-11-25" (a valid supported version). The client throws:
McpException: Server protocol version mismatch. Expected DRAFT-2026-v1, got 2025-11-25
This was discovered when running the client conformance tests with MCP_CONFORMANCE_PROTOCOL_VERSION=DRAFT-2026-v1. 18 of 34 tests failed because the conformance mock server responds with "2025-11-25" for scenarios originally tagged for that version, even when the test suite runs under DRAFT-2026-v1.
Root Cause
In McpClientImpl.cs, the protocol version validation uses a ternary that enforces an exact match when ProtocolVersion is explicitly set:
bool isResponseProtocolValid =
_options.ProtocolVersion is { } optionsProtocol ? optionsProtocol == initializeResponse.ProtocolVersion :
McpSessionHandler.SupportedProtocolVersions.Contains(initializeResponse.ProtocolVersion);
Expected Behavior
The client should accept any server response version that is in SupportedProtocolVersions, regardless of whether ProtocolVersion was explicitly set. The explicit version should still be accepted as a fallback (for forward compatibility with versions not yet in the supported list).
Fix
Change the validation to:
bool isResponseProtocolValid =
McpSessionHandler.SupportedProtocolVersions.Contains(initializeResponse.ProtocolVersion) ||
(_options.ProtocolVersion is { } optionsProtocol && optionsProtocol == initializeResponse.ProtocolVersion);
Why This Was Not Caught
- No conformance scenario explicitly tests protocol version downgrade negotiation.
- The SDK's own
ReturnsNegotiatedProtocolVersion test uses ClientServerTestBase where the server always echoes back the client's requested version.
- The bug only manifests when
ProtocolVersion is explicitly set and the server responds with a different (but supported) version.
Bug Description
When
McpClientOptions.ProtocolVersionis explicitly set, the client requires the server to respond with that exact version. If the server responds with a different but supported version (e.g., negotiating down), the client throwsMcpException: Server protocol version mismatch.This violates proper MCP protocol negotiation, where the server may respond with any version it supports — which may be lower than the version the client requested.
Reproduction
Set
McpClientOptions.ProtocolVersion = "DRAFT-2026-v1"and connect to a server that responds with"2025-11-25"(a valid supported version). The client throws:This was discovered when running the client conformance tests with
MCP_CONFORMANCE_PROTOCOL_VERSION=DRAFT-2026-v1. 18 of 34 tests failed because the conformance mock server responds with"2025-11-25"for scenarios originally tagged for that version, even when the test suite runs underDRAFT-2026-v1.Root Cause
In
McpClientImpl.cs, the protocol version validation uses a ternary that enforces an exact match whenProtocolVersionis explicitly set:Expected Behavior
The client should accept any server response version that is in
SupportedProtocolVersions, regardless of whetherProtocolVersionwas explicitly set. The explicit version should still be accepted as a fallback (for forward compatibility with versions not yet in the supported list).Fix
Change the validation to:
Why This Was Not Caught
ReturnsNegotiatedProtocolVersiontest usesClientServerTestBasewhere the server always echoes back the client's requested version.ProtocolVersionis explicitly set and the server responds with a different (but supported) version.