docker-compose-dev.ymlβ’9.25 kB
# Docker Compose Development Configuration for MCP Server for Splunk
#
# This file is used by the build_and_run.sh script when --docker is specified
# The script automatically detects your Splunk configuration and starts appropriate services
#
# Usage: ./scripts/build_and_run.sh --docker
# - If SPLUNK_HOST=so1: Starts local Splunk + MCP Server + Inspector
# - If SPLUNK_HOST=anything_else: Starts MCP Server + Inspector (connects to external Splunk)
networks:
splunk-network:
driver: bridge
attachable: true
services:
# Traefik reverse proxy and load balancer
traefik:
image: traefik:v3.5
container_name: traefik-dev
restart: unless-stopped
command:
# Enable Docker provider
- --providers.docker=true
- --providers.docker.exposedbydefault=false
# Configure entrypoints
- --entrypoints.web.address=:80
- --entrypoints.mcp.address=:${MCP_SERVER_PORT:-8003}
- --entrypoints.inspector.address=:3002
# Enable API and dashboard (optional, for debugging)
- --api.dashboard=true
- --api.insecure=true
# Logging
- --log.level=INFO
- --accesslog=true
ports:
- "80:80" # HTTP
- "${MCP_SERVER_PORT:-8003}:${MCP_SERVER_PORT:-8003}" # MCP Server port (Traefik entrypoint)
- "3002:3002" # MCP Inspector port (Traefik entrypoint)
- "8080:8080" # Traefik dashboard
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- splunk-network
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.rule=Host(`traefik.localhost`)"
- "traefik.http.routers.traefik.service=api@internal"
# MCP Inspector - Web-based debugging interface
mcp-inspector:
image: node:22-alpine
container_name: mcp-inspector-dev
restart: unless-stopped
working_dir: /app
networks:
- splunk-network
ports:
- "6274:6274" # Inspector UI (same port as local mode)
- "6277:6277" # Inspector Proxy server access
command: >
sh -c "
apk add --no-cache git &&
npm install -g @modelcontextprotocol/inspector@0.16.5 &&
echo 'Starting MCP Inspector...' &&
DANGEROUSLY_OMIT_AUTH=true npx @modelcontextprotocol/inspector --transport streamable-http --server-url http://mcp-server-dev:8001/mcp
"
environment:
- NODE_ENV=development
# Fix binding and origin issues per MCP Inspector docs
- HOST=0.0.0.0
- ALLOWED_ORIGINS=http://localhost:6274,http://127.0.0.1:6274,http://localhost:6277,http://127.0.0.1:6277
depends_on:
- traefik
- mcp-server-dev
labels:
# Enable Traefik for MCP Inspector
- "traefik.enable=true"
# HTTP router for Inspector UI
- "traefik.http.routers.mcp-inspector.rule=Host(`inspector.localhost`) || PathPrefix(`/inspector/`)"
- "traefik.http.routers.mcp-inspector.entrypoints=inspector"
- "traefik.http.routers.mcp-inspector.service=mcp-inspector"
# Service definition pointing to container port 6274 (MCP Inspector default)
- "traefik.http.services.mcp-inspector.loadbalancer.server.port=6274"
# Add middleware for CORS
- "traefik.http.middlewares.inspector-cors.headers.accesscontrolalloworiginlist=*"
- "traefik.http.middlewares.inspector-cors.headers.accesscontrolallowmethods=GET,POST,OPTIONS,PUT,DELETE"
- "traefik.http.middlewares.inspector-cors.headers.accesscontrolallowheaders=Content-Type,Authorization,Accept"
- "traefik.http.middlewares.inspector-cors.headers.accesscontrolmaxage=100"
- "traefik.http.routers.mcp-inspector.middlewares=inspector-cors"
# MCP Server for Splunk (Development Mode with Hot Reload)
mcp-server-dev:
build:
context: .
dockerfile: Dockerfile
container_name: mcp-server-dev
restart: unless-stopped
networks:
- splunk-network
# No direct port mapping - Traefik handles external access
# ports:
# - "8003:8003" # MCP Server direct access (container uses MCP_SERVER_PORT from .env)
env_file:
- .env # Load environment variables from .env file
environment:
# Splunk connection settings - use so1 by default in dev mode
- SPLUNK_HOST=${SPLUNK_HOST:-so1}
- SPLUNK_PORT=${SPLUNK_PORT:-8089}
- SPLUNK_USERNAME=${SPLUNK_USERNAME:-admin}
- SPLUNK_PASSWORD=${SPLUNK_PASSWORD:-Chang3d!}
- SPLUNK_VERIFY_SSL=${SPLUNK_VERIFY_SSL:-false}
# MCP Server settings - container uses port 8001 internally, Traefik uses MCP_SERVER_PORT
- MCP_SERVER_HOST=${MCP_SERVER_HOST:-0.0.0.0}
- MCP_SERVER_PORT=8001
- MCP_TRANSPORT=${MCP_TRANSPORT:-http}
# Development settings - Enable all hot reload features
- MCP_HOT_RELOAD=true
- MCP_RELOAD_MODULES=true
- PYTHONPATH=/app
- PYTHONUNBUFFERED=1
- PYTHONDONTWRITEBYTECODE=1
# FastMCP StreamableHTTP specific environment variables
- FASTMCP_STREAMABLE_HTTP_ALLOWED_ORIGINS=*
- STREAMABLE_HTTP_ALLOW_ALL_ORIGINS=true
- MCP_HTTP_ALLOWED_ORIGINS=*
- MCP_STREAMABLE_HTTP_ORIGINS=*
- FASTMCP_ALLOWED_ORIGINS=*
- DISABLE_ORIGIN_CHECK=true
- MCP_DISABLE_ORIGIN_CHECK=true
- STREAMABLE_HTTP_DISABLE_CORS=true
# OpenAI Agent Settings (loaded from .env file)
- OPENAI_API_KEY=${OPENAI_API_KEY}
- OPENAI_MODEL=${OPENAI_MODEL:-gpt-4o}
- OPENAI_TEMPERATURE=${OPENAI_TEMPERATURE:-0.7}
- OPENAI_MAX_TOKENS=${OPENAI_MAX_TOKENS:-4000}
# Logging level for MCP server (dev)
- MCP_LOG_LEVEL=${MCP_LOG_LEVEL:-INFO}
volumes:
# Mount local data directory for executed workflows persistence
- ./.data:/app/.data
# Ensure relative data dir also maps if used
- ./data:/app/data
depends_on:
- traefik
labels:
# Enable Traefik for this service
- "traefik.enable=true"
# HTTP router for MCP server (Streamable HTTP transport)
- "traefik.http.routers.mcp-server.rule=PathPrefix(`/mcp`)"
- "traefik.http.routers.mcp-server.entrypoints=mcp"
- "traefik.http.routers.mcp-server.service=mcp-server"
# Service definition pointing to container port 8001 (container always uses 8001)
- "traefik.http.services.mcp-server.loadbalancer.server.port=8001"
# Add middleware for CORS headers (important for web clients)
- "traefik.http.middlewares.mcp-cors.headers.accesscontrolalloworiginlist=*"
- "traefik.http.middlewares.mcp-cors.headers.accesscontrolallowmethods=GET,POST,OPTIONS,PUT,DELETE"
- "traefik.http.middlewares.mcp-cors.headers.accesscontrolallowheaders=Content-Type,Authorization,Accept"
- "traefik.http.middlewares.mcp-cors.headers.accesscontrolmaxage=100"
- "traefik.http.routers.mcp-server.middlewares=mcp-cors"
develop:
watch:
# Watch all source files and sync them - fine-grained watching
- path: ./src/tools
action: sync
target: /app/src/tools
ignore:
- "**/__pycache__"
- "**/*.pyc"
- "**/*.pyo"
- "**/.pytest_cache"
# Watch core framework files
- path: ./src/core
action: sync
target: /app/src/core
ignore:
- "**/__pycache__"
- "**/*.pyc"
- "**/*.pyo"
# Watch contrib folder for community tools
- path: ./contrib
action: sync
target: /app/contrib
ignore:
- "**/__pycache__"
- "**/*.pyc"
- "**/*.pyo"
# Watch client and other source files
- path: ./src/client
action: sync
target: /app/src/client
ignore:
- "**/__pycache__"
- "**/*.pyc"
- "**/*.pyo"
# Watch server.py specifically
- path: ./src/server.py
action: sync
target: /app/src/server.py
# Rebuild on configuration changes
- path: ./pyproject.toml
action: rebuild
# Rebuild on Dockerfile changes
- path: ./Dockerfile
action: rebuild
# Splunk Enterprise (Development Mode - only starts when SPLUNK_HOST=so1)
so1:
networks:
splunk-network:
aliases:
- so1
image: ${SPLUNK_IMAGE:-splunk/splunk:latest}
platform: linux/amd64
hostname: so1
container_name: so1
restart: unless-stopped
environment:
- SPLUNK_START_ARGS=--accept-license
- SPLUNK_GENERAL_TERMS=--accept-sgt-current-at-splunk-com
- SPLUNK_HEC_TOKEN=26898dec-83d1-49f1-b06e-90eabff7f543
- SPLUNK_PASSWORD=Chang3d!
ports:
- "9000:8000" # Splunk Web UI
- "8088:8088" # HEC
- "8089:8089" # Management port
# Optional: Provide your own Splunk license by mounting a local file
# volumes:
# - ./lic/splunk.lic:/tmp/license/splunk.lic:ro
healthcheck:
test: ["CMD", "curl", "-s", "-k", "https://localhost:8089/services/server/info"]
interval: 30s
timeout: 10s
retries: 5
start_period: 120s