Skip to main content
Glama

pve-mcp

MCP server for Proxmox VE. Curated tools for everyday work, plus schema-validated access to every API endpoint.

  • Schema: src/pve_mcp/data/pve-api.json.gz, generated from a node's /usr/share/pve-docs/api-viewer/apidoc.js (currently PVE 9.2.24, 680 endpoints). Regenerate after a PVE upgrade: scp root@<node>:/usr/share/pve-docs/api-viewer/apidoc.js schema-src/ && python scripts/gen_schema.py schema-src/apidoc.js <version>

  • Generic: pve_api_search, pve_api_describe, pve_api (validates params, waits for tasks, dry_run).

  • Curated: cluster status/resources, guest status/power/config/snapshots, create/clone/migrate/destroy, guest-agent exec, storage, vzdump backups, tasks, optional node SSH.

Install in your agent

Install in VS Code Install in VS Code Insiders Install in Cursor

It works with any MCP client that can start a stdio command. It needs uv. uvx fetches the pinned release, so no clone or virtualenv is needed. Pick your agent below.

Variable

Meaning

Example

PVE_HOST

Proxmox host or IP

pve.example.lan

PVE_TOKEN_ID

API token id (user@realm!name)

root@pam!mcp

PVE_TOKEN_SECRET

API token secret

xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

Optional: PVE_ALLOW_WRITES=true (writes), PVE_VERIFY_SSL (true or a CA path), PVE_SSH_ENABLED. Without PVE_ALLOW_WRITES the server is read-only. Create the token under Datacenter → Permissions → API Tokens. For read-only use, give it the PVEAuditor role on /.

A different project uses the name pve-mcp on PyPI. Install from this repository as shown, not with pip install pve-mcp.

The VS Code buttons ask for each value, keeping secrets out of files. The Cursor button writes placeholders: edit them in ~/.cursor/mcp.json afterwards. Elsewhere, replace the example values.

claude mcp add proxmox -s user -e PVE_HOST=pve.example.lan -e PVE_TOKEN_ID=root@pam!mcp -e PVE_TOKEN_SECRET=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -- uvx --from git+https://github.com/bigbatmanorg/pve-mcp@v0.1.0 pve-mcp

Settings → Developer → Edit Config (claude_desktop_config.json):

{
  "mcpServers": {
    "proxmox": {
      "command": "uvx",
      "args": [
        "--from",
        "git+https://github.com/bigbatmanorg/pve-mcp@v0.1.0",
        "pve-mcp"
      ],
      "env": {
        "PVE_HOST": "pve.example.lan",
        "PVE_TOKEN_ID": "root@pam!mcp",
        "PVE_TOKEN_SECRET": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
      }
    }
  }
}

Use the button above, or add this to .vscode/mcp.json (workspace) or to the user mcp.json (command MCP: Open User Configuration):

{
  "inputs": [
    {
      "type": "promptString",
      "id": "pve_host",
      "description": "Proxmox host or IP",
      "password": false
    },
    {
      "type": "promptString",
      "id": "pve_token_id",
      "description": "API token id (user@realm!name)",
      "password": false
    },
    {
      "type": "promptString",
      "id": "pve_token_secret",
      "description": "API token secret",
      "password": true
    }
  ],
  "servers": {
    "proxmox": {
      "type": "stdio",
      "command": "uvx",
      "args": [
        "--from",
        "git+https://github.com/bigbatmanorg/pve-mcp@v0.1.0",
        "pve-mcp"
      ],
      "env": {
        "PVE_HOST": "${input:pve_host}",
        "PVE_TOKEN_ID": "${input:pve_token_id}",
        "PVE_TOKEN_SECRET": "${input:pve_token_secret}"
      }
    }
  }
}

Use the button above, or add this to ~/.cursor/mcp.json (global) or .cursor/mcp.json (project):

{
  "mcpServers": {
    "proxmox": {
      "command": "uvx",
      "args": [
        "--from",
        "git+https://github.com/bigbatmanorg/pve-mcp@v0.1.0",
        "pve-mcp"
      ],
      "env": {
        "PVE_HOST": "pve.example.lan",
        "PVE_TOKEN_ID": "root@pam!mcp",
        "PVE_TOKEN_SECRET": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
      }
    }
  }
}

Add this to ~/.codeium/windsurf/mcp_config.json:

{
  "mcpServers": {
    "proxmox": {
      "command": "uvx",
      "args": [
        "--from",
        "git+https://github.com/bigbatmanorg/pve-mcp@v0.1.0",
        "pve-mcp"
      ],
      "env": {
        "PVE_HOST": "pve.example.lan",
        "PVE_TOKEN_ID": "root@pam!mcp",
        "PVE_TOKEN_SECRET": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
      }
    }
  }
}
codex mcp add proxmox --env PVE_HOST=pve.example.lan --env PVE_TOKEN_ID=root@pam!mcp --env PVE_TOKEN_SECRET=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -- uvx --from git+https://github.com/bigbatmanorg/pve-mcp@v0.1.0 pve-mcp

Or add this to ~/.codex/config.toml:

[mcp_servers.proxmox]
command = "uvx"
args = ["--from", "git+https://github.com/bigbatmanorg/pve-mcp@v0.1.0", "pve-mcp"]
env = { PVE_HOST = "pve.example.lan", PVE_TOKEN_ID = "root@pam!mcp", PVE_TOKEN_SECRET = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" }

Add this to ~/.gemini/settings.json (or to .gemini/settings.json in a project):

{
  "mcpServers": {
    "proxmox": {
      "command": "uvx",
      "args": [
        "--from",
        "git+https://github.com/bigbatmanorg/pve-mcp@v0.1.0",
        "pve-mcp"
      ],
      "env": {
        "PVE_HOST": "pve.example.lan",
        "PVE_TOKEN_ID": "root@pam!mcp",
        "PVE_TOKEN_SECRET": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
      }
    }
  }
}

Deep Agents CLI: add this to ~/.deepagents/.mcp.json (all projects) or to .mcp.json in a project. ${VAR} values are read from your shell or ~/.deepagents/.env, so secrets stay out of the file.

{
  "mcpServers": {
    "proxmox": {
      "command": "uvx",
      "args": [
        "--from",
        "git+https://github.com/bigbatmanorg/pve-mcp@v0.1.0",
        "pve-mcp"
      ],
      "env": {
        "PVE_HOST": "${PVE_HOST}",
        "PVE_TOKEN_ID": "${PVE_TOKEN_ID}",
        "PVE_TOKEN_SECRET": "${PVE_TOKEN_SECRET}"
      }
    }
  }
}

Python library (pip install deepagents langchain-mcp-adapters):

import asyncio
import os

from deepagents import create_deep_agent
from langchain_mcp_adapters.client import MultiServerMCPClient

client = MultiServerMCPClient({
    "proxmox": {
        "transport": "stdio",
        "command": "uvx",
        "args": ["--from", "git+https://github.com/bigbatmanorg/pve-mcp@v0.1.0", "pve-mcp"],
        "env": {
            "PVE_HOST": os.environ["PVE_HOST"],
            "PVE_TOKEN_ID": os.environ["PVE_TOKEN_ID"],
            "PVE_TOKEN_SECRET": os.environ["PVE_TOKEN_SECRET"],
        },
    }
})


async def main():
    tools = await client.get_tools()
    agent = create_deep_agent(model="anthropic:claude-sonnet-5-5", tools=tools)
    result = await agent.ainvoke({"messages": [{"role": "user", "content": "What can you do?"}]})
    print(result["messages"][-1].content)


asyncio.run(main())

Save this as agent.yaml, then run docker agent run agent.yaml:

agents:
  root:
    model: anthropic/claude-sonnet-5-5
    description: Assistant with the proxmox MCP tools
    instruction: Use the proxmox tools to answer the user's requests.
    toolsets:
      - type: mcp
        command: uvx
        args:
          - "--from"
          - "git+https://github.com/bigbatmanorg/pve-mcp@v0.1.0"
          - "pve-mcp"
        env:
          PVE_HOST: "pve.example.lan"
          PVE_TOKEN_ID: "root@pam!mcp"
          PVE_TOKEN_SECRET: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

Add this to ~/.hermes/config.yaml, then run /reload-mcp in a chat:

mcp_servers:
  proxmox:
    command: uvx
    args: ["--from", "git+https://github.com/bigbatmanorg/pve-mcp@v0.1.0", "pve-mcp"]
    env:
      PVE_HOST: "pve.example.lan"
      PVE_TOKEN_ID: "root@pam!mcp"
      PVE_TOKEN_SECRET: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

MCP Servers → Configure (cline_mcp_settings.json / mcp_settings.json):

{
  "mcpServers": {
    "proxmox": {
      "command": "uvx",
      "args": [
        "--from",
        "git+https://github.com/bigbatmanorg/pve-mcp@v0.1.0",
        "pve-mcp"
      ],
      "env": {
        "PVE_HOST": "pve.example.lan",
        "PVE_TOKEN_ID": "root@pam!mcp",
        "PVE_TOKEN_SECRET": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
      }
    }
  }
}

Add this to settings.json:

{
  "context_servers": {
    "proxmox": {
      "command": "uvx",
      "args": [
        "--from",
        "git+https://github.com/bigbatmanorg/pve-mcp@v0.1.0",
        "pve-mcp"
      ],
      "env": {
        "PVE_HOST": "pve.example.lan",
        "PVE_TOKEN_ID": "root@pam!mcp",
        "PVE_TOKEN_SECRET": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
      }
    }
  }
}

Add this to opencode.json (project) or ~/.config/opencode/opencode.json:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "proxmox": {
      "type": "local",
      "command": [
        "uvx",
        "--from",
        "git+https://github.com/bigbatmanorg/pve-mcp@v0.1.0",
        "pve-mcp"
      ],
      "environment": {
        "PVE_HOST": "pve.example.lan",
        "PVE_TOKEN_ID": "root@pam!mcp",
        "PVE_TOKEN_SECRET": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
      },
      "enabled": true
    }
  }
}

Run goose configure → Add Extension → Command-line Extension, with the command uvx --from git+https://github.com/bigbatmanorg/pve-mcp@v0.1.0 pve-mcp. Or add this to ~/.config/goose/config.yaml:

extensions:
  proxmox:
    type: stdio
    enabled: true
    cmd: uvx
    args: ["--from", "git+https://github.com/bigbatmanorg/pve-mcp@v0.1.0", "pve-mcp"]
    envs:
      PVE_HOST: "pve.example.lan"
      PVE_TOKEN_ID: "root@pam!mcp"
      PVE_TOKEN_SECRET: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

Most clients take the standard mcpServers JSON shown for Claude Desktop. Some use servers instead.

To install once instead of fetching on each start:

uv tool install git+https://github.com/bigbatmanorg/pve-mcp@v0.1.0

then use "command": "pve-mcp", "args": [].

From a checkout: "command": "uv", "args": ["run", "--directory", "/abs/path/pve-mcp", "pve-mcp"].

Related MCP server: ProxmoxMCP-Plus

Safety

Setting

Effect

default

read-only: only GET calls are sent

PVE_ALLOW_WRITES=true

POST/PUT allowed

confirm=true (per call)

also required for DELETE, stop/reset, rollback, node power

PVE_SSH_ENABLED=true

enables pve_node_ssh (also needs writes)

Task-returning calls wait for the task and fail with its log if it fails.

Configuration

PVE_HOST, PVE_PORT (8006), PVE_TOKEN_ID (user@realm!name), PVE_TOKEN_SECRET, PVE_VERIFY_SSL (false, true, or a CA bundle path such as a copy of /etc/pve/pve-root-ca.pem), PVE_TIMEOUT, PVE_SSH_USER, PVE_SSH_KEY, PVE_SSH_PORT, PVE_NODE_HOSTS (node:addr,...).

Tests

uv run pytest                                   # unit tests (mocked HTTP)
PVE_LAB=1 uv run pytest -m lab   # lifecycle tests on the lab only

Lab tests create and delete real objects; run them only against a disposable instance (PVE_LAB=1 with LABPVE_HOST, LABPVE_TOKEN_ID, LABPVE_TOKEN_SECRET).

License

AGPL-3.0-or-later. The bundled schema (src/pve_mcp/data/pve-api.json.gz) is generated from Proxmox VE's pve-docs API viewer data, which is AGPL-3.0 licensed, Copyright Proxmox Server Solutions GmbH.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables comprehensive management of Proxmox virtualization environments, including VM and container lifecycle, snapshots, backups, monitoring, and OpenAPI integration.
    12
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables management of Proxmox VE environments via the Proxmox API, including node listing, guest management, and VM/LXC creation with Cloud-Init.
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    A PROXMOX implementation containing 152 tools covering QEMU VMs, LXC, unified guest power, storage admin, cluster/tasks, snapshots, backups (incl. scheduled jobs), migration, HA, firewall (incl. IPSet CIDRs), access control, replication, SDN (read), ACME (read), pools, and console tickets.
    1
    MIT