How to Run an MCP Router in Docker
Run Docker’s MCP Gateway with Compose, choose stdio or network transport, secure access, and troubleshoot the separate cubicecho router.
Direct answer: If you mean Docker’s maintained MCP Gateway, create a Compose service using the docker/mcp-gateway image, select the MCP servers you need, mount the Docker socket, and run docker compose up. The Gateway defaults to stdio for local clients; for remote clients, start it with a network transport such as streaming or SSE and configure the client to use the same transport.
“MCP router” can also mean Docker Desktop’s MCP Toolkit or the separate cubicecho/mcp-router project. They have different configuration, persistence, runtime, and security requirements. This guide starts with Docker’s Gateway, then covers those alternatives.
1. Identify which MCP router you need
| Implementation | Best fit | Deployment model | Key detail |
|---|---|---|---|
| Docker MCP Gateway | A general MCP gateway managed from the Docker CLI | CLI process or Docker Compose container | Uses Docker Engine to manage MCP server containers |
| Docker Desktop MCP Toolkit | Teams managing MCP profiles and clients in Docker Desktop | Docker Desktop UI and CLI integration | The current guide describes a beta workflow for Docker Desktop 4.62 and later |
cubicecho/mcp-router |
A standalone router project with its own web and state model | Docker Compose or direct Docker run | Persists configuration and packages under a mounted /data directory |
2. Run Docker’s MCP Gateway with Compose
Prerequisites
- A host with Docker Engine and Docker Compose.
- Permission to access
/var/run/docker.sock. - The names of the MCP servers you intend to enable.
- A trusted host: the Docker socket gives the gateway access to the Docker Engine.
Create the Compose file
Save this as compose.yaml:
services:
gateway:
image: docker/mcp-gateway
command:
- --servers=duckduckgo
volumes:
- /var/run/docker.sock:/var/run/docker.sock
Replace duckduckgo with the server or comma-separated server selection appropriate for your installation. Keep the list small; every enabled server expands the gateway’s available capability and credential surface.
Start the gateway
docker compose up
Run detached when you want the gateway to stay in the background:
docker compose up -d
Inspect startup output and tool calls with:
docker compose logs -f gateway
Stop the service with:
docker compose down
Why the Docker socket is mounted
The Gateway uses the Docker Engine to manage MCP server containers. The socket mount connects the gateway container to that Engine. Treat the mount as a privileged control path: run it on a trusted host, enable only required servers, and do not expose an unprotected gateway to an untrusted network.
3. Connect a local MCP client over stdio
The Gateway CLI defaults to stdio. Docker’s client configuration pattern is:
{
"servers": {
"MCP_DOCKER": {
"command": "docker",
"args": ["mcp", "gateway", "run", "--profile", "my_profile"],
"type": "stdio"
}
}
}
Replace my_profile with the profile used by your client. A stdio client launches the Docker command locally and exchanges MCP messages through the process streams. It does not connect to a TCP port.
4. Listen on a network transport
For a client running elsewhere, start the Gateway with a port and a transport. Docker’s documented pattern uses streaming on port 8080:
docker mcp gateway run --port 8080 --transport streaming
The CLI also documents SSE as a transport option. Configure the client for the exact transport and endpoint emitted or required by the installed Gateway version. Do not reuse a stdio configuration for a network listener.
Network deployment checklist
- Bind and firewall the listener according to your network design.
- Use the authentication and proxy controls provided by your deployment environment.
- Allow only the servers and tools the client needs.
- Keep the Docker Engine and Gateway CLI updated according to your change-control process.
- Review logs before sending secrets or sensitive arguments through tools.
5. Limit servers, tools, and capabilities
The Gateway CLI provides controls for selecting servers and filtering tools:
docker mcp gateway run \
--servers=duckduckgo \
--tools=search,fetch
Flag names and supported values can change between versions. Check the installed help output before copying a production command:
docker mcp gateway run --help
The documented option set also includes controls such as --block-network, --block-secrets, and --verify-signatures. Confirm availability and behavior in your installed version before depending on them.
Credentials and logs
Configure only credentials required by the selected server. Docker documents --log-calls as enabled by default, so inspect what tool arguments may appear in logs before operating the gateway with tokens, personal data, or private URLs.
6. Docker Desktop MCP Toolkit
The MCP Toolkit is a separate Docker Desktop workflow, not the same deployment as the standalone Gateway Compose service. The current guide describes a beta feature for Docker Desktop 4.62 and later.
- Open Docker Desktop settings and enable MCP Toolkit.
- Create a profile.
- Add MCP servers from the catalog.
- Connect your MCP client to that profile.
Earlier Docker Desktop versions may show different menus or lack this workflow. A client can also invoke the Gateway through the Docker CLI using the stdio configuration shown above.
7. If you mean cubicecho/mcp-router
cubicecho/mcp-router is a different project with its own Compose setup, token, persistence model, and runtime limitations.
Compose quickstart
git clone <repository> mcp-router
cd mcp-router
cp .env.example .env
# Set a real MCP_ROUTER_TOKEN in .env
docker compose up -d
Its state, installed packages, and logs are stored under ./data and bind-mounted at /data in the container. Preserve that mount when rebuilding or upgrading so configuration and installed servers remain available.
Runtime limitation
The default image supports npm-based MCP servers. It does not include Python, uv, or other runtimes that some servers require. Those servers need an extended image with the required runtime installed.
Security requirements
- Set a real bearer token in
MCP_ROUTER_TOKEN. - Do not expose the router to untrusted networks without authentication and network controls.
- Install only MCP servers you trust: installed server code runs as a child process and receives configured environment variables.
- Keep
./dataprotected because it contains configuration, packages, and logs.
8. Choosing between the implementations
| Decision | Choose Docker Gateway when… | Choose cubicecho/mcp-router when… |
|---|---|---|
| Ownership | You want Docker’s maintained gateway and CLI workflow | You specifically need that project’s router interface and state model |
| Transport | You need local stdio or a documented network transport | You need the standalone project’s exposed service |
| Persistence | Server selection is managed through Docker profiles or commands | You need persistent packages, configuration, and logs under /data |
| Runtime | Your selected servers fit the Gateway’s container model | You can build an extended image for Python, uv, or another runtime |
| Security | You can protect Docker socket access | You can protect the bearer-token service and trusted child processes |
9. Troubleshooting
Client cannot connect
Cause: The client transport does not match the Gateway. Fix: Use type: "stdio" with the local Docker command, or configure the network endpoint and transport selected with --port and --transport.
The Compose gateway cannot start MCP servers
Cause: Docker Engine is stopped, or the socket path is missing or inaccessible. Fix: Confirm Docker is running and that /var/run/docker.sock:/var/run/docker.sock is present in the service.
A flag is rejected
Cause: CLI options are version-dependent. Fix: Run docker mcp gateway run --help, check the installed version, and use the options supported by that release.
Tool calls expose sensitive values in logs
Cause: Call logging is enabled by default in the documented Gateway configuration. Fix: Review logging settings, restrict credentials, and operate the gateway where logs have appropriate access controls.
cubicecho router loses configuration
Cause: The ./data:/data bind mount was omitted or changed. Fix: Restore the mount and verify the host directory is backed up and writable.
A cubicecho server needs Python or uv
Cause: The default image is npm/Node-oriented. Fix: Build or use an extended image containing the required runtime before installing that server.
Authentication failures in cubicecho/mcp-router
Cause: MCP_ROUTER_TOKEN is missing, placeholder text, or not shared with the client. Fix: Set a real token in .env, restart the Compose service, and update the client’s bearer credential.
10. Reliability, performance, and cost considerations
- Reliability: Use a restart policy or an external service manager for long-running deployments, monitor container logs, and keep the Docker host healthy.
- Performance: Gateway latency includes client transport, container startup, the MCP server itself, and any upstream API. Enable only required servers and tools to reduce discovery and operational overhead.
- Persistence: The Docker Gateway Compose example is intentionally minimal. Add the storage, restart, network, and monitoring settings your environment requires.
- Cost: The software examples do not establish a hosted service price. Budget for the Docker host, upstream MCP services, network traffic, and any paid APIs used by individual servers.
- Security: Socket access, server code, environment variables, and tool-call logs are all operationally significant. Minimize each one.
11. Or skip the browser setup
If your MCP workflow needs website screenshots for an agent, ScreenshotNeo provides an MCP server with take_screenshot, get_page_info, and capture_pdf. It removes cookie banners, newsletter popups, and chat widgets before capture. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and each response reports its verdict and billing status.
One request returns PNG, JPEG, WebP, or PDF. See the ScreenshotNeo API documentation for the complete option list.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
It also supports full-page and element capture, device presets, dark mode, custom CSS and JavaScript, waits, request blocking, cookies and headers, geolocation, PDF controls, caching, signed links, async jobs, bulk capture, and a usage API. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.
12. FAQ
Can I run the Docker Gateway without Docker Desktop?
Yes. The Compose deployment is documented to work with any available Docker Engine; Docker Desktop is not required.
Should I expose the Gateway directly to the internet?
Only after adding the authentication, firewall, proxy, and network controls required by your environment. The minimal Compose example is not a hardened public deployment.
Is Docker Desktop Toolkit the same as the Gateway?
No. Toolkit is a separate Docker Desktop profile and client-management workflow. The Gateway can run independently through the Docker CLI or Compose.
Why does a server work locally but fail in cubicecho/mcp-router?
Check whether it requires Python, uv, or another runtime absent from the default image. Use an extended image with that runtime.
How do I preserve cubicecho router state during upgrades?
Keep the host directory mounted at ./data:/data and back it up before changing images or configuration.


