feat: Add multi-cluster support with JSON config
All checks were successful
Build and Push Proxmox MCP Docker Image / build (push) Successful in 8s
All checks were successful
Build and Push Proxmox MCP Docker Image / build (push) Successful in 8s
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Implementation Details
|
||||
|
||||
Technical documentation for the Proxmox MCP Server implementation.
|
||||
Technical documentation for the Proxmox MCP Server.
|
||||
|
||||
## Architecture
|
||||
|
||||
@@ -8,93 +8,79 @@ Technical documentation for the Proxmox MCP Server implementation.
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ MCP Client (Gemini CLI) │
|
||||
└─────────────────────────┬───────────────────────────────┘
|
||||
│ SSE (Server-Sent Events)
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ Reverse Proxy (Traefik) │
|
||||
│ proxmox-mcp.ext.ben.io:443 │
|
||||
└─────────────────────────┬───────────────────────────────┘
|
||||
│ HTTP
|
||||
│ SSE
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ Docker Container (proxmox-mcp) │
|
||||
│ ┌───────────────────────────────────────────────────┐ │
|
||||
│ │ FastMCP + uvicorn (:8000) │ │
|
||||
│ │ ┌─────────────────────────────────────────────┐ │ │
|
||||
│ │ │ TransportSecuritySettings │ │ │
|
||||
│ │ │ (DNS rebinding protection) │ │ │
|
||||
│ │ └─────────────────────────────────────────────┘ │ │
|
||||
│ └───────────────────────────────────────────────────┘ │
|
||||
│ ┌───────────────────────────────────────────────────┐ │
|
||||
│ │ proxmoxer │ │
|
||||
│ │ (Proxmox API client) │ │
|
||||
│ └───────────────────────┬───────────────────────────┘ │
|
||||
└──────────────────────────┼──────────────────────────────┘
|
||||
│ HTTPS
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ Proxmox VE API │
|
||||
│ pve.local.ben.io:8006 │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
│ │ ClusterManager │ │
|
||||
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
|
||||
│ │ │ prod │ │ homelab │ │ ... │ │ │
|
||||
│ │ └────┬────┘ └────┬────┘ └────┬────┘ │ │
|
||||
│ └─────────┼────────────┼────────────┼──────────────┘ │
|
||||
└────────────┼────────────┼────────────┼──────────────────┘
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌──────────┐ ┌──────────┐ ┌──────────┐
|
||||
│ Proxmox │ │ Proxmox │ │ Proxmox │
|
||||
│ Cluster 1│ │ Cluster 2│ │ Cluster N│
|
||||
└──────────┘ └──────────┘ └──────────┘
|
||||
```
|
||||
|
||||
## Components
|
||||
|
||||
### Transport Layer
|
||||
- **Protocol:** SSE (Server-Sent Events) over HTTP
|
||||
- **Framework:** `mcp.server.fastmcp.FastMCP`
|
||||
- **Server:** `uvicorn` (ASGI)
|
||||
- **Binding:** `0.0.0.0:8000`
|
||||
### ClusterManager
|
||||
- Loads cluster configs from `clusters.json`
|
||||
- Maintains `ProxmoxAPI` connections for each cluster
|
||||
- Handles cluster selection logic (default if single cluster)
|
||||
|
||||
### Security
|
||||
- **DNS Rebinding Protection:** `TransportSecuritySettings` validates Host headers
|
||||
- **Allowed Hosts:** Configurable via `MCP_ALLOWED_HOSTS` environment variable
|
||||
- **SSL:** Configurable verification for self-signed certificates
|
||||
### Transport Security
|
||||
- `TransportSecuritySettings` validates Host headers
|
||||
- Configurable via `MCP_ALLOWED_HOSTS`
|
||||
|
||||
### Proxmox Integration
|
||||
- **Client:** `proxmoxer.ProxmoxAPI`
|
||||
- **Authentication:** API Token (recommended) or Username/Password
|
||||
- **Token Format:** User (`user@realm`) + Token Name (not full ID) + Token Secret
|
||||
### Tool Strategy
|
||||
|
||||
## The Hybrid Tool Strategy
|
||||
**Layer 1: Curated Tools**
|
||||
- `list_clusters()` - Discovery
|
||||
- `list_nodes(cluster)` - Node status
|
||||
- `get_cluster_resources(cluster)` - Resource summary
|
||||
|
||||
Instead of wrapping every Proxmox API endpoint (hundreds exist), we expose two layers:
|
||||
**Layer 2: Raw Access**
|
||||
- `proxmox_api_call(cluster, path, method, data)` - Any API endpoint
|
||||
|
||||
### Layer 1: Curated Tools
|
||||
High-frequency operations with simplified interfaces:
|
||||
- `list_nodes()` - Cluster node status
|
||||
- `get_cluster_resources()` - All VMs, LXCs, and storage
|
||||
## Configuration Format
|
||||
|
||||
### 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
|
||||
```json
|
||||
{
|
||||
"clusters": {
|
||||
"<name>": {
|
||||
"url": "host:port",
|
||||
"user": "user@realm",
|
||||
"token_id": "token_name",
|
||||
"token_secret": "secret",
|
||||
"verify_ssl": false
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Token Authentication
|
||||
The `proxmoxer` library constructs auth headers as:
|
||||
|
||||
The `proxmoxer` library uses:
|
||||
```
|
||||
Authorization: PVEAPIToken={user}!{token_name}={token_value}
|
||||
Authorization: PVEAPIToken={user}!{token_id}={token_secret}
|
||||
```
|
||||
|
||||
Therefore:
|
||||
- `PROXMOX_USER` = Full user (`proxmox-mcp@pam`)
|
||||
- `PROXMOX_TOKEN_ID` = Token name only (`token`)
|
||||
- `PROXMOX_PASSWORD` = Token secret value
|
||||
So for token `mcp@pam!mytoken`:
|
||||
- `user` = `mcp@pam`
|
||||
- `token_id` = `mytoken`
|
||||
|
||||
### Host Header Validation
|
||||
The MCP SDK enforces strict Host header validation. For reverse proxy access:
|
||||
```python
|
||||
transport_security = TransportSecuritySettings(
|
||||
enable_dns_rebinding_protection=True,
|
||||
allowed_hosts=["proxmox-mcp.ext.ben.io", "localhost:*"],
|
||||
)
|
||||
```
|
||||
## Build & Deploy
|
||||
|
||||
- **Build:** `uv` + multi-stage Docker
|
||||
- **Registry:** Gitea Container Registry
|
||||
- **CI/CD:** Gitea Actions
|
||||
- **Deploy:** Docker Compose / Portainer
|
||||
|
||||
Reference in New Issue
Block a user