proxmox-mcp
A Python MCP server for Proxmox VE that lets AI agents read cluster status, power guests on/off, and provision new VMs/containers through natural language, while preventing any destructive actions.
README
proxmox-mcp
A Python MCP server for Proxmox VE. It lets AI coding agents (Claude Code, Claude Desktop, Cursor, or any MCP-compatible client) see and operate your Proxmox homelab through natural language — read cluster status, power guests on and off, and provision new VMs/containers — but never delete anything. Deletion stays a human-only action, by design.
Ask your agent "what's running on my Proxmox?", "spin up a Debian container for a test", or "reboot the docker VM" — and it just works, safely.
Table of contents
- What is this?
- How it works
- Capabilities
- The no-delete guarantee
- Quick start
- Optional: in-guest command execution
- Usage examples
- Testing
- Security model
- Roadmap
What is this?
The Model Context Protocol (MCP) is an open standard that lets AI assistants call external tools. This project is an MCP server: a small program your AI client launches, which then talks to your Proxmox host's REST API on the agent's behalf.
The design goal is safe delegation: give an agent enough power to be useful (observe, operate, deploy) while making destructive actions structurally impossible. There is no "delete VM" tool here, and a runtime guard blocks any destructive API call even if one were added by mistake.
How it works
┌──────────────────┐ stdio ┌──────────────────┐ HTTPS ┌──────────────────┐
│ AI client │ ─────────► │ proxmox-mcp │ ─────────► │ Proxmox VE │
│ (Claude Code, │ │ (this server) │ API token │ (your homelab) │
│ Cursor, …) │ ◄───────── │ │ ◄───────── │ │
└──────────────────┘ tools └──────────────────┘ JSON └──────────────────┘
- Runs on your machine (wherever the AI client runs), not on the Proxmox box.
- Communicates with the client over stdio, and with Proxmox over HTTPS using an API token (no passwords, easy to revoke).
- Tolerates the self-signed certificate a default Proxmox install ships with.
Capabilities
~27 tools across three always-on tiers, plus an optional fourth:
Tier A — read / status (12, strictly read-only)
list_nodes · node_status · cluster_resources · list_vms ·
list_containers · vm_status · container_status · vm_config ·
container_config · list_storage · list_templates · next_vmid
Tier B — lifecycle (8, reversible power state)
start_vm · stop_vm · shutdown_vm · reboot_vm ·
start_container · stop_container · shutdown_container · reboot_container
Tier C — provision (7, additive: create / clone / configure)
create_container · create_vm · clone_vm · clone_container ·
set_vm_config · set_container_config · allocate_vmid
Tier D′ — in-guest exec (2, opt-in, off by default)
exec_in_container · exec_in_vm — run commands inside a guest (e.g.
apt-get update, install/start an app). Disabled unless you explicitly turn it
on; see Optional: in-guest command execution.
Never present: delete / destroy
There is no tool to delete, destroy, remove, purge, roll back, shrink, wipe, or erase anything. That is intentional — see below.
The no-delete guarantee
Deletion is human-only by design. This matters because Proxmox RBAC cannot
separate "create" from "delete": the VM.Allocate privilege required to create
a guest also permits destroying one at the API level. There is no role you can
grant that means "create but not delete."
So the guarantee is enforced inside this server, in two independent layers:
- No destructive tools exist.
build_server()runsassert_no_destructive_tools()at startup and refuses to start if a tool name matching a destructive verb is ever registered. - A runtime guard wraps the client. The proxmoxer API object is wrapped in a
SafeProxmoxproxy that raisesPermissionErrorthe instant any.deleteis touched, anywhere in a call chain.
To cut off access entirely, revoke the API token in Proxmox.
Quick start
1. Set up Proxmox (one-time)
Create a dedicated user, a least-privilege role, an ACL assignment, and an API
token. The fastest path is the pveum CLI on your Proxmox host:
# 1. a dedicated user
pveum user add agent@pve
# 2. a least-privilege role (read + power + provision; NO admin)
pveum role add AgentRole -privs "VM.Audit Sys.Audit Datastore.Audit VM.PowerMgmt VM.Allocate VM.Config.Disk VM.Config.CPU VM.Config.Memory VM.Config.Network VM.Config.Options VM.Clone Datastore.AllocateSpace SDN.Use"
# 3. grant the role (use a pool path instead of / to limit blast radius)
pveum acl modify / -user agent@pve -role AgentRole
# 4. create the API token — prints the secret ONCE; copy it
pveum user token add agent@pve mcp --privsep 0
Note on
SDN.Use: it is required on Proxmox VE 8.x/9.x to attach a guest to any bridge, including the defaultvmbr0(the API checks/sdn/zones/localnetwork/<bridge>). Without it, create/clone fails with403 Forbidden: Permission check failed (... SDN.Use).
Prefer the web UI? Datacenter → Permissions → Users (add agent@pve) →
Roles (create AgentRole with the privileges above) → Add → User
Permission (path /, user agent@pve, role AgentRole) → API Tokens
(add token mcp, uncheck Privilege Separation, copy the secret).
2. Install
pip install -e .
This installs the package and a proxmox-mcp console script. You can also launch
it with python -m proxmox_mcp. Requires Python 3.11+.
3. Configure
All settings come from environment variables. There are two ways to supply them:
- Deployment: set them in your MCP client's
envblock (see step 4). - Local dev / testing: copy
.env.exampleto.envand fill in real values..envis git-ignored — never commit real credentials. Anything set in the actual process environment (e.g. the client'senvblock) overrides.env.
| Variable | Required | Default | Notes |
|---|---|---|---|
PROXMOX_HOST |
✅ | — | Hostname/IP, e.g. proxmox.lan (no scheme) |
PROXMOX_USER |
✅ | — | e.g. agent@pve |
PROXMOX_TOKEN_NAME |
✅ | — | e.g. mcp |
PROXMOX_TOKEN_VALUE |
✅ | — | the token secret copied during setup |
PROXMOX_VERIFY_SSL |
false |
false for self-signed certs |
|
PROXMOX_PORT |
8006 |
Proxmox API port |
(In-guest exec adds more variables — see that section.)
4. Register with your MCP client
.mcp.json (Claude Code project config, Cursor, etc.):
{
"mcpServers": {
"proxmox": {
"command": "proxmox-mcp",
"env": {
"PROXMOX_HOST": "proxmox.lan",
"PROXMOX_USER": "agent@pve",
"PROXMOX_TOKEN_NAME": "mcp",
"PROXMOX_TOKEN_VALUE": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"PROXMOX_VERIFY_SSL": "false"
}
}
}
}
(No console script? Use "command": "python", "args": ["-m", "proxmox_mcp"].)
claude mcp add (Claude Code CLI):
claude mcp add proxmox \
--env PROXMOX_HOST=proxmox.lan \
--env PROXMOX_USER=agent@pve \
--env PROXMOX_TOKEN_NAME=mcp \
--env PROXMOX_TOKEN_VALUE=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
--env PROXMOX_VERIFY_SSL=false \
-- proxmox-mcp
Restart the client, then ask it "list my Proxmox nodes" to confirm.
Optional: in-guest command execution
To let an agent run commands inside a guest (the second half of "deploy an
application" — e.g. apt-get update, install and start a service), enable the
Tier D′ exec tools. They are off by default.
Exec works by SSHing to the Proxmox host and running pct exec (LXC) or
qm guest exec (VM, requires the QEMU guest agent). Every argument is
shlex-quoted so it cannot break out into the host shell, and there is no raw
host-shell tool — only guest-scoped execution.
⚠️ Security: this is a real privilege grant. An agent with exec enabled can run arbitrary commands as root inside any guest, reachable via the SSH credential you configure. Only enable it if you trust the agent with that, and prefer a dedicated SSH key with access limited to what you need.
Set these additional variables:
| Variable | Required for exec | Default | Notes |
|---|---|---|---|
PROXMOX_ENABLE_EXEC |
✅ (true) |
false |
Master switch; registers the exec tools |
PROXMOX_SSH_HOST |
PROXMOX_HOST |
Host to SSH into (defaults to the PVE host) | |
PROXMOX_SSH_PORT |
22 |
SSH port | |
PROXMOX_SSH_USER |
root |
SSH user (must be able to run pct/qm) |
|
PROXMOX_SSH_KEY_FILE |
— | Path to a private key (preferred) | |
PROXMOX_SSH_PASSWORD |
— | Used only if no key file is given |
Example env additions:
"PROXMOX_ENABLE_EXEC": "true",
"PROXMOX_SSH_USER": "root",
"PROXMOX_SSH_KEY_FILE": "/home/you/.ssh/proxmox_agent"
With exec enabled the server exposes 29 tools (27 baseline + 2 exec).
Usage examples
Once registered, you talk to your agent in plain language; it picks the tools.
| You say… | Tools the agent uses |
|---|---|
| "What's running on my Proxmox?" | list_nodes, list_vms, list_containers |
| "How much RAM is free on node pve?" | node_status |
| "Reboot the docker VM (id 102)." | reboot_vm |
| "Create a Debian 12 container, 2 cores, 2 GB, on vmbr0." | list_templates, allocate_vmid, create_container, start_container |
| "Clone template 9000 into a new VM and start it." | clone_vm, start_vm |
| "Install nginx in container 250." (exec enabled) | exec_in_container |
| "Delete that test VM." | ❌ refused — deletion is human-only |
Testing
The test suite is fully offline — proxmoxer and paramiko are mocked, so no env vars and no network are needed:
python -m pytest -q
A live smoke test against a real Proxmox is not part of the offline suite; it just needs the env vars set so the server can connect.
Security model
- Auth: API token only (no passwords); scope it with a least-privilege role
and, ideally, a pool-scoped ACL. Revoke instantly with
pveum user token remove agent@pve mcp. - No deletes: enforced in-server (no destructive tools + runtime guard), because Proxmox RBAC cannot express "create but not delete."
- Secrets: live in env vars or a git-ignored
.env; never in source or argv. - Exec is opt-in and, when on, scoped to guest commands via
pct/qmwith shell-safe quoting — no arbitrary host shell.
Roadmap
- ✅ Tier A/B/C (read, lifecycle, provision) — no-delete guaranteed
- ✅ Tier D′ in-guest exec (opt-in)
- ⏳ cloud-init provisioning helpers for VMs
- ⏳ file push/pull into guests for app deployment
Built with proxmoxer and the official MCP Python SDK.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。