--- title: "Tool invocation" description: "Learn how to invoke tools through the MCP client API" --- MCP allows clients to invoke tools exposed by servers. Tools are discrete operations that servers can perform on behalf of clients, similar to function calls. ## Getting available tools Before invoking tools, you'll need to get a list of available tools from the server. ```typescript TypeScript import { Client } from "@modelcontextprotocol/sdk/client"; import { ListToolsResultSchema } from "@modelcontextprotocol/sdk/types"; // Assuming client is already connected const result = await client.request( { method: "tools/list" }, ListToolsResultSchema ); // Tools are now available in result.tools for (const tool of result.tools) { console.log(`Found tool: ${tool.name}`); console.log(`Description: ${tool.description}`); } ``` ```python Python from mcp.client import Client from mcp.types import ListToolsRequest # Assuming client is already connected result = await client.request( ListToolsRequest(method="tools/list"), ListToolsResultSchema ) # Tools are now available in result.tools for tool in result.tools: print(f"Found tool: {tool.name}") print(f"Description: {tool.description}") ``` ## Tool invocation To invoke a tool, you'll use the `tools/call` method with the tool name and any required arguments. ```typescript TypeScript import { CallToolRequest, CallToolResultSchema } from "@modelcontextprotocol/sdk/types"; const result = await client.request( { method: "tools/call", params: { name: "example_tool", arguments: { param1: "value1", param2: 42 } } }, CallToolResultSchema ); // Tool result is available in result.toolResult console.log("Tool result:", result.toolResult); ``` ```python Python from mcp.types import CallToolRequest, CallToolResult result = await client.request( CallToolRequest( method="tools/call", params={ "name": "example_tool", "arguments": { "param1": "value1", "param2": 42 } } ), CallToolResult ) # Tool result is available in result.tool_result print("Tool result:", result.tool_result) ``` ## Progress tracking For long-running tools, you can track progress using progress notifications. ```typescript TypeScript const result = await client.request( { method: "tools/call", params: { name: "long_running_tool", arguments: { duration: 10 } } }, CallToolResultSchema, (progress) => { console.log(`Progress: ${progress.progress}/${progress.total ?? '?'}`); } ); ``` ```python Python def progress_callback(progress): print(f"Progress: {progress.progress}/{progress.total or '?'}") result = await client.request( CallToolRequest( method="tools/call", params={ "name": "long_running_tool", "arguments": { "duration": 10 } } ), CallToolResult, on_progress=progress_callback ) ``` ## Error handling Tool invocations may fail for various reasons. Always handle potential errors appropriately. ```typescript TypeScript try { const result = await client.request( { method: "tools/call", params: { name: "risky_tool", arguments: { important_param: "value" } } }, CallToolResultSchema ); } catch (error) { if (error instanceof McpError) { console.error(`Tool error (${error.code}): ${error.message}`); if (error.data) { console.error("Additional error data:", error.data); } } else { console.error("Unexpected error:", error); } } ``` ```python Python from mcp.errors import McpError try: result = await client.request( CallToolRequest( method="tools/call", params={ "name": "risky_tool", "arguments": { "important_param": "value" } } ), CallToolResult ) except McpError as e: print(f"Tool error ({e.code}): {e.message}") if e.data: print("Additional error data:", e.data) except Exception as e: print("Unexpected error:", e) ``` ## Complete example Here's a complete example showing how to discover and use tools with proper error handling. ```typescript TypeScript import { Client } from "@modelcontextprotocol/sdk/client"; import { ListToolsResultSchema, CallToolResultSchema, McpError } from "@modelcontextprotocol/sdk/types"; async function invokeTools(client: Client) { try { // Get available tools const toolsList = await client.request( { method: "tools/list" }, ListToolsResultSchema ); // Find a specific tool const tool = toolsList.tools.find(t => t.name === "example_tool"); if (!tool) { console.error("Tool not found"); return; } // Invoke the tool with progress tracking const result = await client.request( { method: "tools/call", params: { name: tool.name, arguments: { // Tool-specific arguments param1: "value1" } } }, CallToolResultSchema, (progress) => { console.log( `Progress: ${progress.progress}/${progress.total ?? '?'}` ); } ); console.log("Tool result:", result.toolResult); } catch (error) { if (error instanceof McpError) { console.error(`Tool error (${error.code}): ${error.message}`); } else { console.error("Unexpected error:", error); } } } ``` ```python Python from mcp.client import Client from mcp.types import ListToolsRequest, CallToolRequest from mcp.errors import McpError async def invoke_tools(client: Client): try: # Get available tools tools_list = await client.request( ListToolsRequest(method="tools/list"), ListToolsResultSchema ) # Find a specific tool tool = next( (t for t in tools_list.tools if t.name == "example_tool"), None ) if not tool: print("Tool not found") return # Invoke the tool with progress tracking result = await client.request( CallToolRequest( method="tools/call", params={ "name": tool.name, "arguments": { # Tool-specific arguments "param1": "value1" } } ), CallToolResult, on_progress=lambda p: print( f"Progress: {p.progress}/{p.total or '?'}" ) ) print("Tool result:", result.tool_result) except McpError as e: print(f"Tool error ({e.code}): {e.message}") except Exception as e: print("Unexpected error:", e) ``` ## Best practices When working with tools: Always check tool availability before invoking Implement comprehensive error handling Use progress callbacks for long-running operations Validate arguments against the tool's input schema ## Common errors | Error Code | Description | Resolution | |------------|-------------|------------| | -32601 | Method not found | Verify the tool name exists | | -32602 | Invalid params | Check the tool's input schema | | -32603 | Internal error | Server-side error, check server logs | | -1 | Connection closed | Check connection status |