OpenLegion supports the Model Context Protocol (MCP) — the emerging standard for LLM tool interoperability — over stdio transport.
stdio transport only. HTTP and SSE transports are not currently wired up in OpenLegion. MCP servers that require those transports won’t work.Default agent image is Python-only. The Python mcp SDK is pre-installed, so Python-based MCP servers work out of the box. Node.js is NOT installed. npm-based servers (@modelcontextprotocol/server-filesystem, -github, -playwright, etc.) require a custom agent Dockerfile that installs Node.js.
Configuration
MCP servers are configured per-agent. Add mcp_servers to any agent definition:
agents:
researcher:
role: "research"
model: "anthropic/claude-haiku-4"
mcp_servers:
- name: sqlite
command: python
args: ["-m", "mcp_server_sqlite", "--db", "/data/research.db"]
- name: fetch
command: python
args: ["-m", "mcp_server_fetch"]
Each server is launched as a subprocess inside the agent container using stdio transport. Tools are discovered automatically via the MCP protocol and appear in the LLM’s tool list alongside built-in skills.
Per-call timeout: 60s. A handshake or tool call that exceeds 60s raises an error. Built-in skills are unaffected.
If one MCP server fails to start, other servers continue normally. Built-in skills are always available regardless of MCP server status.
How It Works
- Agent container reads
MCP_SERVERS from environment (set by the runtime).
MCPClient launches each server subprocess via stdio transport.
- MCP protocol handshake discovers available tools and their schemas.
- Tools are registered in
SkillRegistry with OpenAI function-calling format.
- LLM tool calls route through
MCPClient.call_tool() to the correct server.
- If an MCP tool’s name collides with a built-in skill or another MCP server’s tool, the colliding tool is registered as
mcp_{server_name}_{tool_name} at agent boot. Built-in skills always keep the original name.
Known limitations
- stdio only — HTTP and SSE transports not wired.
- Image and binary content silently dropped. Only text blocks from
CallToolResult are forwarded to the agent (concatenated under the "result" key). MCP servers that return images won’t surface those to the LLM.
- 60s per-call timeout.
- Python-only default image — see warning above.
Server Config Options
| Field | Type | Description |
|---|
name | string | Server identifier (used for logging and conflict prefixes) |
command | string | Command to launch the server |
args | list | Command-line arguments (optional) |
env | dict | Environment variables for the server process (optional) |
Example: SQLite (Python)
mcp_servers:
- name: db
command: python
args: ["-m", "mcp_server_sqlite", "--db", "/data/mydb.sqlite"]
The agent can now query the database — the MCP server translates tool calls into SQL.
Example: filesystem (requires custom image)
The @modelcontextprotocol/server-filesystem reference server is npm-based. To use it, build a custom agent image that installs Node.js on top of the default openlegion-agent:latest:
# Dockerfile.agent-with-node
FROM openlegion-agent:latest
USER root
RUN apt-get update && apt-get install -y nodejs npm \
&& rm -rf /var/lib/apt/lists/*
USER agent
Then point your agent at it and reference the npm package:
agents:
archivist:
image: "openlegion-agent-with-node:latest"
mcp_servers:
- name: fs
command: npx
args: ["-y", "@modelcontextprotocol/server-filesystem", "/data/workspace"]
If you’re staying on the stock image, prefer a Python-based filesystem server or use the built-in file_tool.