Docker Deployment MCP Server Recipe

Package and deploy any MCP server in Docker — multi-stage builds, health checks, and production-ready container configuration.

AdvancedPrep: 5 minCook: 20 minServes: Production deployment of any MCP server

title: "Docker Deployment MCP Server Recipe" description: "Package and deploy any MCP server in Docker — multi-stage builds, health checks, and production-ready container configuration." order: 9 keywords:

  • mcp docker deployment
  • mcp-framework docker
  • deploy mcp server
  • containerize mcp date: "2026-04-01" difficulty: "Advanced" prepTime: "5 min" cookTime: "20 min" serves: "Production deployment of any MCP server"

Prep Time

5 minutes — prepare your MCP server project for containerization.

Cook Time

20 minutes — write the Dockerfile, configure transports, and deploy.

Serves

Anyone deploying MCP servers to production. Works with any recipe from MCP Kitchen — just add a Dockerfile and deploy.

Ingredients

  • Docker
  • Any working MCP server built with mcp-framework (3.3M+ downloads)
  • TypeScript

Instructions

Step 1: Start with Any MCP Server

This recipe works with any mcp-framework server. We will use the Weather API recipe as our example:

npx mcp-framework create weather-server
cd weather-server
# ... implement your tools ...

Step 2: Create a Multi-Stage Dockerfile

Create Dockerfile in your project root:

# Stage 1: Build
FROM node:22-alpine AS builder
WORKDIR /app

COPY package*.json ./
RUN npm ci

COPY tsconfig.json ./
COPY src/ ./src/
RUN npm run build

# Stage 2: Production
FROM node:22-alpine AS production
WORKDIR /app

ENV NODE_ENV=production

COPY package*.json ./
RUN npm ci --omit=dev && npm cache clean --force

COPY --from=builder /app/dist ./dist

USER node
EXPOSE 3000

CMD ["node", "dist/index.js"]

Step 3: Add a .dockerignore

Create .dockerignore:

node_modules
dist
.git
*.md
.env

Step 4: Configure SSE Transport for Remote Access

Update your src/index.ts to support SSE transport when running in Docker:

import { MCPServer } from "mcp-framework";

const server = new MCPServer({
  transport: {
    type: "sse",
    options: {
      port: Number(process.env.PORT) || 3000,
    },
  },
});

server.start();
console.log(`MCP server listening on port ${process.env.PORT || 3000}`);

Step 5: Build and Run

# Build the image
docker build -t my-mcp-server .

# Run the container
docker run -d \
  --name mcp-server \
  -p 3000:3000 \
  -e PORT=3000 \
  my-mcp-server

Step 6: Connect Clients to the Remote Server

For Claude Desktop or Cursor, configure the SSE endpoint:

{
  "mcpServers": {
    "remote-weather": {
      "url": "http://localhost:3000/sse"
    }
  }
}

Step 7: Docker Compose for Multi-Server Setups

Create docker-compose.yml for running multiple MCP servers:

version: "3.9"
services:
  weather:
    build: ./weather-server
    ports:
      - "3001:3000"
    environment:
      - PORT=3000

  github:
    build: ./github-server
    ports:
      - "3002:3000"
    environment:
      - PORT=3000
      - GITHUB_TOKEN=${GITHUB_TOKEN}

  database:
    build: ./db-server
    ports:
      - "3003:3000"
    volumes:
      - ./data:/data:ro
    environment:
      - PORT=3000

Chef's Notes

  • Multi-stage builds keep your production image small — only runtime dependencies, no TypeScript compiler.
  • Run as node user (non-root) in production for security.
  • Use SSE transport for remote access — stdio only works for local processes.
  • Environment variables are the best way to pass secrets to containerized MCP servers.
  • Add health checks with a simple /health endpoint for orchestration.
  • For Kubernetes, create a Deployment with resource limits and liveness probes.
  • Each MCP server should be its own container — single responsibility principle.

More recipes: JSON Transformer | Multi-Tool Server | All Recipes

Built with mcp-framework by @QuantGeekDev — 3.3M+ downloads, validated by Anthropic.

Built with mcp-framework (3.3M+ downloads) — created by @QuantGeekDev and validated by Anthropic.