pve-mcp
MCP server for managing Proxmox VE resources, VM/CT lifecycle, snapshots, backups, and clones via natural language.
README
pve-mcp
An MCP server for managing Proxmox VE (single node or cluster): query resources, manage VM/CT lifecycle, snapshots, backups, clones — from Claude Code or any MCP host.
- Works with both QEMU VMs and LXC containers, on single nodes and clusters.
- Tools that target one guest only need the
vmid— the node and guest type are resolved automatically. - Safety first: an optional read-only mode,
confirm=truerequired for destructive operations, and guest command execution disabled by default.
Requirements
- Python >= 3.11 (a pinned 3.12 is used via
uv) - A Proxmox VE 7/8 host with an API token (see below)
Installation
git clone <this-repo> pve-mcp
cd pve-mcp
uv sync # installs runtime + dev dependencies into .venv
uv run pytest # optional: run the test suite
Or run it directly with uvx (no install):
uvx --from /path/to/pve-mcp pve-mcp
The console entry point is pve-mcp (stdio transport).
Creating a PVE API token
Authentication uses API tokens only (Authorization: PVEAPIToken=<id>=<secret>),
never username/password tickets. Create a dedicated user and token on the PVE
host (as root):
# 1. Dedicated user
pveum user add mcp@pve --comment "MCP server"
# 2a. Read-only usage: PVEAuditor on the whole tree
pveum acl modify / --users mcp@pve --roles PVEAuditor
# 2b. Management usage: PVEVMAdmin (VM/CT lifecycle, snapshots, backups)
pveum acl modify / --users mcp@pve --roles PVEVMAdmin
# For backup/restore you may also need PVEDatastoreUser on the backup storage:
pveum acl modify /storage/<backup-storage> --users mcp@pve --roles PVEDatastoreUser
# 3. Token
pveum user token add mcp@pve mcp --privsep 1
Note the privsep setting: with --privsep 1 (recommended) the token has
its own ACLs — grant the roles above to the token too
(pveum acl modify / --tokens 'mcp@pve!mcp' --roles PVEVMAdmin), or the token
ends up with no permissions. With --privsep 0 the token inherits all
permissions of the user.
The command prints the token secret once — store it safely.
Configuration (environment variables)
| Variable | Required | Default | Description |
|---|---|---|---|
PVE_HOST |
yes | — | PVE API URL, e.g. https://192.168.1.10:8006 |
PVE_TOKEN_ID |
yes | — | Token ID: user@realm!tokenname, e.g. mcp@pve!mcp |
PVE_TOKEN_SECRET |
yes | — | Token secret (UUID) |
PVE_VERIFY_SSL |
no | true |
Set false for self-signed certificates (home labs) |
PVE_TIMEOUT |
no | 30 |
HTTP timeout in seconds |
PVE_MCP_READ_ONLY |
no | false |
true registers only the 12 read-only tools |
PVE_MCP_ENABLE_EXEC |
no | false |
true registers pve_vm_exec (guest agent commands) |
PVE_MCP_TASK_WAIT |
no | 30 |
Seconds to wait for PVE tasks; on timeout the UPID is returned |
A .env file in the working directory is loaded automatically; see
.env.example.
Registering with Claude Code
claude mcp add pve -e PVE_HOST=https://192.168.1.10:8006 \
-e PVE_TOKEN_ID='root@pam!mcp' -e PVE_TOKEN_SECRET=xxx \
-e PVE_VERIFY_SSL=false -- uvx --from /path/to/pve-mcp pve-mcp
Add -e PVE_MCP_READ_ONLY=true for a safe, audit-only setup.
Tools
Read-only (12, always registered)
| Tool | Purpose |
|---|---|
pve_cluster_status |
Cluster/node health, quorum (works on single nodes too) |
pve_list_nodes |
Nodes with CPU/memory/disk usage and online status |
pve_node_status |
One node in detail (load, kernel, PVE version) |
pve_list_vms |
All VMs + CTs; filter by node / type / status |
pve_vm_status |
Live status of one guest (CPU/mem, agent, uptime) |
pve_vm_config |
Full config of one guest (cores, memory, disks, NICs) |
pve_list_storage |
Storage usage (cluster-wide or per node) |
pve_storage_content |
Contents of a storage (iso/backup/vztmpl/images) |
pve_list_backups |
Backups across storages; filter by vmid / storage |
pve_list_snapshots |
Snapshot tree of one guest |
pve_list_tasks |
Recent tasks (all nodes or one), errors-only option |
pve_task_status |
One task's status; failed tasks include a log tail |
Write (11, skipped when PVE_MCP_READ_ONLY=true)
| Tool | Purpose | Destructive |
|---|---|---|
pve_vm_power |
start / shutdown / stop / reboot / suspend / resume | no (stop is a hard power-off — prefer shutdown) |
pve_vm_migrate |
Move a guest to another node (QEMU live / CT restart) | no |
pve_vm_set_config |
Change config keys (cores, memory, onboot, ...) | no (most changes need a guest restart) |
pve_vm_resize_disk |
Grow a disk (+10G or absolute); shrinking unsupported |
no |
pve_vm_clone |
Clone to a new vmid (full or linked) | no |
pve_snapshot_create |
Snapshot a guest (vmstate = include RAM, QEMU only) |
no |
pve_backup_create |
vzdump backup (snapshot/suspend/stop mode) | no |
pve_snapshot_rollback |
Roll back to a snapshot | yes — requires confirm=true |
pve_snapshot_delete |
Delete a snapshot | yes — requires confirm=true |
pve_vm_delete |
Delete a guest and all its disks | yes — requires confirm=true |
pve_backup_restore |
Restore an archive to a vmid | new vmid: no; overwrite: yes — requires force=true + confirm=true |
Exec (1, requires PVE_MCP_ENABLE_EXEC=true)
| Tool | Purpose |
|---|---|
pve_vm_exec |
Run a shell command in a QEMU VM via the guest agent (/bin/sh -c); never registered in read-only mode |
Security model
- Read-only mode — with
PVE_MCP_READ_ONLY=truethe write tools are not registered at all (they don't exist for the model), leaving exactly the 12 read-only tools. - Tool annotations — read-only tools carry
readOnlyHint, the four destructive tools carrydestructiveHint, so MCP hosts (e.g. Claude Code) can prompt appropriately. confirmparameter — destructive tools refuse to run withoutconfirm=trueand explain the consequences first. Nothing is sent to PVE until confirmed.- Exec opt-in —
pve_vm_exec(arbitrary command execution in guests) is only registered withPVE_MCP_ENABLE_EXEC=true, and never in read-only mode.
Combine with a least-privilege token: PVEAuditor for read-only setups,
PVEVMAdmin for management.
Behavior notes
- Async tasks: write operations wait up to
PVE_MCP_TASK_WAITseconds for the PVE task to finish. Long operations (backups, clones, migrations) return{"status": "running", "upid": ...}— follow up withpve_task_status. - Output: responses are JSON with a per-tool field whitelist; byte values
keep the raw number and gain a
*_humancompanion (e.g."31.25 GiB"). - Errors: HTTP/auth/SSL errors are translated into actionable messages (e.g. 403 suggests the missing role; unknown vmids list the existing ones).
Development
uv sync
uv run pytest # unit tests (PVE API mocked with respx)
See DESIGN.md for the full specification.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.