Skip to content

Commit c86b8f3

Browse files
committed
fix(types): correct FastMCP.call_tool and convert_result return types (#1251)
Signed-off-by: SAY-5 <say.apm35@gmail.com>
1 parent 3d7b311 commit c86b8f3

2 files changed

Lines changed: 21 additions & 6 deletions

File tree

src/mcp/server/mcpserver/server.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,8 +399,18 @@ async def list_tools(self) -> list[MCPTool]:
399399

400400
async def call_tool(
401401
self, name: str, arguments: dict[str, Any], context: Context[LifespanResultT, Any] | None = None
402-
) -> Sequence[ContentBlock] | dict[str, Any]:
403-
"""Call a tool by name with arguments."""
402+
) -> Sequence[ContentBlock] | CallToolResult | tuple[Sequence[ContentBlock], dict[str, Any]]:
403+
"""Call a tool by name with arguments.
404+
405+
Because ``convert_result=True`` is always passed to the tool manager, the
406+
return value comes from ``FuncMetadata.convert_result``:
407+
408+
- ``Sequence[ContentBlock]`` when the tool has no output schema and
409+
returned a regular value
410+
- ``CallToolResult`` when the tool returned a ``CallToolResult`` directly
411+
- ``tuple[Sequence[ContentBlock], dict[str, Any]]`` when the tool has
412+
an output schema, where the second element is the structured content
413+
"""
404414
if context is None:
405415
context = Context(mcp_server=self)
406416
return await self._tool_manager.call_tool(name, arguments, context, convert_result=True)

src/mcp/server/mcpserver/utilities/func_metadata.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,17 @@ async def call_fn_with_arg_validation(
8888
else:
8989
return await anyio.to_thread.run_sync(functools.partial(fn, **arguments_parsed_dict))
9090

91-
def convert_result(self, result: Any) -> Any:
91+
def convert_result(
92+
self, result: Any
93+
) -> Sequence[ContentBlock] | CallToolResult | tuple[Sequence[ContentBlock], dict[str, Any]]:
9294
"""Convert a function call result to the format for the lowlevel tool call handler.
9395
94-
- If output_model is None, return the unstructured content directly.
95-
- If output_model is not None, convert the result to structured output format
96-
(dict[str, Any]) and return both unstructured and structured content.
96+
- If the function returned a ``CallToolResult`` directly, return it unchanged.
97+
- If ``output_model`` is None, return the unstructured content
98+
(``Sequence[ContentBlock]``) directly.
99+
- If ``output_model`` is not None, convert the result to structured output
100+
format (``dict[str, Any]``) and return both unstructured and structured
101+
content as a tuple.
97102
98103
Note: we return unstructured content here **even though the lowlevel server
99104
tool call handler provides generic backwards compatibility serialization of

0 commit comments

Comments
 (0)