Skip to main content
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

  1. Agent container reads MCP_SERVERS from environment (set by the runtime).
  2. MCPClient launches each server subprocess via stdio transport.
  3. MCP protocol handshake discovers available tools and their schemas.
  4. Tools are registered in SkillRegistry with OpenAI function-calling format.
  5. LLM tool calls route through MCPClient.call_tool() to the correct server.
  6. 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

FieldTypeDescription
namestringServer identifier (used for logging and conflict prefixes)
commandstringCommand to launch the server
argslistCommand-line arguments (optional)
envdictEnvironment 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.