- mcpware
mcpware
mcpware
Route MCP requests intelligently to multiple backend servers with comprehensive security validation.
🎯 Key Features
🚀 Bypass Tool Limits
- Challenge: MCP clients often have limits on how many tools can be loaded at once
- Solution: mcpware exposes only 2 routing tools while providing access to unlimited backend tools
- Result: Connect to GitHub (50+ tools), databases, and more through a single gateway!
🔒 Built-in Security 🧪 (Experimental)
- Prevents cross-backend data leakage (e.g., database → GitHub)
- Blocks SQL injection and sensitive data exposure
- Taint tracking stops all access after suspicious activity
- Mandatory security classification for each backend (public/internal/sensitive)
- Opt In/Out Security Check from config.json
🔧 Additional Benefits
- Single entry point for multiple MCP servers
- Automatic process management for backend servers
- Docker-based isolation and deployment
Quick Start
# Clone the repository
git clone https://github.com/delexw/mcpware.git
cd mcpware
# Build the Docker image
docker build -t mcpware .
# Configure Claude Desktop (see Installation section)
# Add the configuration to claude_desktop_config.json
# Restart Claude Desktop after configuration
Then configure Claude Desktop as shown in the Installation section.
How it Works
mcpware runs as a Docker container that:
- Receives requests from Claude Desktop via stdio
- Routes them to the appropriate backend MCP server (also running in Docker)
- Returns responses back to Claude
Important: Backend servers must be Docker containers when running mcpware in Docker. NPM-based backends require running mcpware on the host.
Installation
Prerequisites
- Docker
- Claude Desktop app
Setup with Claude Desktop
-
Clone this repository:
git clone https://github.com/delexw/mcpware.git cd mcpware -
Configure your backends in
config.json(see Configuration section below) -
Set up your environment variables:
# Create a .env file with your tokens echo "GITHUB_PERSONAL_ACCESS_TOKEN=your_token_here" > .env -
Add to Claude Desktop configuration:
Config file locations:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
Configuration (Direct Docker Run):
{ "mcpServers": { "mcpware": { "command": "docker", "args": [ "run", "-i", "--rm", "-v", "/path/to/mcpware/config.json:/app/config.json:ro", "-v", "/var/run/docker.sock:/var/run/docker.sock", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN", "mcpware" ], "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "your_github_token_here" } } } }Important:
- Replace
/path/to/mcpwarewith the absolute path to your cloned repository - Replace
your_github_token_herewith your actual GitHub Personal Access Token - The Docker socket mount (
/var/run/docker.sock) is required for mcpware to launch Docker-based backends
Why mount the Docker socket?
- mcpware needs to launch Docker containers for backend MCP servers (like
ghcr.io/github/github-mcp-server) - The Docker socket mount allows mcpware to communicate with Docker
- Without this mount, mcpware cannot start backend servers that run as Docker containers
- macOS:
-
Restart Claude Desktop to load the new configuration
Platform-Specific Docker Socket Configuration
The gateway needs access to the Docker socket to launch backend containers. The mount path differs by platform:
Why is Docker socket access required?
mcpware acts as a process manager that launches backend MCP servers. When a backend is configured to run as a Docker container (e.g., ghcr.io/github/github-mcp-server), mcpware needs to:
- Create and start Docker containers
- Manage their lifecycle (stop/restart)
- Communicate with them via stdio
Without Docker socket access, mcpware cannot launch Docker-based backends and will fail with permission errors.
Quick Check
Run this script to check your Docker configuration:
python scripts/check_docker_socket.py
Linux/macOS/WSL2
No changes needed. The default configuration works:
volumes:
- /var/run/docker.sock:/var/run/docker.sock
Windows (Native Containers)
Update the Docker socket path in your Claude Desktop configuration:
{
"mcpServers": {
"mcpware": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-v",
"/path/to/mcpware/config.json:/app/config.json:ro",
"-v",
"//./pipe/docker_engine://./pipe/docker_engine",
"-e",
"GITHUB_PERSONAL_ACCESS_TOKEN",
"mcpware"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "your_github_token_here"
}
}
}
}
Note the different Docker socket path: //./pipe/docker_engine instead of /var/run/docker.sock
Check Your Docker Type
To verify which Docker backend you're using on Windows:
docker version --format '{{.Server.Os}}'
linux= WSL2/Hyper-V backend (use default config)windows= Windows containers (use override file)
Configuration
Create a config.json with your backend servers:
{
"backends": {
"github": {
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN", "ghcr.io/github/github-mcp-server"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_PERSONAL_ACCESS_TOKEN}"
},
"description": "GitHub MCP Server",
"timeout": 30
}
},
"security_policy": {
"backend_security_levels": {
"github": "public"
}
}
}
Required:
security_policywithbackend_security_levelsclassifying each backend aspublic,internal, orsensitive- Backend commands must start with
dockerwhen using Docker
See config.example.json for more backend examples (databases, APIs, etc.).
Usage
The gateway exposes two main tools:
use_tool
Routes a tool call to a specific backend server.
Parameters:
backend_server: Name of the backend serverserver_tool: Name of the tool to calltool_arguments: Arguments to pass to the tool
Example:
{
"backend_server": "github",
"server_tool": "create_issue",
"tool_arguments": {
"owner": "myorg",
"repo": "myrepo",
"title": "New issue",
"body": "Issue description"
}
}
discover_backend_tools
Discovers available backends and their tools.
Parameters:
backend_name: (Optional) Specific backend to query
Using mcpware Alongside Other MCP Servers
mcpware is designed to work alongside other MCP servers in your Claude Desktop configuration. You can:
- Use mcpware as a gateway for multiple backend servers
- Keep some MCP servers separate for direct access
- Mix and match based on your needs
Example mixed configuration:
{
"mcpServers": {
"mcpware": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-v", "/path/to/mcpware/config.json:/app/config.json:ro",
"-v", "/var/run/docker.sock:/var/run/docker.sock",
"-e", "GITHUB_PERSONAL_ACCESS_TOKEN",
"mcpware"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "your_token"
}
},
"redis-direct": {
"command": "docker",
"args": ["run", "--rm", "-i", "-e", "REDIS_HOST=localhost", "mcp/redis"]
}
}
}
This allows you to:
- Access multiple servers through mcpware when you need routing
- Connect directly to specific servers when you need dedicated access
- Organize your MCP servers based on your workflow
Development
Prerequisites
Ensure you have Python 3.10+ installed:
python --version # Should show Python 3.10 or higher
Development Setup
-
Clone the repository:
git clone https://github.com/delexw/mcpware.git cd mcpware -
Create a virtual environment (recommended):
python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate -
Install development dependencies:
pip install -r requirements.txt
Development Dependencies
The project uses minimal dependencies. All core functionality is implemented using the Python standard library.
Testing dependencies (included in requirements.txt):
pytest- Testing frameworkpytest-asyncio- Async test supportpytest-cov- Code coverage reporting
Optional development tools (install separately if needed):
# Code formatting
pip install black isort
# Linting
pip install flake8 pylint mypy
# Development convenience
pip install pytest-watch # Auto-run tests on file changes
Running Locally
# Run the gateway server
python gateway_server.py --config config.json
# Run with debug logging
python gateway_server.py --config config.json --log-level DEBUG
Code Style
Format your code before committing:
# Format with black (if installed)
black src/ tests/ gateway_server.py
# Sort imports (if installed)
isort src/ tests/ gateway_server.py
# Run linting (if installed)
flake8 src/ tests/ gateway_server.py --max-line-length=120
Running Tests
# Run all tests
pytest
# Run with coverage report
pytest --cov=src --cov=gateway_server --cov-report=html
# Run specific test file
pytest tests/test_config.py
# Run tests in watch mode (requires pytest-watch)
pytest-watch
Docker
Build and run with Docker:
# Build the image
docker build -t mcpware .
# Run interactively (for testing)
docker run -it --rm \
-v $(pwd)/config.json:/app/config.json:ro \
-v /var/run/docker.sock:/var/run/docker.sock \
-e GITHUB_PERSONAL_ACCESS_TOKEN \
mcpware
# Run with specific config file
docker run -it --rm \
-v /path/to/your/config.json:/app/config.json:ro \
-v /var/run/docker.sock:/var/run/docker.sock \
-e GITHUB_PERSONAL_ACCESS_TOKEN \
mcpware
Environment Variables
The gateway supports environment variable substitution in backend configurations. Set these in your .env file:
# Example .env file
GITHUB_PERSONAL_ACCESS_TOKEN=ghp_xxxxxxxxxxxxx
ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxx
# Add other tokens as needed
Environment variables referenced in config.json using ${VAR_NAME} syntax will be automatically substituted.
Testing
The project includes comprehensive unit and integration tests.
Running Tests
-
Install test dependencies:
pip install -r requirements.txt -
Run all tests:
pytest -
Run tests with coverage:
pytest --cov=src --cov=gateway_server --cov-report=html -
Run specific test modules:
pytest tests/test_config.py pytest tests/test_backend.py pytest tests/test_protocol.py -
Run tests in watch mode:
pytest-watch
Security Details
mcpware prevents cross-backend information leakage through multiple layers:
Attack Prevention Example
- Attacker creates malicious GitHub issue with prompt injection
- User asks: "Review my GitHub issues"
- Agent reads malicious issue and tries to query database
- mcpware blocks: Cannot send database data back to GitHub (public backend)
Security Tools
- Use
security_statustool to monitor session security - Configure policies in
config.json(seeconfig.example.jsonfor full options) - Automatic taint tracking after suspicious activity
Architecture
mcpware uses a "Docker-out-of-Docker" approach:
- Runs as a container with access to host Docker daemon
- Launches backend containers as siblings (not children)
- Backends can access host services via
host.docker.internal - Communication via stdio pipes between containers
License
MIT