9
9
from mcp import ClientSession
10
10
from pydantic import AnyUrl
11
11
12
+ import fastmcp
12
13
from fastmcp .client .logging import (
13
14
LogHandler ,
14
15
MessageHandler ,
@@ -45,8 +46,8 @@ class Client:
45
46
MCP client that delegates connection management to a Transport instance.
46
47
47
48
The Client class is responsible for MCP protocol logic, while the Transport
48
- handles connection establishment and management. Client provides methods
49
- for working with resources, prompts, tools and other MCP capabilities.
49
+ handles connection establishment and management. Client provides methods for
50
+ working with resources, prompts, tools and other MCP capabilities.
50
51
51
52
Args:
52
53
transport: Connection source specification, which can be:
@@ -62,18 +63,18 @@ class Client:
62
63
message_handler: Optional handler for protocol messages
63
64
progress_handler: Optional handler for progress notifications
64
65
timeout: Optional timeout for requests (seconds or timedelta)
66
+ init_timeout: Optional timeout for initial connection (seconds or timedelta).
67
+ Set to 0 to disable. If None, uses the value in the FastMCP global settings.
65
68
66
69
Examples:
67
- ```python
68
- # Connect to FastMCP server
69
- client = Client("http://localhost:8080")
70
+ ```python # Connect to FastMCP server client =
71
+ Client("http://localhost:8080")
70
72
71
73
async with client:
72
- # List available resources
73
- resources = await client.list_resources()
74
+ # List available resources resources = await client.list_resources()
74
75
75
- # Call a tool
76
- result = await client.call_tool("my_tool", {"param": "value"})
76
+ # Call a tool result = await client.call_tool("my_tool", {"param":
77
+ "value"})
77
78
```
78
79
"""
79
80
@@ -93,6 +94,7 @@ def __init__(
93
94
message_handler : MessageHandler | None = None ,
94
95
progress_handler : ProgressHandler | None = None ,
95
96
timeout : datetime .timedelta | float | int | None = None ,
97
+ init_timeout : datetime .timedelta | float | int | None = None ,
96
98
):
97
99
self .transport = infer_transport (transport )
98
100
self ._session : ClientSession | None = None
@@ -111,6 +113,17 @@ def __init__(
111
113
if isinstance (timeout , int | float ):
112
114
timeout = datetime .timedelta (seconds = timeout )
113
115
116
+ # handle init handshake timeout
117
+ if init_timeout is None :
118
+ init_timeout = fastmcp .settings .settings .client_init_timeout
119
+ if isinstance (init_timeout , datetime .timedelta ):
120
+ init_timeout = init_timeout .total_seconds ()
121
+ elif not init_timeout :
122
+ init_timeout = None
123
+ else :
124
+ init_timeout = float (init_timeout )
125
+ self ._init_timeout = init_timeout
126
+
114
127
self ._session_kwargs : SessionKwargs = {
115
128
"sampling_callback" : None ,
116
129
"list_roots_callback" : None ,
@@ -168,7 +181,7 @@ async def _context_manager(self):
168
181
self ._session = session
169
182
# Initialize the session
170
183
try :
171
- with anyio .fail_after (1 ):
184
+ with anyio .fail_after (self . _init_timeout ):
172
185
self ._initialize_result = await self ._session .initialize ()
173
186
yield
174
187
except TimeoutError :
0 commit comments