All checks were successful
Build and Push Proxmox MCP Docker Image / build (push) Successful in 7s
5.4 KiB
5.4 KiB
Implementation Details
Technical documentation for the Proxmox MCP Server implementation.
Architecture
┌─────────────────────────────────────────────────────────┐
│ MCP Client (Gemini CLI) │
└─────────────────────────┬───────────────────────────────┘
│ SSE (Server-Sent Events)
▼
┌─────────────────────────────────────────────────────────┐
│ Reverse Proxy (Traefik) │
│ proxmox-mcp.ext.ben.io:443 │
└─────────────────────────┬───────────────────────────────┘
│ HTTP
▼
┌─────────────────────────────────────────────────────────┐
│ Docker Container (proxmox-mcp) │
│ ┌───────────────────────────────────────────────────┐ │
│ │ FastMCP + uvicorn (:8000) │ │
│ │ ┌─────────────────────────────────────────────┐ │ │
│ │ │ TransportSecuritySettings │ │ │
│ │ │ (DNS rebinding protection) │ │ │
│ │ └─────────────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────────┘ │
│ ┌───────────────────────────────────────────────────┐ │
│ │ proxmoxer │ │
│ │ (Proxmox API client) │ │
│ └───────────────────────┬───────────────────────────┘ │
└──────────────────────────┼──────────────────────────────┘
│ HTTPS
▼
┌─────────────────────────────────────────────────────────┐
│ Proxmox VE API │
│ pve.local.ben.io:8006 │
└─────────────────────────────────────────────────────────┘
Components
Transport Layer
- Protocol: SSE (Server-Sent Events) over HTTP
- Framework:
mcp.server.fastmcp.FastMCP - Server:
uvicorn(ASGI) - Binding:
0.0.0.0:8000
Security
- DNS Rebinding Protection:
TransportSecuritySettingsvalidates Host headers - Allowed Hosts: Configurable via
MCP_ALLOWED_HOSTSenvironment variable - SSL: Configurable verification for self-signed certificates
Proxmox Integration
- Client:
proxmoxer.ProxmoxAPI - Authentication: API Token (recommended) or Username/Password
- Token Format: User (
user@realm) + Token Name (not full ID) + Token Secret
The Hybrid Tool Strategy
Instead of wrapping every Proxmox API endpoint (hundreds exist), we expose two layers:
Layer 1: Curated Tools
High-frequency operations with simplified interfaces:
list_nodes()- Cluster node statusget_cluster_resources()- All VMs, LXCs, and storage
Layer 2: Raw API Access
proxmox_api_call(path, method, data)- Direct access to any Proxmox API endpoint- Benefit: Zero maintenance. New Proxmox features work immediately without code changes.
Build & CI/CD
- Build Tool:
uv(fast Python package manager) - Container: Multi-stage Docker build
- Registry: Gitea Container Registry
- CI/CD: Gitea Actions (build & push on commit to main/master)
- Orchestration: Portainer (Docker Compose stack)
Key Implementation Notes
Token Authentication
The proxmoxer library constructs auth headers as:
Authorization: PVEAPIToken={user}!{token_name}={token_value}
Therefore:
PROXMOX_USER= Full user (proxmox-mcp@pam)PROXMOX_TOKEN_ID= Token name only (token)PROXMOX_PASSWORD= Token secret value
Host Header Validation
The MCP SDK enforces strict Host header validation. For reverse proxy access:
transport_security = TransportSecuritySettings(
enable_dns_rebinding_protection=True,
allowed_hosts=["proxmox-mcp.ext.ben.io", "localhost:*"],
)