The Problem

Operators of Proxmox VE must stitch together raw API calls, shell scripts, and ad‑hoc glue code to perform day‑2 tasks (VM/LXC lifecycle, snapshots, backups, ISO handling, long‑running jobs). The resulting workflows are fragile, hard to audit, and difficult to expose safely to LLM‑driven agents.

What This Does

ProxmoxMCP‑Plus provides a single, policy‑enforced surface for both MCP (Claude Desktop, Open WebUI) and OpenAPI clients.

  • Core logic lives under src/proxmox_mcp/, e.g. src/proxmox_mcp/server.py (the HTTP server) and src/proxmox_mcp/tools/ (helpers for containers, VMs, backups, ISO, storage).
  • Configuration is read from proxmox-config/config.json (host, port, auth token, optional SSH section, optional jobs persistence).
  • Observability (Prometheus metrics) is in src/proxmox_mcp/observability/metrics.py.
  • Security policy (command whitelisting, role checks) lives in src/proxmox_mcp/security/command_policy.py.

How It Is Wired

Execution starts at main.py:36main() which constructs a ProxmoxMCPServer (defined in src/proxmox_mcp/server.py). The server:

  1. Calls _wrap_sync (used in 40 places) to adapt async helpers for the sync FastAPI/Express stack.
  2. Registers background jobs via _register_background_job (19 callers) that persist state through src/proxmox_mcp/services/jobs.py → SQLite file (default jobs.db).
  3. Routes HTTP requests to src/proxmox_mcp/openapi_proxy.pydispatch() which invokes the appropriate tool module (e.g., tools/containers.py, tools/vm.py).

The most frequent internal calls are:

  • _err (23 callers) – central error formatter.
  • _get (14 callers) – generic data fetcher used by many tools.

External effects are concentrated in a few modules:

  • Networksrc/proxmox_mcp/core/proxmox.py builds a ProxmoxManager that talks to the Proxmox API (HTTPS).
  • Filesystemsetup.py and the config loader open files; the server reads config.json and writes job state.
  • Subprocesssrc/proxmox_mcp/tools/console/container_manager.py runs ssh/scp via subprocess.run (e.g., ssh_effective_config).

No circular imports were detected; the import graph is shallow (10 edges, 57 modules). The hub modules (services/__init__, tools/containers, observability/metrics) have low indegree, meaning a change there has a wide blast radius but limited upstream coupling.

How To Use It

# Clone the exact repo
git clone https://github.com/moses-y/ProxmoxMCP-Plus
cd ProxmoxMCP-Plus

# Install Python dependencies (lockfile missing – see health notes)
pip install -e .

# Prepare configuration
cp proxmox-config/config.example.json proxmox-config/config.json
# Edit proxmox-config/config.json with:
#   propxox.host, propxox.port, auth.user, auth.token_name, auth.token_value
#   optional ssh and jobs sections as needed

# Run the server (development mode)
python -m proxmox_mcp.server   # entry point is src/proxmox_mcp/server.py
# or via Docker
docker build -t proxmox-mcp-plus .
docker run -p 8000:8000 -v $(pwd)/proxmox-config:/app/proxmox-config proxmox-mcp-plus

The OpenAPI spec is served at http://localhost:8000/openapi.json; MCP clients connect to the same host/port using the MCP protocol defined in manifest.json.

Real‑World Use

A CI pipeline can invoke the OpenAPI endpoint to spin up a test LXC, take a snapshot, run a container command, and delete the snapshot—all under a single job ID tracked in SQLite. An LLM‑driven chatbot can call the MCP surface to “create a VM with 2 vCPU, 4 GB RAM, and attach ISO debian‑12.iso”, and the policy layer will reject any command not listed in security/command_policy.py.

Code Health & Issues

  • Critical – Privileged checkout of PR code in .github/workflows/publish-mcp-registry.yml.
  • High – GitHub Actions not pinned to commit SHAs; missing lockfile for pyproject.toml.
  • Medium – Broad exception handling, deep nesting, oversized files, high branching density, missing least‑privilege GITHUB_TOKEN permissions, no Dependabot, mutable base image, persistent checkout credentials, missing job timeouts.
  • Low – No job timeout values in CI workflow.

These findings are produced by deterministic static analysis; no additional issues were inferred.

The Bottom Line

ProxmoxMCP‑Plus consolidates Proxmox VE operations behind a single, policy‑driven API that can be consumed by both LLM agents and traditional automation. The codebase is functional but suffers from several maintainability and supply‑chain risks (duplicate logic, deep nesting, missing lockfile, insecure CI settings). Teams that need a quick, extensible bridge to Proxmox and are prepared to address the highlighted health concerns will find this repo a solid foundation.