44from asyncio import Lock
55from contextlib import AsyncExitStack
66from enum import Enum
7- from typing import TYPE_CHECKING , Any , Self
7+ from typing import TYPE_CHECKING , Any
88
9- from mcp .types import (
10- AudioContent ,
11- ContentBlock ,
12- ImageContent ,
13- TextContent ,
14- Tool as MCPTool ,
15- )
9+ from typing_extensions import Self
1610
1711from pydantic_ai .exceptions import ModelRetry
1812from pydantic_ai .mcp import TOOL_SCHEMA_VALIDATOR , messages
2620 from fastmcp .exceptions import ToolError
2721 from fastmcp .mcp_config import MCPConfig
2822 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+
2931except ImportError as _import_error :
3032 raise ImportError (
3133 'Please install the `fastmcp` package to use the FastMCP server, '
@@ -70,6 +72,13 @@ class FastMCPToolset(AbstractToolset[AgentDepsT]):
7072 def __init__ (
7173 self , fastmcp_client : Client [Any ], tool_retries : int = 2 , tool_error_behavior : ToolErrorBehavior | None = None
7274 ):
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+ """
7382 self ._tool_retries = tool_retries
7483 self ._fastmcp_client = fastmcp_client
7584 self ._enter_lock = Lock ()
@@ -150,7 +159,7 @@ def from_fastmcp_server(
150159 async def my_tool(a: int, b: int) -> int:
151160 return a + b
152161
153- toolset = FastMCPToolset.from_fastmcp_server(fastmcp_server=fastmcp_server)
162+ FastMCPToolset.from_fastmcp_server(fastmcp_server=fastmcp_server)
154163 ```
155164 """
156165 transport = FastMCPTransport (fastmcp_server )
@@ -168,23 +177,15 @@ def from_mcp_server(
168177
169178 Example:
170179 ```python
171- from pydantic_ai import Agent
172180 from pydantic_ai.toolsets.fastmcp import FastMCPToolset
173181
174182 time_mcp_server = {
175- 'command': 'uvx',
176- 'args': [
177- 'mcp-server-time',
178- ]
183+ 'command': 'uv',
184+ 'args': ['run', 'mcp-run-python', 'stdio'],
179185 }
180186
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)
186188 ```
187- 1. This will start the MCP Server running over stdio.
188189 """
189190 mcp_config : MCPConfig = MCPConfig .from_dict (config = {name : mcp_server })
190191
@@ -198,35 +199,23 @@ def from_mcp_config(
198199
199200 Example:
200201 ```python
201- from pydantic_ai import Agent
202202 from pydantic_ai.toolsets.fastmcp import FastMCPToolset
203203
204204 mcp_config = {
205205 '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'],
211209 },
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'],
217213 }
218214 }
219215 }
220216
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)
227218 ```
228-
229- 1. This will start both MCP Servers running over stdio`.
230219 """
231220 transport : MCPConfigTransport = MCPConfigTransport (config = mcp_config )
232221 fastmcp_client : Client [MCPConfigTransport ] = Client [MCPConfigTransport ](transport = transport )
0 commit comments