An enhanced Python-based Model Context Protocol (MCP) server for interacting with Proxmox virtualization platforms. This project extends canvrno/ProxmoxMCP with additional features including complete OpenAPI integration and expanded virtualization management capabilities.
This project is built upon the open-source project ProxmoxMCP by @canvrno.
| Feature Category | Description | Tools |
|---|---|---|
| VM Lifecycle Management | Complete virtual machine creation, management, and deletion | create_vm, delete_vm |
| Power Management | Control VM power states | start_vm, stop_vm, shutdown_vm, reset_vm |
| Container Support | Full LXC container lifecycle management | get_containers, create_container, delete_container, start_container, stop_container, restart_container, update_container_resources |
| Snapshot Management | Create and manage VM/container snapshots | list_snapshots, create_snapshot, delete_snapshot, rollback_snapshot |
| Backup and Restore | Backup and restore VMs and containers | list_backups, create_backup, restore_backup, delete_backup |
| ISO and Template Management | Manage installation media and templates | list_isos, list_templates, download_iso, delete_iso |
| Monitoring | Cluster and resource monitoring | get_nodes, get_node_status, get_vms, get_storage, get_cluster_status |
| OpenAPI Integration | REST API endpoints for external integration | 20+ API endpoints |
| Security and Stability | Production-grade error handling and validation | Token-based authentication, comprehensive logging |
- Proxmoxer - Python wrapper for Proxmox API
- MCP SDK - Model Context Protocol SDK
- Pydantic - Data validation using Python type annotations
- Full integration with Cline and Open WebUI
- Built with the official MCP SDK
- Secure token-based authentication with Proxmox
- Complete VM lifecycle management (create, start, stop, reset, shutdown, delete)
- VM console command execution
- LXC container management support
- Intelligent storage type detection (LVM/file-based)
- Configurable logging system
- Type-safe implementation with Pydantic
- Rich output formatting with customizable themes
- OpenAPI REST endpoints for integration
- 20+ fully functional API endpoints
- Complete snapshot management (create, delete, rollback)
- Backup and restore capabilities
- ISO and template management
- UV package manager (recommended)
- Python 3.9 or higher
- Git
- Access to a Proxmox server with API token credentials
Before starting, ensure you have:
- Proxmox server hostname or IP
- Proxmox API token (see API Token Setup)
- UV installed (
pip install uv)
-
Clone and set up environment:
# Clone repository git clone https://github.com/RekklesNA/ProxmoxMCP-Plus.git cd ProxmoxMCP-Plus # Create and activate virtual environment uv venv source .venv/bin/activate # Linux/macOS # OR .\.venv\Scripts\Activate.ps1 # Windows
-
Install dependencies:
# Install with development dependencies uv pip install -e ".[dev]"
-
Create configuration:
# Create config directory and copy template mkdir -p proxmox-config cp proxmox-config/config.example.json proxmox-config/config.json -
Edit
proxmox-config/config.json:{ "proxmox": { "host": "PROXMOX_HOST", # Required: Your Proxmox server address "port": 8006, # Optional: Default is 8006 "verify_ssl": false, # Optional: Set false for self-signed certs "service": "PVE" # Optional: Default is PVE }, "auth": { "user": "USER@pve", # Required: Your Proxmox username "token_name": "TOKEN_NAME", # Required: API token ID "token_value": "TOKEN_VALUE" # Required: API token value }, "logging": { "level": "INFO", # Optional: DEBUG for more detail "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s", "file": "proxmox_mcp.log" # Optional: Log to file }, "mcp": { "host": "127.0.0.1", # Optional: Host for SSE/STREAMABLE transports "port": 8000, # Optional: Port for SSE/STREAMABLE transports "transport": "STDIO" # Optional: STDIO, SSE, or STREAMABLE } }
-
Check Python environment:
python -c "import proxmox_mcp; print('Installation OK')" -
Run the tests:
pytest
-
Verify configuration:
# Linux/macOS PROXMOX_MCP_CONFIG="proxmox-config/config.json" python -m proxmox_mcp.server # Windows (PowerShell) $env:PROXMOX_MCP_CONFIG="proxmox-config\config.json"; python -m proxmox_mcp.server
- Log into your Proxmox web interface
- Navigate to Datacenter -> Permissions -> API Tokens
- Create a new API token:
- Select a user (e.g., root@pam)
- Enter a token ID (e.g., "mcp-token")
- Uncheck "Privilege Separation" if you want full access
- Save and copy both the token ID and secret
For testing and development:
# Activate virtual environment first
source .venv/bin/activate # Linux/macOS
# OR
.\.venv\Scripts\Activate.ps1 # Windows
# Run the server
python -m proxmox_mcp.serverThe MCP server supports multiple transport modes. Configure these in the mcp section of
your proxmox-config/config.json:
STDIO: Default. Run over stdio for MCP clients like Claude Desktop/Cline.SSE: Serve MCP over Server-Sent Events (SSE).STREAMABLE: Serve MCP over streamable HTTP.
Deploy ProxmoxMCP Plus as standard OpenAPI REST endpoints for integration with Open WebUI and other applications.
# Install mcpo (MCP-to-OpenAPI proxy)
pip install mcpo
# Start OpenAPI service on port 8811
./start_openapi.sh# Build and run with Docker
docker build -t proxmox-mcp-api .
docker run -d --name proxmox-mcp-api -p 8811:8811 \
-v $(pwd)/proxmox-config:/app/proxmox-config proxmox-mcp-api
# Or use Docker Compose
docker-compose up -dOnce deployed, access your service at:
- API Documentation: http://your-server:8811/docs
- OpenAPI Specification: http://your-server:8811/openapi.json
- Health Check: http://your-server:8811/health
For Claude Desktop users, add this configuration to your MCP settings file:
Configuration file location:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
Quick Setup:
-
Copy the example configuration:
# macOS cp proxmox-config/claude_desktop_config.example.json ~/Library/Application\ Support/Claude/claude_desktop_config.json # Linux cp proxmox-config/claude_desktop_config.example.json ~/.config/Claude/claude_desktop_config.json # Windows (PowerShell) Copy-Item proxmox-config\claude_desktop_config.example.json $env:APPDATA\Claude\claude_desktop_config.json
-
Edit the file and replace the following values:
/absolute/path/to/ProxmoxMCP-Plus- Full path to your installationyour-proxmox-host- Your Proxmox server IP or hostnameusername@pve- Your Proxmox usernametoken-name- Your API token nametoken-value- Your API token value
Configuration:
{
"mcpServers": {
"ProxmoxMCP-Plus": {
"command": "/absolute/path/to/ProxmoxMCP-Plus/.venv/bin/python",
"args": ["-m", "proxmox_mcp.server"],
"env": {
"PYTHONPATH": "/absolute/path/to/ProxmoxMCP-Plus/src",
"PROXMOX_MCP_CONFIG": "/absolute/path/to/ProxmoxMCP-Plus/proxmox-config/config.json",
"PROXMOX_HOST": "your-proxmox-host",
"PROXMOX_USER": "username@pve",
"PROXMOX_TOKEN_NAME": "token-name",
"PROXMOX_TOKEN_VALUE": "token-value",
"PROXMOX_PORT": "8006",
"PROXMOX_VERIFY_SSL": "false",
"PROXMOX_SERVICE": "PVE",
"LOG_LEVEL": "DEBUG"
}
}
}
}After configuration:
- Restart Claude Desktop
- The ProxmoxMCP-Plus tools will be available in your conversations
- You can now manage your Proxmox infrastructure through Claude Desktop!
For Cline users, add this configuration to your MCP settings file (typically at ~/.config/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json):
{
"mcpServers": {
"ProxmoxMCP-Plus": {
"command": "/absolute/path/to/ProxmoxMCP-Plus/.venv/bin/python",
"args": ["-m", "proxmox_mcp.server"],
"cwd": "/absolute/path/to/ProxmoxMCP-Plus",
"env": {
"PYTHONPATH": "/absolute/path/to/ProxmoxMCP-Plus/src",
"PROXMOX_MCP_CONFIG": "/absolute/path/to/ProxmoxMCP-Plus/proxmox-config/config.json",
"PROXMOX_HOST": "your-proxmox-host",
"PROXMOX_USER": "username@pve",
"PROXMOX_TOKEN_NAME": "token-name",
"PROXMOX_TOKEN_VALUE": "token-value",
"PROXMOX_PORT": "8006",
"PROXMOX_VERIFY_SSL": "false",
"PROXMOX_SERVICE": "PVE",
"LOG_LEVEL": "DEBUG"
},
"disabled": false,
"autoApprove": []
}
}
}The server provides comprehensive MCP tools and corresponding REST API endpoints:
Create a new virtual machine with specified resources.
Parameters:
node(string, required): Name of the nodevmid(string, required): ID for the new VMname(string, required): Name for the VMcpus(integer, required): Number of CPU cores (1-32)memory(integer, required): Memory in MB (512-131072)disk_size(integer, required): Disk size in GB (5-1000)storage(string, optional): Storage pool nameostype(string, optional): OS type (default: l26)
API Endpoint:
POST /create_vm
Content-Type: application/json
{
"node": "pve",
"vmid": "200",
"name": "my-vm",
"cpus": 1,
"memory": 2048,
"disk_size": 10
}Example Response:
VM 200 created successfully.
VM Configuration:
- Name: my-vm
- Node: pve
- VM ID: 200
- CPU Cores: 1
- Memory: 2048 MB (2.0 GB)
- Disk: 10 GB (local-lvm, raw format)
- Storage Type: lvmthin
- Network: virtio (bridge=vmbr0)
- QEMU Agent: Enabled
Task ID: UPID:pve:001AB729:0442E853:682FF380:qmcreate:200:root@pam!mcp
start_vm: Start a virtual machine
POST /start_vm
{"node": "pve", "vmid": "200"}stop_vm: Force stop a virtual machine
POST /stop_vm
{"node": "pve", "vmid": "200"}shutdown_vm: Gracefully shutdown a virtual machine
POST /shutdown_vm
{"node": "pve", "vmid": "200"}reset_vm: Reset (restart) a virtual machine
POST /reset_vm
{"node": "pve", "vmid": "200"}delete_vm: Completely delete a virtual machine
POST /delete_vm
{"node": "pve", "vmid": "200", "force": false}List all snapshots for a VM or container.
Parameters:
node(string, required): Host node name (e.g. 'pve')vmid(string, required): VM or container ID (e.g. '100')vm_type(string, optional): Type - 'qemu' for VMs, 'lxc' for containers (default: 'qemu')
API Endpoint: POST /list_snapshots
Example:
POST /list_snapshots
{"node": "pve", "vmid": "100", "vm_type": "qemu"}Create a snapshot of a VM or container.
Parameters:
node(string, required): Host node namevmid(string, required): VM or container IDsnapname(string, required): Snapshot name (no spaces, e.g. 'before-update')description(string, optional): Description for the snapshotvmstate(boolean, optional): Include memory state (VMs only, default: false)vm_type(string, optional): Type - 'qemu' or 'lxc' (default: 'qemu')
API Endpoint:
POST /create_snapshot
Content-Type: application/json
{
"node": "pve",
"vmid": "100",
"snapname": "pre-upgrade",
"description": "Before system upgrade",
"vmstate": true
}Delete a snapshot.
Parameters:
node(string, required): Host node namevmid(string, required): VM or container IDsnapname(string, required): Snapshot name to deletevm_type(string, optional): Type - 'qemu' or 'lxc' (default: 'qemu')
API Endpoint:
POST /delete_snapshot
{"node": "pve", "vmid": "100", "snapname": "old-snapshot"}Rollback VM/container to a previous snapshot.
WARNING: This will stop the VM/container and restore to the snapshot state!
Parameters:
node(string, required): Host node namevmid(string, required): VM or container IDsnapname(string, required): Snapshot name to restorevm_type(string, optional): Type - 'qemu' or 'lxc' (default: 'qemu')
API Endpoint:
POST /rollback_snapshot
{"node": "pve", "vmid": "100", "snapname": "before-update"}List all LXC containers across the cluster.
API Endpoint: POST /get_containers
Example Response:
Containers
nginx-server (ID: 200)
- Status: RUNNING
- Node: pve
- CPU Cores: 2
- Memory: 1.5 GB / 2.0 GB (75.0%)
Create a new LXC container with specified configuration.
Parameters:
node(string, required): Host node name (e.g. 'pve')vmid(string, required): Container ID number (e.g. '200')ostemplate(string, required): OS template path (e.g. 'local:vztmpl/alpine-3.19-default_20240207_amd64.tar.xz')hostname(string, optional): Container hostname (defaults to 'ct-{vmid}')cores(integer, optional): Number of CPU cores (default: 1)memory(integer, optional): Memory size in MiB (default: 512)swap(integer, optional): Swap size in MiB (default: 512)disk_size(integer, optional): Root disk size in GB (default: 8)storage(string, optional): Storage pool for rootfs (auto-detects if not specified)password(string, optional): Root passwordssh_public_keys(string, optional): SSH public keys for root usernetwork_bridge(string, optional): Network bridge name (default: 'vmbr0')start_after_create(boolean, optional): Start container after creation (default: false)unprivileged(boolean, optional): Create unprivileged container (default: true)
API Endpoint:
POST /create_container
Content-Type: application/json
{
"node": "pve",
"vmid": "200",
"ostemplate": "local:vztmpl/alpine-3.19-default_20240207_amd64.tar.xz",
"hostname": "my-container",
"cores": 2,
"memory": 1024,
"disk_size": 10
}Delete/remove an LXC container completely.
WARNING: This operation permanently deletes the container and all its data!
Parameters:
selector(string, required): Container selector - '123' | 'pve1:123' | 'pve1/name' | 'name'force(boolean, optional): Force deletion even if container is running (default: false)
API Endpoint:
POST /delete_container
Content-Type: application/json
{
"selector": "200",
"force": false
}List available backups across the cluster.
Parameters:
node(string, optional): Filter by nodestorage(string, optional): Filter by storage poolvmid(string, optional): Filter by VM/container ID
API Endpoint: POST /list_backups
Example:
POST /list_backups
{"node": "pve", "storage": "backup-storage"}Create a backup of a VM or container.
Parameters:
node(string, required): Node where VM/container runsvmid(string, required): VM or container ID to backupstorage(string, required): Target backup storagecompress(string, optional): Compression - '0', 'gzip', 'lz4', 'zstd' (default: 'zstd')mode(string, optional): Backup mode - 'snapshot', 'suspend', 'stop' (default: 'snapshot')notes(string, optional): Notes/description for the backup
API Endpoint:
POST /create_backup
Content-Type: application/json
{
"node": "pve",
"vmid": "100",
"storage": "backup-storage",
"compress": "zstd",
"mode": "snapshot",
"notes": "Weekly backup"
}Restore a VM or container from a backup.
Parameters:
node(string, required): Target node for restorearchive(string, required): Backup volume ID (from list_backups output)vmid(string, required): New VM/container ID for the restored machinestorage(string, optional): Target storage for disks (uses original if not specified)unique(boolean, optional): Generate unique MAC addresses (default: true)
API Endpoint:
POST /restore_backup
Content-Type: application/json
{
"node": "pve",
"archive": "backup:backup/vzdump-qemu-100-2024_01_15.vma.zst",
"vmid": "200",
"unique": true
}Delete a backup file from storage.
WARNING: This permanently deletes the backup!
Parameters:
node(string, required): Node namestorage(string, required): Storage pool namevolid(string, required): Backup volume ID to delete
API Endpoint:
POST /delete_backup
{
"node": "pve",
"storage": "backup-storage",
"volid": "backup:backup/vzdump-qemu-100-2024_01_15.vma.zst"
}List available ISO images across the cluster.
Parameters:
node(string, optional): Filter by nodestorage(string, optional): Filter by storage pool
API Endpoint: POST /list_isos
Returns: List of ISOs with filename, size, and storage location.
List available OS templates for container creation.
Parameters:
node(string, optional): Filter by nodestorage(string, optional): Filter by storage pool
API Endpoint: POST /list_templates
Returns: List of templates (vztmpl) with name, size, and storage. Use the returned Volume ID with create_container's ostemplate parameter.
Download an ISO image from a URL to Proxmox storage.
Parameters:
node(string, required): Target node namestorage(string, required): Target storage pool (must support ISO content)url(string, required): URL to download fromfilename(string, required): Target filename (e.g. 'ubuntu-22.04-live-server-amd64.iso')checksum(string, optional): Checksum for verificationchecksum_algorithm(string, optional): Algorithm - 'sha256', 'sha512', 'md5' (default: 'sha256')
API Endpoint:
POST /download_iso
Content-Type: application/json
{
"node": "pve",
"storage": "local",
"url": "https://releases.ubuntu.com/22.04/ubuntu-22.04-live-server-amd64.iso",
"filename": "ubuntu-22.04-live-server-amd64.iso",
"checksum": "a1b2c3..."
}Delete an ISO or template from storage.
Parameters:
node(string, required): Node namestorage(string, required): Storage pool namefilename(string, required): ISO/template filename to delete
API Endpoint:
POST /delete_iso
{
"node": "pve",
"storage": "local",
"filename": "old-distro.iso"
}Lists all nodes in the Proxmox cluster.
API Endpoint: POST /get_nodes
Example Response:
Proxmox Nodes
pve-compute-01
- Status: ONLINE
- Uptime: 156d 12h
- CPU Cores: 64
- Memory: 186.5 GB / 512.0 GB (36.4%)
Get detailed status of a specific node.
Parameters:
node(string, required): Name of the node
API Endpoint: POST /get_node_status
List all VMs across the cluster.
API Endpoint: POST /get_vms
List available storage pools.
API Endpoint: POST /get_storage
Get overall cluster status and health.
API Endpoint: POST /get_cluster_status
Execute a command in a VM's console using QEMU Guest Agent.
Parameters:
node(string, required): Name of the node where VM is runningvmid(string, required): ID of the VMcommand(string, required): Command to execute
API Endpoint: POST /execute_vm_command
Requirements:
- VM must be running
- QEMU Guest Agent must be installed and running in the VM
- Access your Open WebUI instance
- Navigate to Settings → Connections → OpenAPI
- Add new API configuration:
{
"name": "Proxmox MCP API Plus",
"base_url": "http://your-server:8811",
"api_key": "",
"description": "Enhanced Proxmox Virtualization Management API"
}The system supports natural language VM creation requests through AI assistants. Example requests:
- "Can you create a VM with 1 cpu core and 2 GB ram with 10GB of storage disk"
- "Create a new VM for testing with minimal resources"
- "I need a development server with 4 cores and 8GB RAM"
The AI assistant will automatically call the appropriate APIs and provide detailed feedback.
ProxmoxMCP Plus automatically detects storage types and selects appropriate disk formats:
- Format:
raw - High performance
- Note: No cloud-init image support
- Format:
qcow2 - Cloud-init support
- Flexible snapshot capabilities
ProxmoxMCP-Plus/
├── src/ # Source code
│ └── proxmox_mcp/
│ ├── server.py # Main MCP server implementation
│ ├── config/ # Configuration handling
│ ├── core/ # Core functionality
│ ├── formatting/ # Output formatting and themes
│ ├── tools/ # Tool implementations
│ │ ├── vm.py # VM management
│ │ ├── container.py # Container management
│ │ └── console/ # VM console operations
│ └── utils/ # Utilities (auth, logging)
│
├── tests/ # Unit test suite
├── test_scripts/ # Integration tests & demos
│ ├── README.md # Test documentation
│ ├── test_vm_power.py # VM power management tests
│ ├── test_vm_start.py # VM startup tests
│ ├── test_create_vm.py # VM creation tests
│ └── test_openapi.py # OpenAPI service tests
│
├── proxmox-config/ # Configuration files
│ └── config.json # Server configuration
│
├── Configuration Files
│ ├── pyproject.toml # Project metadata
│ ├── docker-compose.yml # Docker orchestration
│ ├── Dockerfile # Docker image definition
│ └── requirements.in # Dependencies
│
├── Scripts
│ ├── start_server.sh # MCP server launcher
│ └── start_openapi.sh # OpenAPI service launcher
│
└── Documentation
├── README.md # This file
├── VM_CREATION_GUIDE.md # VM creation guide
├── OPENAPI_DEPLOYMENT.md # OpenAPI deployment
└── LICENSE # MIT License
pytestcd test_scripts
# Test VM power management
python test_vm_power.py
# Test VM creation
python test_create_vm.py
# Test OpenAPI service
python test_openapi.py# Test node listing
curl -X POST "http://your-server:8811/get_nodes" \
-H "Content-Type: application/json" \
-d "{}"
# Test VM creation
curl -X POST "http://your-server:8811/create_vm" \
-H "Content-Type: application/json" \
-d '{
"node": "pve",
"vmid": "300",
"name": "test-vm",
"cpus": 1,
"memory": 2048,
"disk_size": 10
}'Set up secure API access:
export PROXMOX_API_KEY="your-secure-api-key"
export PROXMOX_MCP_CONFIG="/app/proxmox-config/config.json"Example nginx configuration:
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://localhost:8811;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}-
Port already in use
netstat -tlnp | grep 8811 # Change port if needed mcpo --port 8812 -- ./start_server.sh
-
Configuration errors
# Verify config file cat proxmox-config/config.json -
Connection issues
# Test Proxmox connectivity curl -k https://your-proxmox:8006/api2/json/version
# View service logs
tail -f proxmox_mcp.log
# Docker logs
docker logs proxmox-mcp-api -f- VM Creation (user requirement: 1 CPU + 2GB RAM + 10GB storage)
- VM Power Management (start VPN-Server ID:101)
- VM Deletion Feature
- Container Management (LXC)
- Container Creation and Deletion
- Snapshot Management (create, delete, rollback)
- Backup and Restore
- ISO and Template Management
- Storage Compatibility (LVM/file-based)
- OpenAPI Integration (port 8811)
- Open WebUI Integration
- Error Handling & Validation
- Complete Documentation & Testing
ProxmoxMCP Plus is ready for production deployment. The system supports natural language VM creation requests through AI assistants. When a user requests VM creation (e.g., "create a VM with 1 cpu core and 2 GB ram with 10GB of storage disk"), the system will:
- Call the
create_vmAPI endpoint - Automatically select appropriate storage and format
- Create VMs matching the specified requirements
- Return detailed configuration information
- Provide next-step recommendations
After activating your virtual environment:
- Run tests:
pytest - Format code:
black . - Type checking:
mypy . - Lint:
ruff .
MIT License
- @canvrno for the foundational project ProxmoxMCP
- Thanks to the Proxmox community for providing the powerful virtualization platform
- Thanks to all contributors and users for their support
ProxmoxMCP Plus with OpenAPI integration is ready for production deployment.