proxmox-monitor
README.md
# Proxmox Monitoring MCP Server
Read-only monitoring and config auditing for the Proxmox IaaS cluster,
served to Claude over MCP. Runs locally over stdio; there is **no write path
anywhere in this package** (`proxmox_mcp/client.py` only implements GET), and
the API token uses the PVEAuditor role so Proxmox itself enforces read-only.
## 1. Create the API token on Proxmox (one time, as root on any node)
```bash
pveum user add claude-monitor@pve --comment "Read-only MCP monitoring"
pveum acl modify / --users claude-monitor@pve --roles PVEAuditor
pveum user token add claude-monitor@pve mcp --privsep 1
pveum acl modify / --tokens 'claude-monitor@pve!mcp' --roles PVEAuditor
```
The `token add` command prints the secret **once** — copy it immediately.
With privilege separation (`--privsep 1`) the token's effective rights are the
intersection of the user's and the token's ACLs, which is why PVEAuditor must
be granted to **both** (the fourth command is the one everyone forgets).
GUI equivalent: Datacenter → Permissions → Users → Add; Datacenter →
Permissions → API Tokens → Add; then Datacenter → Permissions → Add → both a
*User Permission* and an *API Token Permission* on path `/`, role `PVEAuditor`,
Propagate on.
## 2. Configure and install (this machine)
```bash
cd <your-workspace>/proxmox-mcp
python -m venv .venv
.venv/Scripts/pip install -r requirements.txt
cp .env.example .env # then fill in PROXMOX_HOST / TOKEN_ID / TOKEN_SECRET
```
## 3. Register with Claude Code
```bash
claude mcp add proxmox --scope user -- <your-workspace>/proxmox-mcp/.venv/Scripts/python.exe <your-workspace>/proxmox-mcp/run_server.py
```
## Tools
| Tool | What it answers |
|---|---|
| `capabilities` | "What can this do?" |
| `cluster_health` | Quorum, node status, CPU/mem rollup |
| `list_nodes` / `node_status` | Per-host detail, versions, load |
| `list_guests` / `guest_config` | VM/LXC inventory and full configs |
| `storage_status` | Every datastore with usage |
| `backup_status` | Backup jobs + guests covered by **no** job |
| `snapshot_audit` | All snapshots with ages and RAM-state flag |
| `recent_tasks` | Failed (or all) recent cluster tasks |
| `pending_updates` | Packages awaiting install per node |
| `config_audit` | **Flagship** — every check below, graded warn/info |
`config_audit` checks: backup coverage, stale snapshots, storage >85%, node
memory >90%, memory overcommit >1.5x, CPU overcommit >4x, PVE version drift
across nodes, default kvm64 CPU type, guest agent disabled, disks on the IDE
bus, and tasks that failed in the last 48h. Thresholds are tunable in `.env`.
Three MCP prompts ship with the server (visible in claude.ai under "Add from
proxmox-monitor"): Cluster Config Audit, Cluster Health Brief, Backup
Coverage Check.
## Serving it to the team (remote, Entra-authenticated)
The server is dual-transport. `MCP_TRANSPORT=stdio` (default) is local Claude
Code; `MCP_TRANSPORT=http` serves streamable HTTP with Microsoft Entra ID auth
in resource-server mode, per `~/.claude/context/mcp-server-playbook.md`.
- **Entra:** `scripts/setup_entra_app.ps1` provisions the app, the
`access_as_user` scope, both Claude redirect URIs, v2 tokens, the client
secret, and the `Proxmox-MCP-Users` security group with its members. Run it
with `-ResolveOnly` first to check the teammate list resolves. Details and
the manual fallback: [docs/ENTRA_SETUP_CHECKLIST.md](docs/ENTRA_SETUP_CHECKLIST.md).
- **Deploy:** host port 8119 on 10.0.0.10, public hostname
`proxmox-mcp.example.com`. Steps, stack variables and the NPM proxy-host
config: [PORTAINER_DEPLOY.md](PORTAINER_DEPLOY.md).
**Deployment is blocked** until the docker host's `default-address-pools`
maintenance happens — it is at 31/31 networks, so any new stack fails at
creation. The Entra registration can be done now; the stdio server keeps
working meanwhile.
## Tests
```bash
<your-workspace>/proxmox-mcp/.venv/Scripts/python.exe -m pytest tests -q
```
They need no Proxmox connection. They assert every tool and prompt is
registered, that each prompt names its own connector (vocabulary collides
across a dozen attached connectors), that `ProxmoxClient` has grown no
mutating method, and that auth refuses to start half-configured.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues