Skip to content

Commit 3d95841

Browse files
ChuckJonasDouweM
andcommitted
Apply suggestions from code review
Co-authored-by: Douwe Maan <[email protected]>
1 parent be9c95f commit 3d95841

File tree

6 files changed

+25
-288
lines changed

6 files changed

+25
-288
lines changed

docs/mcp/client.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,9 +231,9 @@ calculator_server = MCPServerSSE(
231231
agent = Agent('openai:gpt-4o', toolsets=[weather_server, calculator_server])
232232
```
233233

234-
## Tool Metadata
234+
## Tool `meta`, `annotations` & `output_schema`
235235

236-
MCP tools often include metadata that provides additional information about the tool's characteristics, which can use useful in filtering and middleware. This metadata is available in the [`ToolDefinition.metadata`][pydantic_ai.tools.ToolDefinition.metadata] field.
236+
MCP tools often include metadata that provides additional information about the tool's characteristics, which can use useful in [`toolset filtering`][pydantic_ai.toolsets.FilteredToolset] and middleware. These properties are available in the [`ToolDefinition.metadata`][pydantic_ai.tools.ToolDefinition.metadata].
237237

238238
## Custom TLS / SSL configuration
239239

pydantic_ai_slim/pydantic_ai/mcp.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,11 @@ async def get_tools(self, ctx: RunContext[Any]) -> dict[str, ToolsetTool[Any]]:
254254
name=name,
255255
description=mcp_tool.description,
256256
parameters_json_schema=mcp_tool.inputSchema,
257-
metadata=mcp_tool.meta,
257+
metadata={
258+
'meta': mcp_tool.meta,
259+
'annotations': mcp_tool.annotations.model_dump() if mcp_tool.annotations else None,
260+
'output_schema': mcp_tool.outputSchema or None
261+
}
258262
),
259263
)
260264
for mcp_tool in await self.list_tools()

pydantic_ai_slim/pydantic_ai/tools.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ class ToolDefinition:
489489
"""
490490

491491
metadata: dict[str, Any] | None = None
492-
"""Tool metadata, primarily used for filtering and tool behavior customization.
492+
"""Tool metadata that can be set by the toolset this tool came from. It is not sent to the model, but can be used for filtering and tool behavior customization.
493493
494494
For MCP tools, this contains the `_meta` field from the tool definition.
495495
"""

tests/mcp_server.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@
1111
SamplingMessage,
1212
TextContent,
1313
TextResourceContents,
14+
ToolAnnotations,
1415
)
1516
from pydantic import AnyUrl, BaseModel
1617

1718
mcp = FastMCP('Pydantic AI MCP Server')
1819
log_level = 'unset'
1920

2021

21-
@mcp.tool()
22+
@mcp.tool(annotations=ToolAnnotations(title='Celsius to Fahrenheit'))
2223
async def celsius_to_fahrenheit(celsius: float) -> float:
2324
"""Convert Celsius to Fahrenheit.
2425

tests/test_mcp.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1251,6 +1251,21 @@ async def test_tool_returning_multiple_items(allow_model_requests: None, agent:
12511251
)
12521252

12531253

1254+
async def test_tool_metadata_extraction():
1255+
"""Test that MCP tool metadata is properly extracted into ToolDefinition."""
1256+
1257+
server = MCPServerStdio('python', ['-m', 'tests.mcp_server'])
1258+
async with server:
1259+
ctx = RunContext(deps=None, model=TestModel(), usage=RunUsage())
1260+
tools = [tool.tool_def for tool in (await server.get_tools(ctx)).values()]
1261+
# find `celsius_to_fahrenheit`
1262+
celsius_to_fahrenheit = next(tool for tool in tools if tool.name == 'celsius_to_fahrenheit')
1263+
assert celsius_to_fahrenheit.metadata is not None
1264+
assert celsius_to_fahrenheit.metadata.get('annotations') is not None
1265+
assert celsius_to_fahrenheit.metadata.get('annotations', {}).get('title', None) == 'Celsius to Fahrenheit'
1266+
assert celsius_to_fahrenheit.metadata.get('output_schema') is not None
1267+
assert celsius_to_fahrenheit.metadata.get('output_schema', {}).get('type', None) == 'object'
1268+
12541269
async def test_client_sampling(run_context: RunContext[int]):
12551270
server = MCPServerStdio('python', ['-m', 'tests.mcp_server'])
12561271
server.sampling_model = TestModel(custom_output_text='sampling model response')

tests/test_mcp_metadata.py

Lines changed: 0 additions & 283 deletions
This file was deleted.

0 commit comments

Comments
 (0)