Skip to main content
Glama
TECHNICAL_DOCUMENTATION.md11.2 kB
# Technical Documentation - Docker MCP Server ## 1. Architecture Overview ### 1.1 System Design ```mermaid graph TB A[Claude Code] -->|JSON-RPC| B[Docker MCP Server] B -->|Python Docker SDK| C[Docker Daemon] C --> D[Containers] C --> E[Images] C --> F[Volumes] C --> G[Networks] B --> H[Handler Layer] H --> I[Docker Executor] I --> J[Response Formatter] ``` ### 1.2 Component Responsibilities | Component | Responsibility | Technology | |-----------|---------------|------------| | Server Entry Point | Initialize MCP server, handle lifecycle | Python asyncio | | Handler Layer | Process tool calls, validate inputs | MCP SDK | | Docker Executor | Execute Docker operations | docker-py | | Response Formatter | Format responses for Claude | JSON/Text | ## 2. Installation & Setup ### 2.1 Prerequisites ```bash # System Requirements - Docker Engine 20.10+ - Python 3.11+ - 100MB disk space - Unix-based OS (Linux/macOS) ``` ### 2.2 Installation Steps #### Method 1: Docker Container (Recommended) ```bash # Clone repository git clone https://github.com/your-org/docker-mcp-py cd docker-mcp-py # Build Docker image sudo docker build -t docker-mcp-py:latest . # Configure Claude Code cat >> ~/.claude.json << 'EOF' { "mcpServers": { "docker-mcp-py": { "type": "stdio", "command": "/path/to/docker-mcp-py/start-docker.sh", "args": [], "env": {} } } } EOF ``` #### Method 2: Local Python Installation ```bash # Install dependencies pip install -r requirements.txt # Run directly python docker_mcp_server.py ``` ## 3. API Reference ### 3.1 Container Management #### create-container Creates a new Docker container. **Parameters:** ```typescript { image: string; // Required: Docker image name?: string; // Container name ports?: { // Port mapping [containerPort: string]: hostPort: string }; environment?: { // Environment variables [key: string]: value: string }; volumes?: string[]; // Volume mounts network?: string; // Network to join restart?: string; // Restart policy command?: string; // Override CMD } ``` **Example:** ```json { "image": "nginx:alpine", "name": "web-server", "ports": {"80": "8080"}, "environment": {"ENV": "production"} } ``` #### list-containers Lists Docker containers with filtering options. **Parameters:** ```typescript { all?: boolean; // Include stopped containers filters?: { status?: string; // running|exited|paused label?: string; // Label filter name?: string; // Name pattern network?: string; // Network name } } ``` #### get-logs Retrieves container logs. **Parameters:** ```typescript { container_name: string; // Required tail?: number; // Lines from end (default: 100) follow?: boolean; // Stream logs timestamps?: boolean; // Include timestamps since?: string; // Since timestamp until?: string; // Until timestamp } ``` ### 3.2 Docker Compose Management #### deploy-compose Deploys a Docker Compose stack. **Parameters:** ```typescript { project_name: string; // Required: Project name compose_yaml?: string; // YAML content compose_file?: string; // OR file path environment?: { // Environment overrides [key: string]: string } } ``` **Example:** ```json { "project_name": "myapp", "compose_yaml": "version: '3.8'\nservices:\n web:\n image: nginx" } ``` #### compose-down Stops and removes a Compose stack. **Parameters:** ```typescript { project_name: string; // Required remove_volumes?: boolean; // Remove named volumes remove_images?: boolean; // Remove images } ``` ### 3.3 Image Management #### pull-image Downloads a Docker image. **Parameters:** ```typescript { image: string; // Image name with optional tag } ``` #### list-images Lists available Docker images. **Parameters:** ```typescript {} // No parameters required ``` ### 3.4 Volume Management #### list-volumes Lists Docker volumes. **Parameters:** ```typescript { filters?: { dangling?: boolean; // Only dangling volumes label?: string; // Label filter } } ``` ## 4. Error Handling ### 4.1 Error Response Format ```json { "type": "text", "text": "Error: <error_type>: <message> | Context: <details>" } ``` ### 4.2 Common Errors | Error Code | Description | Resolution | |------------|-------------|------------| | DKR-001 | Docker daemon not accessible | Check Docker service status | | DKR-002 | Container not found | Verify container name/ID | | DKR-003 | Image not found | Pull image first | | DKR-004 | Invalid configuration | Check parameter format | | DKR-005 | Permission denied | Check socket permissions | | DKR-006 | Port already in use | Use different port | ### 4.3 Error Recovery ```python # Automatic retry logic MAX_RETRIES = 3 RETRY_DELAY = 1 # seconds async def execute_with_retry(operation): for attempt in range(MAX_RETRIES): try: return await operation() except TransientError as e: if attempt < MAX_RETRIES - 1: await asyncio.sleep(RETRY_DELAY * (attempt + 1)) else: raise ``` ## 5. Security Implementation ### 5.1 Input Validation ```python # Parameter validation using Pydantic from pydantic import BaseModel, validator class ContainerParams(BaseModel): image: str name: Optional[str] = None ports: Optional[Dict[str, str]] = None @validator('image') def validate_image(cls, v): if not re.match(r'^[a-zA-Z0-9][a-zA-Z0-9_.-]+(/[a-zA-Z0-9_.-]+)*(:[a-zA-Z0-9_.-]+)?$', v): raise ValueError('Invalid image format') return v ``` ### 5.2 Socket Security ```yaml # Docker socket mounting (read-only where possible) volumes: - /var/run/docker.sock:/var/run/docker.sock:ro ``` ### 5.3 Secret Handling ```python # Never log sensitive information def sanitize_env_vars(env_dict): sensitive_keys = ['PASSWORD', 'SECRET', 'TOKEN', 'KEY'] sanitized = {} for key, value in env_dict.items(): if any(s in key.upper() for s in sensitive_keys): sanitized[key] = '***REDACTED***' else: sanitized[key] = value return sanitized ``` ## 6. Performance Optimization ### 6.1 Async Operations ```python # Parallel execution for multiple operations async def list_all_resources(): tasks = [ list_containers(), list_images(), list_volumes(), list_networks() ] results = await asyncio.gather(*tasks) return combine_results(results) ``` ### 6.2 Caching Strategy ```python # LRU cache for frequently accessed data from functools import lru_cache from datetime import datetime, timedelta @lru_cache(maxsize=128) def get_cached_image_info(image_id): return docker_client.images.get(image_id) # Cache invalidation def invalidate_cache(): get_cached_image_info.cache_clear() ``` ### 6.3 Resource Limits ```yaml # Container resource constraints resources: limits: cpus: '0.5' memory: 256M reservations: cpus: '0.25' memory: 128M ``` ## 7. Testing ### 7.1 Unit Test Example ```python import pytest from unittest.mock import Mock, patch @pytest.mark.asyncio async def test_create_container(): mock_docker = Mock() mock_docker.containers.create.return_value = Mock(id='abc123') with patch('docker.from_env', return_value=mock_docker): result = await create_container({ 'image': 'nginx:latest', 'name': 'test-container' }) assert 'abc123' in result['text'] mock_docker.containers.create.assert_called_once() ``` ### 7.2 Integration Test ```python @pytest.mark.integration async def test_full_container_lifecycle(): # Create container create_result = await create_container({ 'image': 'alpine:latest', 'name': 'test-lifecycle', 'command': 'sleep 30' }) # Verify running list_result = await list_containers({'filters': {'name': 'test-lifecycle'}}) assert 'test-lifecycle' in list_result # Stop and remove await stop_container({'container_name': 'test-lifecycle'}) await remove_container({'container_name': 'test-lifecycle'}) ``` ## 8. Debugging ### 8.1 Debug Mode ```bash # Enable debug logging export MCP_DEBUG=true export LOG_LEVEL=DEBUG # Run with verbose output ./start-docker.sh 2>&1 | tee debug.log ``` ### 8.2 Common Issues #### Issue: Connection Failed ```bash # Check Docker daemon sudo systemctl status docker # Verify socket permissions ls -la /var/run/docker.sock # Test socket connectivity docker version ``` #### Issue: Import Error - Module Path ```python # Fixed import path issue # Wrong: from src.docker_mcp.server import main # Correct: from src.server import main ``` #### Issue: Async Runtime Warning ```python # Wrong: Missing async context if __name__ == "__main__": sys.exit(main()) # RuntimeWarning # Correct: Proper async execution if __name__ == "__main__": asyncio.run(main()) ``` ### 8.3 Log Analysis ```bash # Filter errors from logs grep -E "ERROR|CRITICAL" /var/log/docker-mcp-py.log # Monitor real-time tail -f /var/log/docker-mcp-py.log | grep -v DEBUG # JSON log parsing cat logs.json | jq '.[] | select(.level == "ERROR")' ``` ## 9. Monitoring ### 9.1 Health Check Implementation ```python @server.list_resources() async def handle_health_check(): try: docker_client = docker.from_env() docker_client.ping() return { "status": "healthy", "docker": "connected", "version": docker_client.version() } except Exception as e: return { "status": "unhealthy", "error": str(e) } ``` ### 9.2 Metrics Collection ```python # Prometheus metrics from prometheus_client import Counter, Histogram operation_counter = Counter('docker_mcp_operations_total', 'Total operations', ['operation', 'status']) operation_duration = Histogram('docker_mcp_operation_duration_seconds', 'Operation duration', ['operation']) @operation_duration.time() async def tracked_operation(operation_name, func): try: result = await func() operation_counter.labels(operation_name, 'success').inc() return result except Exception as e: operation_counter.labels(operation_name, 'error').inc() raise ``` ## 10. Migration Guide ### 10.1 From Direct Docker Commands ```bash # Before: Direct Docker CLI docker run -d --name web -p 8080:80 nginx # After: Via MCP Tool { "tool": "create-container", "params": { "image": "nginx", "name": "web", "ports": {"80": "8080"} } } ``` ### 10.2 From Docker Compose CLI ```bash # Before: Docker Compose CLI docker-compose -f stack.yml up -d # After: Via MCP Tool { "tool": "deploy-compose", "params": { "project_name": "mystack", "compose_file": "stack.yml" } } ``` --- **Document Version**: 1.0.0 **Last Updated**: 2025-08-28 **Technical Contact**: DevOps Team

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/diegofornalha/docker-mcp-py'

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