Skip to content
39 changes: 33 additions & 6 deletions src/fastmcp/client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import asyncio
import copy
import datetime
import inspect
import secrets
from contextlib import AsyncExitStack, asynccontextmanager
from dataclasses import dataclass, field
Expand Down Expand Up @@ -831,6 +832,7 @@ async def call_tool_mcp(
arguments: dict[str, Any],
progress_handler: ProgressHandler | None = None,
timeout: datetime.timedelta | float | int | None = None,
meta: dict[str, Any] | None = None,
) -> mcp.types.CallToolResult:
"""Send a tools/call request and return the complete MCP protocol result.

Expand All @@ -842,6 +844,7 @@ async def call_tool_mcp(
arguments (dict[str, Any]): Arguments to pass to the tool.
timeout (datetime.timedelta | float | int | None, optional): The timeout for the tool call. Defaults to None.
progress_handler (ProgressHandler | None, optional): The progress handler to use for the tool call. Defaults to None.
meta (dict[str, Any] | None, optional): Additional metadata to send with the tool call.

Returns:
mcp.types.CallToolResult: The complete response object from the protocol,
Expand All @@ -854,12 +857,32 @@ async def call_tool_mcp(

if isinstance(timeout, int | float):
timeout = datetime.timedelta(seconds=float(timeout))
result = await self.session.call_tool(
name=name,
arguments=arguments,
read_timeout_seconds=timeout,
progress_callback=progress_handler or self._progress_handler,
)

# Check if meta parameter is supported, remove this once MCP >= 1.19 is required
sig = inspect.signature(self.session.call_tool)
meta_supported = "meta" in sig.parameters

# Include meta parameter if supported, warn user if they tried to use it but it's not supported
if meta_supported:
result = await self.session.call_tool(
name=name,
arguments=arguments,
read_timeout_seconds=timeout,
progress_callback=progress_handler or self._progress_handler,
meta=meta,
)
else:
if meta is not None:
logger.warning(
"The 'meta' parameter is not supported by your installed version of MCP. "
"Please update to MCP >= 1.19 to use this feature. Proceeding without meta."
)
result = await self.session.call_tool(
name=name,
arguments=arguments,
read_timeout_seconds=timeout,
progress_callback=progress_handler or self._progress_handler,
)
return result

async def call_tool(
Expand All @@ -869,6 +892,7 @@ async def call_tool(
timeout: datetime.timedelta | float | int | None = None,
progress_handler: ProgressHandler | None = None,
raise_on_error: bool = True,
meta: dict[str, Any] | None = None,
) -> CallToolResult:
"""Call a tool on the server.

Expand All @@ -879,6 +903,8 @@ async def call_tool(
arguments (dict[str, Any] | None, optional): Arguments to pass to the tool. Defaults to None.
timeout (datetime.timedelta | float | int | None, optional): The timeout for the tool call. Defaults to None.
progress_handler (ProgressHandler | None, optional): The progress handler to use for the tool call. Defaults to None.
raise_on_error (bool, optional): Whether to raise a ToolError if the tool call results in an error. Defaults to True.
meta (dict[str, Any] | None, optional): Additional metadata to send with the tool call.

Returns:
CallToolResult:
Expand All @@ -898,6 +924,7 @@ async def call_tool(
arguments=arguments or {},
timeout=timeout,
progress_handler=progress_handler,
meta=meta,
)
data = None
if result.isError and raise_on_error:
Expand Down
Loading