MCP tools
Connect agents to external MCP servers for remote tool execution
MCP tools execute on external MCP servers. Unlike server tools (where the tool code runs in Letta’s sandbox) or client tools (where the tool code runs in your app), MCP tools only require registering the server URL - the tool execution happens on the MCP server.
Tool execution comparison
Section titled “Tool execution comparison”| Tool type | Where code runs | You provide | Use case |
|---|---|---|---|
| Server tools | Letta sandbox | Tool code | Custom logic, API calls |
| Client tools | Your application | Tool schema + local handler | Local resources, HITL |
| MCP tools | External MCP server | Server URL only | You have an existing MCP server you want to use |
Register an MCP server
Section titled “Register an MCP server”from letta_client import Letta
client = Letta()
# Register a remote MCP serverserver = client.mcp_servers.create( server_name="github", config={ "mcp_server_type": "streamable_http", "server_url": "https://mcp.example.com/github", "auth_header": "Authorization", "auth_token": "Bearer your-token", })
# List available tools from the servertools = client.mcp_servers.list_tools(server.id)for tool in tools: print(f"{tool.name}: {tool.description}")import Letta from "@letta-ai/letta-client";
const client = new Letta();
// Register a remote MCP serverconst server = await client.mcpServers.create({ server_name: "github", config: { mcp_server_type: "streamable_http", server_url: "https://mcp.example.com/github", auth_header: "Authorization", auth_token: "Bearer your-token", },});
// List available tools from the serverconst tools = await client.mcpServers.listTools(server.id);for (const tool of tools) { console.log(`${tool.name}: ${tool.description}`);}Attach MCP tools to an agent
Section titled “Attach MCP tools to an agent”Once registered, attach MCP tools to agents like any other tool:
# Create agent with MCP toolsagent = client.agents.create( name="github-assistant", tool_ids=[tool.id for tool in tools], # MCP tools from server)// Create agent with MCP toolsconst agent = await client.agents.create({ name: "github-assistant", tool_ids: tools.map((t) => t.id), // MCP tools from server});Transport types
Section titled “Transport types”| Transport | Letta API | Docker | Notes |
|---|---|---|---|
| Streamable HTTP | ✅ | ✅ | Recommended. Supports auth headers. |
| SSE | ✅ | ✅ | Legacy, for compatibility only. |
| stdio | ❌ | ✅ | Local development only. |
Streamable HTTP (recommended)
Section titled “Streamable HTTP (recommended)”client.mcp_servers.create( server_name="my-server", config={ "mcp_server_type": "streamable_http", "server_url": "https://mcp.example.com/endpoint", "auth_header": "Authorization", "auth_token": "Bearer token", "custom_headers": {"X-API-Version": "v1"} })stdio (Docker only)
Section titled “stdio (Docker only)”client.mcp_servers.create( server_name="local-server", config={ "mcp_server_type": "stdio", "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path"] })Agent-scoped variables
Section titled “Agent-scoped variables”Use templated variables in auth tokens for per-agent credentials:
client.mcp_servers.create( server_name="user-api", config={ "mcp_server_type": "streamable_http", "server_url": "https://api.example.com/mcp", "auth_token": "Bearer {{USER_API_KEY | default_key}}", # Falls back to default_key })Set variables per-agent using tool variables.
Execution flow
Section titled “Execution flow”sequenceDiagram
participant Agent as Letta Agent
participant Server as Letta Server
participant MCP as MCP Server
Agent->>Server: Tool call (create_issue)
Server->>MCP: Forward request
MCP->>MCP: Execute tool
MCP-->>Server: Return result
Server-->>Agent: Continue with result
The agent doesn’t need credentials or API details - the MCP server handles authentication and execution.