Skip to content

Commit 0e38647

Browse files
committed
Upgrade mcp SDK from 2.0.0b1 to 2.0.0b2
The b2 release replaces httpx with httpx2 internally. Update the MCP transport client factory in client.py to use httpx2.AsyncClient and related types. Adjust the corresponding test mock path accordingly.
1 parent c757e63 commit 0e38647

4 files changed

Lines changed: 51 additions & 113 deletions

File tree

MIGRATION_MCP_V2.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# CPEX MCP SDK v1 → v2 Migration Strategy
22

33
**Date:** 2025-07-03
4-
**Target SDK:** `mcp==2.0.0b1`, `mcp-types==2.0.0b1` (already pinned in `pyproject.toml`)
4+
**Target SDK:** `mcp==2.0.0b2`, `mcp-types==2.0.0b2` (already pinned in `pyproject.toml`)
55
**Source of truth:** [MCP Python SDK v2 Migration Guide](https://py.sdk.modelcontextprotocol.io/v2/migration/)
66

77
---
@@ -470,8 +470,8 @@ from mcp.client.stdio import stdio_client
470470

471471
The `pyproject.toml` already pins:
472472
```toml
473-
"mcp==2.0.0b1",
474-
"mcp-types==2.0.0b1",
473+
"mcp==2.0.0b2",
474+
"mcp-types==2.0.0b2",
475475
```
476476

477477
Per the [Dependency floors section](https://py.sdk.modelcontextprotocol.io/v2/migration/#dependency-floors-raised-and-new-required-dependencies), these new floors apply:

cpex/framework/external/mcp/client.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from typing import Any, Awaitable, Callable, Optional
2020

2121
# Third-Party
22-
import httpx
22+
import httpx2
2323
import orjson
2424
from mcp import ClientSession, MCPError, StdioServerParameters
2525
from mcp.client.stdio import stdio_client
@@ -315,10 +315,10 @@ async def __connect_to_http_server(self, uri: str) -> None:
315315

316316
def _tls_httpx_client_factory(
317317
headers: Optional[dict[str, str]] = None,
318-
timeout: Optional[httpx.Timeout] = None,
319-
auth: Optional[httpx.Auth] = None,
320-
) -> httpx.AsyncClient:
321-
"""Build an httpx client with TLS configuration for external MCP servers.
318+
timeout: Optional[httpx2.Timeout] = None,
319+
auth: Optional[httpx2.Auth] = None,
320+
) -> httpx2.AsyncClient:
321+
"""Build an httpx2 client with TLS configuration for external MCP servers.
322322
323323
Args:
324324
headers: Optional HTTP headers to include in requests.
@@ -334,14 +334,14 @@ def _tls_httpx_client_factory(
334334

335335
kwargs: dict[str, Any] = {"follow_redirects": True}
336336
if uds_path:
337-
kwargs["transport"] = httpx.AsyncHTTPTransport(uds=uds_path)
337+
kwargs["transport"] = httpx2.AsyncHTTPTransport(uds=uds_path)
338338
if headers:
339339
kwargs["headers"] = headers
340340
http_settings = get_http_client_settings()
341341
kwargs["timeout"] = (
342342
timeout
343343
if timeout
344-
else httpx.Timeout(
344+
else httpx2.Timeout(
345345
connect=http_settings.httpx_connect_timeout,
346346
read=http_settings.httpx_read_timeout,
347347
write=http_settings.httpx_write_timeout,
@@ -352,7 +352,7 @@ def _tls_httpx_client_factory(
352352
kwargs["auth"] = auth
353353

354354
# Add connection pool limits
355-
kwargs["limits"] = httpx.Limits(
355+
kwargs["limits"] = httpx2.Limits(
356356
max_connections=http_settings.httpx_max_connections,
357357
max_keepalive_connections=http_settings.httpx_max_keepalive_connections,
358358
keepalive_expiry=http_settings.httpx_keepalive_expiry,
@@ -361,14 +361,14 @@ def _tls_httpx_client_factory(
361361
if not tls_config:
362362
# Use skip_ssl_verify setting when no custom TLS config
363363
kwargs["verify"] = not http_settings.skip_ssl_verify
364-
return httpx.AsyncClient(**kwargs)
364+
return httpx2.AsyncClient(**kwargs)
365365

366366
# Create SSL context using the utility function
367367
# This implements certificate validation per test_client_certificate_validation.py
368368
ssl_context = create_ssl_context(tls_config, self.name)
369369
kwargs["verify"] = ssl_context
370370

371-
return httpx.AsyncClient(**kwargs)
371+
return httpx2.AsyncClient(**kwargs)
372372

373373
max_retries = 3
374374
base_delay = 1.0

tests/unit/cpex/framework/external/mcp/test_client_coverage.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
from unittest.mock import AsyncMock, MagicMock, patch
88

99
# Third-Party
10-
import httpx
1110
import orjson
1211
import pytest
1312
from mcp_types import TextContent
@@ -587,7 +586,7 @@ async def __aexit__(self, *args):
587586
patch("cpex.framework.external.mcp.client.streamable_http_client", return_value=OkCtx()),
588587
patch("cpex.framework.external.mcp.client.ClientSession", return_value=mock_session),
589588
patch("cpex.framework.external.mcp.client.create_ssl_context", return_value="sslctx"),
590-
patch("cpex.framework.external.mcp.client.httpx.AsyncClient") as mock_httpx,
589+
patch("cpex.framework.external.mcp.client.httpx2.AsyncClient") as mock_httpx,
591590
patch("cpex.framework.external.mcp.client.get_http_client_settings", return_value=mock_http_settings),
592591
):
593592
plugin._exit_stack = AsyncExitStack()

0 commit comments

Comments
 (0)