MCP Servers
Connecting and configuring Model Context Protocol (MCP) servers to extend agent capabilities.
Overview
MCP integration allows swarm to connect to external tool servers using the Model Context Protocol. Tools from MCP servers are registered in the tool registry with prefixed names and appear as regular tools to all agents.
How It Works
- Startup — The orchestrator reads
mcpServersfrom your configuration and connects to each server - Discovery — Each server's tools are listed and registered with prefixed names:
mcp__<server>__<tool> - Execution — When an agent calls an MCP tool, the
McpProxyToolroutes the call to the correct server - Shutdown — All MCP servers are gracefully shut down when the session ends
MCP servers are started once per orchestrator session and shared across all agents.
Step 1: Add MCP Servers to Configuration
Add the mcpServers section to your project config in ~/.swarm/settings.json:
{
"version": 2,
"/home/user/my-project": {
"agents": [ ... ],
"mcpServers": {
"server-name": {
"transport": { ... },
"env": { ... }
}
}
}
}
Each server has a unique name (the key) and a configuration object with transport and optional env fields.
Step 2: Choose a Transport
Swarm supports three MCP transport types:
Stdio Transport
Spawns a child process and communicates via JSON-RPC over stdin/stdout. Best for locally installed tools.
{
"mcpServers": {
"filesystem": {
"transport": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "."]
}
}
}
}
| Field | Type | Required | Description |
|---|---|---|---|
type | "stdio" | Yes | Transport discriminator |
command | String | Yes | Command to execute |
args | String[] | No | Command arguments |
HTTP Transport
Connects over Streamable HTTP. Best for remote servers with request-response semantics.
{
"mcpServers": {
"github": {
"transport": {
"type": "http",
"url": "https://api.example.com/mcp/",
"headers": {
"Authorization": "Bearer ${GITHUB_TOKEN}"
}
}
}
}
}
| Field | Type | Required | Description |
|---|---|---|---|
type | "http" | Yes | Transport discriminator |
url | String | Yes | Server URL |
headers | Map<String, String> | No | HTTP headers |
SSE Transport
Connects over Server-Sent Events (legacy EventSource). Best for servers that push updates.
{
"mcpServers": {
"events": {
"transport": {
"type": "sse",
"url": "https://sse.example.com/events",
"headers": {
"X-Token": "abc123"
}
}
}
}
}
| Field | Type | Required | Description |
|---|---|---|---|
type | "sse" | Yes | Transport discriminator |
url | String | Yes | SSE endpoint URL |
headers | Map<String, String> | No | HTTP headers |
Step 3: Configure Environment Variables (Optional)
MCP servers launched via stdio transport can receive environment variables:
{
"mcpServers": {
"database": {
"transport": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@bytebase/dbhub"]
},
"env": {
"DB_URL": "sqlite:///path/to/db",
"DB_READ_ONLY": "true"
}
}
}
}
The env map is injected into the child process environment when the server is spawned.
Step 4: Use MCP Tools
Once configured, MCP tools appear in the agent's tool registry with prefixed names:
mcp__<server_name>__<tool_name>
For example, a server named github that exposes a search_repos tool creates:
mcp__github__search_repos
Agents can call these tools like any other tool. The McpProxyTool handles routing the call to the correct server, serializing the input as JSON-RPC, and returning the result.
Tool Discovery
Each MCP server advertises its tools via the tools/list JSON-RPC method. Swarm calls this during startup and registers each tool with:
- Name:
mcp__<server>__<tool>(prefixed to avoid conflicts with built-in tools) - Description: As provided by the server
- Input schema: As provided by the server
Permission Integration
MCP tools respect the permission system. You can allow or deny specific MCP tools:
{
"permissions": {
"allow": ["mcp__filesystem__read_file(*)"],
"deny": ["mcp__filesystem__write_file(*)"]
}
}
JSON-RPC Protocol
Swarm communicates with MCP servers using JSON-RPC 2.0. The key message exchanges:
Initialize
// Request
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-03-26",
"capabilities": {},
"clientInfo": { "name": "swarm", "version": "0.1.0" }
}
}
// Response
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2025-03-26",
"capabilities": { "tools": {} },
"serverInfo": { "name": "server-name", "version": "1.0" }
}
}
List Tools
// Request
{ "jsonrpc": "2.0", "id": 2, "method": "tools/list" }
// Response
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"tools": [
{
"name": "search_repos",
"description": "Search GitHub repositories",
"inputSchema": { "type": "object", "properties": { ... } }
}
]
}
}
Call Tool
// Request
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "search_repos",
"arguments": { "query": "swarm" }
}
}
// Response
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [
{ "type": "text", "text": "Found 3 repositories..." }
]
}
}
Complete Example
A configuration with two MCP servers:
{
"version": 2,
"/home/user/my-project": {
"agents": [
{
"name": "backend",
"prompt": "You are a backend engineer with access to the database and filesystem tools."
}
],
"mcpServers": {
"filesystem": {
"transport": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "."]
}
},
"database": {
"transport": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@bytebase/dbhub"]
},
"env": {
"DB_URL": "sqlite:///home/user/my-project/data.db"
}
}
}
}
}
This gives the backend agent access to:
mcp__filesystem__read_filemcp__filesystem__write_filemcp__filesystem__list_directorymcp__database__querymcp__database__list_tables- (and any other tools the servers expose)
Error Handling
- Failed server: If an MCP server fails to start, swarm logs a warning and continues. Other servers and agents are not affected.
- Failed tool listing: If
tools/listfails for a server, its tools are not registered but the server remains connected. - Tool call error: Transport and JSON-RPC errors are returned as tool execution errors to the agent.
- Transport retry: Transport errors are retried once before being returned as failures.
Troubleshooting
"Failed to connect to MCP server"
- Verify the command is installed and in your
PATH(for stdio transport) - Check that the URL is reachable (for http/sse transport)
- Review the server's stderr output in swarm logs
Tools not appearing
- Ensure the server's
tools/listresponse is valid - Check that the server name doesn't contain characters that would break the prefix format
- Verify the server completes initialization within the timeout
Permission denied for MCP tools
MCP tools use the prefixed name format for permission rules. Use mcp__<server>__<tool>(*) in your permission rules.
Related
- MCP Concept — Architecture and internals
- Tools — How tools work in swarm
- Config Schema — Full
McpServerConfigreference - ADR-005: MCP Integration — Design rationale