MCP Integration

Swarm integrates with external tool servers via the Model Context Protocol (MCP). This allows agents to use tools provided by external processes, expanding capabilities beyond the built-in tool set.

Architecture

The MCP integration consists of three layers:

ComponentModulePurpose
McpClientmcp::clientSingle-server JSON-RPC client for tool discovery and invocation
McpManagermcp::managerMulti-server lifecycle manager (start, route, shutdown)
Transportsmcp::transportConnection layer (Stdio, HTTP, SSE)

Transports

Swarm supports three MCP transport types:

Stdio

Launches the MCP server as a subprocess. Communication happens over stdin/stdout using JSON-RPC.

{
  "transport": {
    "type": "stdio",
    "command": "npx",
    "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/dir"]
  }
}

HTTP

Connects to an MCP server over HTTP. Each JSON-RPC request is a POST.

{
  "transport": {
    "type": "http",
    "url": "http://localhost:3000/mcp",
    "headers": {
      "Authorization": "Bearer token123"
    }
  }
}

SSE (Server-Sent Events)

Connects via SSE for server-push capabilities, with HTTP POST for client requests.

{
  "transport": {
    "type": "sse",
    "url": "http://localhost:3000/sse",
    "headers": {}
  }
}

McpClient

The McpClient wraps a transport and provides the MCP protocol methods:

MethodDescription
initialize()Send the MCP initialization handshake
list_tools()Discover available tools from the server
call_tool(name, args)Invoke a tool with JSON arguments
shutdown()Gracefully close the connection

Each client uses an IdGenerator for unique JSON-RPC request IDs.

McpToolDefinition

Tools discovered from MCP servers are represented as:

FieldTypeDescription
nameStringTool name as reported by the server
descriptionOption<String>Human-readable tool description
input_schemaValueJSON Schema for tool inputs

McpManager

The McpManager manages the lifecycle of multiple MCP server connections:

MethodDescription
start_all(configs)Connect to all configured servers; skip failures with warnings
connect_server(name, config)Connect to a single server
all_tool_definitions()Collect and prefix tools from all servers
call_tool(prefixed_name, args)Route a tool call to the correct server
shutdown_all()Gracefully shutdown all server connections

Tool Namespacing

To avoid name collisions between different MCP servers and built-in tools, MCP tools are prefixed with the server name:

mcp__<server_name>__<tool_name>

For example, a tool read_file from a server named filesystem becomes:

mcp__filesystem__read_file

The parse_prefixed_name() function extracts the server and tool names from this format. The PrefixedToolDefinition struct carries the original tool definition along with the prefixed name.

Configuration

MCP servers are configured in the mcpServers section of settings.json:

{
  "mcpServers": {
    "filesystem": {
      "transport": {
        "type": "stdio",
        "command": "npx",
        "args": ["-y", "@modelcontextprotocol/server-filesystem", "."]
      },
      "env": {
        "NODE_PATH": "/usr/local/lib/node_modules"
      }
    },
    "api": {
      "transport": {
        "type": "http",
        "url": "http://localhost:8080/mcp"
      }
    }
  }
}

Each server entry has:

FieldTypeDescription
transportMcpTransportConnection configuration (stdio/http/sse)
envHashMap<String, String>Optional environment variables for the server process

Server Lifecycle

  1. During orchestrator start (Step 9), the McpManager connects to all configured servers
  2. Tool definitions are fetched and registered in the ToolRegistry with prefixed names
  3. During agent sessions, MCP tool calls are routed through the manager to the correct server
  4. On shutdown, all servers are gracefully disconnected

Failed server connections are logged as warnings but don't prevent the swarm from starting.