Repository navigation
Description
Initial Checks
- I confirm that I'm using the latest version of MCP Python SDK
- I confirm that I searched for my issue in https://github.com/modelcontextprotocol/python-sdk/issues before opening this issue
Description
I could not determine if this may be design intent, but I ran into issue where ClientSession.initialize() hardcodes protocolVersion=types.LATEST_PROTOCOL_VERSION with no way for the caller to override it. When connecting to an MCP server that requires a specific protocol version (e.g. Snowflake's managed MCP server requires "2025-06-18"), the only workaround is to mutate the module-level constant before calling initialize() and restore it afterward. Please feel free me to provide guidance if this can be resolved differently.
Current behaviour (mcp/client/session.py, v1.26.0)
async def initialize(self) -> types.InitializeResult:
result = await self.send_request(
types.ClientRequest(
types.InitializeRequest(
params=types.InitializeRequestParams(
protocolVersion=types.LATEST_PROTOCOL_VERSION, # no override possible
...
)
)
),
types.InitializeResult,
)
ClientSession.init() accepts many optional parameters (sampling_callback, client_info, etc.) but has no protocol_version parameter.
Steps to reproduce
- Install mcp>=1.0
- Connect to any MCP server that requires a protocol version other than LATEST_PROTOCOL_VERSION
- Call session.initialize() — the server rejects the handshake
- Concrete example: Snowflake managed MCP server requires "2025-06-18". With mcp==1.26.0 (LATEST_PROTOCOL_VERSION = "2025-11-25"), the session is terminated immediately after initialize().
Proposed fix
Add an optional protocol_version parameter to ClientSession.init():
def __init__(
self,
read_stream: ...,
write_stream: ...,
...
protocol_version: str | None = None, # NEW — defaults to LATEST_PROTOCOL_VERSION
) -> None:
self._protocol_version = protocol_version or types.LATEST_PROTOCOL_VERSION
Then use it in initialize():
protocolVersion=self._protocol_version,
Non-breaking change; existing callers get the current default. Callers that need a specific version pass it explicitly without touching any globals.
Example Code
"""
ClientSession.initialize() hardcodes LATEST_PROTOCOL_VERSION
with no way to override it via the public API.
Tested with: Python 3.14.2, mcp==1.26.0
"""
import asyncio
import mcp.types as mcp_types
from mcp.client.session import ClientSession
from mcp.client.streamable_http import streamablehttp_client
MCP_URL = "https://<your-account>.snowflakecomputing.com/api/v2/databases/<DB>/schemas/<SCHEMA>/mcp-servers/<SERVER>"
HEADERS = {"Authorization": "Bearer <your-pat>", "X-Snowflake-Role": "<your-role>"}
# The version Snowflake's MCP server requires during initialize handshake.
# The library hardcodes "2025-11-25" — Snowflake rejects it with "Session terminated".
REQUIRED_VERSION = "2025-06-18"
async def main():
# Without the patch — Snowflake terminates the session:
async with streamablehttp_client(url=MCP_URL, headers=HEADERS) as (r, w, _):
async with ClientSession(r, w) as session:
await session.initialize() # raises: "Session terminated"
asyncio.run(main())Python & MCP Python SDK
Python: 3.14.2
MCP Python SDK: 1.26.0
Activity
feat(client): add protocol_version parameter to ClientSession
feat: Add protocol_version parameter to ClientSession
feat: Add protocol_version parameter to ClientSession
goingforstudying-ctrl commentedon Mar 20, 2026
Submitted PR #2321 to implement this feature: #2321
This adds the protocol_version parameter to ClientSession, allowing users to connect to servers that require a specific protocol version (like Snowflake). Please review when you have time. Thanks!
tsingh2k15 commentedon Mar 21, 2026
Tested and confirmed working.
I couldn't test PR #2321 directly, I applied the PR's two changes manually to the installed mcp==1.26.0 session.py:
Added
protocol_version: str | None = None to ClientSession.__init__()Stored as
self._protocol_version = protocol_version or types.LATEST_PROTOCOL_VERSIONUsed
self._protocol_versionininitialize()instead of the hardcoded constantWith those changes in place, I updated my code to pass
protocol_version="2025-06-18"directly toClientSessionand removed my module-level global mutation workaround entirely. The smoke test against Snowflake's managed MCP server passed; data returned successfully.The fix is clean and non-breaking.
Thanks @goingforstudying-ctrl for picking this up quickly.
feat: Add protocol_version parameter to ClientSession
feat: Add protocol_version parameter to ClientSession
maxisbey commentedon Aug 10, 2026
The client offering its newest protocol version is the spec's negotiation model — a server that doesn't support that version responds with one it does, and the client accepts the counter-offer (e.g.
2025-06-18); on v2 the handshake version is deliberately not pinnable (docs/protocol-versions.md, "Pinning a version"). Closing this as part of a wider backlog cleanup following the v2 launch. Feel free to reopen if this is still relevant.AI Disclaimer