Skip to main content
Glama

Odoo MCP Server Advanced

by AlanOgic
DOCKER.mdβ€’21.2 kB
# Docker Deployment Guide **Containerized MCP Server for Odoo - Three Transport Options** This guide covers building, running, and deploying the Odoo MCP Server using Docker containers. --- ## Table of Contents - [Quick Start](#quick-start) - [Available Images](#available-images) - [Building Images](#building-images) - [Running Containers](#running-containers) - [Configuration](#configuration) - [Docker Compose](#docker-compose) - [Production Deployment](#production-deployment) - [Troubleshooting](#troubleshooting) - [Advanced Usage](#advanced-usage) --- ## Quick Start ### 1. Prepare Environment File ```bash # Copy example and configure cp .env.example .env # Edit with your Odoo credentials vim .env ``` Required variables: ```bash ODOO_URL=https://your-instance.odoo.com ODOO_DB=your-database ODOO_USERNAME=your-username ODOO_PASSWORD=your-password ``` ### 2. Build and Run **STDIO Transport (Claude Desktop):** ```bash docker build -t mcp-odoo:stdio -f Dockerfile . docker run -i --rm --env-file .env mcp-odoo:stdio ``` **SSE Transport (Web Browsers):** ```bash docker build -t mcp-odoo:sse -f Dockerfile.sse . docker run -p 8009:8009 --env-file .env mcp-odoo:sse ``` **HTTP Transport (API Integrations):** ```bash docker build -t mcp-odoo:http -f Dockerfile.http . docker run -p 8008:8008 --env-file .env mcp-odoo:http ``` --- ## Available Images ### Official Images (Docker Hub) Pre-built images are available at `alanogic/mcp-odoo-adv`: ```bash # Pull images docker pull alanogic/mcp-odoo-adv:latest # STDIO transport docker pull alanogic/mcp-odoo-adv:sse # SSE transport docker pull alanogic/mcp-odoo-adv:http # HTTP transport # Run immediately docker run -i --rm --env-file .env alanogic/mcp-odoo-adv:latest docker run -p 8009:8009 --env-file .env alanogic/mcp-odoo-adv:sse docker run -p 8008:8008 --env-file .env alanogic/mcp-odoo-adv:http ``` ### Transport Comparison | Transport | Image Tag | Port | Use Case | Interactive | |-----------|-----------|------|----------|-------------| | **STDIO** | `latest` | - | Claude Desktop, CLI tools | Yes (`-i`) | | **SSE** | `sse` | 8009 | Web browsers, streaming | No | | **HTTP** | `http` | 8008 | API integrations, REST clients | No | --- ## Building Images ### Build All Transports ```bash # STDIO (default) docker build -t mcp-odoo:stdio -f Dockerfile . # SSE docker build -t mcp-odoo:sse -f Dockerfile.sse . # HTTP docker build -t mcp-odoo:http -f Dockerfile.http . ``` ### Build with Specific Python Version All Dockerfiles support Python 3.10-3.14: ```bash # Python 3.13 (default in SSE/HTTP) docker build -t mcp-odoo:stdio -f Dockerfile . # Python 3.14 (bleeding edge) docker build --build-arg PYTHON_VERSION=3.14 -t mcp-odoo:stdio -f Dockerfile . # Python 3.10 (maximum compatibility) docker build --build-arg PYTHON_VERSION=3.10 -t mcp-odoo:sse -f Dockerfile.sse . ``` ### Build Optimization Docker images use multi-layer caching for fast rebuilds: ```bash # Layer 1: System dependencies (rarely changes) # Layer 2: Python dependencies (changes when pyproject.toml updates) # Layer 3: Source code (changes frequently) # First build: ~2-3 minutes docker build -t mcp-odoo:stdio . # Subsequent builds (code changes only): ~10-15 seconds docker build -t mcp-odoo:stdio . ``` ### Tag for Docker Hub ```bash # Build and tag for publishing docker build -t alanogic/mcp-odoo-adv:latest -f Dockerfile . docker build -t alanogic/mcp-odoo-adv:sse -f Dockerfile.sse . docker build -t alanogic/mcp-odoo-adv:http -f Dockerfile.http . # Push to Docker Hub docker push alanogic/mcp-odoo-adv:latest docker push alanogic/mcp-odoo-adv:sse docker push alanogic/mcp-odoo-adv:http ``` --- ## Running Containers ### STDIO Transport **For Claude Desktop integration:** ```bash # Interactive mode (required for STDIO) docker run -i --rm --env-file .env mcp-odoo:stdio # With inline environment variables docker run -i --rm \ -e ODOO_URL=https://demo.odoo.com \ -e ODOO_DB=demo \ -e ODOO_USERNAME=admin \ -e ODOO_PASSWORD=admin \ mcp-odoo:stdio # Named container (persistent) docker run -i --name odoo-mcp --env-file .env mcp-odoo:stdio # Stop named container docker stop odoo-mcp docker rm odoo-mcp ``` **Claude Desktop Configuration:** Add to `claude_desktop_config.json`: ```json { "mcpServers": { "odoo": { "command": "docker", "args": [ "run", "-i", "--rm", "-e", "ODOO_URL=https://your-instance.odoo.com", "-e", "ODOO_DB=your-database", "-e", "ODOO_USERNAME=your-username", "-e", "ODOO_PASSWORD=your-password", "alanogic/mcp-odoo-adv:latest" ] } } } ``` Or with `.env` file: ```json { "mcpServers": { "odoo": { "command": "docker", "args": [ "run", "-i", "--rm", "--env-file", "/absolute/path/to/.env", "alanogic/mcp-odoo-adv:latest" ] } } } ``` ### SSE Transport **For web browser connections:** ```bash # Standard run docker run -p 8009:8009 --env-file .env mcp-odoo:sse # Background (daemon) mode docker run -d -p 8009:8009 --env-file .env --name odoo-mcp-sse mcp-odoo:sse # Check logs docker logs -f odoo-mcp-sse # Stop daemon docker stop odoo-mcp-sse docker rm odoo-mcp-sse ``` **Test SSE Endpoint:** ```bash # Health check curl http://localhost:8009/health # SSE stream (keeps connection open) curl -N http://localhost:8009/sse ``` ### HTTP Transport **For API integrations:** ```bash # Standard run docker run -p 8008:8008 --env-file .env mcp-odoo:http # Background mode with restart policy docker run -d \ -p 8008:8008 \ --env-file .env \ --name odoo-mcp-http \ --restart unless-stopped \ mcp-odoo:http # View logs docker logs -f odoo-mcp-http ``` **Test HTTP Endpoint:** ```bash # Health check curl http://localhost:8008/health # MCP endpoint curl -X POST http://localhost:8008/mcp \ -H "Content-Type: application/json" \ -d '{"method": "tools/list"}' ``` --- ## Configuration ### Environment Variables **Required:** ```bash ODOO_URL=https://your-instance.odoo.com ODOO_DB=your-database ODOO_USERNAME=your-username ODOO_PASSWORD=your-password ``` **Optional:** ```bash # Custom configuration directory (highest priority) ODOO_CONFIG_DIR=~/mcp-odoo-env # Custom directory for .env file # ODOO_CONFIG_DIR=/etc/odoo-mcp # Or system-wide config # Odoo API configuration ODOO_API_VERSION=json-2 # "json-2" (Odoo 19+) or "json-rpc" (default) ODOO_API_KEY=your_api_key # For JSON-2 API (replaces password) ODOO_TIMEOUT=30 # Connection timeout (default: 30s) ODOO_VERIFY_SSL=true # SSL verification (default: true) # Network proxy HTTP_PROXY=http://proxy:8080 # HTTP proxy for Odoo connection # Server configuration (SSE/HTTP only) MCP_HOST=0.0.0.0 # Bind address (default: 0.0.0.0) MCP_PORT=8009 # Port for SSE (default: 8009) MCP_PORT=8008 # Port for HTTP (default: 8008) # Debugging DEBUG=1 # Enable debug logging ``` ### Using Custom Config Directory **Organize multiple environments:** ```bash # Create directory structure mkdir -p ~/mcp-odoo-env/{production,staging,development} # Configure each environment cat > ~/mcp-odoo-env/production/.env << 'EOF' ODOO_URL=https://production.odoo.com ODOO_DB=prod-db ODOO_USERNAME=admin ODOO_PASSWORD=prod-password EOF cat > ~/mcp-odoo-env/staging/.env << 'EOF' ODOO_URL=https://staging.odoo.com ODOO_DB=staging-db ODOO_USERNAME=admin ODOO_PASSWORD=staging-password EOF # Run with specific environment docker run -i --rm \ -e ODOO_CONFIG_DIR=/config/production \ -v ~/mcp-odoo-env:/config \ alanogic/mcp-odoo-adv:latest ``` **Docker Compose with custom config:** ```yaml services: odoo-mcp-production: image: alanogic/mcp-odoo-adv:sse environment: - ODOO_CONFIG_DIR=/config/production volumes: - ~/mcp-odoo-env:/config ports: - "8009:8009" odoo-mcp-staging: image: alanogic/mcp-odoo-adv:sse environment: - ODOO_CONFIG_DIR=/config/staging volumes: - ~/mcp-odoo-env:/config ports: - "8010:8009" ``` ### Using .env File **Method 1: Mount .env file** ```bash docker run -i --rm --env-file /path/to/.env mcp-odoo:stdio ``` **Method 2: Mount as volume (not recommended - use --env-file)** ```bash docker run -i --rm -v $(pwd)/.env:/app/.env mcp-odoo:stdio ``` **Method 3: Inline environment variables** ```bash docker run -i --rm \ -e ODOO_URL=https://demo.odoo.com \ -e ODOO_DB=demo \ -e ODOO_USERNAME=admin \ -e ODOO_PASSWORD=admin \ mcp-odoo:stdio ``` ### Persistent Logs Mount logs directory to persist across container restarts: ```bash # Create local logs directory mkdir -p ./logs # Mount logs volume docker run -p 8009:8009 \ --env-file .env \ -v $(pwd)/logs:/app/logs \ mcp-odoo:sse # Logs are now saved to ./logs/mcp_server_*.log ``` --- ## Docker Compose ### Single Transport **docker-compose.stdio.yml:** ```yaml services: odoo-mcp-stdio: build: context: . dockerfile: Dockerfile args: PYTHON_VERSION: 3.13 env_file: .env stdin_open: true # Required for STDIO tty: true volumes: - ./logs:/app/logs ``` Run: ```bash docker compose -f docker-compose.stdio.yml up ``` **docker-compose.sse.yml:** ```yaml services: odoo-mcp-sse: build: context: . dockerfile: Dockerfile.sse args: PYTHON_VERSION: 3.13 env_file: .env ports: - "8009:8009" volumes: - ./logs:/app/logs restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8009/health"] interval: 30s timeout: 10s retries: 3 ``` Run: ```bash docker compose -f docker-compose.sse.yml up -d ``` **docker-compose.http.yml:** ```yaml services: odoo-mcp-http: build: context: . dockerfile: Dockerfile.http args: PYTHON_VERSION: 3.13 env_file: .env ports: - "8008:8008" volumes: - ./logs:/app/logs restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8008/health"] interval: 30s timeout: 10s retries: 3 ``` Run: ```bash docker compose -f docker-compose.http.yml up -d ``` ### All Transports Together **docker-compose.yml:** ```yaml services: # SSE Transport odoo-mcp-sse: build: context: . dockerfile: Dockerfile.sse env_file: .env ports: - "8009:8009" volumes: - ./logs/sse:/app/logs restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8009/health"] interval: 30s timeout: 10s retries: 3 # HTTP Transport odoo-mcp-http: build: context: . dockerfile: Dockerfile.http env_file: .env ports: - "8008:8008" volumes: - ./logs/http:/app/logs restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8008/health"] interval: 30s timeout: 10s retries: 3 ``` Run: ```bash # Start all services docker compose up -d # View logs docker compose logs -f # Stop all services docker compose down ``` --- ## Production Deployment ### Best Practices **1. Use Secrets for Credentials** Never commit `.env` to version control. Use Docker secrets or environment variables: ```bash # Docker Swarm secrets echo "your-password" | docker secret create odoo_password - # Reference in service docker service create \ --name odoo-mcp \ --secret odoo_password \ -e ODOO_PASSWORD_FILE=/run/secrets/odoo_password \ alanogic/mcp-odoo-adv:sse ``` **2. Health Checks** Add health checks to monitor container status: ```yaml healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8009/health"] interval: 30s timeout: 10s retries: 3 start_period: 10s ``` **3. Resource Limits** Prevent resource exhaustion: ```yaml deploy: resources: limits: cpus: '1.0' memory: 512M reservations: cpus: '0.5' memory: 256M ``` **4. Logging** Configure log rotation: ```yaml logging: driver: "json-file" options: max-size: "10m" max-file: "3" ``` **5. Network Isolation** Use custom networks for security: ```yaml networks: odoo-mcp-network: driver: bridge services: odoo-mcp-sse: networks: - odoo-mcp-network ``` ### Production Docker Compose **docker-compose.prod.yml:** ```yaml services: odoo-mcp-sse: image: alanogic/mcp-odoo-adv:sse env_file: .env ports: - "8009:8009" volumes: - logs:/app/logs restart: unless-stopped deploy: resources: limits: cpus: '1.0' memory: 512M reservations: cpus: '0.5' memory: 256M healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8009/health"] interval: 30s timeout: 10s retries: 3 start_period: 10s logging: driver: "json-file" options: max-size: "10m" max-file: "3" networks: - odoo-mcp-network odoo-mcp-http: image: alanogic/mcp-odoo-adv:http env_file: .env ports: - "8008:8008" volumes: - logs:/app/logs restart: unless-stopped deploy: resources: limits: cpus: '1.0' memory: 512M reservations: cpus: '0.5' memory: 256M healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8008/health"] interval: 30s timeout: 10s retries: 3 start_period: 10s logging: driver: "json-file" options: max-size: "10m" max-file: "3" networks: - odoo-mcp-network volumes: logs: networks: odoo-mcp-network: driver: bridge ``` Deploy: ```bash docker compose -f docker-compose.prod.yml up -d ``` ### Reverse Proxy (Nginx) **nginx.conf:** ```nginx upstream odoo_mcp_sse { server localhost:8009; } upstream odoo_mcp_http { server localhost:8008; } server { listen 80; server_name mcp.example.com; # SSE endpoint location /sse { proxy_pass http://odoo_mcp_sse; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_buffering off; proxy_cache off; } # HTTP endpoint location /mcp { proxy_pass http://odoo_mcp_http; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } # Health checks location /health { proxy_pass http://odoo_mcp_sse; } } ``` ### SSL/TLS with Let's Encrypt ```bash # Install certbot sudo apt-get install certbot python3-certbot-nginx # Obtain certificate sudo certbot --nginx -d mcp.example.com # Auto-renewal (crontab) 0 0 * * * certbot renew --quiet ``` --- ## Troubleshooting ### Common Issues **1. Container exits immediately** Check logs: ```bash docker logs <container_id> # Or for compose docker compose logs odoo-mcp-sse ``` **2. Connection refused** Verify port mapping: ```bash # Check if port is exposed docker ps # Check if service is listening inside container docker exec <container_id> netstat -tulpn | grep 8009 ``` **3. Authentication failures** Test credentials: ```bash # Run interactively to see errors docker run -it --env-file .env mcp-odoo:stdio # Or check environment inside container docker exec <container_id> env | grep ODOO ``` **4. Image build fails** Clear build cache: ```bash # Remove build cache docker builder prune -a # Rebuild without cache docker build --no-cache -t mcp-odoo:stdio . ``` **5. Permission denied on logs** Fix logs directory permissions: ```bash # Make logs writable chmod 777 ./logs # Or run container as current user docker run --user $(id -u):$(id -g) -p 8009:8009 --env-file .env mcp-odoo:sse ``` ### Debug Mode Enable debug logging: ```bash docker run -p 8009:8009 \ --env-file .env \ -e DEBUG=1 \ mcp-odoo:sse ``` ### Interactive Shell Access container shell for debugging: ```bash # Run with shell docker run -it --env-file .env --entrypoint /bin/bash mcp-odoo:stdio # Or access running container docker exec -it <container_id> /bin/bash # Inside container python -m odoo_mcp # Test manually env | grep ODOO # Check environment ``` --- ## Advanced Usage ### Multi-Stage Builds (Future) For smaller production images: ```dockerfile # Build stage FROM python:3.13-slim AS builder WORKDIR /app COPY pyproject.toml README.md ./ RUN pip install --no-cache-dir build && python -m build # Production stage FROM python:3.13-slim WORKDIR /app COPY --from=builder /app/dist/*.whl ./ RUN pip install --no-cache-dir *.whl ENTRYPOINT ["python", "-m", "odoo_mcp"] ``` ### Custom Entrypoint Override entrypoint for testing: ```bash # Use custom script docker run -it \ --env-file .env \ --entrypoint python \ mcp-odoo:stdio \ -c "from odoo_mcp.odoo_client import get_odoo_client; print(get_odoo_client())" ``` ### Docker Swarm Deployment ```bash # Initialize swarm docker swarm init # Deploy stack docker stack deploy -c docker-compose.prod.yml odoo-mcp # Scale service docker service scale odoo-mcp_odoo-mcp-sse=3 # View services docker service ls docker service logs odoo-mcp_odoo-mcp-sse ``` ### Kubernetes Deployment **deployment.yaml:** ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: odoo-mcp-sse spec: replicas: 2 selector: matchLabels: app: odoo-mcp-sse template: metadata: labels: app: odoo-mcp-sse spec: containers: - name: odoo-mcp-sse image: alanogic/mcp-odoo-adv:sse ports: - containerPort: 8009 env: - name: ODOO_URL valueFrom: secretKeyRef: name: odoo-credentials key: url - name: ODOO_DB valueFrom: secretKeyRef: name: odoo-credentials key: database - name: ODOO_USERNAME valueFrom: secretKeyRef: name: odoo-credentials key: username - name: ODOO_PASSWORD valueFrom: secretKeyRef: name: odoo-credentials key: password livenessProbe: httpGet: path: /health port: 8009 initialDelaySeconds: 10 periodSeconds: 30 resources: limits: cpu: "1" memory: "512Mi" requests: cpu: "500m" memory: "256Mi" --- apiVersion: v1 kind: Service metadata: name: odoo-mcp-sse spec: selector: app: odoo-mcp-sse ports: - protocol: TCP port: 8009 targetPort: 8009 type: LoadBalancer ``` Deploy: ```bash # Create secret kubectl create secret generic odoo-credentials \ --from-literal=url=https://demo.odoo.com \ --from-literal=database=demo \ --from-literal=username=admin \ --from-literal=password=admin # Deploy kubectl apply -f deployment.yaml # Check status kubectl get pods kubectl logs -f deployment/odoo-mcp-sse ``` --- ## Image Sizes Approximate image sizes after build: | Transport | Size | Layers | |-----------|------|--------| | STDIO | ~180 MB | 8 | | SSE | ~175 MB | 7 | | HTTP | ~175 MB | 7 | Size breakdown: - Python 3.13-slim base: ~125 MB - Dependencies (FastMCP, requests): ~40 MB - Source code: ~5 MB - System packages (gcc, procps): ~10 MB --- ## Security Considerations 1. **Never commit .env files** - Use `.gitignore` 2. **Use secrets management** - Docker secrets, Kubernetes secrets, or env files outside repo 3. **Limit container capabilities** - Run as non-root user (future improvement) 4. **Scan images for vulnerabilities** - Use `docker scan` or Trivy 5. **Keep base images updated** - Rebuild regularly for security patches 6. **Use SSL/TLS** - Always use HTTPS for Odoo connections 7. **Network isolation** - Use custom networks, firewall rules 8. **Resource limits** - Prevent DoS attacks --- ## Performance Tuning ### CPU Optimization ```yaml deploy: resources: limits: cpus: '2.0' # Allow using 2 cores ``` ### Memory Optimization ```bash # Monitor memory usage docker stats <container_id> # Set memory limit docker run --memory="512m" --memory-swap="1g" -p 8009:8009 --env-file .env mcp-odoo:sse ``` ### Connection Pooling Odoo MCP Server reuses connections automatically. No additional configuration needed. --- ## References - **Dockerfile Reference**: https://docs.docker.com/reference/dockerfile/ - **Docker Compose**: https://docs.docker.com/compose/ - **Docker Security**: https://docs.docker.com/engine/security/ - **FastMCP**: https://gofastmcp.com - **Odoo Documentation**: https://www.odoo.com/documentation/ --- **Connect AI to Odoo with Docker. Simple. Powerful. Production-ready.** 🐳

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/AlanOgic/mcp-odoo-adv'

If you have feedback or need assistance with the MCP directory API, please join our Discord server