Skip to content

Commit 3c5f2da

Browse files
committed
Support SSL certificate verification option when creating httpx AsyncClient
1 parent d1ac8d6 commit 3c5f2da

File tree

3 files changed

+19
-1
lines changed

3 files changed

+19
-1
lines changed

src/mcp/client/sse.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ async def sse_client(
2828
sse_read_timeout: float = 60 * 5,
2929
httpx_client_factory: McpHttpClientFactory = create_mcp_http_client,
3030
auth: httpx.Auth | None = None,
31+
verify: bool | None = None,
3132
):
3233
"""
3334
Client transport for SSE.
@@ -55,7 +56,10 @@ async def sse_client(
5556
try:
5657
logger.debug(f"Connecting to SSE endpoint: {remove_request_params(url)}")
5758
async with httpx_client_factory(
58-
headers=headers, auth=auth, timeout=httpx.Timeout(timeout, read=sse_read_timeout)
59+
headers=headers,
60+
timeout=httpx.Timeout(timeout, read=sse_read_timeout),
61+
auth=auth,
62+
verify=verify,
5963
) as client:
6064
async with aconnect_sse(
6165
client,

src/mcp/client/streamable_http.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,7 @@ async def streamablehttp_client(
448448
terminate_on_close: bool = True,
449449
httpx_client_factory: McpHttpClientFactory = create_mcp_http_client,
450450
auth: httpx.Auth | None = None,
451+
verify: bool | None = None,
451452
) -> AsyncGenerator[
452453
tuple[
453454
MemoryObjectReceiveStream[SessionMessage | Exception],
@@ -481,6 +482,7 @@ async def streamablehttp_client(
481482
headers=transport.request_headers,
482483
timeout=httpx.Timeout(transport.timeout, read=transport.sse_read_timeout),
483484
auth=transport.auth,
485+
verify=verify,
484486
) as client:
485487
# Define callbacks that need access to tg
486488
def start_get_stream() -> None:

src/mcp/shared/_httpx_utils.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@ def __call__(
1313
headers: dict[str, str] | None = None,
1414
timeout: httpx.Timeout | None = None,
1515
auth: httpx.Auth | None = None,
16+
verify: bool | None = None,
1617
) -> httpx.AsyncClient: ...
1718

1819

1920
def create_mcp_http_client(
2021
headers: dict[str, str] | None = None,
2122
timeout: httpx.Timeout | None = None,
2223
auth: httpx.Auth | None = None,
24+
verify: bool | None = None,
2325
) -> httpx.AsyncClient:
2426
"""Create a standardized httpx AsyncClient with MCP defaults.
2527
@@ -32,6 +34,8 @@ def create_mcp_http_client(
3234
timeout: Request timeout as httpx.Timeout object.
3335
Defaults to 30 seconds if not specified.
3436
auth: Optional authentication handler.
37+
verify: Either True to use default CA bundle, False to disable verification, or an instance of ssl.SSLContext.
38+
3539
3640
Returns:
3741
Configured httpx.AsyncClient instance with MCP defaults.
@@ -60,6 +64,10 @@ def create_mcp_http_client(
6064
auth = BasicAuth(username="user", password="pass")
6165
async with create_mcp_http_client(headers, timeout, auth) as client:
6266
response = await client.get("/protected-endpoint")
67+
68+
# With SSL verification disabled
69+
async with create_mcp_http_client(verify=False) as client:
70+
response = await client.get("/insecure-endpoint")
6371
"""
6472
# Set MCP defaults
6573
kwargs: dict[str, Any] = {
@@ -80,4 +88,8 @@ def create_mcp_http_client(
8088
if auth is not None:
8189
kwargs["auth"] = auth
8290

91+
# Handle SSL verification
92+
if verify is not None:
93+
kwargs["verify"] = verify
94+
8395
return httpx.AsyncClient(**kwargs)

0 commit comments

Comments
 (0)