Orchestration tool for managing multiple MCP servers with a Docker Compose-style interface and a unified HTTP proxy.
A comprehensive orchestration tool for managing Model Context Protocol (MCP) servers with container and proxy capabilities. MCP-Compose provides a Docker Compose-style interface for deploying, configuring, and managing multiple MCP servers through a unified HTTP proxy.
MCP-Compose bridges the gap between traditional MCP STDIO servers and modern HTTP-based architectures. It combines the simplicity of Docker Compose configuration with robust MCP protocol support, enabling seamless integration with clients like Claude Desktop, OpenWebUI, and custom applications.
⚠️ CRITICAL SECURITY REQUIREMENTS ⚠️
Before using MCP-Compose, please review these security requirements:
mcp-compose_example.yaml
for secure configuration patternsCopy .env.example
to .env
and configure:
# Core authentication
MCP_API_KEY=your-secure-random-api-key-here
POSTGRES_PASSWORD=your-secure-database-password
# Optional external services
GITHUB_TOKEN=ghp_your-github-token-here
OPENROUTER_API_KEY=sk-or-v1-your-openrouter-api-key-here
OAUTH_CLIENT_SECRET=your-oauth-client-secret-here
Generate secure keys:
# Generate a secure API key
openssl rand -hex 32
# Or using /dev/urandom
head -c 32 /dev/urandom | base64
Create a mcp-compose.yaml
file:
version: '1'
servers:
filesystem:
image: "mcp/filesystem:latest"
capabilities: [resources, tools]
Run with:
export MCP_API_KEY="your-secure-key-here"
./mcp-compose up
./mcp-compose proxy --port 9876
Your MCP servers are now available at http://localhost:9876
!
For a more complete setup with file access, memory, and search:
version: '1'
# Simple authentication
proxy_auth:
enabled: true
api_key: "${MCP_API_KEY}"
servers:
# File system access
filesystem:
image: "mcp/filesystem:latest"
capabilities: [resources, tools]
volumes:
- "${HOME}/Documents:/workspace:ro"
# Persistent memory/notes
memory:
image: "mcp/memory:latest"
capabilities: [tools, resources]
env:
DATABASE_URL: "sqlite:///data/memory.db"
volumes:
- "mcp-memory-data:/data"
# Web search
search:
image: "mcp/search:latest"
capabilities: [tools]
env:
SEARCH_ENGINE: "duckduckgo"
volumes:
mcp-memory-data:
driver: local
For enterprise features like OAuth, audit logging, and complex deployments, see Advanced Configuration.
# Download for your platform
curl -LO https://github.com/phildougherty/mcp-compose/releases/latest/download/mcp-compose-linux-amd64
chmod +x mcp-compose-linux-amd64
sudo mv mcp-compose-linux-amd64 /usr/local/bin/mcp-compose
git clone https://github.com/phildougherty/mcp-compose.git
cd mcp-compose
make build
sudo cp build/mcp-compose /usr/local/bin/
# mcp-compose.yaml for developers
version: '1'
proxy_auth:
enabled: true
api_key: "${MCP_API_KEY}"
servers:
filesystem:
image: "mcp/filesystem:latest"
capabilities: [resources, tools]
volumes:
- "${HOME}/code:/workspace:rw"
git:
image: "mcp/git:latest"
capabilities: [tools]
volumes:
- "${HOME}/.gitconfig:/root/.gitconfig:ro"
- "${HOME}/code:/workspace:rw"
# mcp-compose.yaml for writers/researchers
version: '1'
proxy_auth:
enabled: true
api_key: "${MCP_API_KEY}"
servers:
filesystem:
image: "mcp/filesystem:latest"
capabilities: [resources, tools]
volumes:
- "${HOME}/Documents:/documents:rw"
search:
image: "mcp/search:latest"
capabilities: [tools]
env:
SEARCH_ENGINE: "duckduckgo"
memory:
image: "mcp/memory:latest"
capabilities: [tools, resources]
env:
DATABASE_URL: "sqlite:///data/notes.db"
volumes:
- "content-memory:/data"
volumes:
content-memory:
driver: local
For production deployments with OAuth, audit logging, monitoring, and advanced security, see mcp-compose-advanced.yaml.
# 1. Install mcp-compose (see Installation section above)
# 2. Create your first configuration
cat > mcp-compose.yaml << 'EOF'
version: '1'
servers:
filesystem:
image: "mcp/filesystem:latest"
capabilities: [resources, tools]
EOF
# 3. Set your API key
export MCP_API_KEY=$(openssl rand -hex 32)
echo "Your API key: $MCP_API_KEY"
# 4. Start the servers
./mcp-compose up
# 5. Start the proxy in another terminal
./mcp-compose proxy --port 9876 --api-key "$MCP_API_KEY"
Your MCP servers are now running! Test with:
curl -H "Authorization: Bearer $MCP_API_KEY" http://localhost:9876/api/servers
# Stop current setup
./mcp-compose down
# Update configuration to add memory and search
cat > mcp-compose.yaml << 'EOF'
version: '1'
proxy_auth:
enabled: true
api_key: "${MCP_API_KEY}"
servers:
filesystem:
image: "mcp/filesystem:latest"
capabilities: [resources, tools]
volumes:
- "${HOME}/Documents:/workspace:ro"
memory:
image: "mcp/memory:latest"
capabilities: [tools, resources]
env:
DATABASE_URL: "sqlite:///data/memory.db"
volumes:
- "mcp-memory:/data"
search:
image: "mcp/search:latest"
capabilities: [tools]
volumes:
mcp-memory:
driver: local
EOF
# Restart with new configuration
./mcp-compose up
./mcp-compose proxy --port 9876
# Generate Claude Desktop configuration
./mcp-compose create-config --type claude --output ./claude-config
# Copy the generated config to Claude Desktop settings
# Location varies by OS:
# - macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
# - Linux: ~/.config/Claude/claude_desktop_config.json
# - Windows: %APPDATA%\Claude\claude_desktop_config.json
If you're currently running individual MCP servers, migration is straightforward:
Before (individual servers):
npx @modelcontextprotocol/server-filesystem /path/to/files
npx @modelcontextprotocol/server-memory
After (mcp-compose):
version: '1'
servers:
filesystem:
image: "mcp/filesystem:latest"
capabilities: [resources, tools]
volumes:
- "/path/to/files:/workspace:ro"
memory:
image: "mcp/memory:latest"
capabilities: [tools, resources]
If you're already using Docker Compose for MCP servers:
Before (docker-compose.yml):
version: '3.8'
services:
mcp-filesystem:
image: mcp/filesystem
ports:
- "3000:3000"
After (mcp-compose.yaml):
version: '1'
servers:
filesystem:
image: "mcp/filesystem:latest"
capabilities: [resources, tools]
Benefits of migrating:
Before (manual Claude Desktop config):
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["@modelcontextprotocol/server-filesystem", "/path"],
"env": {}
}
}
}
After (with mcp-compose):
mcp-compose.yaml
(see examples above)./mcp-compose create-config --type claude
version: '1'
proxy_auth:
enabled: true
api_key: "${MCP_API_KEY}" # Set via environment variable
servers:
filesystem:
image: "mcp/filesystem:latest"
capabilities: [resources, tools]
version: '1'
# No proxy_auth section = no authentication required
servers:
filesystem:
image: "mcp/filesystem:latest"
capabilities: [resources, tools]
⚠️ Never use no authentication in production!
For OAuth 2.1, RBAC, audit logging, and enterprise features, see mcp-compose-advanced.yaml.
# Generate configuration
./mcp-compose create-config --type claude --output ./claude-config
# Your servers will be available as:
# - http://localhost:9876/filesystem
# - http://localhost:9876/memory
# - http://localhost:9876/search
Each server provides its own OpenAPI endpoint:
# Filesystem server API docs
curl http://localhost:9876/filesystem/openapi.json
# Memory server API docs
curl http://localhost:9876/memory/openapi.json
Direct HTTP API access:
# List available tools
curl -H "Authorization: Bearer $MCP_API_KEY" \
http://localhost:9876/filesystem -X POST \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
# Call a tool
curl -H "Authorization: Bearer $MCP_API_KEY" \
http://localhost:9876/filesystem -X POST \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"read_file","arguments":{"path":"/workspace/README.md"}}}'
"Server not found" error:
# Check if servers are running
./mcp-compose ls
# Check logs for errors
./mcp-compose logs filesystem
"Connection refused" error:
# Ensure proxy is running
./mcp-compose proxy --port 9876
# Check if port is already in use
lsof -i :9876
Authentication errors:
# Verify API key is set
echo $MCP_API_KEY
# Check proxy authentication config
grep -A5 "proxy_auth:" mcp-compose.yaml
# Enable debug logging
export MCP_LOG_LEVEL=debug
./mcp-compose up
# View detailed proxy logs
./mcp-compose proxy --port 9876 --debug
# Add connection timeouts (optional)
connections:
default:
timeouts:
connect: "10s"
read: "30s"
write: "30s"
idle: "60s"
For complete configuration reference, see mcp-compose-advanced.yaml
Client → HTTP Proxy → [Protocol Translation] → MCP Server
↓
[STDIO|HTTP|SSE|TCP]
Docker Network (mcp-net)
├── mcp-compose-filesystem (HTTP:3000)
├── mcp-compose-memory (STDIO→TCP:12347)
├── mcp-compose-cron (SSE:8080)
└── mcp-compose-postgres (TCP:5432)
# Install dependencies
go mod download
# Run tests
go test ./...
# Build with development flags
go build -tags dev -o mcp-compose-dev cmd/mcp-compose/main.go
# Run linter
golangci-lint run
This project is licensed under the GNU Affero General Public License v3.0 - see the LICENSE file for details.
A Python-based server for programmatically managing Clappia applications, forms, and submissions via its API.
An MCP server for the Arduino CLI, offering tools to manage sketches, boards, libraries, and files.
Integrates with the unofficial Google Gemini CLI, allowing file access within configured directories.
Generate MCP servers using Smithery with Cursor IDE integration.
A Model Context Protocol server for generating visual charts using AntV.
The definitive Vibe Coder's sanity check MCP server: Prevents cascading errors by calling a "Vibe-check" agent to ensure alignment and prevent scope creep
An example of a remote MCP server deployable on Cloudflare Workers without authentication.
Performs gene set enrichment analysis using the Enrichr API, supporting all available gene set libraries.
An MCP server for interacting with the native Windows API, enabling control over system functions and resources.
A server for generating version 7 universally unique identifiers (UUIDv7).