--- title: Tool Operations sidebarTitle: Tools description: Discover and execute server-side tools with the FastMCP client. icon: wrench --- import { VersionBadge } from '/snippets/version-badge.mdx' Tools are executable functions exposed by MCP servers. The FastMCP client provides methods to discover available tools and execute them with arguments. ## Discovering Tools Use `list_tools()` to retrieve all tools available on the server: ```python async with client: tools = await client.list_tools() # tools -> list[mcp.types.Tool] for tool in tools: print(f"Tool: {tool.name}") print(f"Description: {tool.description}") if tool.inputSchema: print(f"Parameters: {tool.inputSchema}") ``` ## Executing Tools ### Basic Execution Execute a tool using `call_tool()` with the tool name and arguments: ```python async with client: # Simple tool call result = await client.call_tool("add", {"a": 5, "b": 3}) # result -> list[mcp.types.TextContent | mcp.types.ImageContent | ...] # Access the result content print(result[0].text) # Assuming TextContent, e.g., '8' ``` ### Advanced Execution Options The `call_tool()` method supports additional parameters for timeout control and progress monitoring: ```python async with client: # With timeout (aborts if execution takes longer than 2 seconds) result = await client.call_tool( "long_running_task", {"param": "value"}, timeout=2.0 ) # With progress handler (to track execution progress) result = await client.call_tool( "long_running_task", {"param": "value"}, progress_handler=my_progress_handler ) ``` **Parameters:** - `name`: The tool name (string) - `arguments`: Dictionary of arguments to pass to the tool (optional) - `timeout`: Maximum execution time in seconds (optional, overrides client-level timeout) - `progress_handler`: Progress callback function (optional, overrides client-level handler) ## Handling Results Tool execution returns a list of content objects. The most common types are: - **`TextContent`**: Text-based results with a `.text` attribute - **`ImageContent`**: Image data with image-specific attributes - **`BlobContent`**: Binary data content ```python async with client: result = await client.call_tool("get_weather", {"city": "London"}) for content in result: if hasattr(content, 'text'): print(f"Text result: {content.text}") elif hasattr(content, 'data'): print(f"Binary data: {len(content.data)} bytes") ``` ## Error Handling ### Exception-Based Error Handling By default, `call_tool()` raises a `ToolError` if the tool execution fails: ```python from fastmcp.exceptions import ToolError async with client: try: result = await client.call_tool("potentially_failing_tool", {"param": "value"}) print("Tool succeeded:", result) except ToolError as e: print(f"Tool failed: {e}") ``` ### Manual Error Checking For more granular control, use `call_tool_mcp()` which returns the raw MCP protocol object with an `isError` flag: ```python async with client: result = await client.call_tool_mcp("potentially_failing_tool", {"param": "value"}) # result -> mcp.types.CallToolResult if result.isError: print(f"Tool failed: {result.content}") else: print(f"Tool succeeded: {result.content}") ``` ## Argument Handling Arguments are passed as a dictionary to the tool: ```python async with client: # Simple arguments result = await client.call_tool("greet", {"name": "World"}) # Complex arguments result = await client.call_tool("process_data", { "config": {"format": "json", "validate": True}, "items": [1, 2, 3, 4, 5], "metadata": {"source": "api", "version": "1.0"} }) ``` For multi-server clients, tool names are automatically prefixed with the server name (e.g., `weather_get_forecast` for a tool named `get_forecast` on the `weather` server).