Skip to content

MCP Server Integration

AgentZero integrates with MCP (Model Context Protocol) servers as first-class tools. Each tool exposed by an MCP server is registered individually — the LLM sees mcp__filesystem__read_file, not a generic “call MCP” dispatcher.

Create an mcp.json file. AgentZero discovers servers from two locations:

LocationPathScope
Global~/.agentzero/mcp.jsonAvailable to all projects
Project{workspace}/.agentzero/mcp.jsonProject-specific servers

Project servers override global ones with the same name.

Terminal window
mkdir -p ~/.agentzero
cat > ~/.agentzero/mcp.json << 'EOF'
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@anthropic/mcp-server-filesystem", "/tmp"]
}
}
}
EOF

Add to your agentzero.toml:

[security.mcp]
enabled = true
Terminal window
agentzero tools list | grep mcp

You should see tools like mcp__filesystem__read_file, mcp__filesystem__write_file, etc.


The format matches the Claude Code / VS Code convention:

{
"mcpServers": {
"server-name": {
"command": "path/to/binary",
"args": ["arg1", "arg2"],
"env": {
"API_KEY": "value"
}
}
}
}
FieldRequiredDescription
commandYesThe executable to run (e.g. npx, python3, /usr/local/bin/my-server)
argsNoCommand-line arguments passed to the executable
envNoEnvironment variables set for the subprocess

Read and write files in a scoped directory:

{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@anthropic/mcp-server-filesystem", "/path/to/allowed/dir"]
}
}
}

Create issues, PRs, search repos:

{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_TOKEN": "ghp_..." }
}
}
}

Web search via Brave:

{
"mcpServers": {
"brave-search": {
"command": "npx",
"args": ["-y", "@anthropic/mcp-server-brave-search"],
"env": { "BRAVE_API_KEY": "BSA..." }
}
}
}

Any executable that speaks JSON-RPC 2.0 over stdio:

{
"mcpServers": {
"my-tools": {
"command": "/usr/local/bin/my-mcp-server",
"args": ["--verbose"],
"env": { "MY_CONFIG": "/etc/my-config.json" }
}
}
}

[security.mcp]
enabled = true # master switch (default: false)
allowed_servers = [] # empty = all servers; non-empty = allowlist filter

When allowed_servers is non-empty, only servers whose names appear in the list are loaded. This lets you define many servers globally but restrict which ones a specific project can use.

The AGENTZERO_MCP_SERVERS environment variable provides a final override layer:

Terminal window
export AGENTZERO_MCP_SERVERS='{"my-server":{"command":"my-binary","args":[]}}'

This is useful for CI/CD or ephemeral environments. For normal use, prefer mcp.json files.


When the same server name appears in multiple locations, later sources override earlier ones:

  1. Global ~/.agentzero/mcp.json
  2. Project {workspace}/.agentzero/mcp.json
  3. Environment AGENTZERO_MCP_SERVERS

At startup, AgentZero:

  1. Reads and merges all mcp.json sources
  2. Filters by allowed_servers (if non-empty)
  3. Connects to each server subprocess via stdio
  4. Calls tools/list to discover available tools
  5. Registers each tool as its own McpIndividualTool with:
    • Name: mcp__{server}__{tool} (e.g. mcp__filesystem__read_file)
    • Description: From the server’s tool metadata
    • Schema: The inputSchema from tools/list, passed directly to the LLM

Tool names follow the pattern mcp__{server}__{tool}:

  • Double underscores (__) separate the server name from the tool name
  • Non-alphanumeric characters in tool names are replaced with _
  • Example: server brave-search, tool web_searchmcp__brave_search__web_search

Multiple tools from the same server share a single connection (subprocess + stdin/stdout handles). The first tool call spawns the process; subsequent calls reuse it.

Arc<McpServerConnection>
(shared subprocess)
/ | \
mcp__fs__read mcp__fs__write mcp__fs__list

If a connection error occurs during a tool call, the session is cleared and retried once automatically. If the retry also fails, the error is returned to the agent.

If a server fails to connect at startup (missing binary, timeout, protocol error), it is skipped with a warning — other servers and all built-in tools continue to work normally. This prevents one misconfigured server from blocking the entire agent.


  • MCP servers run as subprocesses with the same OS permissions as the AgentZero process
  • Use allowed_servers to restrict which servers are available in production
  • Server environment variables (API keys, tokens) are passed only to that specific subprocess
  • The enabled = false default means MCP is opt-in — no servers are loaded unless explicitly enabled
  • Consider running AgentZero with reduced OS privileges when using MCP servers from untrusted sources

SymptomCauseFix
No mcp__* tools in tools listMCP not enabledAdd [security.mcp] with enabled = true
Server not foundNo mcp.json fileCreate ~/.agentzero/mcp.json or .agentzero/mcp.json
npx command not foundNode.js not installedInstall Node.js and npm
Server skipped at startupServer failed to connectCheck the server command and args, run manually to debug
Tool call returns errorServer-side errorEnable -vvv for debug logs showing the JSON-RPC exchange

AgentZero can also run as an MCP server, exposing its tools to any MCP client (Claude Desktop, Cursor, Windsurf, etc.).

Run AgentZero as an MCP server over stdin/stdout:

Terminal window
agentzero mcp-serve

This reads JSON-RPC messages from stdin and writes responses to stdout. Configure it in Claude Desktop’s MCP settings:

{
"mcpServers": {
"agentzero": {
"command": "agentzero",
"args": ["mcp-serve"]
}
}
}

All tools registered in your agentzero.toml (file ops, shell, web search, etc.) become available as MCP tools.

When the gateway starts with a config, the MCP server is automatically initialized. Use the HTTP endpoint:

POST /mcp/message
Content-Type: application/json
{"jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {}}

The POST /v1/tool-execute endpoint executes tools directly (used by lite-mode nodes for remote delegation):

Terminal window
curl -X POST http://localhost:8080/v1/tool-execute \
-H "Content-Type: application/json" \
-d '{"tool": "read_file", "input": {"path": "/tmp/test.txt"}}'
MethodDescription
initializeHandshake — returns server capabilities
tools/listList all available tools with schemas
tools/callExecute a tool by name with arguments
pingHealth check