list_targets
List configured Proxmox targets without exposing credentials. A target name is required for other tools when multiple targets are configured.
approval_token
io.github.RekklesNA由 GitHub 账号 RekklesNA 发布v0.6.9更新于 Nov 4, 2026
Proxmox VE MCP server for VMs, LXCs, snapshots, backups, storage, and cluster operations.
让助手查看并操作 Proxmox VE 集群的 MCP 服务器,涵盖节点、存储、虚拟机、LXC 容器、快照、备份与长时间任务。
Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。
参照 仓库 中的启动说明。
Operate Proxmox VE from MCP clients, AI agents, and OpenAPI tooling through one security-conscious control plane for VMs, LXCs, snapshots, backups, ISOs, container commands, and persistent long-running jobs.
[PyPI] [GitHub Release] [CI] [GHCR] [License]
Quick Start | Client Install | Demo | Tools | Safety | Scenarios | Docs | Wiki
MCP and OpenAPI are alternative entry points into the same workflows and may run in separate processes. Solid arrows show requests and execution; dashed arrows show persisted job and audit state. Approval gates, SSH execution and MCP HTTP OAuth depend on configuration. Select the diagram to view it at full size.
ProxmoxMCP-Plus sits between AI clients and Proxmox VE so operators do not have to stitch together raw API calls, one-off shell scripts, and custom job polling for every workflow.
It exposes the same operational surface in two ways:
MCP for Claude Desktop, Cursor, VS Code, Open WebUI, Codex, and other MCP-capable agentsOpenAPI for HTTP automation, dashboards, internal tools, and no-code workflowsWhat you get:
Create a Proxmox API token with only the permissions your workflows need. Then create the local config file:
Then edit proxmox-config/config.json with your environment. At minimum, it needs:
proxmox.hostproxmox.portauth.userauth.token_nameauth.token_valueAdd an ssh section as well if you want container command execution.
Add a jobs section if you want job state persisted somewhere other than the default local SQLite file.
For real live verification, use a separate proxmox-config/config.live.json created from proxmox-config/config.live.example.json.
Do not point live e2e at a placeholder or local-only config.json unless you intentionally run a local API tunnel there.
Optional job persistence config:
Optional tool exposure filtering can reduce the schemas sent to MCP clients. It is
disabled by default, so existing configurations continue to expose every available
tool. Configure exactly one mode under mcp:
Alternatively, use tool_denylist, or the comma-separated environment variables
MCP_TOOL_ALLOWLIST and MCP_TOOL_DENYLIST. Do not configure both modes. Environment
selection replaces the file-level filtering mode. An empty allowlist exposes no tools;
an empty denylist hides none. Exact lowercase tool names are required, and unknown names
fail startup so a typo cannot silently widen access. Restart or reconnect the MCP server
after changing the filter.
Docker examples publish host ports on 127.0.0.1 by default; Compose modes are opt-in. Set
only the selected mode's key: MCP_API_KEY for native HTTP or PROXMOX_API_KEY
for OpenAPI. See Compose deployment and upgrade notes
for reverse proxies, tunnels, explicit LAN bindings and container recreation.
Or install it first:
Use this path when the MCP client launches a local stdio server.
Code Mode is disabled by default to preserve the legacy full tool catalog. Enable it
with mcp.code_mode: true in the config file or MCP_CODE_MODE=true. When enabled,
MCP exposes three tools instead: proxmox_code_search, proxmox_code_get_schema, and
proxmox_code_execute. Code execution runs in an isolated sandbox and reaches domain
tools through the existing validation, policy, and approval path. Discovery uses the
filtered runtime catalog, so it also works in installed wheels. For example:
The final expression is returned as data.result; tool results use MCP JSON content
blocks (and structured content where supplied). Use proxmox_code_get_schema for
arguments, including target and approval tokens. Scripts have no filesystem or
network access except registered tool calls. Limits: 64,000 source characters,
100 MB sandbox memory, 25 tool calls, 16 KB final JSON, and two concurrent executions.
Execution has a 30-second budget; cancelling or failing a script does not roll back
tool side effects. Do not automatically retry a failed mutation script.
Optional worker reuse: set mcp.code_mode_pool_reuse: true or
MCP_CODE_MODE_POOL_REUSE=true. The default remains one fresh worker per execution.
Reuse keeps up to two workers for the server lifetime, recycles each after 100
checkouts, and starts a new sandbox session per request. Globals, approvals, output
collectors and call limits are not shared between requests. HTTP clients share the
server-owned pool; disconnecting a client does not close it. Run
python scripts/benchmark_code_mode.py to measure local startup overhead; this is
a microbenchmark, not an estimate of Proxmox operation latency.
Use this path when a remote MCP client supports Streamable HTTP:
Point MCP clients at:
For remote clients, use the configured proxy/tunnel URL or explicitly widen the host binding as described in Docker deployment.
Send Authorization: Bearer <MCP_API_KEY> with every native MCP HTTP request.
The key is independent of Proxmox credentials. Native Streamable HTTP and SSE
require a key by default. For an endpoint protected by an external access-control
layer such as Tailscale ACLs, explicitly set MCP_ALLOW_UNAUTHENTICATED_HTTP=true
or mcp.allow_unauthenticated_http: true in JSON configuration. This allows
keyless startup and logs a warning; it does not configure or verify the external
access controls. A configured MCP_API_KEY is always enforced, even with opt-out.
This setting does not change OpenAPI authentication or DNS rebinding protection.
Native MCP HTTP can optionally expose an OAuth authorization-code flow with PKCE
while keeping MCP_API_KEY as the only human credential an operator has to
manage. OAuth protocol handling is delegated to the MCP Python SDK
(mcp>=1.30.0,<2), while ProxmoxMCP-Plus provides the API-key consent policy
and persistent OAuth state.
OAuth state is stored in PostgreSQL. This allows multiple MCP server instances or hosts, when deployed explicitly, to share registered clients, authorization codes, access tokens, refresh tokens, refresh-token replay protection, and login-rate-limit state without relying on a local filesystem.
The client starts at the SDK /authorize endpoint. After the SDK validates the
client, redirect URI, scope, PKCE request, and resource, the browser is redirected
to /oauth/consent on the same MCP origin. The user reviews the client name,
redirect origin, and requested scopes, then enters MCP_API_KEY. The API key is
never placed in a URL and is never returned to the OAuth client.
Required OAuth settings:
Example server:
Then connect the OAuth-capable client to:
OAuth mode exposes these endpoints on the same public origin:
/.well-known/oauth-protected-resource/mcp - RFC 9728 protected-resource metadata/.well-known/oauth-authorization-server - SDK authorization-server metadata/register - SDK dynamic client registration (DCR)/authorize - SDK authorization endpoint/token - SDK authorization-code/refresh-token exchange/oauth/consent - ProxmoxMCP-Plus API-key consent pageThe SDK requires PKCE S256 and protects the MCP resource with issued OAuth
access tokens. Browser consent transactions are short-lived, HMAC-signed, and
stateless. All durable OAuth state is stored in PostgreSQL.
Authorization-code consumption and refresh-token rotation use PostgreSQL transactions. A code or refresh token is deleted and its replacement tokens are inserted atomically, so concurrent server instances cannot successfully replay the same credential. Dynamic client registration capacity is also serialized with a PostgreSQL transaction-scoped advisory lock; inactive registrations are pruned before the configured limit is exceeded.
MCP_API_KEY is the sole source of truth for the browser consent credential.
This runtime does not persist the key or its verifier in PostgreSQL. The server process
validates consent directly against the value supplied in its environment. If the
service is explicitly deployed as multiple containers or instances, configure the
same secret for each instance. Stop all instances before changing the key, then
restart/recreate all of them with the new value before routing traffic again.
Existing OAuth clients and issued tokens are independent of the browser-gate key
and remain valid until they expire or are revoked.
Required when OAuth is enabled:
Optional OAuth environment variables:
To rotate the browser-gate credential, stop every MCP instance using this issuer,
update MCP_API_KEY in the deployment environment, and restart/recreate all
instances with the same new key. The environment is read when the provider starts;
editing a running container's environment does not reload its key. No OAuth
database metadata or key-version update is required. Pending consent transactions
created with the previous key will no longer validate after every instance has
restarted; already issued OAuth tokens remain governed by their normal lifetime
and revocation rules. A rolling key change leaves old instances accepting the old
key and causes consent requests routed between different-key instances to fail.
There is no database guard to detect or disable a stale instance. Changing the
browser-gate key does not revoke existing access tokens, refresh tokens, or
authorization codes; use explicit revocation for compromised OAuth credentials.
When upgrading from an OAuth build that used MCP_OAUTH_KEY_VERSION, startup
ignores the old variable and leaves proxmox_mcp_oauth_metadata untouched. Fresh
databases do not create that table. Registered clients and issued OAuth credentials
are preserved; no manual SQL migration is required. Keeping legacy metadata avoids
breaking old workers' queries and permits rollback with the same API key and
legacy key version. Back up the database before upgrading and stop all old
instances before rotating the key. After a key change, the legacy metadata still
describes the old key: rollback requires restoring the old configuration or
following the old version's rotation procedure, which invalidates OAuth state.
Only remove the legacy table manually once all old instances are retired and a
rollback is no longer needed; it can still contain the previous key's verifier.
The database role must be able to create and modify the
proxmox_mcp_oauth_* tables in its database. The tables contain OAuth client
metadata, including issued client secrets, plus authorization codes and active
tokens, so the PostgreSQL database and backups must be protected as credential
storage.
If several MCP instances use the same MCP_OAUTH_DATABASE_URL, OAuth state and
one-time-token enforcement are shared across them. Size the database capacity with
the total number of MCP processes in mind because the configured pool limits apply
per process.
If the server is behind a trusted reverse proxy and per-user login rate limiting
must use the original client address, set MCP_OAUTH_CLIENT_IP_HEADER to a header
that the proxy overwrites (for example CF-Connecting-IP). Leave it unset unless
the proxy prevents clients from spoofing that header.
When MCP_OAUTH_ENABLED=true, a raw Authorization: Bearer <MCP_API_KEY>
request to /mcp is intentionally rejected. The API key is accepted only by the
consent page; MCP requests must use an issued OAuth access token.
When serving MCP HTTP behind a reverse proxy, keep DNS rebinding protection enabled and allow only the hostnames you expect.
OpenAPI mode is the default Docker runtime and requires an API key:
Verify the OpenAPI surface:
For local unauthenticated development only, set PROXMOX_ALLOW_NO_AUTH=true.
The 8811 service is the OpenAPI/REST bridge. The 8000 service is the native MCP HTTP endpoint.
Use the one-click buttons when your client supports MCP install deeplinks, or copy the JSON config below.
[Install in VS Code] [Install in Cursor]
Recommended stdio config:
Use a local config file if you prefer not to keep credentials in the client config:
Client-specific examples for Claude Desktop, Cursor, VS Code, Codex, OpenCode, Open WebUI, Streamable HTTP, and OpenAPI are in the Client Setup Guide and Integrations Guide.
This demo is a direct terminal recording of qwen/qwen3.6-plus driving a live MCP session in English against a local Proxmox lab. It shows natural-language control flowing through MCP tools to create and start an LXC, execute a container command, and confirm the authenticated HTTP /health surface.
Start with read-only discovery, then move to mutating tools only after the target node, storage, VMID, and permissions are clear.
For the full tool map, see the Tool Selection Guide and API & Tool Reference.
ProxmoxMCP-Plus is an access layer, not a replacement for Proxmox RBAC, network controls, or client-side MCP approval prompts.
The project gives operators several control points:
PROXMOX_API_KEY protects the OpenAPI bridge by default.MCP_API_KEY protects native Streamable HTTP and SSE with Bearer authentication; it is required unless MCP_ALLOW_UNAUTHENTICATED_HTTP=true explicitly delegates access control.command_policy controls command execution and high-risk operations.approval_token can gate command execution and high-risk mutating actions.Read the Security Guide before exposing the server outside a trusted local environment.
ProxmoxMCP-Plus provides a unified control surface for the operational tasks most teams actually need in Proxmox VE. The same server can expose these workflows to MCP clients for LLM and AI-agent use cases, and to HTTP consumers through the OpenAPI bridge.
Supported workflow areas:
Validation and contract entry points in this repository:
python -m pytest -q (see Contributing for the full CI coverage gate)ruff check .mypy src --ignore-missing-importspython -m pip_audit -r requirements/runtime.lock --require-hashes --disable-pip --stricttests/integration/test_real_contract.pytests/scripts/run_real_e2e.pytests/scripts/run_real_e2e.py now prefers proxmox-config/config.live.json or PROXMOX_MCP_E2E_CONFIG.
This avoids accidentally running live checks against a machine-specific default config.json.
Many Proxmox mutations are asynchronous. ProxmoxMCP-Plus now wraps those tasks in a persistent job layer so MCP and OpenAPI clients can track them through a stable Job ID.
Long-running tools such as VM create/start/stop, container create/start/stop, snapshot changes, backup/restore, and ISO download/delete now return both:
task_id: the raw Proxmox UPIDjob_id: the stable server-side job recordThe job record stores:
UPIDsBy default the job store persists to proxmox-jobs.sqlite3, so restart does not lose in-flight or completed job metadata.
Audit events are appended to a separate SQLite table. Existing history is migrated
on startup and the API's audit_log format stays unchanged. Retention is unlimited
by default; set jobs.audit_retention_days to a positive number in JSON config to
prune expired events at startup and when each job is updated. This never deletes
the job itself. Stop all workers sharing the database and back it up before this
upgrade. Do not run old and new versions against the same database; restore the
pre-upgrade backup if downgrading and retaining audit history is required.
A cancellation request is not completion. Poll until the task is failed/cancelled
before calling retry_job; pending cancellation cannot be retried.
list_jobsget_jobpoll_jobcancel_jobretry_jobWhen the OpenAPI proxy is enabled and a local JobStore is available, these routes are exposed directly:
Common error codes:
404: unknown job_id409: the job exists but that operation is not valid now503: the OpenAPI proxy was started without a local JobStoretests/scripts/run_real_e2e.py now prefers proxmox-config/config.live.json or PROXMOX_MCP_E2E_CONFIG.
This avoids accidentally running live checks against a machine-specific default config.json.
Ready-to-copy examples live in docs/examples/:
These are written for both human operators and LLM-driven usage.
The README is intentionally optimized for fast GitHub comprehension. Longer operational docs live in docs/wiki/ and can also be published to the GitHub Wiki.
Published wiki:
src/proxmox_mcp/: MCP server, config loading, security, OpenAPI bridgemain.py: MCP entrypoint for local and client-driven usagedocker-compose.yml: HTTP/OpenAPI runtimerequirements/: auxiliary dependency sources and runtime install listsscripts/: helper startup scripts for local workflowstests/scripts/run_real_e2e.py: live Proxmox and Docker/OpenAPI pathtests/: unit and integration coveragedocs/examples/: scenario-driven prompts and HTTP examplesdocs/wiki/: longer-form operator, integration, and reference docsSee Contributing for environment setup, test prerequisites, and pull request guidance.
CI also runs PostgreSQL-backed tests and enforces full runtime statement coverage and full branch coverage for critical modules. See Contributing for the exact coverage commands and Dependency updates for the reviewed runtime lock workflow.
Use list_isos to find an existing ISO volume (or download_iso to obtain one).
create_vm accepts iso_volume="local:iso/debian.iso", mounts it on ide3 by
default and boots CD-ROM before disk. update_vm_config can mount or change that
ISO, eject with iso_volume="none", set boot_order="scsi0;ide3", or change
network_bridge on net0 while retaining MAC/VLAN/firewall settings. Choose a
free cdrom_device; existing data disks and cloud-init drives are never replaced.
Media and bridge edits read current configuration and therefore need VM.Audit
as well as the relevant configuration privileges. Existing sizing/cloud-init-only
updates still do not require a preliminary read.
LXC uses OS templates, not installer ISOs. create_container retains DHCP by default
and now accepts network_bridge, ip="192.168.1.50/24", gw="192.168.1.1", ip6
and gw6. update_container_network edits those fields on an existing interface
(default net0, selectable through net31) and preserves all unspecified options.
Use an empty gateway string to remove it; changing to DHCP/manual removes the old
gateway for that address family. Network changes can interrupt guest connectivity.
Both edit tools follow named-target, read-only and high-risk approval policies.
Add update_container_network to custom high-risk lists and desired tool allowlists.
See v0.5.19 release notes for upgrade details.
来源:README.md,提交 ab1fcf7
List configured Proxmox targets without exposing credentials. A target name is required for other tools when multiple targets are configured.
approval_tokenList all nodes in the Proxmox cluster with their status, CPU, memory, and role information. Example: {"node": "pve1", "status": "online", "cpu_usage": 0.15, "memory": {"used": "8GB", "total": "32GB"}}
targetapproval_tokenGet detailed status information for a specific Proxmox node. Parameters: node* - Name/ID of node to query (e.g. 'pve1') Example: {"cpu": {"usage": 0.15}, "memory": {"used": "8GB", "total": "32GB"}}
node必填targetapproval_tokenRead node epoch time, local time and timezone to diagnose PVE ticket clock skew. Read-only; requires node and accepts an optional configured target.
node必填targetapproval_tokenList available network bridges (Linux, OVS and permitted SDN VNets) on a node for VM/LXC networking. Returns the Proxmox network records as JSON.
node必填targetapproval_tokenRead CPU, I/O wait, memory, storage and latest observed RRD disk/network metrics for one node. Missing optional metrics produce partial results. Does not execute shell commands or list processes.
node必填targetapproval_tokenList storage pools across the cluster with their usage and configuration. Example: {"storage": "local-lvm", "type": "lvm", "used": "500GB", "total": "1TB"}
targetapproval_tokenRead storage capacity and active/rootdir status on one specified node. Optionally filter by storage ID. Available bytes do not guarantee migration capacity, especially on thin-provisioned storage.
node必填targetstorageapproval_tokenGet overall Proxmox cluster health and configuration status. Example: {"name": "proxmox", "quorum": "ok", "nodes": 3, "ha_status": "active"}
targetapproval_tokenRead public cluster join metadata and certificate fingerprints. Only documented public fields are returned. Authentication credentials and arbitrary extensions are omitted. Proxmox errors are reported.
targetapproval_tokenReconcile an interrupted retry after verifying its remote task or confirming that no task was submitted. Never submits a new operation.
upidjob_id必填targetapproval_tokenconfirmed_not_submittedList tracked long-running jobs created by MCP tools. Parameters: status - Filter by job status (optional) tool_name - Filter by originating tool (optional) limit - Maximum rows to return (default: 100)
limitstatustargettool_nameapproval_tokenGet the current state of a tracked job by job_id. Parameters: job_id* - Stable job identifier returned by long-running tools refresh - Poll Proxmox before returning the job state (default: false)
job_id必填targetrefreshapproval_tokenPoll the backing Proxmox task for a tracked job and refresh status/progress.
forcejob_id必填targetinclude_auditapproval_tokenBest-effort cancel for a tracked long-running job. This uses the stored Proxmox task UPID when cancellation is supported.
job_id必填targetapproval_tokenRetry a tracked long-running job using its stored retry recipe. The same job_id is preserved and its attempt counter is incremented.
job_id必填targetapproval_tokenList all virtual machines across the cluster with their status and resource usage. Example: {"vmid": "100", "name": "ubuntu", "status": "running", "cpu": 2, "memory": 4096}
targetapproval_tokenRead-only QEMU offline migration assessment using native Proxmox migration preconditions plus VM inventory, storage capacity, bridges and HA checks. Missing evidence blocks readiness. Requires VM.Migrate permission even for the native read. Backup restorability, workload drain and CPU compatibility need external verification. Does not move or stop a VM or reserve capacity.
node必填vmid必填targetdestination必填approval_tokenHigh-risk OFFLINE QEMU migration with local disks after read-only preflight and explicit confirmations of backup, workload drain, CPU compatibility and migration. The VM must already be stopped. Returns a submitted UPID/job ID, never completion. Never automatically retry uncertain submissions.
node必填vmid必填targetdestination必填approval_tokenconfirm_migrationconfirm_backup_verifiedconfirm_workload_drainedconfirm_cpu_compatibilityConfigure VM ttyS0 serial socket and serial VGA display after observing a stopped VM. Requires explicit confirmation and follows target high-risk policy. Preserves other serial devices and uses the config digest against concurrent config changes. The guest must configure serial login separately. SUBMISSION_UNCERTAIN requires inspection before any retry.
node必填vmid必填targetapproval_tokenconfirm_display_changeImport an existing qcow2/raw/vmdk image from Proxmox import-enabled storage into an unused VM SCSI slot via the asynchronous QEMU API. Requires an observed stopped VM, explicit confirmation and configured high-risk approval. Does not fetch URLs, overwrite disks or change boot order. Returns a submitted task, never completion. Inspect SUBMISSION_UNCERTAIN outcomes before any retry.
node必填vmid必填targetdisk_devicesource_volume必填approval_tokenconfirm_importdestination_storage必填Get the full configuration of a QEMU virtual machine. Returns hardware configuration including CPU, memory, disk, network, BIOS type, boot order, and more. This is equivalent to get_container_config but for QEMU VMs. Parameters: node* - Host node name (e.g. 'pve') vmid* - VM ID number (e.g. '100') Example: {"vmid": "100", "name": "ubuntu", "cores": 2, "memory": 4096, "scsi0": "local-lvm:vm-100-disk-0,size=20G"}
node必填vmid必填targetapproval_tokenSet/replace the description (Notes field in the UI) of a QEMU VM. Uses PUT /nodes/{node}/qemu/{vmid}/config. Pass an empty string to clear the notes. Parameters: node* - Host node name (e.g. 'pve') vmid* - VM ID number (e.g. '100') description* - New notes text (replaces any existing notes) Example: set_vm_description node='pve' vmid='100' description='Decommissioned - see #123'
node必填vmid必填targetdescription必填approval_tokenGet the next free VM/container ID in the cluster. Uses GET /cluster/nextid. Call it right before clone_vm or create_vm so the target ID is one Proxmox itself considers unused. Example: {"vmid": "105"}
targetapproval_tokenUpdate sizing, cloud-init, ISO media, boot order and net0 bridge of an existing QEMU VM. iso_volume accepts a storage volume ID or none to eject. cdrom_device defaults to ide3; existing disks and cloud-init drives cannot be overwritten. boot_order uses semicolon-separated device names. network_bridge preserves the other net0 options. Uses PUT /nodes/{node}/qemu/{vmid}/config with only the supplied fields. This is the step between clone_vm and start_vm that makes a fresh clone reachable: inject SSH keys, set the cloud-init user, pick a static IP, resize memory. Parameters: node* - Host node name (e.g. 'pve') vmid* - VM ID number (e.g. '105') memory - RAM in MiB (e.g. 4096) cores - CPU cores per socket sockets - CPU sockets name - New VM name (DNS label) sshkeys - OpenSSH public keys, one per line (cloud-init; percent-encoded for you) ciuser - cloud-init user name (e.g. 'ubuntu') ipconfig0 - cloud-init IP for net0, e.g. 'ip=dhcp' or 'ip=10.0.0.5/24,gw=10.0.0.1' nameserver - cloud-init DNS server(s) searchdomain - cloud-init DNS search domain tags - Proxmox tags, semicolon-separated approval_token - Approval token when required by the target's high-risk policy This tool is classified as high risk, including SSH key changes, and follows the selected target's command_policy.high_risk_* settings. Cloud-init fields take effect at the guest's next boot; sizing changes on a running VM stay pending until it restarts. Example: update_vm_config node='pve' vmid='105' memory=4096 ciuser='hola' sshkeys='ssh-ed25519 AAAA... ci@host'
namenode必填tagsvmid必填coresciusermemorytargetsocketssshkeysipconfig0boot_order另有 6 个Get a running VM's network interfaces and IP addresses via the QEMU guest agent. Uses GET /nodes/{node}/qemu/{vmid}/agent/network-get-interfaces. The VM must be running with qemu-guest-agent active. Loopback is skipped; primary_ip is the first non-loopback IPv4 address. Parameters: node* - Host node name (e.g. 'pve') vmid* - VM ID number (e.g. '105') Example: {"vmid": "105", "primary_ip": "10.0.0.57", "interfaces": [{"name": "eth0", "mac": "bc:24:11:..", "ipv4": ["10.0.0.57"], "ipv6": ["fe80::..."]}]}
node必填vmid必填targetapproval_tokenCreate a new virtual machine with specified configuration. Optionally mount an existing iso_volume (e.g. local:iso/debian.iso) at cdrom_device (default ide3). With an ISO, the default boot order is CD-ROM then disk; boot_order can specify semicolon-separated device names. Parameters: node* - Host node name (e.g. 'pve') vmid* - New VM ID number (e.g. '200', '300') name* - VM name (e.g. 'my-new-vm', 'web-server') cpus* - Number of CPU cores (e.g. 1, 2, 4) memory* - Memory size in MB (e.g. 2048 for 2GB, 4096 for 4GB) disk_size* - Disk size in GB (e.g. 10, 20, 50) storage - Storage name (optional, will auto-detect if not specified) ostype - OS type (optional, default: 'l26' for Linux) network_bridge - Network bridge name (optional, default: 'vmbr0') pool - Target Proxmox resource pool (optional) Examples: - Create VM with 1 CPU, 2GB RAM, 10GB disk: node='pve', vmid='200', name='test-vm', cpus=1, memory=2048, disk_size=10 - Create VM with 2 CPUs, 4GB RAM, 20GB disk: node='pve', vmid='201', name='web-server', cpus=2, memory=4096, disk_size=20
cpus必填name必填node必填poolvmid必填memory必填ostypetargetstoragedisk_size必填boot_orderiso_volume另有 3 个Clone an existing virtual machine. Parameters: node* - Source host node name that currently owns the VM (e.g. 'pve') source_vmid* - Existing source VM ID (e.g. '9000') target_vmid* - New VM ID for the clone (e.g. '201') name - New VM name (optional) target_node - Destination node for the clone (optional, defaults to source node) full - Full clone (true, default) or linked clone (false) storage - Target storage (optional) pool - Target resource pool (optional) snapname - Snapshot name to clone from (optional) Example: clone_vm node='pve' source_vmid='9000' target_vmid='201' name='web-201' full=true
fullnamenode必填pooltargetstoragesnapnamesource_vmid必填target_nodetarget_vmid必填approval_tokenExecute commands in a VM via QEMU guest agent. Parameters: node* - Host node name (e.g. 'pve1') vmid* - VM ID number (e.g. '100') command* - Shell command to run (e.g. 'uname -a') Example: {"success": true, "output": "Linux vm1 5.4.0", "exit_code": 0}
node必填vmid必填targetcommand必填guest_osapproval_tokenStart a virtual machine. Parameters: node* - Host node name (e.g. 'pve') vmid* - VM ID number (e.g. '101') Example: Power on VPN-Server with ID 101 on node pve
node必填vmid必填targetapproval_tokenStop a virtual machine (force stop). Parameters: node* - Host node name (e.g. 'pve') vmid* - VM ID number (e.g. '101') Example: Force stop VPN-Server with ID 101 on node pve
node必填vmid必填targetapproval_tokenShutdown a virtual machine gracefully. Parameters: node* - Host node name (e.g. 'pve') vmid* - VM ID number (e.g. '101') Example: Gracefully shutdown VPN-Server with ID 101 on node pve
node必填vmid必填targetapproval_tokenReset (restart) a virtual machine. Parameters: node* - Host node name (e.g. 'pve') vmid* - VM ID number (e.g. '101') Example: Reset VPN-Server with ID 101 on node pve
node必填vmid必填targetapproval_tokenDelete/remove a virtual machine completely. WARNING: This operation permanently deletes the VM and all its data! Parameters: node* - Host node name (e.g. 'pve') vmid* - VM ID number (e.g. '998') force - Force deletion even if VM is running (optional, default: false) purge - Also remove the VMID from HA resources and backup/replication jobs (optional, default: false). Required when the VM is an HA resource. This will permanently remove: - VM configuration - All virtual disks - All snapshots - Cannot be undone! Examples: - Delete test VM with ID 998 on node pve - Delete HA-managed VM 998 on node pve: purge=True
node必填vmid必填forcepurgetargetapproval_tokenList LXC containers across the cluster (or filter by node). Parameters: - node (optional): Node name to filter (e.g. 'pve1') - include_stats (bool, default false): Fetch per-container live CPU/memory stats - include_raw (bool, default false): Include raw Proxmox API payloads for debugging - format_style ('pretty'|'json', default 'pretty'): Pretty text or raw JSON list Notes: - Live stats from /nodes/{node}/lxc/{vmid}/status/current. - If maxmem is 0 (unlimited), memory limit falls back to /config.memory (MiB). - If live returns zeros, the most recent RRD sample is used as a fallback. - Fields provided: cores (CPU cores/cpulimit), memory (MiB limit), cpu_pct, mem_bytes, maxmem_bytes, mem_pct, unlimited_memory.
nodetargetpayloadinclude_rawformat_styleinclude_statsapproval_tokenStart one or more LXC containers. selector: '123' | 'pve1:123' | 'pve1/name' | 'name' | comma list Example: start_container selector='pve1:101,pve2/web'
targetselector必填format_styleapproval_tokenStop LXC containers. graceful=True uses shutdown; otherwise force stop. selector: same grammar as start_container timeout_seconds: 10 (default)
targetgracefulselector必填format_styleapproval_tokentimeout_secondsRestart LXC containers (reboot). selector: same grammar as start_container
targetselector必填format_styleapproval_tokentimeout_secondsUpdate resources for one or more LXC containers. selector: same grammar as start_container cores: New CPU core count (optional) memory: New memory limit in MiB (optional) swap: New swap limit in MiB (optional) disk_gb: Additional disk size in GiB to add (optional) disk: Disk identifier to resize (default 'rootfs')
diskswapcoresmemorytargetdisk_gbselector必填format_styleapproval_tokenCreate a new LXC container from an OS template (not an ISO). Choose network_bridge and optional ip (IPv4/CIDR, dhcp or manual), gw, ip6 (IPv6/CIDR, auto, dhcp or manual) and gw6. IPv4 defaults to DHCP. Use update_container_network to edit network settings after creation. Parameters: node* - Host node name (e.g. 'pve', 'pveZ3') vmid* - Container ID number (e.g. '200', '300') ostemplate* - OS template path (e.g. 'local:vztmpl/alpine-3.19-default_20240207_amd64.tar.xz') hostname - Container hostname (optional, defaults to 'ct-{vmid}') cores - Number of CPU cores (optional, default: 1) memory - Memory size in MiB (optional, default: 512) swap - Swap size in MiB (optional, default: 512) disk_size - Root disk size in GB (optional, default: 8) storage - Storage pool for rootfs (optional, auto-detects if not specified) password - Root password (optional) ssh_public_keys - SSH public keys for root user (optional) network_bridge - Network bridge name (optional, default: 'vmbr0') start_after_create - Start container after creation (optional, default: false) onboot - Start container automatically on host boot (optional, default: false) nesting - Enable LXC nesting (optional, sets features='nesting=1', default: false) unprivileged - Create unprivileged container (optional, default: true) pool - Target Proxmox resource pool (optional) Examples: - Create Alpine container: node='pveZ3', vmid='200', ostemplate='local:vztmpl/alpine-3.19-default_20240207_amd64.tar.xz' - Create with custom resources: node='pve', vmid='201', ostemplate='local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst', cores=2, memory=2048, disk_size=20
gwipgw6ip6node必填poolswapvmid必填coresmemoryonboottarget另有 11 个Update an existing LXC network interface: bridge, static IPv4/IPv6, DHCP and gateways. Preserves MAC, VLAN, firewall and other NIC settings. Use an empty gateway to remove it.
gwipgw6ip6node必填vmid必填targetinterfaceapproval_tokennetwork_bridgeDelete/remove an LXC container completely. WARNING: This operation permanently deletes the container and all its data! Parameters: selector* - Container selector: '123' | 'pve1:123' | 'pve1/name' | 'name' | comma list force - Force deletion even if container is running (optional, default: false) purge - Also remove the CTID from HA resources and backup/replication jobs (optional, default: false). Required when the container is an HA resource. This will permanently remove: - Container configuration - Root filesystem and all data - All snapshots - Cannot be undone! Examples: - Delete container 200: selector='200' - Delete by name: selector='my-container' - Force delete running container: selector='pve:201', force=True - Delete HA-managed container: selector='pve:202', purge=True
forcepurgetargetselector必填format_styleapproval_tokenSubmit an LXC migration after fresh preflight checks. Requires confirm_migration=True; restart=True also requires confirm_downtime=True. Follows the configured target's high-risk approval policy. Returns a submitted task UPID and optional job ID, never completion. Never automatically retries; SUBMISSION_UNCERTAIN requires inspecting Proxmox tasks and guest location before any retry.
node必填vmid必填targetrestartdestination必填approval_tokenconfirm_downtimeconfirm_migrationRead-only LXC migration assessment: checks nodes, rootfs storage and space, runtime, extra mounts/devices, HA and matching backups. Missing evidence blocks readiness. This advisory does not reserve capacity, test restoreability or migrate. Running guests require allow_downtime=True.
node必填vmid必填targetdestination必填allow_downtimeapproval_tokenGet the full configuration of an LXC container. Returns network interfaces, mounts, features, CPU/memory limits, startup options and more. Parameters: node* - Proxmox node name (e.g. 'pve') vmid* - Container ID (e.g. '101') Example: {"vmid": "101", "hostname": "valkey", "cores": 1, "memory": 1024, "net0": "name=eth0,..."}
node必填vmid必填targetapproval_tokenSet/replace the description (Notes field in the UI) of an LXC container. Uses PUT /nodes/{node}/lxc/{vmid}/config. Pass an empty string to clear the notes. Parameters: node* - Proxmox node name (e.g. 'pve') vmid* - Container ID (e.g. '101') description* - New notes text (replaces any existing notes) Example: set_container_description node='pve' vmid='101' description='GitLab Runner host (ct101-alpine)'
node必填vmid必填targetdescription必填approval_tokenGet the current IP address(es) of a running LXC container. Queries /nodes/{node}/lxc/{vmid}/interfaces - works with DHCP (no static IP needed). Parameters: node* - Proxmox node name (e.g. 'pve') vmid* - Container ID (e.g. '101') Returns: {"vmid": "101", "name": "valkey", "interfaces": [...], "primary_ip": "10.1.0.101"}
node必填vmid必填targetapproval_tokenList all snapshots for a VM or container. Parameters: node* - Host node name (e.g. 'pve') vmid* - VM or container ID (e.g. '100') vm_type - Type: 'qemu' for VMs, 'lxc' for containers (default: 'qemu') Example: list_snapshots node='pve' vmid='100' vm_type='qemu'
node必填vmid必填targetvm_typeapproval_tokenCreate a snapshot of a VM or container. Parameters: node* - Host node name vmid* - VM or container ID snapname* - Snapshot name (no spaces, e.g. 'before-update') description - Optional description vmstate - Include memory state (VMs only, default: false) vm_type - Type: 'qemu' or 'lxc' (default: 'qemu') Examples: - Create VM snapshot: node='pve', vmid='100', snapname='pre-upgrade' - Create with RAM state: node='pve', vmid='100', snapname='state1', vmstate=true
node必填vmid必填targetvm_typevmstatesnapname必填descriptionapproval_tokenDelete a snapshot. Parameters: node* - Host node name vmid* - VM or container ID snapname* - Snapshot name to delete vm_type - Type: 'qemu' or 'lxc' (default: 'qemu') Example: delete_snapshot node='pve' vmid='100' snapname='old-snapshot'
node必填vmid必填targetvm_typesnapname必填approval_tokenRollback VM/container to a previous snapshot. WARNING: This will stop the VM/container and restore to the snapshot state! Parameters: node* - Host node name vmid* - VM or container ID snapname* - Snapshot name to restore vm_type - Type: 'qemu' or 'lxc' (default: 'qemu') Example: rollback_snapshot node='pve' vmid='100' snapname='before-update'
node必填vmid必填targetvm_typesnapname必填approval_tokenList available ISO images across the cluster. Parameters: node - Filter by node (optional) storage - Filter by storage pool (optional) Returns list of ISOs with filename, size, and storage location.
nodetargetstorageapproval_tokenList available OS templates for container creation. Parameters: node - Filter by node (optional) storage - Filter by storage pool (optional) Returns list of templates (vztmpl) with name, size, and storage. Use the returned Volume ID with create_container's ostemplate parameter.
nodetargetstorageapproval_tokenDownload an ISO image from a URL to Proxmox storage. Parameters: node* - Target node name storage* - Target storage pool (must support ISO content) url* - URL to download from filename* - Target filename (e.g. 'ubuntu-22.04-live-server-amd64.iso') checksum - Optional checksum for verification checksum_algorithm - Algorithm: sha256, sha512, md5 (default: sha256) Example: download_iso node='pve' storage='local' url='https://...' filename='ubuntu.iso'
url必填node必填targetstorage必填checksumfilename必填approval_tokenchecksum_algorithmSubmit an HTTPS LXC template download through Proxmox (content=vztmpl). Required: node, storage supporting vztmpl, trusted HTTPS url, safe filename ending in .tar.gz/.tar.xz/.tar.zst. Optional checksum and checksum_algorithm (sha256, sha512, md5). TLS verification stays enabled. High-risk/target/read-only policy applies. Rejects observed existing filenames; preflight does not reserve space or prevent concurrent writes. Proxmox downloads from its own network: HTTPS is not an SSRF boundary. Use trusted publishers and preferably a SHA-256/SHA-512 checksum. A submitted UPID is not completed work: poll_job then list_templates. Local job tracking failure retains the UPID. SUBMISSION_UNCERTAIN requires manual task/storage inspection before another call. This operation has no automatic or job retry recipe.
url必填node必填targetstorage必填checksumfilename必填approval_tokenchecksum_algorithmDelete an ISO or template from storage. Parameters: node* - Node name storage* - Storage pool name filename* - ISO/template filename to delete Example: delete_iso node='pve' storage='local' filename='old-distro.iso'
node必填targetstorage必填filename必填approval_tokenList available backups across the cluster. Parameters: node - Filter by node (optional) storage - Filter by storage pool (optional) vmid - Filter by VM/container ID (optional) Returns backups with timestamp, size, compression, and notes. Use the returned Volume ID with restore_backup.
nodevmidtargetstorageapproval_tokenCreate a backup of a VM or container. Parameters: node* - Node where VM/container runs vmid* - VM or container ID to backup storage* - Target backup storage compress - Compression: 0, gzip, lz4, zstd (default: zstd) mode - Backup mode: snapshot, suspend, stop (default: snapshot) notes - Optional notes/description for the backup Example: create_backup node='pve' vmid='100' storage='backup-storage' compress='zstd'
modenode必填vmid必填notestargetstorage必填compressapproval_tokenRestore a VM or container from a backup. Parameters: node* - Target node for restore archive* - Backup volume ID (from list_backups output) vmid* - New VM/container ID for the restored machine storage - Target storage for disks (optional, uses original if not specified) unique - Generate unique MAC addresses (default: true) Example: restore_backup node='pve' archive='backup:backup/vzdump-qemu-100-2024_01_15.vma.zst' vmid='200'
node必填vmid必填targetuniquearchive必填storageapproval_tokenDelete a backup file from storage. WARNING: This permanently deletes the backup! Parameters: node* - Node name storage* - Storage pool name volid* - Backup volume ID to delete Example: delete_backup node='pve' storage='backup-storage' volid='backup:backup/vzdump-qemu-100-2024_01_15.vma.zst'
node必填volid必填targetstorage必填approval_tokenRead syslog entries from a Proxmox node. Parameters: node* - Node name (e.g. 'pve', 'pve1') limit - Maximum number of log lines to return (default: 100, max: 1000) start - Start line for pagination (0-based, optional) since - Show entries from this date/time onward (format: YYYY-MM-DD or YYYY-MM-DD HH:MM or YYYY-MM-DD HH:MM:SS, optional) until - Show entries up to this date/time (same format as since, optional) service - Filter by service name (e.g. 'pvedaemon', 'pveproxy', optional) Example: get_node_syslog node='pve' limit=50 service='pvedaemon'
node必填limitsincestartuntiltargetserviceapproval_tokenGet the log output of a specific Proxmox task by its UPID. Parameters: node* - Node name that ran the task (e.g. 'pve') upid* - Unique Process ID of the task (e.g. the Task ID returned by VM/container operations or list_jobs) start - Start line for pagination (0-based, optional) limit - Maximum number of log lines to return (default: 50, max: 500) Example: get_task_log node='pve' upid='UPID:pve:00001234:...' limit=100
node必填upid必填limitstarttargetapproval_tokenRead recent cluster-wide log entries. Parameters: max_entries - Maximum number of entries to return (default: 50, max: 1000) Each entry includes: time, node, user, tag (service), pri (priority), msg. Example: get_cluster_log max_entries=100
targetmax_entriesapproval_tokenRead the host firewall log of a Proxmox node. Parameters: node* - Node name (e.g. 'pve', 'pve1') limit - Maximum number of log lines to return (default: 100, max: 1000) start - Start line for pagination (0-based, optional) since - Show entries since this UNIX epoch timestamp (optional) until - Show entries until this UNIX epoch timestamp (optional) Example: get_node_firewall_log node='pve' limit=50
node必填limitsincestartuntiltargetapproval_tokenRead the firewall log of a VM (qemu) or container (lxc). Parameters: node* - Node hosting the guest (e.g. 'pve') vmid* - VM/container ID (e.g. 100) vm_type - Guest type: 'qemu' (default) or 'lxc' limit - Maximum number of log lines to return (default: 100, max: 1000) start - Start line for pagination (0-based, optional) since - Show entries since this UNIX epoch timestamp (optional) until - Show entries until this UNIX epoch timestamp (optional) Example: get_guest_firewall_log node='pve' vmid=100 vm_type='qemu' limit=50
node必填vmid必填limitsincestartuntiltargetvm_typeapproval_token已满足适用检查项的 90%
该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。
请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。
cp proxmox-config/config.example.json proxmox-config/config.json{ "jobs": { "sqlite_path": "proxmox-jobs.sqlite3" }}{ "mcp": { "tool_allowlist": ["get_nodes", "get_vms", "get_containers", "get_storage"] }}uvx proxmox-mcp-pluspip install proxmox-mcp-plusproxmox-mcp-plusawait call_tool("get_nodes", {"target": "default"})export MCP_API_KEY="$(openssl rand -hex 32)"docker run --rm -p 127.0.0.1:8000:8000 \ -e PROXMOX_MCP_MODE=mcp-http \ -e MCP_HOST=0.0.0.0 \ -e MCP_PORT=8000 \ -e MCP_TRANSPORT=STREAMABLE_HTTP \ -e MCP_API_KEY="$MCP_API_KEY" \ -v "$(pwd)/proxmox-config/config.json:/app/proxmox-config/config.json:ro" \ ghcr.io/rekklesna/proxmoxmcp-plus:latesthttp://127.0.0.1:8000/mcpexport MCP_API_KEY="$(openssl rand -hex 32)"# Replace <password> with the database user's password.export MCP_OAUTH_DATABASE_URL='postgresql://proxmox_oauth:<password>@postgres.example:5432/proxmox_oauth'docker run --rm -p 127.0.0.1:8000:8000 \ -e PROXMOX_MCP_MODE=mcp-http \ -e MCP_HOST=0.0.0.0 \ -e MCP_PORT=8000 \ -e MCP_TRANSPORT=STREAMABLE_HTTP \ -e MCP_API_KEY="$MCP_API_KEY" \ -e MCP_OAUTH_ENABLED=true \ -e MCP_OAUTH_ISSUER=https://mcp.example.com \ -e MCP_OAUTH_DATABASE_URL="$MCP_OAUTH_DATABASE_URL" \ -e MCP_ALLOWED_HOSTS=mcp.example.com:*,localhost:* \ -e MCP_ALLOWED_ORIGINS=https://mcp.example.com \ -v "$(pwd)/proxmox-config/config.json:/app/proxmox-config/config.json:ro" \ ghcr.io/rekklesna/proxmoxmcp-plus:latesthttps://mcp.example.com/mcpexport PROXMOX_API_KEY="$(openssl rand -hex 32)"docker run --rm -p 127.0.0.1:8811:8811 \ -e PROXMOX_API_KEY="$PROXMOX_API_KEY" \ -v "$(pwd)/proxmox-config/config.json:/app/proxmox-config/config.json:ro" \ ghcr.io/rekklesna/proxmoxmcp-plus:latestcurl -f http://localhost:8811/livezcurl -f -H "Authorization: Bearer $PROXMOX_API_KEY" http://localhost:8811/healthcurl -H "Authorization: Bearer $PROXMOX_API_KEY" http://localhost:8811/openapi.jsongit clone https://github.com/RekklesNA/ProxmoxMCP-Plus.gitcd ProxmoxMCP-Plusuv venvuv pip install -e ".[dev]"python main.py{ "mcpServers": { "proxmox-mcp-plus": { "command": "uvx", "args": ["proxmox-mcp-plus"], "env": { "PROXMOX_HOST": "your-proxmox-host", "PROXMOX_USER": "root@pam", "PROXMOX_TOKEN_NAME": "mcp-token", "PROXMOX_TOKEN_VALUE": "your-token-secret", "PROXMOX_PORT": "8006", "PROXMOX_VERIFY_SSL": "true" } } }}{ "mcpServers": { "proxmox-mcp-plus": { "command": "uvx", "args": ["proxmox-mcp-plus"], "env": { "PROXMOX_MCP_CONFIG": "/path/to/ProxmoxMCP-Plus/proxmox-config/config.json" } } }}python -m pytest -qruff check .mypy src --ignore-missing-importspython -m pip_audit -r requirements/runtime.lock --require-hashes --disable-pip --strictpython -m build