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:
| Component | Module | Purpose |
|---|---|---|
McpClient | mcp::client | Single-server JSON-RPC client for tool discovery and invocation |
McpManager | mcp::manager | Multi-server lifecycle manager (start, route, shutdown) |
| Transports | mcp::transport | Connection 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:
| Method | Description |
|---|---|
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:
| Field | Type | Description |
|---|---|---|
name | String | Tool name as reported by the server |
description | Option<String> | Human-readable tool description |
input_schema | Value | JSON Schema for tool inputs |
McpManager
The McpManager manages the lifecycle of multiple MCP server connections:
| Method | Description |
|---|---|
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:
| Field | Type | Description |
|---|---|---|
transport | McpTransport | Connection configuration (stdio/http/sse) |
env | HashMap<String, String> | Optional environment variables for the server process |
Server Lifecycle
- During orchestrator start (Step 9), the
McpManagerconnects to all configured servers - Tool definitions are fetched and registered in the
ToolRegistrywith prefixed names - During agent sessions, MCP tool calls are routed through the manager to the correct server
- On shutdown, all servers are gracefully disconnected
Failed server connections are logged as warnings but don't prevent the swarm from starting.
Related
- MCP Servers — Configuration guide
- Tools — How MCP tools integrate with the tool system
- Configuration — Where MCP servers are configured