All checks were successful
Build and Push Proxmox MCP Docker Image / build (push) Successful in 32s
- Migrate from SSE to HTTP transport using fastmcp>=2.0 - Add /health endpoint for Docker health checks and load balancers - Remove MCP_ALLOWED_HOSTS (no longer needed with http_app approach) - Add lifespan handler for proper task group initialization - Install curl in Docker image for health checks - Update Makefile with test-health and test-mcp targets - Update documentation to reflect new endpoint structure Fixes: Health check fails with 421 Misdirected Request when MCP_ALLOWED_HOSTS doesn't include localhost
108 lines
2.6 KiB
Markdown
108 lines
2.6 KiB
Markdown
# Custom Proxmox MCP Server
|
|
|
|
A robust, maintenance-free Model Context Protocol (MCP) server for Proxmox VE with **multi-cluster support**.
|
|
|
|
## Features
|
|
|
|
- **Multi-Cluster:** Manage multiple Proxmox clusters from a single container
|
|
- **Hybrid Approach:** Curated high-level tools + raw API access for 100% coverage
|
|
- **Zero Maintenance:** Raw API tool works with any Proxmox feature without code changes
|
|
|
|
## Tools
|
|
|
|
| Tool | Description |
|
|
|------|-------------|
|
|
| `list_clusters` | Lists all configured Proxmox clusters |
|
|
| `list_nodes` | Lists nodes in a cluster |
|
|
| `get_cluster_resources` | Gets VMs, LXCs, and storage summary |
|
|
| `proxmox_api_call` | Execute any Proxmox API call directly |
|
|
|
|
All tools accept a `cluster` parameter. If only one cluster is configured, it's optional.
|
|
|
|
## Configuration
|
|
|
|
### 1. Create `clusters.json`
|
|
|
|
```json
|
|
{
|
|
"clusters": {
|
|
"production": {
|
|
"url": "pve-prod.example.io:8006",
|
|
"user": "mcp@pam",
|
|
"token_id": "token",
|
|
"token_secret": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
|
"verify_ssl": false
|
|
},
|
|
"homelab": {
|
|
"url": "pve-home.local:8006",
|
|
"user": "root@pam",
|
|
"token_id": "mcp",
|
|
"token_secret": "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy",
|
|
"verify_ssl": false
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
> **Token Format:** If your full token is `user@pam!mytoken`, set `user: "user@pam"` and `token_id: "mytoken"`
|
|
|
|
### 2. Deploy with Docker Compose
|
|
|
|
```yaml
|
|
services:
|
|
proxmox-mcp:
|
|
image: gitea.ext.ben.io/b3nw/proxmox-mcp-custom:latest
|
|
volumes:
|
|
- ./clusters.json:/app/clusters.json:ro
|
|
ports:
|
|
- "8000:8000"
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
restart: unless-stopped
|
|
```
|
|
|
|
### 3. Connect MCP Client
|
|
|
|
MCP endpoint: `https://your-host/mcp`
|
|
|
|
## Endpoints
|
|
|
|
| Endpoint | Description |
|
|
|----------|-------------|
|
|
| `/mcp` | MCP HTTP endpoint |
|
|
| `/health` | Health check endpoint for Docker/load balancers |
|
|
|
|
The `/health` endpoint returns `{"status": "ok"}` (or `{"status": "degraded"}` if no clusters are configured) and is designed for Docker health checks.
|
|
|
|
## Environment Variables
|
|
|
|
| Variable | Default | Description |
|
|
|----------|---------|-------------|
|
|
| `CLUSTERS_CONFIG_PATH` | `/app/clusters.json` | Path to clusters config |
|
|
|
|
## Local Development
|
|
|
|
```bash
|
|
# Setup
|
|
cp clusters.json.example clusters.json
|
|
# Edit clusters.json with your credentials
|
|
|
|
# Build and run
|
|
make build
|
|
make dev
|
|
|
|
# Test
|
|
make logs
|
|
curl http://localhost:8001/health
|
|
make stop
|
|
```
|
|
|
|
## Tech Stack
|
|
|
|
- Python 3.11+ / FastMCP 2.0+ / proxmoxer
|
|
- HTTP transport / uvicorn
|
|
- Docker with multi-stage build
|