4
4
from asyncio import Lock
5
5
from contextlib import AsyncExitStack
6
6
from enum import Enum
7
- from typing import TYPE_CHECKING , Any , Self
7
+ from typing import TYPE_CHECKING , Any
8
8
9
- from mcp .types import (
10
- AudioContent ,
11
- ContentBlock ,
12
- ImageContent ,
13
- TextContent ,
14
- Tool as MCPTool ,
15
- )
9
+ from typing_extensions import Self
16
10
17
11
from pydantic_ai .exceptions import ModelRetry
18
12
from pydantic_ai .mcp import TOOL_SCHEMA_VALIDATOR , messages
26
20
from fastmcp .exceptions import ToolError
27
21
from fastmcp .mcp_config import MCPConfig
28
22
from fastmcp .server .server import FastMCP
23
+ from mcp .types import (
24
+ AudioContent ,
25
+ ContentBlock ,
26
+ ImageContent ,
27
+ TextContent ,
28
+ Tool as MCPTool ,
29
+ )
30
+
29
31
except ImportError as _import_error :
30
32
raise ImportError (
31
33
'Please install the `fastmcp` package to use the FastMCP server, '
@@ -70,6 +72,13 @@ class FastMCPToolset(AbstractToolset[AgentDepsT]):
70
72
def __init__ (
71
73
self , fastmcp_client : Client [Any ], tool_retries : int = 2 , tool_error_behavior : ToolErrorBehavior | None = None
72
74
):
75
+ """Build a new FastMCPToolset.
76
+
77
+ Args:
78
+ fastmcp_client: The FastMCP client to use.
79
+ tool_retries: The number of times to retry a tool call.
80
+ tool_error_behavior: The behavior to take when a tool error occurs.
81
+ """
73
82
self ._tool_retries = tool_retries
74
83
self ._fastmcp_client = fastmcp_client
75
84
self ._enter_lock = Lock ()
@@ -150,7 +159,7 @@ def from_fastmcp_server(
150
159
async def my_tool(a: int, b: int) -> int:
151
160
return a + b
152
161
153
- toolset = FastMCPToolset.from_fastmcp_server(fastmcp_server=fastmcp_server)
162
+ FastMCPToolset.from_fastmcp_server(fastmcp_server=fastmcp_server)
154
163
```
155
164
"""
156
165
transport = FastMCPTransport (fastmcp_server )
@@ -168,23 +177,15 @@ def from_mcp_server(
168
177
169
178
Example:
170
179
```python
171
- from pydantic_ai import Agent
172
180
from pydantic_ai.toolsets.fastmcp import FastMCPToolset
173
181
174
182
time_mcp_server = {
175
- 'command': 'uvx',
176
- 'args': [
177
- 'mcp-server-time',
178
- ]
183
+ 'command': 'uv',
184
+ 'args': ['run', 'mcp-run-python', 'stdio'],
179
185
}
180
186
181
- toolset = FastMCPToolset.from_mcp_server(name='time_server', mcp_server=time_mcp_server)
182
- agent = Agent('openai:gpt-4o', toolsets=[toolset])
183
- async def main():
184
- async with agent: # (1)!
185
- ...
187
+ FastMCPToolset.from_mcp_server(name='time_server', mcp_server=time_mcp_server)
186
188
```
187
- 1. This will start the MCP Server running over stdio.
188
189
"""
189
190
mcp_config : MCPConfig = MCPConfig .from_dict (config = {name : mcp_server })
190
191
@@ -198,35 +199,23 @@ def from_mcp_config(
198
199
199
200
Example:
200
201
```python
201
- from pydantic_ai import Agent
202
202
from pydantic_ai.toolsets.fastmcp import FastMCPToolset
203
203
204
204
mcp_config = {
205
205
'mcpServers': {
206
- 'time_server': {
207
- 'command': 'uvx',
208
- 'args': [
209
- 'mcp-server-time',
210
- ]
206
+ 'first_server': {
207
+ 'command': 'uv',
208
+ 'args': ['run', 'mcp-run-python', 'stdio'],
211
209
},
212
- 'fetch_server': {
213
- 'command': 'uvx',
214
- 'args': [
215
- 'mcp-server-fetch',
216
- ]
210
+ 'second_server': {
211
+ 'command': 'uv',
212
+ 'args': ['run', 'mcp-run-python', 'stdio'],
217
213
}
218
214
}
219
215
}
220
216
221
- fastmcp_toolset = FastMCPToolset.from_mcp_config(mcp_config)
222
-
223
- agent = Agent('openai:gpt-4o', toolsets=[fastmcp_toolset])
224
- async def main():
225
- async with agent: # (1)!
226
- ...
217
+ FastMCPToolset.from_mcp_config(mcp_config)
227
218
```
228
-
229
- 1. This will start both MCP Servers running over stdio`.
230
219
"""
231
220
transport : MCPConfigTransport = MCPConfigTransport (config = mcp_config )
232
221
fastmcp_client : Client [MCPConfigTransport ] = Client [MCPConfigTransport ](transport = transport )
0 commit comments