Skip to main content
Glama
proxmox-mcp

proxmox-mcp

proxmox-mcp

A Docker-first Model Context Protocol (MCP) server for Proxmox VE.

It exposes safe, structured tools for read-only cluster inspection, VM/container lifecycle operations, snapshots, migration, provisioning helpers, and a guarded generic Proxmox API escape hatch.

Status

Alpha. Built with API-token auth and explicit confirmation gates for mutating operations.

Related MCP server: Proxmox MCP Server

Run with Docker Compose

Docker Compose is the primary supported way to run this MCP server.

cp .env.example .env
# edit .env with your Proxmox URL and token
docker compose up -d --build

By default the MCP server listens on:

http://127.0.0.1:8000/mcp

Default MCP transport settings in .env.example:

MCP_TRANSPORT=streamable-http
MCP_PORT=8000
MCP_PATH=/mcp

Inside Docker, the app binds to 0.0.0.0 in the container, but Compose publishes it only on host loopback by default:

ports:
  - "127.0.0.1:8000:8000"

Do not publish this unauthenticated MCP endpoint on all interfaces unless you put real network controls in front of it.

Supported MCP transports:

  • streamable-http — default for Docker and most remote deployments

  • sse — legacy HTTP/SSE MCP transport

  • stdio — local subprocess mode

For HTTPS exposure of the MCP endpoint, put this service behind a reverse proxy such as Caddy, Traefik, or nginx and terminate TLS there. Keep the container on plain HTTP internally unless you have a specific reason to do otherwise.

Proxmox protocol configuration

Prefer HTTPS for the Proxmox API:

PVE_BASE_URL=https://proxmox.lan:8006
PVE_VERIFY_SSL=false # only for self-signed homelab certs

If you intentionally need plain HTTP for Proxmox, make it explicit:

PVE_BASE_URL=http://proxmox.lan:8006
PVE_ALLOW_INSECURE_HTTP=true

Plain HTTP sends credentials over the network. That is usually a bad idea outside a tightly controlled lab network.

Authentication

Prefer a Proxmox API token:

PVE_API_TOKEN_ID=user@pam!token-name
PVE_API_TOKEN_SECRET=replace-me

Password-ticket auth is also supported, but API tokens are cleaner for MCP:

PVE_USERNAME=user@pam
PVE_PASSWORD=replace-me

Hermes config for Docker HTTP MCP

mcp_servers:
  proxmox:
    url: "http://127.0.0.1:8000/mcp"
    timeout: 120
    connect_timeout: 30

If deployed on a remote host behind TLS:

mcp_servers:
  proxmox:
    url: "https://proxmox-mcp.example.internal/mcp"
    timeout: 120
    connect_timeout: 30

Run without Docker

Local stdio mode remains available for development:

MCP_TRANSPORT=stdio uvx proxmox-mcp
# or from a checkout:
MCP_TRANSPORT=stdio uv run proxmox-mcp

Local HTTP mode without Docker:

MCP_TRANSPORT=streamable-http MCP_HOST=127.0.0.1 MCP_PORT=8000 MCP_PATH=/mcp uv run proxmox-mcp

Safety model

  • GET requests are allowed by default.

  • POST, PUT, and DELETE require confirm=true.

  • High-level lifecycle/provisioning tools also require confirm=true.

  • Secrets are never intentionally returned.

  • Generic API paths reject full URLs, query strings, fragments, traversal, encoded traversal, and encoded slash tricks.

  • Path segments are validated and encoded before being sent to Proxmox.

Tool coverage

Phase 1: Read-only

  • pve_get_version

  • pve_get_cluster_status

  • pve_list_nodes

  • pve_list_resources

  • pve_list_vms

  • pve_get_vm_status

  • pve_get_vm_config

  • pve_list_storage

  • pve_list_backups

  • pve_get_task_status

  • pve_get_node_metrics

Phase 2: Safe actions

  • pve_start_vm

  • pve_shutdown_vm

  • pve_stop_vm

  • pve_reboot_vm

  • pve_suspend_vm

  • pve_resume_vm

  • pve_create_snapshot

  • pve_delete_snapshot

  • pve_rollback_snapshot

  • pve_migrate_vm

Phase 3: Admin/provisioning + escape hatch

  • pve_clone_vm

  • pve_create_lxc

  • pve_create_qemu_vm

  • pve_delete_vm

  • pve_resize_disk

  • pve_set_vm_config

  • pve_api_request

Development

uv sync --extra dev
uv run pytest
uv run ruff check .

Available Tools

28 tools
pve_api_requestC

Call any Proxmox API path. GET is allowed; POST/PUT/DELETE require confirm=true.

Inputs: path (required), method (required), params, confirm. Returns: object

pve_clone_vmC

Clone a QEMU VM. Requires confirm=true.

Inputs: node (required), newid (required), source_vmid (required), full, +4 more. Returns: object

pve_create_lxcC

Create an LXC container. Requires confirm=true.

Inputs: node (required), vmid (required), storage (required), ostemplate (required), +8 more. Returns: object

pve_create_qemu_vmC

Create a QEMU VM. Requires confirm=true.

Inputs: node (required), vmid (required), ide2, name, +7 more. Returns: object

pve_create_snapshotB

Create a VM/container snapshot. Requires confirm=true.

Inputs: node (required), vmid (required), snapname (required), confirm, +3 more. Returns: object

pve_delete_snapshotA

Delete a VM/container snapshot. Requires confirm=true.

Inputs: node (required), vmid (required), snapname (required), confirm, +1 more. Returns: object

pve_delete_vmC

Delete a VM/container. Requires confirm=true.

Inputs: node (required), vmid (required), purge, confirm, +2 more. Returns: object

pve_get_cluster_statusA

Return Proxmox cluster status.

Inputs: no named parameters. Returns: object

pve_get_node_metricsC

Get node status and metrics.

Inputs: node (required). Returns: object

pve_get_task_statusC

Get task status by UPID.

Inputs: node (required), upid (required). Returns: object

pve_get_versionA

Return Proxmox VE version information.

Inputs: no named parameters. Returns: object

pve_get_vm_configA

Get config for a QEMU VM or LXC container.

Inputs: node (required), vmid (required), vm_type. Returns: object

pve_get_vm_statusB

Get current status for a QEMU VM or LXC container.

Inputs: node (required), vmid (required), vm_type. Returns: object

pve_list_backupsB

List backup content for a node storage.

Inputs: node (required), storage (required). Returns: object

pve_list_nodesA

List Proxmox nodes.

Inputs: no named parameters. Returns: object

pve_list_resourcesB

List cluster resources, optionally filtered by type such as vm, storage, node.

Inputs: resource_type. Returns: object

pve_list_storageA

List storage globally or for a node.

Inputs: node. Returns: object

pve_list_vmsA

List QEMU VMs and LXC containers from cluster resources.

Inputs: no named parameters. Returns: object

pve_migrate_vmB

Migrate a VM/container to another node. Requires confirm=true.

Inputs: node (required), vmid (required), target (required), online, +4 more. Returns: object

pve_reboot_vmA

Reboot a VM/container. Requires confirm=true.

Inputs: node (required), vmid (required), confirm, vm_type. Returns: object

pve_resize_diskC

Resize a QEMU VM disk. Requires confirm=true.

Inputs: disk (required), node (required), size (required), vmid (required), +1 more. Returns: object

pve_resume_vmB

Resume a VM/container. Requires confirm=true.

Inputs: node (required), vmid (required), confirm, vm_type. Returns: object

pve_rollback_snapshotC

Rollback to a snapshot. Requires confirm=true.

Inputs: node (required), vmid (required), snapname (required), confirm, +1 more. Returns: object

pve_set_vm_configC

Update VM/container config. Requires confirm=true.

Inputs: node (required), vmid (required), config (required), confirm, +1 more. Returns: object

pve_shutdown_vmB

Gracefully shut down a VM/container. Requires confirm=true.

Inputs: node (required), vmid (required), confirm, timeout, +2 more. Returns: object

pve_start_vmC

Start a VM/container. Requires confirm=true.

Inputs: node (required), vmid (required), confirm, vm_type. Returns: object

pve_stop_vmA

Hard stop a VM/container. Requires confirm=true.

Inputs: node (required), vmid (required), confirm, vm_type. Returns: object

pve_suspend_vmC

Suspend a VM/container. Requires confirm=true.

Inputs: node (required), vmid (required), confirm, vm_type. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.1/5.0

    Scored across 28 tools

    Disambiguation4/5

    Most tools target a distinct resource/action combination, and lifecycle verbs like start, shutdown, stop, and reboot are clear. The main ambiguity comes from the overlapping read-only listing tools (list_resources, list_vms, list_nodes, list_storage), though the descriptions help differentiate them. pve_api_request is a deliberate escape hatch rather than a source of confusion.

    Naming Consistency5/5

    All tools follow a consistent pve_verb_noun snake_case pattern. Verbs are predictable: list/get for reads, create/delete/set for mutations, and explicit lifecycle verbs for VM/container actions. There are no mixed naming conventions or vague generic names.

    Tool Count2/5

    28 tools exceeds the 25+ threshold and feels heavy for a single server. Several listing and config tools could be consolidated, and the generic pve_api_request already provides broad fallback coverage. The domain is broad but the surface is larger than necessary.

    Completeness4/5

    Core VM/container lifecycle, snapshot management, migration, cloning, creation, deletion, config updates, and disk resize are covered. Notable gaps like LXC clone/resize and advanced storage/network management are not directly exposed, but pve_api_request provides a workaround. The surface has no critical dead ends.

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      B
      maintenance
      An open-source MCP server for managing Proxmox environments, including nodes, virtual machines, and containers. It enables users to perform inventory checks, status monitoring, and control operations directly through MCP-compatible tools.
      102 npm
      2
      MIT
    • A
      license
      B
      quality
      C
      maintenance
      An MCP server that exposes Proxmox VE node/cluster as tools for MCP clients, enabling management of VMs and containers including power control, resource reconfiguration, snapshots, and backups.
      20
      MIT