Direct Tool Calls
MCP-Use allows you to call MCP server tools directly without needing an LLM or agent. This is useful when you want to use MCP servers as a simple interface to various tools and APIs, or when you need programmatic control over tool execution.
Direct tool calls are appropriate when:
- You know exactly which tool to call and with what parameters
- You don’t need an LLM to make decisions about tool selection
- You want to integrate MCP tools into existing Python applications
- You need deterministic, programmatic control over tool execution
Direct tool calls will not work for tools that require sampling/completion, as
these need an LLM to generate responses.
Basic Example
Here’s how to call tools directly using the MCPClient:
import { MCPClient } from 'mcp-use'
async function callToolExample() {
// Configure the MCP server
const config = {
mcpServers: {
everything: {
command: 'npx',
args: ['-y', '@modelcontextprotocol/server-everything']
}
}
}
// Create client from configuration
const client = new MCPClient(config)
try {
// Initialize all configured sessions
await client.createAllSessions()
// Get the session for a specific server
const session = client.getSession('everything')
// List available tools
const tools = await session.listTools()
const toolNames = tools.map(t => t.name)
console.log(`Available tools: ${toolNames}`)
// Call a specific tool with arguments
const result = await session.callTool(
'add',
{ a: 1, b: 2 }
)
// Handle the result
if (result.isError) {
console.error(`Error: ${result.content}`)
} else {
console.log(`Tool result: ${result.content}`)
console.log(`Text result: ${result.content[0].text}`)
}
} finally {
// Clean up resources
await client.closeAllSessions()
}
}
callToolExample().catch(console.error)
The call_tool method returns a CallToolResult object with the following attributes:
content: A list of ContentBlock objects containing the tool’s output
structuredContent: A dictionary with the structured result (for non-sampling tools)
isError: Boolean indicating if the tool call encountered an error
Accessing Results
// Call a tool
const result = await session.callTool(
'get_weather',
{ location: 'San Francisco' }
)
// Check for errors
if (result.isError) {
console.error(`Tool error: ${result.content}`)
} else {
// Access text content
const textResult = result.content[0].text
console.log(`Weather: ${textResult}`)
// Access structured content if available
if (result.structuredContent) {
const structured = result.structuredContent
console.log(`Temperature: ${structured.temperature}`)
}
}
Multiple Server Example
You can work with multiple MCP servers and call tools from each:
import { MCPClient } from 'mcp-use'
async function multiServerExample() {
const config = {
mcpServers: {
filesystem: {
command: 'npx',
args: ['-y', '@modelcontextprotocol/server-filesystem'],
env: { FILE_PATH: '/tmp' }
},
time: {
command: 'npx',
args: ['-y', '@modelcontextprotocol/server-time']
}
}
}
const client = new MCPClient(config)
try {
await client.createAllSessions()
// Call tool from filesystem server
const fsSession = client.getSession('filesystem')
const files = await fsSession.callTool(
'list_files',
{ path: '/tmp' }
)
console.log(`Files: ${files.content[0].text}`)
// Call tool from time server
const timeSession = client.getSession('time')
const currentTime = await timeSession.callTool(
'get_current_time',
{}
)
console.log(`Current time: ${currentTime.content[0].text}`)
} finally {
await client.closeAllSessions()
}
}
multiServerExample().catch(console.error)
Before calling tools, you may want to discover what’s available:
async function discoverTools() {
const client = new MCPClient(config)
await client.createAllSessions()
try {
const session = client.getSession('my_server')
// Get all tools
const tools = await session.listTools()
for (const tool of tools) {
console.log(`Tool: ${tool.name}`)
console.log(` Description: ${tool.description}`)
// Print input schema if available
if (tool.inputSchema) {
console.log(` Parameters: ${JSON.stringify(tool.inputSchema)}`)
}
console.log()
}
} finally {
await client.closeAllSessions()
}
}
Error Handling
Always handle potential errors when making direct tool calls:
async function safeToolCall() {
try {
const result = await session.callTool(
'some_tool',
{ param: 'value' }
)
if (result.isError) {
// Handle tool-specific errors
const errorMsg = result.content?.[0]?.text || 'Unknown error'
console.error(`Tool returned error: ${errorMsg}`)
return null
}
return result.content[0].text
} catch (error) {
// Handle connection or other errors
console.error(`Failed to call tool: ${error}`)
return null
}
}
Limitations
When using direct tool calls, be aware of these limitations:
- No Sampling Support: Tools that require sampling/completion (like text generation) won’t work without an LLM
- Manual Tool Selection: You need to know which tool to call - there’s no automatic selection
- No Context Management: Unlike agents, direct calls don’t maintain conversation context
- Parameter Validation: You’re responsible for providing correct parameters
Complete Example
View the complete working example in the repository:
examples/direct_tool_call.py
Next Steps