MCP server for Proxmox VE VMs. Screenshot and input over VNC, text I/O over serial console, plus power, snapshots, backups, and guest-agent exec.
curl -fsSL https://raw.githubusercontent.com/paltaio/pve-computer-use/main/install-pve-skill | bash- Proxmox VE 8+
- PVE user with at least
VM.Console+VM.Audit
Download from the latest release:
curl -L -o pve-computer-use https://github.com/paltaio/pve-computer-use/releases/latest/download/pve-computer-use-linux-x64
chmod +x pve-computer-useAssets: pve-computer-use-{linux,darwin}-{x64,arm64}, pve-computer-use-windows-x64.exe.
git clone <repo-url> && cd pve-computer-use
bun install
bun build --compile --target=bun-linux-x64 --outfile=dist/pve-computer-use src/index.tsOr build to JS for Node:
bun run build
node dist/index.js| Variable | Required | Default | Notes |
|---|---|---|---|
PVE_HOST |
yes | -- | PVE node/cluster |
PVE_PORT |
no | 8006 |
|
PVE_USER |
yes | -- | e.g. mcp-agent@pve |
PVE_PASSWORD |
yes | -- | |
PVE_VERIFY_SSL |
no | true |
false for self-signed |
MCP client config (~/.claude/mcp_servers.json or claude_desktop_config.json):
{
"mcpServers": {
"pve-computer-use": {
"command": "/path/to/pve-computer-use",
"env": {
"PVE_HOST": "192.168.1.10",
"PVE_USER": "mcp-agent@pve",
"PVE_PASSWORD": "your-password",
"PVE_VERIFY_SSL": "false"
}
}
}
}Display (VNC): connect, disconnect, screenshot, get_screen_size, mouse_click, mouse_move, drag, scroll, type_text, press_key
Serial console: serial_connect, serial_disconnect, serial_read, serial_send, serial_key, serial_resize
VM management: list_vms, vm_create, vm_delete, vm_start, vm_shutdown, vm_stop, vm_status, vm_notes, vm_disk_list, vm_disk_set, vm_config_set, vm_config_delete, exec_command, timeline
Snapshots: snapshot_list, snapshot_create, snapshot_delete, snapshot_rollback
Backups: backup_list, backup_create
timeline runs a scheduled sequence of actions in one call (connect, mouse/keyboard events, exec_command, waits). See the tool schema for the step shape.
# User
pveum user add mcp-agent@pve --password <password>
# Role (full: screen + power + snapshots + backups + guest agent)
pveum role add MCPComputerUseFull \
--privs "VM.Console,VM.Audit,VM.Allocate,VM.Clone,VM.PowerMgmt,VM.Config.Disk,VM.Config.CDROM,VM.Config.CPU,VM.Config.Memory,VM.Config.Network,VM.Config.HWType,VM.Config.Options,VM.Config.Cloudinit,VM.GuestAgent.Unrestricted,VM.Snapshot,VM.Backup,Datastore.Audit,Datastore.AllocateSpace"
# ACLs (per VM or pool, plus storage for backups)
pveum acl modify /vms/100 --users mcp-agent@pve --roles MCPComputerUseFull
pveum acl modify /storage --users mcp-agent@pve --roles MCPComputerUseFullFull permissions mode:
pveum role modify MCPComputerUseFull \
--privs "VM.Allocate,VM.Clone,VM.Audit,VM.Console,VM.PowerMgmt,VM.Config.Disk,VM.Config.CDROM,VM.Config.CPU,VM.Config.Memory,VM.Config.Network,VM.Config.HWType,VM.Config.Options,VM.Config.Cloudinit,VM.GuestAgent.Unrestricted,VM.Snapshot,VM.Backup,Datastore.Audit,Datastore.AllocateSpace"
pveum acl modify / --users mcp-agent@pve --roles MCPComputerUseFull| Privilege | For |
|---|---|
VM.Console |
VNC + serial |
VM.Audit |
status, list, snapshot list |
VM.Allocate |
create and delete VM |
VM.PowerMgmt |
start / stop / shutdown |
VM.Config.* |
create and edit VM config |
VM.Snapshot |
snapshot ops |
VM.Backup |
backup ops (per VM) |
VM.GuestAgent.Unrestricted |
exec_command (needs qemu-guest-agent) |
Datastore.Audit / Datastore.AllocateSpace |
backup list / create (on /storage/*) |
PVE: qm set <vmid> -serial0 socket
Debian/Ubuntu guest: systemctl enable --now serial-getty@ttyS0.service. For boot messages, add console=ttyS0,115200n8 to GRUB_CMDLINE_LINUX and update-grub.
VNC tickets are VM-scoped and expire in ~40s. Auth tickets refresh before their 2h expiry; 403s trigger a retry with a fresh ticket. Credentials come from env vars only. Runs as a local stdio subprocess - no network exposure of the MCP server itself.
| Symptom | Fix |
|---|---|
401 authentication failed |
Test creds: curl -k -d 'username=USER&password=PW' https://HOST:8006/api2/json/access/ticket |
Invalid PVEVNC Ticket |
Ticket expires in ~40s; retry |
VM not found in cluster |
Wrong VMID or missing VM.Audit |
WebSocket closed before handshake |
VM not running, or port 8006 blocked |
| TLS errors | PVE_VERIFY_SSL=false |
| Serial shows nothing | No serial0 on VM, or no getty in guest |
Apache-2.0. See LICENSE.