Skip to content

MCP (Model Context Protocol)

Chimera’s MCP module lets agents connect to external MCP servers and use their tools as native Chimera BaseTool instances. This enables agents to interact with databases, filesystems, APIs, and any other service that exposes an MCP interface — without writing custom tool code.

from chimera.mcp import MCPClient
from chimera.core.agent import Agent
from chimera.core.tool_group import DEFAULT_TOOLS
client = MCPClient()
client.add_stdio("fs", "npx", ["-y", "@modelcontextprotocol/server-filesystem"])
client.connect_all()
agent = Agent(tools=list(DEFAULT_TOOLS) + client.tools)
result = agent.run("List files in the current directory")
client.disconnect_all()
ClassDescription
MCPClientManages connections to one or more MCP servers. Discovers tools and exposes them as BaseTool instances.
MCPToolWraps an individual MCP tool definition as a Chimera BaseTool. Created automatically by MCPClient.tools.
MCPToolSourceConvenience class with static methods for quickly connecting to MCP servers and getting tools.
MCPTransportAbstract base class for MCP transport implementations (JSON-RPC 2.0).
StdioTransportTransport that communicates via stdin/stdout of a subprocess using newline-delimited JSON.
HTTPTransportTransport that communicates via HTTP POST requests to an MCP endpoint.

MCPClient is the primary interface. Register servers, connect, and retrieve tools:

from chimera.mcp import MCPClient
client = MCPClient()
# Add a stdio-based server
client.add_stdio("filesystem", "npx", ["-y", "@mcp/server-fs"])
# Add an HTTP-based server
client.add_http("api", "https://mcp.example.com/v1", auth="sk-my-token")
# Connect to all servers and discover tools
client.connect_all()
# Access all discovered tools as BaseTool instances
tools = client.tools
# Ping servers to check health
status = client.ping() # {"filesystem": True, "api": True}
status = client.ping("api") # {"api": True}
# Re-discover tools after a server update
client.refresh_tools()
client.refresh_tools("filesystem") # Refresh a specific server
# Disconnect when done
client.disconnect_all()

MCPClient also supports context manager usage:

with MCPClient() as client:
client.add_stdio("fs", "npx", ["-y", "@mcp/server-fs"])
# connect_all() is called automatically on __enter__
agent = Agent(tools=list(DEFAULT_TOOLS) + client.tools)
result = agent.run("Read the README.md file")
# disconnect_all() is called automatically on __exit__

For simple cases where you just need tools from a single server:

from chimera.mcp import MCPToolSource
from chimera.core.agent import Agent
from chimera.core.tool_group import DEFAULT_TOOLS
# One-liner: connect to a stdio server and get tools
tools = MCPToolSource.from_stdio("npx", ["-y", "@mcp/server-fs"])
agent = Agent(tools=list(DEFAULT_TOOLS) + tools)

Load MCP servers from a config dict (matches .mcp.json format):

from chimera.mcp import MCPToolSource
config = {
"servers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@mcp/server-fs"],
},
"api": {
"url": "https://mcp.example.com/v1",
"auth": "sk-my-token",
},
}
}
client, tools = MCPToolSource.from_config(config)

Implement MCPTransport to create a custom transport:

from chimera.mcp import MCPTransport, MCPClient
from typing import Any
class WebSocketTransport(MCPTransport):
def __init__(self, url: str) -> None:
self._url = url
def start(self) -> None:
# Open WebSocket connection
...
def send(self, message: dict[str, Any]) -> dict[str, Any] | None:
# Send JSON-RPC message and return response
...
def close(self) -> None:
# Close connection
...
client = MCPClient()
client.add_transport("custom", WebSocketTransport("ws://localhost:8080"))
client.connect_all()

MCPClient.call_tool() includes built-in retry logic with exponential backoff (1s, 2s, 4s) for transport-level errors (ConnectionError, TimeoutError, OSError). Tool-level errors returned in the JSON-RPC response are not retried.

result = client.call_tool(
transport=transport,
tool_name="read_file",
arguments={"path": "/tmp/data.txt"},
max_retries=3,
)

Chimera bundles six MCP servers under chimera/mcp_servers/. All speak JSON-RPC 2.0 over stdin/stdout and are listed in chimera-plugin/plugin.json with both a subprocess command and a direct module field.

ServerModuleTools exposed
search_serverchimera.mcp_servers.search_serverCodebaseIndex TF-IDF search, symbol lookup, path validation.
review_serverchimera.mcp_servers.review_serverMulti-perspective code review (8 perspectives + composite).
testgen_serverchimera.mcp_servers.testgen_serverTest skeleton generation, coverage-gap detection.
migration_serverchimera.mcp_servers.migration_serverScan / apply / list-presets for MigrationPlanner (python2-to-3, commonjs-to-esm, custom).
rag_serverchimera.mcp_servers.rag_serverDoc search, API lookup, grounded answers.
benchmark_serverchimera.mcp_servers.benchmark_serverEval harness + HumanEval problem fetcher.

Run a server directly:

Terminal window
python3 -m chimera.mcp_servers.search_server

Or wire it into an agent via MCPClient:

from chimera.mcp import MCPClient
from chimera.core.agent import Agent
from chimera.core.tool_group import DEFAULT_TOOLS
client = MCPClient()
client.add_stdio(
"chimera-search",
"python3",
["-m", "chimera.mcp_servers.search_server"],
)
client.connect_all()
agent = Agent(tools=list(DEFAULT_TOOLS) + client.tools)
result = agent.run("Find every callsite of CostTracker.record_usage")

For the loaded set in any project, install chimera-plugin and the directory loader registers all six automatically.

  • Agent tools: MCPClient.tools returns MCPTool instances that extend BaseTool. Add them to any agent’s tool list alongside DEFAULT_TOOLS.
  • REPL: The chimera code REPL automatically loads MCP servers from ~/.chimera/mcp.json on startup.
  • Plugin system: MCP servers can be configured via .mcp.json in the project root or through the plugin directory loader (chimera.plugins.dir_loader). The directory loader also reads mcp_servers{} blocks from plugin.json.
  • Config format: The .mcp.json file uses the {"servers": {"name": {"command": "...", "args": [...]}}} format, supporting both stdio and HTTP servers.
from chimera.mcp import MCPClient, MCPTool, MCPToolSource
from chimera.mcp import MCPTransport, StdioTransport, HTTPTransport
from chimera.mcp.tools import MCPToolSource # from_stdio(), from_config()