AI & Agent Dev Bug Sandbox logo
AI & Agent Dev Bug Sandbox
Back to Radar

Stdio Sessions Hang Forever When A Server Never Responds (No Default Read_timeout_seconds)

langchain_mcp_adapters.sessions._create_stdio_session constructs an MCP ClientSession without a default read_timeout_seconds, so any request to a non-responsive stdio server (e.g., during initialize()/call_tool()/list_tools()) blocks indefinitely. The MCP SDK already supports per-request timeouts via read_timeout_seconds; this library simply fails to set a default.

highConfidence 95%Langchain-Mcp-AdaptersAffected V0.3.2Affected Vmain

Origin Analysis

ClientSession accepts read_timeout_seconds (timedelta | None) and passes it to BaseSession.send_request, which wraps the awaited response in anyio.fail_after(read_timeout_seconds). When this value is None (the SDK default), anyio.fail_after(None) applies no timeout, leaving the caller awaiting forever if the server never responds. _create_stdio_session does not set read_timeout_seconds when constructing ClientSession, so the default None remains.
Create hanging_server.py: ```python import sys, time sys.stdin.readline() time.sleep(3600) ``` Then run: ```python import anyio, sys from langchain_mcp_adapters.sessions import _create_stdio_session async def main(): async with _create_stdio_session(command=sys.executable, args=["hanging_server.py"]) as session: with anyio.fail_after(3): await session.initialize() # hangs past this bound with no read_timeout_seconds anyio.run(main) ``` The test's own anyio.fail_after(3) raises TimeoutError, demonstrating that nothing internal bounds the wait.

Fixing Code Block

Edge Case Audit

If a legitimate MCP operation legitimately takes longer than 60 seconds (e.g., large tool execution), the new default will cause McpError timeouts. Callers can override by passing session_kwargs={'read_timeout_seconds': None} to disable the timeout, or a larger timedelta. Rollback: revert the one-line default addition; no other changes required. Older MCP SDK versions that do not support read_timeout_seconds in ClientSession may raise TypeError; ensure the installed mcp package is recent enough (>= the version that introduced read_timeout_seconds). Under concurrency, each send_request has its own timeout, so no cross-request interference. However, timeout only covers the JSON-RPC response wait, not internal server-side processing; a server that hangs during connection setup may still block before send_request.

Ecosystem Topology