added specs
This commit is contained in:
parent
9681ec94e6
commit
21a38ebe74
1 changed files with 3532 additions and 60 deletions
|
|
@ -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 |
|
||||
Loading…
Reference in a new issue