Skip to main content
Glama
ry-ops

Proxmox MCP Server

by ry-ops

โœจ Highlights

  • ๐Ÿงฐ The whole API, not a demo. 340 tools across 14 areas: nodes, QEMU VMs, LXC containers, storage and backup, cluster and HA, access control, firewall, disks, Ceph, ACME, SDN, notifications, pools and appliances.

  • ๐Ÿ–ฅ๏ธ Inside your guests too. Run commands through the QEMU guest agent (vm_agent_exec โ†’ vm_agent_exec_status) and read back the exit code and output.

  • ๐Ÿ”’ Look-but-don't-touch with one switch. PROXMOX_READ_ONLY=true refuses every write inside the server, and 149 read-only tools keep working.

  • ๐Ÿ”‘ API tokens or passwords. Tokens are recommended; pair them with a PVEAuditor role for monitoring.

  • ๐Ÿณ Runs anywhere. Use uv from a clone, or the multi-arch image on ghcr.io.

  • ๐Ÿค A2A-ready. agent-card.json lists every tool in 14 skill categories, for agent-to-agent discovery.

  • ๐Ÿ›ก๏ธ Appliances. deploy_fortigate_vm builds a FortiGate-VM from Fortinet's KVM image, with WAN/LAN NICs on the bridges and VLANs you choose. deploy_cloud_vms builds cluster-ready VMs from a cloud image, with your SSH key and a static IP each, ready for k3s-mcp-server's create_cluster.

Related MCP server: ProxmoxEmCP

๐Ÿ’ฌ Talk to your cluster

Once it's connected, just ask:

"Can you list all VMs in my Proxmox cluster?" "What's the status of VM 100 on node pve1?" "Create a snapshot called 'backup-2025' for VM 100 on pve1." "Show me the storage usage on all nodes." "List all running tasks in the cluster." "Clone VM 9000 to a new VM called web-02 and start it." "Run df -h inside VM 120 using the guest agent and show me the output." "Make three Ubuntu VMs on pve1 at 192.168.1.181โ€“183 with my SSH key, ready for a K3s cluster."

There are more worked examples in USAGE.md.

โš™๏ธ How it works

  • Your MCP client (Claude Desktop, Claude Code, or anything that speaks MCP) starts the server and talks to it over stdio.

  • The server (Python, httpx, the MCP SDK) turns each tool call into a request to the Proxmox VE REST API over HTTPS on port 8006, authenticated with an API token or a password.

  • Read-only mode is checked in the server's HTTP client, so a refused write never leaves your machine.

๐Ÿงฐ 340 tools, 14 areas

Area

Tools

Highlights

Nodes

38

Status, config, DNS/hosts/time, network interfaces, services, APT updates, syslog, power

QEMU VMs

46

Lifecycle, create/clone/delete, config, snapshots, migration, disk resize/move, RRD metrics, guest agent (vm_agent_exec, vm_agent_exec_status), VNC proxy

LXC containers

28

Lifecycle, create/clone/delete, config, snapshots, migration, resize

Storage & backup

14

Storage definitions, content and volumes, URL downloads, vzdump backup and restore

Cluster

37

Status, resources, options, log, tasks, HA resources/groups, replication, backup jobs

Access control

33

Users, API tokens, groups, roles, ACLs, realms

Firewall

31

Cluster and node rules, security groups, aliases, IP sets, macros, logs (per-VM and per-container rules are in the guest modules)

Disks

17

SMART, wipe, GPT init, LVM, LVM-thin, ZFS, directory storage

Ceph

33

Status, OSDs, monitors, managers, MDS, pools, flags, CRUSH

ACME & certificates

17

ACME accounts and plugins, node certificate ordering, custom certs

SDN

16

Zones, VNets, subnets, apply

Notifications

23

Gotify, sendmail, SMTP and webhook endpoints, matchers

Pools

5

Resource pool CRUD

Appliances

2

deploy_fortigate_vm: FortiGate-VM from Fortinet's KVM image, WAN/LAN NICs on chosen bridges and VLANs, sized for the free evaluation license. deploy_cloud_vms: VMs from a cloud image (e.g. Ubuntu's) with cloud-init user, SSH key and a static IP or DHCP each, disk grown and started

Tool names follow the Proxmox API: list_*, get_*, create_*, update_*/set_*, delete_*, plus actions such as start_vm, migrate_container or apply_sdn. Each area is one module in proxmox_mcp/tools/. Your MCP client shows every tool with its full input schema, or you can list them all locally:

uv run python -c "from proxmox_mcp.server import ALL_TOOLS; print('\n'.join(sorted(t.name for t in ALL_TOOLS)))"

Handy recipes

Task

Tools

Inventory

list_nodes, get_cluster_resources, list_vms, list_containers, list_storage

VM lifecycle

start_vm, shutdown_vm, stop_vm, reboot_vm, create_vm, clone_vm, migrate_vm

Disk images

download_url_to_storage with content=import, then create_vm with scsi0=local-lvm:0,import-from=local:import/<image>, or import_vm_disk

Snapshots

create_vm_snapshot, list_vm_snapshots, rollback_vm_snapshot, delete_vm_snapshot

Monitoring

get_node_status, get_vm_status, get_vm_rrddata, get_node_storage_status

Tasks

list_cluster_tasks, list_node_tasks, get_task_status, get_task_log

Guest agent

vm_agent_exec (returns a PID), then vm_agent_exec_status for the exit code and output

Cluster nodes

download_url_to_storage for a cloud image with content=import, then deploy_cloud_vms; hand the IPs to k3s-mcp-server's create_cluster

๐Ÿš€ Quick start

You need Python 3.10+ with uv, or Docker, and Proxmox VE 6.0 or later.

1. Make an API token. In the Proxmox UI, go to Datacenter โ†’ Permissions โ†’ API Tokens โ†’ Add. For full access, uncheck Privilege Separation so the token inherits your user's permissions. Copy the secret; you won't see it again. The full token ID looks like root@pam!automation.

2. Run the server with one of these:

curl -LsSf https://astral.sh/uv/install.sh | sh     # if you don't have uv
git clone https://github.com/ry-ops/proxmox-mcp-server && cd proxmox-mcp-server
./setup.sh                                          # or: uv sync

export PROXMOX_HOST="192.168.1.100"
export PROXMOX_USER="root@pam"
export PROXMOX_TOKEN_NAME="automation"
export PROXMOX_TOKEN_VALUE="your-token-here"
./test-connection.sh                                # checks connection, auth and permissions

A .env file in the project directory is loaded automatically; see .env.example.

A multi-arch image is published to GitHub Container Registry on every push to main and for each release tag:

docker pull ghcr.io/ry-ops/proxmox-mcp-server:latest   # or a version tag, e.g. :2.4.0
docker run -i --rm --env-file .env ghcr.io/ry-ops/proxmox-mcp-server:latest

MCP clients talk over stdio, so run the container interactively (-i). docker-compose.yaml does the same using your .env.

3. Connect your MCP client. For Claude Desktop, edit ~/Library/Application Support/Claude/claude_desktop_config.json on macOS, or %APPDATA%/Claude/claude_desktop_config.json on Windows:

{
  "mcpServers": {
    "proxmox": {
      "command": "uv",
      "args": ["--directory", "/absolute/path/to/proxmox-mcp-server", "run", "proxmox-mcp-server"],
      "env": {
        "PROXMOX_HOST": "192.168.1.100",
        "PROXMOX_USER": "root@pam",
        "PROXMOX_TOKEN_NAME": "automation",
        "PROXMOX_TOKEN_VALUE": "your-token-value-here"
      }
    }
  }
}

Use the absolute path to your clone.

{
  "mcpServers": {
    "proxmox": {
      "command": "uv",
      "args": ["--directory", "/absolute/path/to/proxmox-mcp-server", "run", "proxmox-mcp-server"],
      "env": {
        "PROXMOX_HOST": "192.168.1.100",
        "PROXMOX_USER": "root@pam",
        "PROXMOX_PASSWORD": "your-password-here"
      }
    }
  }
}
{
  "mcpServers": {
    "proxmox": {
      "command": "docker",
      "args": ["run", "-i", "--rm",
        "-e", "PROXMOX_HOST", "-e", "PROXMOX_USER", "-e", "PROXMOX_TOKEN_NAME", "-e", "PROXMOX_TOKEN_VALUE",
        "ghcr.io/ry-ops/proxmox-mcp-server:latest"],
      "env": {
        "PROXMOX_HOST": "192.168.1.100",
        "PROXMOX_USER": "root@pam",
        "PROXMOX_TOKEN_NAME": "automation",
        "PROXMOX_TOKEN_VALUE": "your-token-value-here"
      }
    }
  }
}

4. Restart your client completely (quit it, don't just close the window), and ask it to list your VMs. More detail in QUICKSTART.md and SETUP.md.

๐Ÿ”ง Configuration

Variable

Required

Default

What it does

PROXMOX_HOST

โœ…

Hostname or IP, without scheme or port (192.168.1.100, not https://192.168.1.100:8006)

PROXMOX_USER

โœ…

e.g. root@pam, admin@pve

PROXMOX_TOKEN_NAME + PROXMOX_TOKEN_VALUE

one of

API token auth (recommended)

PROXMOX_PASSWORD

one of

Password auth

PROXMOX_PORT

8006

API port

PROXMOX_VERIFY_SSL

false

Verify the server's TLS certificate

PROXMOX_READ_ONLY

false

Refuse every write; see below

๐Ÿ”’ Read-only mode and security

PROXMOX_READ_ONLY=true makes the server look-but-don't-touch. Only GET requests are sent, and every create, update, delete or action tool is refused inside the server before it reaches the network. 149 of the 340 tools are read-only and keep working. Three read-style tools send POST requests, so they're blocked too:

  • vm_agent_ping;

  • get_vm_vnc_proxy and get_vm_spice_proxy, which create console access tickets.

The rest of the security picture:

  • For monitoring-only use, combine both locks: PROXMOX_READ_ONLY=true and a token with the PVEAuditor role. The flag stops the server sending writes; the role makes Proxmox refuse them anyway.

  • The token's permissions are the real limit. The server exposes destructive operations: deleting VMs, wiping disks, and running commands inside guests. Whatever the token can do, a connected AI client can ask for. Grant the minimum.

  • Prefer API tokens over passwords. They can be revoked on their own.

  • Set PROXMOX_VERIFY_SSL=true in production with valid certificates.

  • Keep credentials out of version control, and restrict network access to the API with firewall rules.

๐Ÿค Agent-to-agent (A2A)

agent-card.json is this server's identity and capability manifest for other agents. It's generated from the tool registry, and lists all 340 tools in 14 skill categories, each with its name, description and inputs. It also covers authentication requirements and MCP protocol details.

Category

Tools

Category

Tools

node_management

38

disk_management

17

virtual_machine_management

46

ceph_management

33

container_management

28

certificate_management

17

storage_management

14

sdn_management

16

cluster_management

37

notification_management

23

access_control

33

pool_management

5

firewall_management

31

appliances

2

import json

with open('agent-card.json') as f:
    agent_card = json.load(f)

print(f"Agent: {agent_card['name']}  Version: {agent_card['version']}")
for skill in agent_card['skills']:
    print(f"\n{skill['category']}:")
    for capability in skill['capabilities']:
        print(f"  - {capability['name']}: {capability['description']}")
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

server_params = StdioServerParameters(
    command="uv",
    args=["--directory", "/path/to/proxmox-mcp-server", "run", "proxmox-mcp-server"],
    env={
        "PROXMOX_HOST": "192.168.1.100",
        "PROXMOX_USER": "root@pam",
        "PROXMOX_TOKEN_NAME": "automation",
        "PROXMOX_TOKEN_VALUE": "your-token-value",
    },
)

async with stdio_client(server_params) as (read, write):
    async with ClientSession(read, write) as session:
        await session.initialize()
        tools = await session.list_tools()
        result = await session.call_tool("list_vms", arguments={})
        print(result.content)
# Snapshot every VM, then hand off to other agents
async def backup_workflow():
    vms = await proxmox_agent.call_tool("list_vms", {})
    for vm in vms['data']:
        await proxmox_agent.call_tool("create_vm_snapshot", {
            "node": vm['node'],
            "vmid": vm['vmid'],
            "snapname": f"backup-{datetime.now():%Y%m%d-%H%M%S}",
        })
    await storage_agent.call_tool("check_capacity", {})
    await notification_agent.call_tool("send_alert", {"message": f"Backup completed: {len(vms['data'])} VMs"})

๐Ÿฉบ Troubleshooting

  • Double-check the credentials and that the user has the permissions you need.

  • For API tokens, make sure the token hasn't expired or been revoked.

  • If the token was created with Privilege Separation on, give the token its own permissions, or recreate it with that option off.

  • Check PROXMOX_HOST (no scheme, no port) and PROXMOX_PORT.

  • Check you can reach the host: curl -k https://YOUR_HOST:8006/api2/json/version

  • If PROXMOX_VERIFY_SSL=true, the certificate must be valid for that host.

The user or token needs privileges for each operation. Common ones: VM.Monitor, VM.Audit, Datastore.Audit, Sys.Audit, VM.PowerMgmt, VM.Snapshot.

  • The path in the config must be absolute.

  • The config file must be valid JSON.

  • Quit Claude Desktop completely and start it again.

  • Check Claude Desktop's logs. The server logs its authentication method and connection status to stderr, which shows up there.

./test-connection.sh

It checks the connection, the API, authentication, permission to list nodes, and access to cluster resources.

๐Ÿ› ๏ธ Development

uv sync                          # dependencies, including dev tools
uv run proxmox-mcp-server        # run the server directly
uv run pytest                    # tests
uv run ruff check . && uv run black .
proxmox_mcp/
โ”œโ”€โ”€ server.py        MCP server entrypoint and tool registry
โ”œโ”€โ”€ client.py        Proxmox API client: token/password auth, read-only guard
โ””โ”€โ”€ tools/           one module per API area:
                     nodes, qemu, lxc, storage, cluster, access, firewall,
                     disks, ceph, acme, sdn, notifications, pools, appliances
docs/                the animations on this page
agent-card.json      A2A agent card
Dockerfile, docker-compose.yaml, setup.sh, test-connection.sh
QUICKSTART.md ยท SETUP.md ยท USAGE.md ยท CHANGELOG.md

Dependencies:

  • mcp (>=1.0.0, <2): 2.x changed the server API and isn't supported yet.

  • httpx: the async HTTP client.

  • python-dotenv: loads .env.

๐Ÿ—บ๏ธ Roadmap

  • Streamable-HTTP transport, to run the server as a network service (#24, #29)

  • Support for mcp 2.x

  • Automatic ticket refresh for long-running password-authenticated sessions

  • A broader automated test suite

What has shipped is in CHANGELOG.md.

๐Ÿ™Œ Contributing

Issues and pull requests are welcome: new tools, better error handling, performance, docs, tests and bug fixes.

๐Ÿ“š Learn more

License

MIT. See LICENSE.


Related MCP Connectors

Related MCP Servers