4.8 KiB
Custom Proxmox MCP Server Implementation
Architecture Overview
This project implements a Model Context Protocol (MCP) server for Proxmox VE using a "Hybrid" design pattern. It combines specific, high-value tools with raw API access to ensure both usability and comprehensive coverage.
Core Components
-
Transport:
- Protocol: Server-Sent Events (SSE) over HTTP.
- Framework:
mcp(official Python SDK) usingFastMCP. - Server:
uvicorn(ASGI server). - Host Binding:
0.0.0.0:8000(exposed for Docker).
-
Proxmox Integration:
- Client Library:
proxmoxer(Python wrapper for Proxmox API). - Authentication: API Token or Username/Password.
- User: Must be full
user@realm(e.g.,proxmox-mcp@pam). - Token ID: Just the token name (e.g.,
token), NOT the full ID.
- User: Must be full
- SSL: Configurable verification (default
falsefor homelabs).
- Client Library:
-
Deployment:
- Container: Docker (multi-stage build with
uv). - Registry: Gitea Container Registry (
gitea.ext.ben.io). - Orchestration: Portainer (Docker Compose stack).
- CI/CD: Gitea Actions (build & push on commit).
- Container: Docker (multi-stage build with
Current Status (Dec 14, 2025)
- Infrastructure: Gitea build pipeline and Docker registry are fully operational.
- Server:
proxmox-mcp-customcontainer is running and accessible via Gemini CLI. - Connectivity: Direct
curltests confirmed Proxmox API connectivity and credential validity. - Resolved Issues:
- ✅ Host Header: Added
TransportSecuritySettingswithMCP_ALLOWED_HOSTSenv var to allow reverse proxy access. - ✅ Token Auth: Fixed user string format (was incorrectly
user@token_id, now justuser). - ✅ Local Testing: Added
docker-compose.dev.yml,Makefile, and.envsupport for local development.
- ✅ Host Header: Added
The Hybrid Tool Strategy
Instead of wrapping every Proxmox API endpoint (of which there are hundreds), we expose two layers of tools:
Layer 1: Curated Tools (High Frequency)
These tools simplify common tasks for the LLM.
list_nodes(): Returns cluster node status.get_cluster_resources(): Returns all VMs, LXCs, and storage.
Layer 2: Raw Access (The "Escape Hatch")
proxmox_api_call(path, method, data): A generic tool that allows the LLM to construct any API call supported byproxmoxer.- Example:
path="nodes/pve1/qemu/100/status/start", method="POST" - Benefit: Zero maintenance. If Proxmox adds a feature, the LLM can use it immediately without code changes.
- Example:
Current Implementation Details
server.py
- Uses
mcp.server.fastmcp.FastMCPto define the server and tools. - Connects to Proxmox using
proxmoxer.ProxmoxAPI. - Exposes
mcp.sse_apptouvicornfor execution. - Configures
TransportSecuritySettingsfor DNS rebinding protection with allowed hosts.
Challenges & Workarounds
- Host Header Validation: Resolved by configuring
TransportSecuritySettingswithMCP_ALLOWED_HOSTS. - Dependency Management: We use
uvfor fast, reliable builds in Docker. - API Client:
proxmoxerrequiresrequests(added topyproject.toml).
Next Steps
- ✅
Resolve the- Fixed withInvalid Host headererrorTransportSecuritySettings. - Update Portainer stack with corrected
PROXMOX_TOKEN_ID(just token name, not full ID). - Connect Gemini CLI via
https://proxmox-mcp.ext.ben.io/sse.
Local Testing Challenges
A significant challenge in this development environment is the lack of direct local testing capabilities. Due to the nature of operating within a sandboxed agent and the separation between the development VM (where this agent runs) and the target Docker/Portainer host, the standard iterative development loop (code -> test -> debug) is heavily impacted:
- No Direct
uvicornExecution: I cannot directly run the Python server locally to quickly test changes. - Remote Docker Environment: Each code change requires:
- Committing and pushing to Gitea.
- Waiting for Gitea Actions to build and push the Docker image.
- Redeploying the Docker stack on the Portainer host.
- Analyzing remote container logs for feedback.
- Limited Debugging: The inability to attach a debugger or inspect live execution locally forces a heavy reliance on log analysis.
- Slow Feedback Loop: This multi-step remote process introduces significant delays, prolonging the time it takes to identify and fix issues (as evidenced by the numerous iterations for
portainer-mcpandproxmox-mcp-custom).
This necessitates careful reasoning, documentation review, and a systematic approach to debugging, often leading to more turns than would be typical in a local development setup.