What it does

proxmox-mcp is an open-source Model Context Protocol server for Proxmox VE, the open-source virtualization platform. It gives an AI client (Claude Desktop, Claude Code, OpenClaw, Codex CLI, or any MCP host) a structured, gated interface to a Proxmox cluster: inventory VMs and LXC containers, inspect node and storage status, read RRD metrics, trace tasks, manage snapshots and backups, run gated reads and shell commands inside guests, and provision, clone, or destroy resources, all over Proxmox API-token auth.

It is built for homelab and virtualization operators who want to point an agent at their cluster without handing it a root shell. The differentiator is the write-safety model: 96 tools split across four tiers, where reads need nothing, safe writes need confirm: true, and destructive operations need confirm: true + destructive: true + a process-level PROXMOX_ENABLE_DESTRUCTIVE=1 env flag. A hallucinated or careless tool call fails closed, before any HTTP traffic reaches Proxmox.

Proof

A real MCP client config. Drop this into Claude Desktop (claude_desktop_config.json) and the 96 tools appear in the client. Reads work immediately; the destructive env gate stays off until you opt in.

{
  "mcpServers": {
    "proxmox": {
      "command": "npx",
      "args": ["-y", "@solomonneas/proxmox-mcp"],
      "env": {
        "PROXMOX_URL": "https://192.0.2.10:8006",
        "PROXMOX_TOKEN_ID": "pve-admin@pam!api-token-1",
        "PROXMOX_TOKEN_SECRET": "00000000-0000-0000-0000-000000000000",
        "PROXMOX_TLS_INSECURE": "false"
      }
    }
  }
}

Tool list (96 tools, verified against source)

Tier markers below are authoritative: each tool's gate is enforced in code (src/gates.ts + per-tool schema), and WriteGateError fires before any HTTP call when a gate is unmet.

proxmox-mcp safety workflow: read tools inventory the cluster and trace tasks, guest reads require confirmation, safe writes stay gated, and destructive tools need the full three-part gate

Generated from docs/assets/workflows/proxmox-safety.json with lidless workflow.

Tool Tier Notes
proxmox_status 1 read Cluster + node status.
proxmox_list_containers 1 read LXC inventory across all nodes.
proxmox_list_vms 1 read QEMU inventory across all nodes.
proxmox_get_resource 1 read Single container or VM config + status by vmid.
proxmox_get_vm_config 1 read QEMU VM config by vmid.
proxmox_get_container_config 1 read LXC container config by vmid.
proxmox_validate_qemu_smoke_source 1 read Preflight a QEMU VM before live smoke cloning.
proxmox_audit_permissions 1 read Inspect effective permissions across smoke-relevant paths.
proxmox_recent_tasks 1 read Recent UPID task list per node.
proxmox_list_backups 1 read Backup inventory by storage.
proxmox_resource_usage 1 read CPU/mem/disk RRD metrics.
proxmox_list_templates 1 read LXC + VM templates available for cloning + container creation.
proxmox_list_storage 1 read Storage status on one node or all nodes.
proxmox_list_snapshots 1 read Snapshot inventory for one LXC or VM.
proxmox_guest_network 1 read Guest network interfaces and usable IPv4 addresses.
proxmox_wait_task 1 read Poll a UPID until stopped or timeout.
proxmox_next_vmid 1 read Get the next available VMID for provisioning.
proxmox_list_pool_resources 1 read Inspect resources assigned to a Proxmox pool, defaulting to mcp-smoke.
proxmox_get_task_status 1 read Single UPID status lookup.
proxmox_get_task_log 1 read Task log tail for a UPID.
proxmox_list_storage_content 1 read List volumes on a storage: ISOs, templates, disk images, backups.
proxmox_list_node_services 1 read Host systemd service states (pveproxy, pvedaemon, corosync).
proxmox_list_disks 1 read Physical disks with model/size/SMART health/wearout.
proxmox_list_updates 1 read Pending APT updates on a node (needs a Sys.Modify token).
proxmox_list_firewall_rules 1 read Firewall rules at cluster/node/guest scope.
proxmox_get_firewall_options 1 read Firewall enable state + default policy at a scope.
proxmox_list_storage_config 1 read Datacenter storage definitions (id/type/content/nodes).
proxmox_list_backup_jobs 1 read Scheduled vzdump backup jobs.
proxmox_list_users 1 read Access users (userid, realm, enabled state).
proxmox_list_roles 1 read Roles and their privileges.
proxmox_list_acl 1 read ACL entries: who holds which role on which path.
proxmox_list_pools 1 read All resource pools.
proxmox_list_tokens 1 read API tokens for a user.
proxmox_cluster_status 1 read Cluster membership + quorum per node.
proxmox_ha_status 1 read HA manager status: quorum, fencing, resource states.
proxmox_list_ha_resources 1 read HA-managed resources.
proxmox_list_ha_rules 1 read HA rules (PVE 9+ replacement for HA groups).
proxmox_list_replication 1 read Storage replication jobs.
proxmox_list_sdn_zones 1 read SDN zones.
proxmox_list_sdn_vnets 1 read SDN virtual networks.
proxmox_list_metric_servers 1 read External metrics servers (InfluxDB/Graphite).
proxmox_get_cluster_options 1 read Datacenter options (keyboard, MAC prefix, tags).
proxmox_cluster_log 1 read Recent cluster-wide log entries.
proxmox_read_file 2 gated guest read Read a file from inside an LXC or QEMU VM (SSH + cat). Requires confirm: true.
proxmox_stat_path 2 gated guest read Inspect guest path metadata. Requires confirm: true.
proxmox_list_directory 2 gated guest read List one guest directory. Requires confirm: true.
proxmox_service_status 2 gated guest read Read systemd service state inside a guest. Requires confirm: true.
proxmox_start_resource 2 safe-write Boot container or VM. Requires confirm: true.
proxmox_stop_resource 2 safe-write Graceful shutdown. Requires confirm: true.
proxmox_reboot_resource 2 safe-write Reboot in place. Requires confirm: true.
proxmox_snapshot_resource 2 safe-write Create named snapshot. Requires confirm: true.
proxmox_run_backup 2 safe-write Trigger vzdump for a vmid. Requires confirm: true.
proxmox_create_container 2 safe-write Provision new LXC from template (POST /nodes/{node}/lxc). Requires confirm: true.
proxmox_create_vm 2 safe-write Provision new QEMU VM (POST /nodes/{node}/qemu). Requires confirm: true.
proxmox_clone_resource 2 safe-write Clone existing container or VM into a fresh vmid. Requires confirm: true.
proxmox_exec 2 safe-write Run a shell command inside an LXC or QEMU VM. Returns stdout/stderr/exit_code. Requires confirm: true.
proxmox_write_file 2 safe-write Write a text file (with parent dirs) inside an LXC or QEMU VM. Requires confirm: true.
proxmox_service_start 2 safe-write Start a systemd service inside a guest. Requires confirm: true.
proxmox_service_stop 2 safe-write Stop a systemd service inside a guest. Requires confirm: true.
proxmox_service_restart 2 safe-write Restart a systemd service inside a guest. Requires confirm: true.
proxmox_update_vm_config 2 safe-write Edit an existing QEMU VM config (cores/memory/net/etc, PUT .../qemu/{vmid}/config). Requires confirm: true.
proxmox_update_container_config 2 safe-write Edit an existing LXC config (cores/memory/hostname/etc, PUT .../lxc/{vmid}/config). Requires confirm: true.
proxmox_resize_disk 2 safe-write Grow a VM or container disk (PUT .../{type}/{vmid}/resize). Grow-only. Requires confirm: true.
proxmox_restore_backup 2 safe-write Restore a vzdump/PBS archive into a VMID. Overwriting an existing VMID escalates to the destructive gate. Requires confirm: true.
proxmox_migrate_resource 2 safe-write Migrate a VM or container to another node (POST .../migrate). Requires confirm: true.
proxmox_suspend_resource 2 safe-write Suspend/pause a running guest (QEMU can hibernate to disk). Requires confirm: true.
proxmox_resume_resource 2 safe-write Resume a suspended guest. Requires confirm: true.
proxmox_reset_resource 2 safe-write Hard-reset a QEMU VM (reset button; no graceful shutdown). Requires confirm: true.
proxmox_convert_to_template 2 safe-write Convert a stopped guest into a clone template (one-way). Requires confirm: true.
proxmox_download_url 2 safe-write Download an ISO or container template from a URL onto a storage. Requires confirm: true.
proxmox_cancel_task 2 safe-write Stop a running task by UPID (abort a stuck migration/backup). Requires confirm: true.
proxmox_add_firewall_rule 2 safe-write Add a firewall rule at cluster/node/guest scope. Requires confirm: true.
proxmox_delete_firewall_rule 2 safe-write Delete a firewall rule by position at a scope. Requires confirm: true.
proxmox_set_firewall_enabled 2 safe-write Enable/disable the firewall at a scope. Requires confirm: true.
proxmox_move_disk 2 safe-write Relocate a VM disk or container volume to another storage. Requires confirm: true.
proxmox_create_storage 2 safe-write Define a new datacenter storage (dir/nfs/lvm/pbs/etc). Requires confirm: true.
proxmox_create_backup_job 2 safe-write Create a scheduled vzdump backup job. Requires confirm: true.
proxmox_delete_backup_job 2 safe-write Delete a scheduled backup job (archives untouched). Requires confirm: true.
proxmox_set_acl 2 safe-write Grant or revoke a role for a user/token/group on a path. Requires confirm: true.
proxmox_create_token 2 safe-write Create an API token; returns the secret once. Requires confirm: true.
proxmox_delete_token 2 safe-write Revoke an API token. Requires confirm: true.
proxmox_create_pool 2 safe-write Create a resource pool. Requires confirm: true.
proxmox_update_pool 2 safe-write Add/remove guests or storage in a pool. Requires confirm: true.
proxmox_delete_pool 2 safe-write Delete an empty resource pool. Requires confirm: true.
proxmox_add_ha_resource 2 safe-write Place a VM/container under HA management. Requires confirm: true.
proxmox_delete_ha_resource 2 safe-write Remove a guest from HA management. Requires confirm: true.
proxmox_create_replication 2 safe-write Create a storage replication job to another node. Requires confirm: true.
proxmox_delete_replication 2 safe-write Delete a replication job. Requires confirm: true.
proxmox_rollback_snapshot 3 destructive Roll back a resource to a named snapshot.
proxmox_destroy_resource 3 destructive Permanently delete an LXC or VM (DELETE /nodes/{node}/{type}/{vmid}).
proxmox_cleanup_smoke_resources 3 destructive Dry-run or destroy smoke-prefixed LXC/QEMU guests from a smoke pool.
proxmox_delete_snapshot 3 destructive Delete a named snapshot.
proxmox_force_stop_resource 3 destructive Non-graceful hard stop of a running container or VM.
proxmox_delete_volume 3 destructive Permanently delete a storage volume (backup, ISO, template, disk image).
proxmox_node_power 3 destructive Reboot or shut down an entire node, taking down every guest on it.
proxmox_delete_storage 3 destructive Remove a storage definition from the datacenter config.

Reads (43): open; no flags required. Gated guest reads (4): guest file/path/directory/service inspection tools require confirm: true because they expose in-guest state through host-backed SSH. Safe writes (41): require confirm: true. The schema documents the gate on every tool. WriteGateError fires before any HTTP call. Destructive (8): require confirm: true + destructive: true + env PROXMOX_ENABLE_DESTRUCTIVE=1. All three gates must be satisfied; if any one is missing the tool throws WriteGateError before resolving the resource.

Eight tools are destructive and can delete, hard-stop, or power off resources: proxmox_destroy_resource, proxmox_cleanup_smoke_resources, proxmox_rollback_snapshot, proxmox_delete_snapshot, proxmox_force_stop_resource, proxmox_delete_volume, proxmox_node_power, and proxmox_delete_storage. They are gated behind the PROXMOX_ENABLE_DESTRUCTIVE=1 process env flag and stay inert until you set it. See SECURITY.md and the Safety section.

Quickstart

Install globally or run on demand with npx:

npm install -g @solomonneas/proxmox-mcp
# or, no install:
npx -y @solomonneas/proxmox-mcp

Set the three required credential env vars (scrub real hosts and IPs out of any shared config):

export PROXMOX_URL=https://192.0.2.10:8006
export PROXMOX_TOKEN_ID=pve-admin@pam!api-token-1
export PROXMOX_TOKEN_SECRET=00000000-0000-0000-0000-000000000000

# Optional: skip TLS cert validation for homelab self-signed certs.
# Accepts true/1/yes (case-insensitive). Defaults to false.
export PROXMOX_TLS_INSECURE=false

Wire it into your MCP client (full per-client config in Setup):

# Claude Code
claude mcp add proxmox -s user -- npx -y @solomonneas/proxmox-mcp

Then ask your agent to list your cluster's containers. Reads work with nothing but the three credential vars; write and destructive tiers stay gated until you opt in.

Note: the latest published version is 0.11.0. npx/npm install pins the published release; this repository may track ahead between releases.

Configuration

Set the following env vars. All three credential vars are required.

PROXMOX_URL=https://192.0.2.10:8006
PROXMOX_TOKEN_ID=pve-admin@pam!api-token-1
PROXMOX_TOKEN_SECRET=00000000-0000-0000-0000-000000000000

# Optional: skip TLS cert validation (homelab self-signed certs).
# Accepts true/1/yes (case-insensitive). Defaults to false.
PROXMOX_TLS_INSECURE=false

Trailing slashes on PROXMOX_URL are stripped. The token secret is registered with the redactor on startup and masked from all log + error output.

In-container exec env vars

The proxmox_exec, proxmox_read_file, and proxmox_write_file tools SSH to the Proxmox host (for LXC, via pct exec) or directly to the VM (for QEMU). All are optional; defaults derive from PROXMOX_URL.

Env var Default Purpose
PROXMOX_SSH_HOST hostname from PROXMOX_URL Proxmox host for pct exec
PROXMOX_SSH_PORT 22 SSH port
PROXMOX_SSH_USER root SSH user on Proxmox host
PROXMOX_SSH_KEY ~/.ssh/id_ed25519 Key path for Proxmox host SSH
PROXMOX_VM_SSH_USER falls through to PROXMOX_SSH_USER Default user for direct VM SSH
PROXMOX_VM_SSH_KEY falls through to PROXMOX_SSH_KEY Default key for direct VM SSH
PROXMOX_SSH_MAX_OUTPUT_BYTES 1048576 Max stdout bytes and max stderr bytes captured per SSH command
PROXMOX_EXEC_BACKEND ssh QEMU exec backend: ssh (direct SSH to the VM) or guest-agent (qemu-guest-agent API, no in-guest SSH key needed). LXC always uses pct exec over host SSH.

Per-VM overrides (read at execute time, no MCP restart needed):

  • PROXMOX_VM_<vmid>_SSH_HOST - pin a VM's IP (bypasses guest agent)
  • PROXMOX_VM_<vmid>_SSH_USER - per-VM user override
  • PROXMOX_VM_<vmid>_SSH_KEY - per-VM key override

For QEMU VMs without a per-VM env override, install qemu-guest-agent in the VM and enable it with qm set <vmid> --agent 1 so the IP can be discovered automatically.

Set PROXMOX_EXEC_BACKEND=guest-agent to run QEMU guest commands entirely through the qemu-guest-agent API instead of SSH. This needs no in-guest SSH key and no network path from the MCP host to the VM (traffic goes through the Proxmox API), but the API token needs the VM.GuestAgent.* privileges (Unrestricted for exec, FileRead/FileWrite for file ops). LXC guests always use pct exec over host SSH regardless of this setting.

Waiting for long-running tasks

Provisioning and disk operations (proxmox_create_container, proxmox_create_vm, proxmox_clone_resource, proxmox_run_backup, proxmox_restore_backup, proxmox_migrate_resource, proxmox_resize_disk, proxmox_download_url, proxmox_destroy_resource) return a task UPID immediately. Pass wait: true (with optional wait_timeout seconds, default 120) to block until the task finishes; the result then includes a task object with done, exitstatus, and ok (true only for an OK exit). Without wait, use proxmox_wait_task to poll the UPID yourself.

CLI

The same package ships a read-only control CLI, proxmoxctl (alias proxops), for shells, cron, and CI. It shares the ProxmoxClient core with the MCP server and reads the same env config (PROXMOX_URL, PROXMOX_TOKEN_ID, PROXMOX_TOKEN_SECRET, PROXMOX_TLS_INSECURE). It exposes only read/inventory/audit operations; every lifecycle, snapshot, backup, and exec action stays in the MCP/plugin surface behind the safety gates.

npx @solomonneas/proxmox-mcp@latest status
# or, installed globally:
proxmoxctl status                       # PVE version + per-node status (exit 1 if a node is offline)
proxmoxctl vms list
proxmoxctl containers list
proxmoxctl vm config 100
proxmoxctl storage list --node pve
proxmoxctl storage content local --node pve --content backup
proxmoxctl disks list --node pve        # physical disks + SMART health
proxmoxctl services list --node pve     # host systemd services
proxmoxctl firewall rules --scope cluster
proxmoxctl backups list --vmid 100
proxmoxctl snapshots list 100
proxmoxctl audit-permissions
proxmoxctl recent-tasks --limit 20
proxmoxctl task status UPID:pve:...
proxmoxctl vms list --json              # raw JSON for piping

Run proxmoxctl help for the full command list. --json emits raw JSON instead of the concise summary. Exit codes: 0 success, 1 runtime error (backend unreachable / call failed, and status when a node is offline), 2 usage error (unknown command/flag or bad value).

Starting the MCP server

proxmoxctl mcp (or the back-compat proxmox-mcp bin) starts the stdio MCP server. If a launcher referenced the file path dist/mcp-server.js directly, it keeps working; new launchers can point at dist/mcp-bin.js (or dist/cli.js mcp). Launchers that use the proxmox-mcp bin name need no change.

Setup

Claude Desktop

~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "proxmox": {
      "command": "npx",
      "args": ["-y", "@solomonneas/proxmox-mcp"],
      "env": {
        "PROXMOX_URL": "https://192.0.2.10:8006",
        "PROXMOX_TOKEN_ID": "pve-admin@pam!api-token-1",
        "PROXMOX_TOKEN_SECRET": "00000000-0000-0000-0000-000000000000",
        "PROXMOX_TLS_INSECURE": "false"
      }
    }
  }
}

Claude Code

claude mcp add proxmox -s user -- npx -y @solomonneas/proxmox-mcp

Then export env vars in your shell (~/.bashrc, ~/.zshrc) or pass --env flags.

OpenClaw

Plugin loads automatically once installed. Config goes in your ~/.openclaw/openclaw.json plugins.entries.proxmox (or use the bundled openclaw.plugin.json):

{
  "plugins": {
    "entries": {
      "proxmox": {
        "package": "@solomonneas/proxmox-mcp",
        "activation": { "onStartup": true }
      }
    }
  }
}

Env vars from ~/.openclaw/workspace/.env are inherited by the plugin.

Codex CLI

~/.codex/config.toml:

[mcp_servers.proxmox]
command = "npx"
args = ["-y", "@solomonneas/proxmox-mcp"]

[mcp_servers.proxmox.env]
PROXMOX_URL = "https://192.0.2.10:8006"
PROXMOX_TOKEN_ID = "pve-admin@pam!api-token-1"
PROXMOX_TOKEN_SECRET = "00000000-0000-0000-0000-000000000000"
PROXMOX_TLS_INSECURE = "false"

Safety

This MCP uses a three-tier write-gating model. The tier is enforced in code, not just documented.

  • Tier 1 (reads): open. No confirm flag needed. Status, listings, config inspection, QEMU smoke-source validation, permission audit, usage, recent tasks, backup inventory, template inventory, storage inventory, snapshot inventory, guest network lookup, task wait, next-VMID lookup, task status/log, pool resource audit, storage content listing, node service/disk/update inventory, and firewall rule/option inspection, storage-config and backup-job listing, and access/role/ACL/pool/token inspection, and cluster/HA/SDN/replication observability live here.
  • Tier 2 (gated guest reads + safe writes): require an explicit confirm: true arg. Guest file/path/directory/service inspection, start, stop, reboot, snapshot create, run backup, create container, create VM, clone, VM/container config edit, disk resize, backup restore (to a new VMID), node migration, suspend/resume/reset, convert-to-template, ISO/template download, task cancel, firewall rule add/delete and enable-toggle, disk move, storage creation, backup-job create/delete, ACL grant/revoke, API-token create/delete, pool create/update/delete, HA resource add/remove, replication job create/delete, in-container exec, in-container write_file, and guest service start/stop/restart live here. A tool call without the confirm flag throws WriteGateError before any HTTP traffic. Restoring a backup over an existing VMID escalates to the Tier-3 gate because it wipes the target's disks.
  • Tier 3 (destructive): require confirm: true + destructive: true + the env flag PROXMOX_ENABLE_DESTRUCTIVE=1 on the MCP process. Permanent resource deletion, smoke pool cleanup, snapshot rollback/deletion, non-graceful force-stop, storage-volume deletion, storage-definition removal, and node reboot/shutdown live here.

Destructive operations env gate

Tier 3 destructive tools (proxmox_destroy_resource, proxmox_cleanup_smoke_resources, proxmox_rollback_snapshot, proxmox_delete_snapshot, proxmox_force_stop_resource, proxmox_delete_volume, proxmox_node_power, proxmox_delete_storage) require an additional safety gate beyond the per-tool confirm: true + destructive: true args: the env var PROXMOX_ENABLE_DESTRUCTIVE=1 must be set on the MCP process. Without it, the tools throw WriteGateError before any HTTP call is made. proxmox_cleanup_smoke_resources defaults to dry_run: true, which previews targets without the destructive env gate.

This is intentional: destructive ops are rare. The env flag is a coarse "I am actively doing smoke-test cycles" toggle. Leave it unset day to day; flip it only when actively destroying resources is part of the workflow.

API token scope recommendation: start with a read-only token (PVE Datastore.Audit + VM.Audit + Sys.Audit) and verify the read tools work end to end. Grade up to write privileges (VM.PowerMgmt, VM.Snapshot, VM.Backup) only after you have confirmed the redactor is masking your secret in your transcripts and that the model is honoring the confirm gate. Tokens are tied to a PVE user and can be revoked instantly from Datacenter > Permissions > API Tokens.

The PROXMOX_TLS_INSECURE=true toggle exists for homelab self-signed certs. Leave it false in any environment with a real CA-signed cert.

Full security policy, reporting, and in-scope/out-of-scope detail in SECURITY.md.

Live smoke testing

Read-only live smoke:

PROXMOX_ENABLE_LIVE_SMOKE=1 npm run smoke:live

Full scratch CT lifecycle smoke requires a token that can create, start, stop, inspect, and destroy resources in the mcp-smoke pool:

PROXMOX_ENABLE_LIVE_SMOKE=1 \
PROXMOX_SMOKE_CREATE=1 \
PROXMOX_ENABLE_DESTRUCTIVE=1 \
npm run smoke:live

Optional scratch CT backup and snapshot rollback smoke:

PROXMOX_ENABLE_LIVE_SMOKE=1 \
PROXMOX_SMOKE_CREATE=1 \
PROXMOX_SMOKE_BACKUP=1 \
PROXMOX_SMOKE_BACKUP_STORAGE=local \
PROXMOX_SMOKE_SNAPSHOT_ROLLBACK=1 \
PROXMOX_ENABLE_DESTRUCTIVE=1 \
npm run smoke:live

Create a scoped smoke-test role/user/token on the Proxmox host:

PROXMOX_CREATE_SMOKE_TOKEN=1 bash scripts/create-smoke-token.sh

The script creates or updates role McpSmokeRole, pool mcp-smoke, user mcp-smoke@pve, token mcp-smoke@pve!live-smoke, and ACLs for the smoke pool plus local and local-lvm storage. Proxmox prints the token secret once; store it in your private environment and do not commit it.

Proxmox also checks /vms/<vmid> before creating a new CT/VM. For one-off smoke tests, grant the exact next VMID before running the lifecycle smoke:

PROXMOX_CREATE_SMOKE_TOKEN=1 PROXMOX_SMOKE_VMID_GRANT=102 bash scripts/create-smoke-token.sh

npm run smoke:live now attempts that exact VMID grant automatically before creating a scratch CT or QEMU clone when PROXMOX_SSH_HOST, PROXMOX_SSH_USER, and PROXMOX_SSH_KEY are available. Set PROXMOX_SMOKE_SKIP_AUTO_GRANT=1 to disable it.

Optional QEMU clone smoke:

PROXMOX_ENABLE_LIVE_SMOKE=1 \
PROXMOX_ENABLE_DESTRUCTIVE=1 \
PROXMOX_SMOKE_QEMU_SOURCE_VMID=9000 \
npm run smoke:live

This validates the source, full-clones it to a scratch VMID, starts it, waits for guest-agent network data, stops it, and destroys it. Use PROXMOX_SMOKE_QEMU_TARGET_VMID or PROXMOX_SMOKE_QEMU_NAME to override the generated target.

The QEMU source should be a small stopped VM or template with agent: enabled=1, DHCP networking, no PCI/USB passthrough, no raw args, and a modest disk size. Check it first:

# tool: proxmox_validate_qemu_smoke_source { "vmid": 9000 }

Audit smoke-token permissions:

# tool: proxmox_audit_permissions {
#   "userid": "mcp-smoke@pve!live-smoke",
#   "source_vmid": 103,
#   "target_vmid": 102
# }

Optional systemd service smoke:

PROXMOX_ENABLE_LIVE_SMOKE=1 \
PROXMOX_SMOKE_SYSTEMD_VMID=100 \
PROXMOX_SMOKE_SERVICE=basic.target \
npm run smoke:live

To run a live service action as well as status, add PROXMOX_SMOKE_SERVICE_ACTION=start|stop|restart and PROXMOX_SMOKE_SERVICE_ACTION_CONFIRM=1.

Audit or clean leftover smoke resources:

# Read-only pool audit
# tool: proxmox_list_pool_resources { "pool": "mcp-smoke" }

# Dry-run cleanup, only resources named mcp-smoke-* in the pool are targeted
# tool: proxmox_cleanup_smoke_resources {}

# Actual cleanup waits for delete tasks and skips running guests unless force:true
# tool: proxmox_cleanup_smoke_resources { "dry_run": false, "confirm": true, "destructive": true }

Why not the alternatives?

  • The Proxmox web UI is the canonical control plane and you should keep it. proxmox-mcp is not a replacement; it is the agent-facing read/operate surface so an AI client can inventory, trace, and operate the cluster in the same loop it is already running, without you driving a browser.
  • Hand-rolling Proxmox API calls in your agent works, but the agent has to manage token auth, the redactor, retry, task polling, and (critically) safety on its own. proxmox-mcp ships the token redactor, structured MCP error payloads, and the three-tier write gate so a careless or hallucinated call fails closed instead of deleting a guest.
  • A general "run any HTTP request" MCP tool gives a model unbounded access to the Proxmox API with no guardrails. proxmox-mcp is the opposite: a fixed, named tool surface where every state change is gated and every destructive op needs an explicit process-level env flag.
  • Terraform / Ansible / pct + qm are the right tools for declarative, reviewed, repeatable infrastructure. proxmox-mcp is for interactive, agent-driven inspection and operation, not for codifying your cluster.

What proxmox-mcp is not

  • It is not a tool for blind automation of destructive operations. The destructive tier exists for deliberate, supervised work (smoke-test cycles, intentional teardown), not for unattended agents. The PROXMOX_ENABLE_DESTRUCTIVE=1 flag is a coarse "I am actively doing this right now" toggle; leave it unset day to day.
  • It is not a Proxmox cluster manager or orchestrator. It does not schedule, it does not run in the background, and it holds no state of its own. It translates MCP tool calls into Proxmox API calls and SSH commands, and that is all.
  • It is not a substitute for least-privilege tokens. The write gate is a guardrail against a misbehaving model, not a substitute for a properly scoped Proxmox API token. Start read-only and grade up. See SECURITY.md.
  • It is not stable yet. It is WIP, pre-1.0, and the tool surface can change between minor versions.

Contributing

Bug reports and patches are welcome. See CONTRIBUTING.md for what lands easily, local dev, and the safety rules every change must keep. By participating you agree to the Code of Conduct.

Changelog

See CHANGELOG.md for the release history.

License

MIT. See LICENSE.