Proximo — the Proxmox MCP you can hand the keys MCP Server
io.github.john-broadway/proximo-proxmox
AI-safe Proxmox hypervisor control: plan, prove, undo, diagnose—with tamper-evident audit ledger and fail-closed mutations.
What is the Proximo — the Proxmox MCP you can hand the keys MCP server?
Proximo is a Proxmox MCP server that gives AI agents safe, audited access to Proxmox VE, Backup Server, Mail Gateway, and Datacenter Manager. Every mutation is planned first (showing blast radius), proven via a keyed hash-chained ledger, and undoable where the platform allows—with read-only as the default and full transparency into what changed.
Proximo bridges the gap between read-only inspection tools and dangerous full-access SSH. It exposes 924 tools across four Proxmox products through a single governed control plane with built-in trust: mutations require explicit confirmation after showing their impact, every change is recorded in a tamper-evident audit log, and risky operations can snapshot first and fail closed if they can't. Designed for operators who want to hand an AI agent real infrastructure keys without losing control or visibility.
How to install Proximo — the Proxmox MCP you can hand the keys
Copy-paste configuration for popular MCP clients.
Tools & capabilities
Tools this server exposes to the agent.
pve_guest_status— Query node and guest status across Proxmox VEpve_guest_config_revert— Revert a guest configuration to its prior statect_exec— Execute a command inside an LXC container with optional snapshot-first safetyct_psql— Run psql commands inside a containerpve_rollback— Restore a guest from a snapshotaudit_verify— Verify the integrity of the keyed hash-chained audit ledgerpbs_datastores— List and manage Proxmox Backup Server datastorespbs_snapshots— Query and manage PBS snapshotspmg_mail_flow— Inspect and manage mail flow on Proxmox Mail Gatewaypdm_fleet_read— Read federated fleet state from Proxmox Datacenter Managerpdm_guest_control— Governed control (power/snapshot/migrate) across PDM fleet with dry-run-first
Use cases
- Diagnose container performance issues by pulling logs and running diagnostics inside the container without SSH access
- Plan and apply infrastructure changes (VM snapshots, config updates, power operations) with full visibility into what will change before confirming
- Audit every mutation performed by an AI agent via a tamper-evident ledger that detects edits, reordering, or truncation
- Manage multi-site Proxmox deployments (VE, PBS, PMG, PDM) through a single MCP interface with consistent trust controls
- Safely delegate hypervisor operations to an AI agent by starting read-only and gradually raising permissions as needed
Proximo — the Proxmox MCP you can hand the keys MCP server FAQ
Proximo is an MCP server that lets AI agents (Claude, Cursor, etc.) safely operate Proxmox infrastructure. Every mutation is planned first (showing impact), recorded in a tamper-evident audit log, and undoable where possible. It covers Proxmox VE, Backup Server, Mail Gateway, and Datacenter Manager.
Yes. Proximo is open-source under the Apache 2.0 license and available on PyPI as `proximo-proxmox`. There is no cloud dependency, no phone-home, and no standing server required.
Use the one-click install badge in the README (for VS Code / Cursor), or add it manually to your MCP config with `command: uvx` and `args: ["proximo-proxmox"]`. You'll need to set three environment variables: `PROXIMO_API_BASE_URL` (your Proxmox API endpoint), `PROXIMO_NODE` (default node name), and `PROXIMO_TOKEN_PATH` (path to a token file, never inlined).
A Proxmox API token (USER@REALM!TOKENID=SECRET format) stored in a file on disk. Proximo reads the token by file path, never from inline config. Start with a read-only token; use `uvx proximo-proxmox mint` to generate the least-privilege runbook for your use case.
Yes, where the platform supports it. Config changes return their prior state automatically (revert with `pve_guest_config_revert`). Container exec and psql can snapshot first (`snapshot=true`) and fail closed if the snapshot can't be taken. Guest snapshots can be restored with `pve_rollback`. Planes without snapshot primitives (firewall, SDN, ACL) have no rollback.
Every mutation is recorded in a keyed (HMAC-SHA256), hash-chained ledger. `audit_verify()` detects edits, reordering, and insertion. You can pin the head off-box (`expected_head`) to catch truncation too. The ledger is on by default and tamper-evident by design.
README (reference)
Source of truth, from the repository.
Named for Proximo, the lanista of Gladiator. The story is the design, joint for joint.
He armed his fighter with exactly what he needed, never more. He answered for every move in the arena. A lanista, not a jailer. The Spaniard earns his name by conduct, on the record, and the helmet comes off: truth said plainly, at cost. His last act opened the cages, holding the wooden sword of his own freedom. A tool should hope to end that well.
"Win the crowd and you will win your freedom."
The others make you pick: a read-only toy, or full keys and pray. Proximo won't. Every dangerous move is planned: see the blast radius first. Every move is proven: a tamper-evident record. And undoable wherever the platform gives us a primitive: a config change hands back the exact prior state, and a risky in-container command can take a snapshot first, and refuses to run if it can't.
Trust built into the substrate, not bolted on after. Hand an AI agent the keys; keep the receipts.
Sovereign and agent-agnostic. Your metal, your token, a ledger you own. No cloud, no phone-home, no standing server unless you opt in.
What it does
Ask, in plain English: "why is ct 105 thrashing?" An AI agent pulls node and guest status, tails the logs, and runs a diagnostic inside the container to find out.
If there's a fix, it shows you the plan before it touches anything. Takes a snapshot first if you ask it to, and won't run if it can't. Applies. Hands you a signed receipt of exactly what changed.
That's the product: a hypervisor an AI can operate without being able to wreck it.
Read-only by default. No mutation runs on the first call: it returns its blast radius as a plan for you to see first. A tamper-evident receipt for every change.
The comparison isn't Proximo vs. the GUI. It's Proximo vs. handing an LLM your root token and hoping.
Don't take our word for any of it. Verify it yourself.
<details> <summary><b>Verify in 60 seconds</b>: three receipts, no trust required</summary># 1. The tool count is real. Ask the server itself, cold (=> 924).
# (in a clone of this repo, after `uv sync`)
uv run python -c "import asyncio; from proximo import server; \
print(len(asyncio.run(server.mcp.list_tools())))"
# 2. The container image is what the repo built. Sigstore provenance (exit 0 = verified):
gh attestation verify oci://ghcr.io/john-broadway/proximo:latest --owner john-broadway
# 3. The security posture is graded by a third party, not by us:
# https://scorecard.dev/viewer/?uri=github.com/john-broadway/proximo
The rest is in VERIFY.md: forge a ledger byte and watch verify() refuse, grep
the outbound surface for phone-home (there is none). These checks work on any tool, from any
vendor. Demand them everywhere.
<p align="center"> <picture> <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/john-broadway/proximo/main/docs/brand/proximo-architecture-dark-b2d87987.svg"> <img alt="Proximo architecture: MCP clients (stdio and Streamable HTTP), A2A, and HTTP/OpenAPI clients all land on one governed spine, pass the six-pillar trust spine (PLAN, PROVE, UNDO, DIAGNOSE standing by default; CONSENT and CONTAIN yours to raise), sit on the Proxmox-enforced token floor, and reach four products — PVE, PBS, PMG, PDM" src="https://raw.githubusercontent.com/john-broadway/proximo/main/docs/brand/proximo-architecture-light-cd1a0a42.svg" width="860"> </picture> </p> <p align="center"><sub>Every transport enters <b>one governed dispatch</b> and crosses the <b>same trust spine</b>; the token floor beneath it all is enforced by Proxmox itself. <br>Watch it hold in the <a href="#demo">Demo</a>.</sub></p>
Quickstart
// your MCP client config (Claude Desktop / Claude Code / Cursor / …)
{
"mcpServers": {
"proximo": {
"command": "uvx",
"args": ["proximo-proxmox"],
"timeout": 60, // startup is ~3.5s; a 3s client default drops the server silently
"env": {
"PROXIMO_API_BASE_URL": "https://your-pve:8006/api2/json",
"PROXIMO_NODE": "your-node",
"PROXIMO_TOKEN_PATH": "/path/to/token-file" // USER@REALM!TOKENID=SECRET, by reference, never inlined
}
}
}
}
Claude Code, one line:
claude mcp add proximo --env PROXIMO_API_BASE_URL=https://your-pve:8006/api2/json \
--env PROXIMO_NODE=your-node --env PROXIMO_TOKEN_PATH=/path/to/token-file -- uvx proximo-proxmox
Or install with one click:
<sub>Both prompt for the token file path; the secret never lands in client config. No token yet? uvx proximo-proxmox mint prints the least-privilege runbook.</sub>
Then preflight what your token can actually do (read-only):
uvx proximo-proxmox doctor
Start with a read-only token. Proximo is useful long before you grant it write. Full token-first walkthrough: docs/SETUP.md · more install paths: Install & run.
Why Proximo exists
The Proxmox MCP landscape is split. API-based servers manage nodes and VMs but structurally cannot run a command inside an LXC: the REST API has no exec endpoint. SSH-based servers can, through broad shell access with little scoping.
Proximo builds the principled whole. Both halves, one audited surface, least-privilege. Trust by construction:
| Read-only inspector | Full-access executor | Proximo | |
|---|---|---|---|
| Can mutate | no, that's the safety | yes | yes, plan recorded first, then confirm=true |
| Preview before a change | n/a | rarely | default: blast radius + live state, every mutation |
| Record of what happened | no | app logs, editable | keyed hash-chained ledger, tamper-evident, on by default |
| Undo | n/a | rare | snapshot-first, wherever the platform can snapshot |
| Command inside an LXC | no | broad SSH | opt-in, fail-closed CTID allowlist |
| Products covered | usually PVE | usually PVE | PVE + PBS + PMG + PDM, one audited plane |
| Verify the artifact you run | varies | varies | signed image · PyPI provenance · SBOM · Scorecard |
(The archetype columns describe the split above, not any specific project. There is no official Proxmox MCP; Proximo is a community project, standing on its own.)
The trust layer: what makes Proximo different
The spine has six pillars. Four stand by default:
| Control | What it does |
|---|---|
| PLAN | Every mutation first returns a recorded preview: the exact change, live state, blast radius, an advisory risk rating. Nothing mutates without its plan recorded; one confirm=true call records and performs. |
| PROVE | Keyed (HMAC-SHA256), hash-chained audit ledger; audit_verify catches edits, reordering, insertion. Pin the head off-box (expected_head) to catch truncation too: that's the strong guarantee, and it's opt-in. |
| UNDO | Where the platform has a primitive: a config change returns its prior_config automatically (revert with pve_guest_config_revert), ct_exec/ct_psql take snapshot=true for an auto-snapshot and then fail closed (if the snapshot can't be taken the command does not run) and pve_rollback restores a guest snapshot. The exec snapshot is per call, not automatic. Planes with no snapshot primitive (firewall/SDN/ACL) have no rollback, said plainly. |
| DIAGNOSE | Read-only evidence battery + node health → advisory flags that surface incompleteness too, so an empty list never reads as a false clean bill. |
Two are yours to raise, by design, off until their state paths exist, because both are only worth having if those paths sit outside the agent's reach. A pillar Proximo raised for you would be a pillar the agent could lower for itself:
| Pillar (off until configured) | What it holds |
|---|---|
| CONSENT | Independent, out-of-band approval per plan: an agent (compromised, confused, or steered by injected text) cannot confirm its own mutation. Grants live in a directory only you write (PROXIMO_CONSENT_DIR), expire on a TTL, and never clear a taint. |
| CONTAIN | The kill-switch: one trip file halts every mutation immediately, mid-incident, no redeploy and no restart. Checked fresh on every mutation; fails closed. Put the trip path where only you can write (PROXIMO_CONTAIN_TRIP_PATH). |
proximo doctor reports the spine: which pillars stand, which sockets are empty, and exactly how to fill them. Seven more controls ship off until configured: ARM (write only while armed), an arm-LEASE, an arm-time SCOPE, MIRROR (guest reach from the platform's own map), a FORBID/RATE ENVELOPE, TAINT (the prompt-injection mitigation), and PRINCIPAL (who-asked attribution). What each one defends against: SECURITY.md.
Honesty note (load-bearing): risk ratings are an advisory heuristic, not a sandbox —
LOWmeans "no state change," not "safe," and the absence of aHIGHflag is not a safety signal. Review every change yourself. The floor beneath it all is the token you mint: Proxmox RBAC holds even if Proximo's process is fully compromised — a stronger guarantee than anything Proximo's own code provides. Scope it to exactly what you mean to grant: SECURITY.md.
Hold any tool to this, including this one: The Keys Test. Ten questions to ask before you hand an AI agent real infrastructure. Proximo's own scorecard published, partials included.
Demo
The record defends itself:
<p align="center"> <img src="https://raw.githubusercontent.com/john-broadway/proximo/main/docs/demo/hand-the-keys.svg" alt="Hand-the-keys demo: three agent moves land in the keyed hash-chained ledger and audit_verify answers ok=True keyed=True; an in-place edit breaks the chain at the exact line (ok=False); a truncation that fools the forward walk is caught by the pinned head" width="860"> </p> <p align="center"><sub>Three agent moves land in the keyed ledger; one entry gets edited in place; <code>audit_verify()</code> breaks at the exact line, <b>ok=False</b>; the truncation a forward walk would miss is caught against the pinned head. Real code, real crypto, nothing staged, recorded on 0.30.0. Run it yourself anywhere: <a href="./scripts/demo/hand_the_keys.py"><code>scripts/demo/hand_the_keys.py</code></a> (needs only the pip package) · against your own host: <code>--live</code> · verify by hand: <a href="VERIFY.md">VERIFY.md</a>.</sub></p>Surfaces & tools: one control plane
| Surface | Backend | For |
|---|---|---|
| Proxmox VE | REST API + scoped token | node/guest lifecycle, storage, SDN, identity, HA, firewall |
| Proxmox Backup Server | REST API + scoped token | datastores, namespaces, snapshots, sync, GC, verify, tape |
| Proxmox Mail Gateway | Ticket auth | mail flow, quarantine, filtering rules, domains, services |
| Proxmox Datacenter Manager | API token | federated fleet: reads plus governed control (power/snapshot/migrate, dry-run-first) |
| Container exec | ssh → pct exec | run-command-in-container, psql, log tailing: what the API structurally can't do |
Those backends are deliberately boring. Anyone can call them. The product is the trust layer over them.
924 tools is an estate, not a starting point, and you only carry the part you use. Since 0.30 the floor IS the default: a bare install serves the search-and-call facade (~1,740 tokens of context) with every tool this box serves still callable; one domain like pve.guests runs ~9,781, a whole plane ~101,398, PROXIMO_TOOLSETS=catalog the classic auto-scoped catalog. The estate is 924. The doorway is yours to size. Coverage and context stopped being the same number.
Where an operator actually starts:
| You want to… | Start with | Worth knowing |
|---|---|---|
| See the whole cluster at once | pve_cluster_resources, pve_list_guests | one call, every node |
| Find out why a container is sick | ct_diagnose, ct_logs, pve_guest_status | read-only evidence battery |
| Preflight a token / config | proximo doctor (CLI) or pve_doctor, pve_overbroad_grants | run this before wiring an agent |
| Power / lifecycle | pve_guest_power | returns a PLAN first; nothing moves without confirm=true |
| Snapshot before touching anything | pve_snapshot_create, pve_rollback | UNDO's foundation |
| Check backups are actually fresh | pve_backup_freshness, pbs_snapshots_list | walks real archives; "task OK" is never evidence |
| Run a command in a container | ct_exec | opt-in (PROXIMO_ENABLE_EXEC=1), fail-closed allowlist |
| Trace / release mail | pmg_tracker_list, pmg_quarantine_spam | full PMG plane behind it |
| Operate the federated fleet | pdm_resources_list, pdm_pve_lxc_list | governed control, dry-run-first |
| Prove the record wasn't touched | audit_verify | registered on every surface, always |
Every tool with typed inputs: docs/TOOLS.md · sizing the surface to your model: docs/SETUP.md.
Install & run
📦
0.44.0: on PyPI, GitHub, and GHCR (signed multi-arch image).New in 0.44.0 (our own artifacts run the newest mcp). The lock, both hash-pinned requirement exports, the container image and the SBOM move to
mcp==2.2.0, retiring the constraint that had held them at 1.x since 0.39.0. The published floor does not move:mcp>=1.24,<3still admits 1.x, and the CI compat leg installs the newest 1.x unpinned to keep that claim honest. Proven on the newest of each major before shipping. 924 tools.Recent: 0.43.0 opened a raw GET door on every plane and gave Datacenter Manager its own identity core. See SECURITY.md for what each control honestly holds.
Proximo runs on your machine, on demand. No daemon, no open port.
uvx proximo-proxmox # zero-install run (PyPI package: proximo-proxmox; command stays `proximo`)
# or: pip install proximo-proxmox the MCP core
# or: pip install "proximo-proxmox[a2a]" + the optional A2A face
# or: pip install "proximo-proxmox[http]" + the optional HTTP/OpenAPI face
# or: pip install "proximo-proxmox[mcp-http]" + the optional MCP-over-streamable-HTTP face
# or, from source: git clone https://github.com/john-broadway/proximo.git && cd proximo && uv pip install -e .
Wire it into your MCP client as the command proximo, with the PROXIMO_* env vars; see packaging/proximo.env.example.
Docker (GHCR): docker run -i --rm … ghcr.io/john-broadway/proximo:latest. Multi-arch, SBOM, sigstore-signed provenance (gh attestation verify oci://ghcr.io/john-broadway/proximo --owner john-broadway). Mirrored to Docker Hub (docker.io/jebroadway/proximo, identical digest); GHCR stays the signed primary.
Safe by default: API-only out of the box. The two near-root edges are opt-in and say so loudly: LXC exec (
PROXIMO_ENABLE_EXEC=1, near-root on the host) and the qemu-guest-agent edge (PROXIMO_ENABLE_AGENT=1, near-root in a guest). Each is scoped by its own fail-closed allowlist.Smallest footprint by design: you don't have to load the whole estate: what a box serves is autoscoped to what it configures. A PBS-only box gets that plane's tools plus the always-on audit trail;
PROXIMO_SURFACES=pve,execscopes the searchable catalog to that pair (320 tools); a typo'd surface refuses startup rather than serving a surprise. Surfaces choose which planes are searchable, never how many schemas load; the doorway stays the default unless you name another withPROXIMO_TOOLSETS. Scoping is context hygiene, not an authorization control: it changes what is advertised, never what a token is allowed to do. The default doorway (dynamic mode) keeps four search-and-call tools resident (proximo_readruns read-only tools with an enforcedreadOnlyHint;proximo_callruns anything) plus the two ledger tools (audit_verifyproves the chain,audit_entriesreads who did what) andproximo_recallwhile estate memory is on (the default;PROXIMO_MEMORY=0opts out), with the full catalog reachable by name. That narrowing is guarded at every entry point (0.27.0 closed a path where an opt-in flag could silently cut the registry to 5 tools), and the gates don't shrink with the doorway: PLAN and PROVE apply however small the visible surface gets.
The network faces (experimental, opt-in): proximo-a2a speaks Agent2Agent. proximo-http serves plain HTTP + generated /openapi.json for no-code clients. proximo-mcp-http serves MCP itself over Streamable HTTP (the SDK's native transport) for networked MCP clients: no third-party stdio→HTTP bridge, so the perimeter stays Proximo's. LXC on your Proxmox host, one line: on the PVE node as root, bash -c "$(curl -fsSL https://raw.githubusercontent.com/john-broadway/proximo/main/packaging/lxc/ct/proximo.sh)" builds a Debian 13 container running proximo-mcp-http with Proximo from PyPI, its own service user, and a minted bearer on port 41243. Community-scripts engine (MIT) pointed at Proximo's own tree, their telemetry off; the same line inside the container updates it. Details: docs/SETUP.md, files: packaging/lxc/.
All three serve the full surface through the same spine as MCP. No second code path; trust spine and token scope inherited. Fail-closed perimeter: loopback, bearer-token required off-localhost, DNS-rebind and CSRF defended. Details: SECURITY.md.
At scale
One container is the demo. A cluster is the point.
- The whole cluster in one call.
pve_cluster_resources: every VM, node, storage pool, SDN object. - One tamper-evident record across every node. "Show me every state-changing action this month, and prove the log wasn't touched" becomes a query you can actually answer. No human at the CLI walks away with that.
- Where the time comes back. On one node a senior at the CLI is faster, and that's fine. Across a dozen nodes and hundreds of guests, a bounded, audited agent earns its keep.
Many boxes, one Proximo: register remotes in a TOML file (secrets by reference, never inlined), point PROXIMO_TARGETS at it, aim any tool with proximo_target="edge-pve". The target travels with the call. PLAN and EXECUTE hit the same box, the ledger records which, cross-plane calls error. Config shape: packaging/targets.example.toml.
Status: the arena record
- 🩸 0.44.0: our own artifacts run the newest mcp. The lock, the hash-pinned requirement
exports, the container image and the SBOM move to
mcp==2.2.0; the[tool.uv]constraint that pinned them to 1.x since 0.39.0 is gone. The published range is unchanged atmcp>=1.24,<3, and the dual-major CI matrix is inverted so the compat leg installs the newest 1.x unpinned, which is now the only proof behind the 1.x half of that range. Measured on the newest of each major: 12,482 passed / 12 skipped on 2.2.0, and 12,478 / 16 on 1.30.0.
Every release before it (every pillar, every redteam, every fix) lives in CHANGELOG.md.
The numbers, honestly: 924 MCP tools, proved in two deliberate layers. 12,000+ in-process tests (ruff + pyright clean) pin every tool's shape. A separate live-smoke harness drives real Proxmox hardware: a 3-node PVE 9.2 cluster, PBS 4.2, PMG 9.1, PDM 1.1.4, a real cross-datacenter move. The two are kept apart on purpose: passing shape tests never gets to masquerade as "works on a real host." And this workspace administers its own Proxmox estate through Proximo daily (dogfood). The blast-radius engine carries the destructive surface: across eleven op-classes it names the specific guests, nodes, principals, or disks at risk. Nothing falls back to a bare confirm.
Proven live (not mocks): the trust spine end-to-end; identity/storage/SDN/firewall/HA create→read→delete with the ledger verified throughout; offline + online live-migration and HA fencing (softdog) on a real 3-node cluster; full PBS/PMG/PDM planes including a real cross-datacenter move.
Not yet proven — said plainly: hardware-watchdog fencing (needs physical iTCO/IPMI) and behavior at production scale. The unrecoverable ops (SDN apply, etc.) are deliberately never fired live: proven by plan, held back by design, not a gap. Per-surface detail: CHANGELOG.md.
Documentation
| Document | What it answers |
|---|---|
| Setup | Token-first walkthrough: mint a least-privilege token, verify it, widen deliberately. |
| The Junction | Why Proximo exists: two roots on two planes, and the door that governs both lanes. |
| Verify | Every trust claim paired with the command that proves it. Run them cold. |
| Security | The two-deployment trust model, all thirteen controls, what each honestly holds, reporting. |
| Threat model | What Proximo defends against, what it doesn't, where the boundaries sit. |
| Tools | All 924 tools, grouped by surface, typed inputs. |
| Agents | The page written for the agent itself: Proximo's sharp edges, stated first. |
| Known issues | What's broken or odd right now, said plainly. |
| Contributing | Dev setup, the CI gates, what a PR is expected to keep intact. |
| Changelog | Every release, every redteam, every fix: the full build history. |
License
Apache-2.0, chosen for the patent grant that suits infrastructure tooling. Full text in LICENSE.
Credits
Built by John Broadway with Claude and Maude: a human-AI partnership, and the first thing we made on this box to give away to the world. Claude Opus 4.8 built the trust pillars and the original tool surface and has carried the work since; Claude Fable 5 ran the 101-agent release audit and the first publish. Every commit carries its co-author trailer.
"Are you not entertained?" Stars, issues, and sparring partners welcome. Strength and honor. ⚔️
Related MCP servers
Governed agent access to ERPNext — MCP + A2A doors, one spine. No debit without a credit.
Post-quantum (ML-DSA-65/FIPS-204) agent identity + AI-decision receipts, verifiable offline.
Post-quantum (ML-DSA-65/Dilithium-3) proof, provenance & AI-decision receipts, paid via x402.
View repository →
LastMinuteDeals Booking API
Last-minute booking slots across 11 suppliers. Search, price, and execute bookings via AI agents.

io.github.johnbeans/ten
Ten formal algebra for machine intelligence — encode, decode, compose, and verify

Valuation API
Deterministic finance tools for AI agents — IRR, NPV, MOIC, DCF, WACC and sensitivity.

