added specs

This commit is contained in:
Zack Lee 2024-11-18 11:36:07 -05:00
commit 21a38ebe74
No known key found for this signature in database

View file

@ -1,8 +1,329 @@
---
title: "Tool Invocation"
description: "Invoke MCP tools from clients"
title: 'Tool Invocation'
description: 'Learn how to invoke tools through the MCP client API'
---
# Tool Invocation
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.
Invoke MCP tools from clients
## Getting available tools
Before invoking tools, you'll need to get a list of available tools from the server.
<CodeGroup>
```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}")
```
</CodeGroup>
## Tool invocation
To invoke a tool, you'll use the `tools/call` method with the tool name and any required arguments.
<CodeGroup>
```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)
```
</CodeGroup>
## Progress tracking
For long-running tools, you can track progress using progress notifications.
<CodeGroup>
```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
)
```
</CodeGroup>
## Error handling
Tool invocations may fail for various reasons. Always handle potential errors appropriately.
<CodeGroup>
```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)
```
</CodeGroup>
## Complete example
Here's a complete example showing how to discover and use tools with proper error handling.
<CodeGroup>
```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)
```
</CodeGroup>
## Best practices
When working with tools:
<CardGroup cols={2}>
<Card title="Validation" icon="check-circle">
Always check tool availability before invoking
</Card>
<Card title="Error handling" icon="shield-check">
Implement comprehensive error handling
</Card>
<Card title="Progress" icon="bars-progress">
Use progress callbacks for long-running operations
</Card>
<Card title="Arguments" icon="input-text">
Validate arguments against the tool's input schema
</Card>
</CardGroup>
## 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 |