Skip to content

Commit fff3c11

Browse files
authored
Prevent MCP ClientSession hang
Per https://modelcontextprotocol.io/specification/draft/basic/lifecycle#timeouts "Implementations SHOULD establish timeouts for all sent requests, to prevent hung connections and resource exhaustion. When the request has not received a success or error response within the timeout period, the sender SHOULD issue a cancellation notification for that request and stop waiting for a response. SDKs and other middleware SHOULD allow these timeouts to be configured on a per-request basis."
1 parent 178020e commit fff3c11

File tree

1 file changed

+9
-1
lines changed

1 file changed

+9
-1
lines changed

src/agents/mcp/server.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import abc
44
import asyncio
55
from contextlib import AbstractAsyncContextManager, AsyncExitStack
6+
from datetime import timedelta
67
from pathlib import Path
78
from typing import Any, Literal
89

@@ -69,6 +70,9 @@ def __init__(self, cache_tools_list: bool):
6970
self._cleanup_lock: asyncio.Lock = asyncio.Lock()
7071
self.cache_tools_list = cache_tools_list
7172

73+
self.timeout: float = 5
74+
"""The timeout for the MCP ClientSession. Defaults to 5 seconds."""
75+
7276
# The cache is always dirty at startup, so that we fetch tools at least once
7377
self._cache_dirty = True
7478
self._tools_list: list[MCPTool] | None = None
@@ -101,7 +105,11 @@ async def connect(self):
101105
try:
102106
transport = await self.exit_stack.enter_async_context(self.create_streams())
103107
read, write = transport
104-
session = await self.exit_stack.enter_async_context(ClientSession(read, write))
108+
session = await self.exit_stack.enter_async_context(
109+
ClientSession(
110+
read, write, read_timeout_seconds=timedelta(seconds=self.timeout)
111+
)
112+
)
105113
await session.initialize()
106114
self.session = session
107115
except Exception as e:

0 commit comments

Comments
 (0)