version: "3.9"
services:
# Example upstream MCP server (weather API)
# Replace this with your actual MCP server
weather-server:
image: node:20-slim
working_dir: /app
command: >
sh -c "npm install -g @modelcontextprotocol/server-weather &&
exec npx @modelcontextprotocol/server-weather"
environment:
PORT: 3000
networks:
- mcp-network
healthcheck:
test: ["CMD", "node", "-e", "fetch('http://localhost:3000').catch(()=>process.exit(1))"]
interval: 10s
timeout: 5s
retries: 3
# MCP Observability Sidecar (proxies to weather-server)
mcp-sidecar:
build: .
environment:
# Upstream server configuration
MCP_UPSTREAM_URL: http://weather-server:3000
MCP_UPSTREAM_NAME: weather-api
MCP_UPSTREAM_TIMEOUT_MS: 30000
# Listen configuration
PORT: 4000
HOST: 0.0.0.0
# OpenTelemetry configuration
OTEL_SERVICE_NAME: mcp-sidecar
SERVICE_VERSION: 0.2.0
OTEL_ENV: dev
OTEL_EXPORTER_OTLP_PROTOCOL: http/protobuf
OTEL_EXPORTER_OTLP_ENDPOINT: http://otelcol:4318
OTEL_METRIC_EXPORT_INTERVAL: 10000
# Logging
LOG_LEVEL: info
ports:
- "4000:4000"
networks:
- mcp-network
depends_on:
weather-server:
condition: service_healthy
otelcol:
condition: service_started
healthcheck:
test: ["CMD", "node", "-e", "fetch('http://localhost:4000/health').catch(()=>process.exit(1))"]
interval: 10s
timeout: 5s
retries: 3
# OpenTelemetry Collector (sidecar pattern)
otelcol:
image: otel/opentelemetry-collector-contrib:0.113.0
command: ["--config=/etc/otelcol/config.yaml"]
volumes:
- ./otel-collector-config.yaml:/etc/otelcol/config.yaml:ro
ports:
- "8889:8889" # Prometheus exporter
- "4318:4318" # OTLP HTTP receiver
networks:
- mcp-network
# Prometheus (metrics storage)
prometheus:
image: prom/prometheus:v2.52.0
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
- ./alerts.yml:/etc/prometheus/alerts.yml:ro
ports:
- "9090:9090"
networks:
- mcp-network
depends_on:
- otelcol
# Grafana (visualization)
grafana:
image: grafana/grafana:11.0.0
environment:
GF_SECURITY_ADMIN_PASSWORD: admin
GF_SECURITY_ADMIN_USER: admin
ports:
- "3000:3000"
volumes:
- ./grafana/provisioning/dashboards/default.yaml:/etc/grafana/provisioning/dashboards/default.yaml:ro
- ./grafana/dashboards:/var/lib/grafana/dashboards:ro
- ./grafana/provisioning/datasources:/etc/grafana/provisioning/datasources:ro
networks:
- mcp-network
depends_on:
- prometheus
networks:
mcp-network:
driver: bridge