Run the server as a container with a local volume for storage. Suitable for single-machine deployments, local testing with Docker, and as the base for more complex orchestration setups.
services:
mcp:
image: ghcr.io/openapi/mcp-server:latest
# or build locally:
# build:
# context: .
# dockerfile: docker/latest/Dockerfile
ports:
- "8080:8080"
environment:
MCP_PORT: "8080"
MCP_BASE_URL: "http://localhost:8080"
MCP_STORAGE_BACKEND: "local"
MCP_STORAGE_PATH: "/app/openapi_storage"
volumes:
- openapi_storage:/app/openapi_storage
volumes:
openapi_storage:Start:
docker compose up| Variable | Value | Notes |
|---|---|---|
MCP_STORAGE_BACKEND |
local |
Files written inside the container |
MCP_STORAGE_PATH |
/app/openapi_storage |
Map this to a named or bind-mounted volume |
Important: without a volume, files are lost when the container is recreated. Always map
MCP_STORAGE_PATHto a Docker volume or a host bind mount if you need downloaded documents to persist.
volumes:
- type: bind
source: ./openapi_storage
target: /app/openapi_storageFor a fully cloud-like setup without an actual cloud account, add MinIO to the
compose file and use MCP_STORAGE_BACKEND=s3:
services:
mcp:
environment:
MCP_STORAGE_BACKEND: "s3"
MCP_STORAGE_BUCKET: "openapi-mcp"
MCP_STORAGE_REGION: "us-east-1"
AWS_ACCESS_KEY_ID: "minioadmin"
AWS_SECRET_ACCESS_KEY: "minioadmin"
AWS_ENDPOINT_URL: "http://minio:9000"
minio:
image: minio/minio
command: server /data --console-address ":9001"
ports:
- "9000:9000"
- "9001:9001"
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
volumes:
- minio_data:/data
volumes:
minio_data:For a single-container local setup the in-process dict is sufficient (no cache env vars needed). To share callback state across multiple replicas, add Redis:
services:
mcp:
environment:
MCP_CACHE_BACKEND: "redis"
MCP_CACHE_URL: "redis://redis:6379"
redis:
image: redis:7-alpine
ports:
- "6379:6379"The container must be reachable from the internet for async API callbacks.
Set MCP_BASE_URL to the public address of the host:
environment:
MCP_BASE_URL: "https://my-server.example.com"For local testing, use a tunnel (e.g. ngrok http 8080) and update MCP_BASE_URL
accordingly.
The docker/dev/Dockerfile adds debugpy on port 5678 and bind-mounts ./src
for live code reload. The main compose.yml is already configured for this mode.
See the project README.md for the full VS Code one-click debug workflow.
services:
mcp:
build:
context: .
dockerfile: docker/latest/Dockerfile
ports:
- "8080:8080"
environment:
MCP_PORT: "8080"
MCP_BASE_URL: "https://my-server.example.com"
MCP_STORAGE_BACKEND: "local"
MCP_STORAGE_PATH: "/app/openapi_storage"
MCP_CACHE_BACKEND: "redis"
MCP_CACHE_URL: "redis://redis:6379"
volumes:
- openapi_storage:/app/openapi_storage
depends_on:
- redis
restart: unless-stopped
redis:
image: redis:7-alpine
restart: unless-stopped
volumes:
openapi_storage: