Jeremiah Lowin commited on
Commit
b056b3b
·
1 Parent(s): dab7514

Add global setting

Browse files
src/fastmcp/client/client.py CHANGED
@@ -9,6 +9,7 @@ from exceptiongroup import catch
9
  from mcp import ClientSession
10
  from pydantic import AnyUrl
11
 
 
12
  from fastmcp.client.logging import (
13
  LogHandler,
14
  MessageHandler,
@@ -45,8 +46,8 @@ class Client:
45
  MCP client that delegates connection management to a Transport instance.
46
 
47
  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.
50
 
51
  Args:
52
  transport: Connection source specification, which can be:
@@ -57,25 +58,23 @@ class Client:
57
  - MCPConfig: MCP server configuration
58
  - dict: Transport configuration
59
  roots: Optional RootsList or RootsHandler for filesystem access
60
- sampling_handler: Optional handler for sampling requests
61
- log_handler: Optional handler for log messages
62
- message_handler: Optional handler for protocol messages
63
- progress_handler: Optional handler for progress notifications
64
- timeout: Optional timeout for requests (seconds or timedelta)
65
- init_timeout: Optional timeout for initial connection (seconds or
66
- timedelta)
67
 
68
  Examples:
69
- ```python
70
- # Connect to FastMCP server
71
- client = Client("http://localhost:8080")
72
 
73
  async with client:
74
- # List available resources
75
- resources = await client.list_resources()
76
 
77
- # Call a tool
78
- result = await client.call_tool("my_tool", {"param": "value"})
79
  ```
80
  """
81
 
@@ -95,7 +94,7 @@ class Client:
95
  message_handler: MessageHandler | None = None,
96
  progress_handler: ProgressHandler | None = None,
97
  timeout: datetime.timedelta | float | int | None = None,
98
- init_timeout: datetime.timedelta | float | int = 1,
99
  ):
100
  self.transport = infer_transport(transport)
101
  self._session: ClientSession | None = None
@@ -114,14 +113,16 @@ class Client:
114
  if isinstance(timeout, int | float):
115
  timeout = datetime.timedelta(seconds=timeout)
116
 
117
- if isinstance(init_timeout, int):
118
- self._init_timeout = float(init_timeout)
119
- elif isinstance(init_timeout, datetime.timedelta):
120
- self._init_timeout = float(init_timeout.total_seconds())
121
- elif isinstance(init_timeout, float):
122
- self._init_timeout = init_timeout
 
123
  else:
124
- raise ValueError("init_timeout must be int, float or datetime.timedelta")
 
125
 
126
  self._session_kwargs: SessionKwargs = {
127
  "sampling_callback": None,
 
9
  from mcp import ClientSession
10
  from pydantic import AnyUrl
11
 
12
+ import fastmcp
13
  from fastmcp.client.logging import (
14
  LogHandler,
15
  MessageHandler,
 
46
  MCP client that delegates connection management to a Transport instance.
47
 
48
  The Client class is responsible for MCP protocol logic, while the Transport
49
+ handles connection establishment and management. Client provides methods for
50
+ working with resources, prompts, tools and other MCP capabilities.
51
 
52
  Args:
53
  transport: Connection source specification, which can be:
 
58
  - MCPConfig: MCP server configuration
59
  - dict: Transport configuration
60
  roots: Optional RootsList or RootsHandler for filesystem access
61
+ sampling_handler: Optional handler for sampling requests log_handler:
62
+ Optional handler for log messages message_handler: Optional handler for
63
+ protocol messages progress_handler: Optional handler for progress
64
+ notifications timeout: Optional timeout for requests (seconds or
65
+ timedelta) init_timeout: Optional timeout for initial connection
66
+ (seconds or timedelta). Set to 0 to disable. If None, uses the value
67
+ in the FastMCP global settings.
68
 
69
  Examples:
70
+ ```python # Connect to FastMCP server client =
71
+ Client("http://localhost:8080")
 
72
 
73
  async with client:
74
+ # List available resources resources = await client.list_resources()
 
75
 
76
+ # Call a tool result = await client.call_tool("my_tool", {"param":
77
+ "value"})
78
  ```
79
  """
80
 
 
94
  message_handler: MessageHandler | None = None,
95
  progress_handler: ProgressHandler | None = None,
96
  timeout: datetime.timedelta | float | int | None = None,
97
+ init_timeout: datetime.timedelta | float | int | None = None,
98
  ):
99
  self.transport = infer_transport(transport)
100
  self._session: ClientSession | None = None
 
113
  if isinstance(timeout, int | float):
114
  timeout = datetime.timedelta(seconds=timeout)
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
 
127
  self._session_kwargs: SessionKwargs = {
128
  "sampling_callback": None,
src/fastmcp/settings.py CHANGED
@@ -87,6 +87,14 @@ class Settings(BaseSettings):
87
  ),
88
  ] = False
89
 
 
 
 
 
 
 
 
 
90
  @model_validator(mode="after")
91
  def setup_logging(self) -> Self:
92
  """Finalize the settings."""
 
87
  ),
88
  ] = False
89
 
90
+ client_init_timeout: Annotated[
91
+ float | None,
92
+ Field(
93
+ default=1,
94
+ description="The timeout for the client's initialization handshake, in seconds. Set to None or 0 to disable.",
95
+ ),
96
+ ] = None
97
+
98
  @model_validator(mode="after")
99
  def setup_logging(self) -> Self:
100
  """Finalize the settings."""