This document details Agent Zero's integration with the Model Context Protocol (MCP), a standard protocol for AI assistants to interact with external tools and resources. Agent Zero implements MCP in a dual role architecture: it can both consume external MCP servers as a client and expose itself as an MCP server to other AI assistants like Claude Desktop.
For general integration patterns beyond MCP, see External Integration Interfaces. For the Agent-to-Agent (A2A) protocol, see A2A Communication. For the external HTTP API, see External API Integration.
Agent Zero's MCP implementation supports bidirectional integration through two distinct subsystems:
| Role | Purpose | Implementation | Authentication |
|---|---|---|---|
| MCP Client | Consume external MCP tools | MCPConfig, MCPClientBase | Per-server auth headers |
| MCP Server | Expose Agent Zero to other AI assistants | FastMCP, DynamicMcpProxy | Token-based (mcp_server_token) |
This architecture enables Agent Zero to both extend its capabilities through external tools and provide its own capabilities to other AI systems.
Dual Role Architecture
Sources: python/helpers/mcp_handler.py1-1255 python/helpers/mcp_server.py1-490 Diagram 4
The client subsystem enables Agent Zero to discover and execute tools from external MCP servers. It supports three connection types:
| Type | Protocol | Use Case | Configuration Key |
|---|---|---|---|
| SSE | Server-Sent Events | Remote HTTP servers | type: "sse", url: "..." |
| Streamable HTTP | HTTP streaming | Remote HTTP servers (alternative) | type: "streamable-http", url: "..." |
| StdIO | Standard I/O pipes | Local command-line servers | command: "...", args: [...] |
The MCPConfig singleton manages all MCP server connections through a JSON configuration stored in settings.mcp_servers. Configuration follows the standard MCP format used by Claude Desktop:
The configuration is normalized and parsed by MCPConfig.normalize_config() which handles multiple JSON formats for backward compatibility.
Configuration Lifecycle
Sources: python/helpers/mcp_handler.py379-493 python/helpers/mcp_handler.py516-640
MCPServerRemote handles HTTP-based connections (SSE and streamable HTTP):
url, headers, type, verify, init_timeout, tool_timeoutMCPClientRemote manages sessions via sse_client() or streamablehttp_client()httpx for HTTP requests with configurable SSL verificationMCPServerLocal handles local command-line servers:
command, args, env, encoding, encoding_error_handlerMCPClientLocal manages sessions via stdio_client()Both inherit from a common pattern using MCPClientBase with session-per-operation lifecycle:
This ensures cleanup after each operation without maintaining persistent connections.
Sources: python/helpers/mcp_handler.py221-292 python/helpers/mcp_handler.py294-367 python/helpers/mcp_handler.py809-895
Tools are discovered during server initialization and cached on the client instance:
Tool Discovery Flow
Cached tools are exposed to the agent via MCPConfig.get_tools_prompt() which generates a formatted string for inclusion in the system prompt:
When the agent requests a tool, MCPConfig.get_tool() returns an MCPTool instance wrapping the remote tool:
Tool Execution Flow
Tools are namespaced by server name (e.g., "sqlite.query") to avoid conflicts when multiple servers provide similarly-named tools.
Sources: python/helpers/mcp_handler.py101-141 python/helpers/mcp_handler.py711-803 python/helpers/mcp_handler.py897-926 python/helpers/mcp_handler.py928-966
The client uses a session-per-operation pattern rather than persistent connections:
AsyncExitStack contextClientSession is initialized with read timeoutAsyncExitStackThis design simplifies error handling and prevents resource leaks from failed connections:
Timeouts are configurable per-server (init_timeout, tool_timeout) or globally via settings.
Sources: python/helpers/mcp_handler.py834-895 python/helpers/mcp_handler.py928-966
The server subsystem exposes Agent Zero as an MCP server, allowing external AI assistants like Claude Desktop to interact with it. This is implemented using the fastmcp library with custom routing for authentication and project isolation.
The core server is defined using the FastMCP class with two main tools:
Tool Definitions
send_message creates or continues conversations:
message, attachments, chat_id, persistent_chatToolResponse(response, chat_id) or ToolError(error, chat_id)chat_id provided: continues existing contextpersistent_chat=True: context persists for future callspersistent_chat=False: context deleted after completionfinish_chat terminates persistent conversations:
chat_idToolResponse("Chat finished", chat_id)context.reset() and AgentContext.remove(chat_id)Sources: python/helpers/mcp_server.py30-244 python/helpers/mcp_server.py67-184 python/helpers/mcp_server.py195-243
The DynamicMcpProxy class provides dynamic reconfiguration and token-based authentication without requiring server restart:
Proxy Architecture
Token-based routing enables secure, multi-tenant access:
/mcp/t-{token}/sse or /mcp/t-{token}/httpsettings.mcp_server_tokenProject-based routing provides workspace isolation:
/mcp/t-{token}/p-{project}/ssecontextvars.ContextVarsend_message() via _mcp_project_name.get()projects.activate_project(context_id, project_name)The proxy strips project segments before forwarding to underlying apps, since FastMCP was configured without project-specific paths.
Sources: python/helpers/mcp_server.py294-477 python/helpers/mcp_server.py423-476 python/helpers/mcp_server.py136-168
The proxy supports runtime reconfiguration when the token changes:
Reconfiguration Flow
The _create_custom_http_app() method manually manages the StreamableHTTPSessionManager lifecycle to ensure proper cleanup on reconfiguration.
Sources: python/helpers/mcp_server.py315-347 python/helpers/mcp_server.py349-421
MCP server access is controlled through multiple layers:
The mcp_server_token is generated from user credentials and serves as the primary authentication mechanism:
| Authentication Method | Configuration | Usage |
|---|---|---|
| URL-based | /t-{token}/ path prefix | Recommended for MCP clients |
| Bearer header | Authorization: Bearer {token} | Alternative for API calls |
| API key header | X-API-KEY: {token} | Alternative for API calls |
| Query parameter | ?api_key={token} | Fallback for simple clients |
Token Validation in DynamicMcpProxy
For A2A protocol, similar token validation is implemented in DynamicA2AProxy.__call__().
Sources: python/helpers/mcp_server.py423-476 python/helpers/fasta2a_server.py428-551
Both MCP and A2A servers can be disabled via settings:
This middleware checks mcp_server_enabled and a2a_server_enabled flags before processing requests.
Sources: python/helpers/mcp_server.py479-489 python/helpers/fasta2a_server.py361-374
Project-scoped authentication ensures contexts belong to the correct project:
This prevents cross-project access when continuing conversations.
Sources: python/helpers/mcp_server.py150-157
The Web UI provides a JSON editor for MCP client configuration with real-time server status monitoring:
MCP Configuration UI Components
Status Display shows for each server:
Status Indicators:
The store implements auto-refresh polling:
Sources: webui/components/settings/mcp/client/mcp-servers-store.js1-147 webui/components/settings/mcp/client/mcp-servers.html1-191 python/api/mcp_servers_apply.py1-25
MCP Bidirectional Integration
Sources: python/helpers/mcp_handler.py1-1255 python/helpers/mcp_server.py1-490 Diagram 4 Diagram 8
Refresh this wiki