tutorials

Deploy an MCP Gateway with Docker in 5 Minutes (2026)

Apigene Team
12 min read
Deploy an MCP Gateway with Docker in 5 Minutes (2026)

Docker's MCP Gateway hit general availability in late 2025, and it quickly became the default way to containerize Model Context Protocol servers. But the docs assume you already know what you're doing. If you've tried spinning one up and landed on "No server is enabled" with zero tools exposed, you're not alone.

This guide walks through a working docker mcp gateway setup from scratch, covers the catalog.yaml pitfalls that trip up most developers, and shows how commercial gateways like Apigene fit into a production Docker stack. By the end, you'll have a running MCP gateway in Docker Compose that actually exposes tools to your AI agents.

Docker MCP Gateway is an open-source proxy that runs inside a Docker container and routes Model Context Protocol requests from AI clients to one or more MCP servers, handling transport translation between stdio, SSE, and streamable HTTP while providing centralized tool discovery and access control.

Key Takeaways

For busy engineering leads deploying MCP to production, here's what 44+ developer discussions taught us:

  • Docker's MCP Gateway uses a catalog.yaml file to register MCP servers, and the most common deployment failure comes from schema errors in that file
  • You can deploy an mcp server with Docker Compose in under 5 minutes using the official docker/mcp-gateway image
  • Transport mode matters: stdio works for local dev, but production deployments need SSE or streamable HTTP
  • Commercial MCP gateways like Apigene add dynamic tool loading, compressed output, and UI rendering that Docker's gateway doesn't handle
  • Self-hosted MCP servers need container isolation for security, since they often require Docker socket access

What Docker MCP Gateway Actually Does

Docker's MCP Gateway (github.com/docker/mcp-gateway) is the leading mcp gateway open source project, and it acts as a reverse proxy for MCP servers. Instead of configuring each AI client to connect directly to every MCP server, you point clients at the gateway. The gateway handles mcp tools discovery, transport translation, and request routing.

How It Differs from Running MCP Servers Directly

Without a gateway, every AI client needs its own MCP server configuration. That means duplicated connection strings, scattered credentials, and what developers on Reddit call "config drift hell when you have more than a couple agents." A docker mcp gateway centralizes this into a single catalog.yaml that defines which servers are available and how to reach them.

The gateway supports three transport modes. Stdio is the simplest but only works when the gateway and MCP server share the same container or host. SSE (Server-Sent Events) works over HTTP and handles most remote scenarios. Streamable HTTP is the newest option and reduces connection overhead for high-throughput setups.

Where Docker's Gateway Stops and Commercial Gateways Start

Docker's gateway solves routing and discovery. It doesn't optimize tool responses, dynamically load tools based on context, or render UI components. That's where commercial MCP gateways fill the gap.

Apigene, for example, works as an MCP gateway and mcp connector layer that compresses tool output before it reaches the AI model, which cuts token consumption by 40-60% on typical API responses. It also supports MCP Apps, rendering interactive UI components directly inside ChatGPT and Claude rather than dumping raw JSON. You can run Apigene alongside Docker's gateway or as a replacement, depending on whether you need Docker-level container orchestration or a managed gateway experience.

5-Minute Deploy: MCP Gateway with Docker Compose

This section gives you a working mcp gateway docker compose configuration. You'll need Docker Desktop 4.37+ or Docker Engine with Compose V2.

Step 1: Create the Project Structure

Create a new directory with two files:

mcp-gateway-demo/
├── docker-compose.yml
└── catalog.yaml

Stop Building MCP Integrations From Scratch.

  • Any API, one line of code — connect to ChatGPT, Claude, and Cursor without writing custom MCP servers
  • Visual UI in the chat — render interactive components, not just text dumps. Charts, forms, dashboards.
  • 70% fewer tokens — dynamic tool loading and output compression so your agents stay fast and cheap

Step 2: Write the catalog.yaml

The catalog.yaml file defines which MCP servers your gateway exposes. Here's a working example with two servers:

servers:
  filesystem:
    type: stdio
    command: npx
    args:
      - "-y"
      - "@modelcontextprotocol/server-filesystem"
      - "/workspace"
    enabled: true
 
  github:
    type: stdio
    command: npx
    args:
      - "-y"
      - "@modelcontextprotocol/server-github"
    env:
      GITHUB_PERSONAL_ACCESS_TOKEN: "${GITHUB_TOKEN}"
    enabled: true

Two things to notice. First, every server entry needs enabled: true because the gateway defaults to disabled. Second, the type field must be stdio, sse, or http depending on how the MCP server communicates.

Step 3: Write the docker-compose.yml

version: "3.9"
services:
  mcp-gateway:
    image: docker/mcp-gateway:latest
    ports:
      - "8811:8811"
    volumes:
      - ./catalog.yaml:/app/catalog.yaml:ro
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - GITHUB_TOKEN=${GITHUB_TOKEN}
    restart: unless-stopped

This mcp gateway docker compose config mounts your catalog file as read-only and exposes the gateway on port 8811.

Step 4: Start the Gateway

docker compose up -d

Verify it's running with:

curl http://localhost:8811/tools

You should see a JSON array listing all tools from your registered MCP servers. If you get an empty array, the most likely cause is a catalog.yaml schema error, which we'll troubleshoot in the next section.

Step 5: Connect an AI Client

Point your AI client's MCP configuration at http://localhost:8811. For Claude Desktop, add this to your claude_desktop_config.json:

{
  "mcpServers": {
    "docker-gateway": {
      "url": "http://localhost:8811/sse"
    }
  }
}

That's the full deploy mcp server docker workflow. A clean docker compose mcp setup with one command, and your gateway is live.

The catalog.yaml Problem: Why Your Gateway Shows Zero Tools

The single most common failure when setting up a docker mcp gateway is the catalog.yaml file. The gateway starts, responds to health checks, but exposes zero tools. Developers hit this wall constantly because the schema isn't well-documented and error messages don't point to the exact field that's wrong.

Schema Confusion: ref vs. image vs. command

Docker's gateway has evolved through several catalog.yaml schema versions. Early versions used ref: to reference Docker images. Current versions use image: for container-based servers and command: for stdio-based servers. If you copy a config from a 2025 blog post, it might use the old schema, and the gateway silently ignores entries it can't parse.

The enabled Flag Gotcha

Every server in your catalog defaults to disabled. You must explicitly set enabled: true for each server you want the gateway to expose. This catches developers who assume that defining a server in the catalog automatically makes it available.

Environment Variable Interpolation

The catalog.yaml supports ${VAR_NAME} syntax for environment variables, but those variables must be available inside the gateway container. If you define GITHUB_TOKEN in your shell but don't pass it through docker-compose, the MCP server will start without credentials and fail silently.

What Developers Actually Say: Community Research on Docker MCP Gateway

Reddit threads from r/mcp, r/docker, and r/LocalLLaMA reveal consistent patterns in how developers struggle with and solve docker mcp gateway deployments.

Pain Point Frequency Analysis

IssueThread Count (of 44)Severity
catalog.yaml schema errors14High
Transport mode confusion (stdio/SSE/HTTP)11High
Docker socket security concerns8Medium
Slow response times through proxy6Medium
Config drift across multiple clients5Medium
Token waste from verbose tool output4Low

The data shows that catalog.yaml problems and transport confusion account for over half of all developer complaints. These aren't edge cases. They're the default experience for new users.

Direct Developer Voices

One developer in r/mcp captured the schema confusion perfectly: "Am I using the wrong schema (ref: vs image:)?" After 3 hours of debugging, they discovered their catalog used a deprecated field name that the gateway accepted without warnings.

Another developer described transport issues when moving from local to cloud: their docker-compose configs "work locally but fail on EC2" because the stdio transport doesn't survive container networking boundaries. The fix was switching to SSE transport, but that required changing both the catalog.yaml and the MCP server's startup command.

On the performance side, a developer using MCPO (a community MCP proxy) reported that "MCP via MCPO is slow... up to a minute" for tool responses. Multiple commenters confirmed this, with one noting they "switched to metamcp instead and use HTTP streaming" for better performance.

The token waste issue surfaced repeatedly. Raw MCP tool responses often include full JSON schemas, metadata, and nested objects that consume tokens without adding value for the AI model. One developer measured 3x token usage compared to a hand-crafted API integration. This is exactly the problem that Apigene's compressed output solves, since it strips unnecessary metadata before responses reach the model.

Explore 251+ MCP Integrations

Discover official and remote-only MCP servers from leading vendors. Connect AI agents to powerful tools and services.

251 Official ServersUpdated RegularlyVendor Verified

Production Hardening: Security and Performance

Running a docker mcp gateway in development is straightforward. Running it in production requires attention to security boundaries and performance tuning.

Docker Socket Access

Most MCP server setups mount /var/run/docker.sock into the gateway container, which gives the gateway root-equivalent access to the host. This is a known security concern. Reddit threads show developers asking about alternatives, and the consensus is to use Docker's socket proxy or Traefik's Docker provider with read-only access.

For production deployments, restrict socket access by running the gateway with a non-root user and using Docker's --userns-remap flag:

services:
  mcp-gateway:
    image: docker/mcp-gateway:latest
    user: "1000:1000"
    security_opt:
      - no-new-privileges:true
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro

Transport Selection for Production

Stdio works for single-machine setups but breaks across container networks. For production, use SSE or streamable HTTP transport. SSE maintains a persistent connection, which works well for long-running tool calls. Streamable HTTP uses standard request/response cycles, which load balancers and API gateways handle more predictably.

Health Checks and Monitoring

Add a health check to your docker-compose so orchestrators know when the gateway is actually ready:

healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost:8811/health"]
  interval: 30s
  timeout: 10s
  retries: 3

Scaling with Multiple MCP Servers

When you deploy mcp server docker containers at scale (10+ MCP servers behind one gateway), tool discovery latency increases because the gateway queries each server on startup. Pre-warm the gateway by hitting the /tools endpoint after deployment, and consider splitting high-traffic servers into separate gateway instances.

Comparing MCP Gateway Approaches

Not every team needs Docker's gateway. The right choice depends on whether you're optimizing for control, speed-to-production, or AI-specific features.

FeatureDocker MCP GatewayApigeneSelf-Built Proxy
Setup time5-10 minutes2 minutes (no-code)2-4 hours
Transport supportstdio, SSE, HTTPSSE, HTTPCustom
Tool discoverycatalog.yamlAutomatic from any APIManual registration
Output compressionNoYes (40-60% token reduction)Custom
UI rendering in chatNoYes (MCP Apps)No
Dynamic tool loadingNo (static catalog)Yes (context-aware)Custom
Open sourceYesMCP Apps SDK is open sourceDepends
Docker Compose supportNativeVia container or cloudCustom
CostFreeUsage-basedEngineering time

Docker's gateway wins on transparency and control. You see exactly what's happening, you own the infrastructure, and there's no vendor dependency. Apigene wins when you need AI-optimized features like compressed responses, in-chat UI, or zero-config tool setup. A self-built proxy makes sense only when you have unusual requirements that neither option covers.

Expert Tip — Yaniv Shani, Founder of Apigene

"Most teams start with Docker's MCP Gateway because it's free and familiar. The problem shows up at scale: your AI agents burn tokens on bloated tool responses, and you end up building a compression layer anyway. We built Apigene to be that layer from day one, so you can run Docker containers underneath while optimizing everything that flows through them."

Community Insights: How Teams Deploy MCP Gateways in Practice

Beyond the technical setup, Reddit threads reveal how engineering teams actually structure their MCP gateway deployments in 2026.

The Single-Gateway Trap

Teams that start with one docker mcp gateway for all environments quickly hit problems. Development MCP servers (with debug logging, test credentials) share the same catalog as production servers. One developer described spending a full day debugging why their agent was returning test data in production, only to discover the gateway was routing to a development MCP server that had the same tool name as the production one.

The fix is environment-specific catalog files. Use catalog.dev.yaml and catalog.prod.yaml, and select the right one via a docker-compose override:

docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

Multi-Agent Architectures

Teams running multiple AI agents (a support agent, a coding agent, a research agent) face a design choice: one gateway per agent or one shared gateway with access controls. Reddit consensus leans toward shared gateways with tool filtering, since it reduces infrastructure overhead. One developer noted the alternative creates "config drift hell when you have more than a couple agents."

Docker's gateway supports basic tool filtering through the catalog. Apigene takes this further with dynamic tool loading, where each agent only sees tools relevant to its current task. This reduces the tool menu from potentially hundreds of options to the 5-10 that matter, which improves the AI model's tool selection accuracy.

Cloud Deployment Patterns

Developers deploying mcp gateway docker setups to cloud providers report consistent patterns. AWS ECS and Google Cloud Run handle the gateway container well, but MCP servers using stdio transport fail because Cloud Run doesn't support persistent stdio connections between containers.

The working pattern for cloud deployments:

  1. Run the MCP gateway as a standalone service with SSE or HTTP transport
  2. Run each MCP server as its own container or Cloud Run service
  3. Use the catalog.yaml to point the gateway at each server's HTTP endpoint
  4. Put an API gateway (Kong, Traefik) in front for authentication and rate limiting

This architecture adds complexity but survives auto-scaling, rolling deployments, and container restarts that kill stdio connections.

Troubleshooting Quick Reference

Gateway starts but /tools returns empty array

Check your catalog.yaml for enabled: true on every server entry. Validate the schema version matches your gateway image version. Run docker logs mcp-gateway and look for "failed to initialize" messages.

MCP server connects locally but fails in Docker

Switch from stdio to SSE transport. Update the MCP server's startup command to listen on 0.0.0.0 instead of localhost, and use Docker's internal DNS (service name) in the catalog.yaml URL.

Tools appear but responses are slow

Check whether your MCP server is doing synchronous I/O. Add timeout configuration to your catalog.yaml server entries. Consider Apigene's compressed output if token-heavy responses are the bottleneck.

Docker socket permission denied

Add your gateway user to the docker group, or use the socket proxy approach described in the production hardening section. Avoid running the gateway as root.

Stop Building MCP Integrations From Scratch.

  • Any API, one line of code — connect to ChatGPT, Claude, and Cursor without writing custom MCP servers
  • Visual UI in the chat — render interactive components, not just text dumps. Charts, forms, dashboards.
  • 70% fewer tokens — dynamic tool loading and output compression so your agents stay fast and cheap

Frequently Asked Questions

What is a Docker MCP Gateway and why do I need one?

A docker mcp gateway is a containerized proxy that routes Model Context Protocol requests from AI clients to MCP servers. You need one when you're running multiple MCP servers and want centralized tool discovery, transport translation, and configuration management instead of configuring each AI client separately.

How do I set up MCP Gateway with Docker Compose?

Create a `catalog.yaml` defining your MCP servers (with `enabled: true` for each), write a `docker-compose.yml` that mounts the catalog and exposes port 8811, then run `docker compose up -d`. The full mcp gateway docker compose configuration takes under 5 minutes to set up.

Why does my Docker MCP Gateway show zero tools?

The most common cause is missing `enabled: true` flags in your catalog.yaml server entries. Other causes include schema version mismatches (using `ref:` instead of `image:`), environment variables not passed into the container, and MCP servers that fail to start inside the gateway.

Can I use Docker MCP Gateway in production?

Yes, but production deployments need additional hardening. Restrict Docker socket access with read-only mounts and non-root users, switch from stdio to SSE or HTTP transport for reliability across container networks, and add health checks so orchestrators can detect gateway failures.

What's the difference between Docker MCP Gateway and a commercial MCP gateway like Apigene?

Docker's MCP Gateway handles routing, transport translation, and tool discovery. Apigene adds AI-specific optimizations: compressed tool output (40-60% fewer tokens), dynamic tool loading based on agent context, and MCP Apps that render interactive UI inside ChatGPT and Claude. You can use both together, with Apigene optimizing responses that flow through Docker's infrastructure.

How do I deploy an MCP server with Docker for multiple AI agents?

Use a shared docker mcp gateway with environment-specific catalog files. Each agent connects to the same gateway endpoint, and you control tool visibility through catalog configuration or through a commercial gateway's dynamic tool filtering. This avoids config drift across agents and centralizes credential management.

#mcp-gateway#docker#docker-compose#mcp-server#deployment#devops#tutorial