GPU Manager MCP
by quxlzx
README.md
# GPU Manager MCP
Read-only GPU monitoring and AI-workload planning over the
[Model Context Protocol](https://modelcontextprotocol.io). One stdio server,
any MCP client, no LLM required.
Discover NVIDIA, AMD and Intel GPUs, watch utilization / VRAM / temperature /
power / clocks, keep bounded local history in SQLite, and estimate whether
your LLM actually fits before you load it.
- **Cross-platform backends** — NVML (via `pynvml`) and `nvidia-smi` for
NVIDIA; amdgpu sysfs (no ROCm needed) and `rocm-smi` fallback for AMD;
i915/xe sysfs for Intel.
- **Honest telemetry** — every reading carries a timestamp, unit and source.
Unsupported sensors are reported as `available: false` **with a reason**,
never silently zeroed.
- **Read-only by design** — no shell tool, no overclocking, no voltage, no
fan control, no process termination. External helpers run from a fixed
allowlist with timeouts and no shell interpolation.
- **AI-aware** — `estimate_model_fit()` computes weights + runtime overhead +
KV-cache needs for a given quantization, context length and parallel
request count, then checks it against live free VRAM.
## Installation
```bash
pip install gpu-manager-mcp # (once published; see below)
# or from source
git clone https://github.com/quxlzx/gpu-manager-mcp
cd gpu-manager-mcp
python -m venv .venv && .venv/bin/pip install -e .
```
Optional NVIDIA NVML bindings (recommended on NVIDIA hosts):
```bash
pip install "gpu-manager-mcp[nvidia]" # or: pip install nvidia-ml-py
```
Requirements: Python 3.11+. Linux is fully supported; on Windows the AMD
backend is not yet implemented (see Known limitations).
## Supported GPUs
| Vendor | Path | Util | VRAM | Temp | Power | Clocks | Processes |
|---|---|---|---|---|---|---|---|
| NVIDIA (GeForce/Quadro/RTX/Tesla) | NVML (`pynvml`) | ✅ | ✅ | ✅ | ✅* | ✅* | ✅* |
| NVIDIA (fallback) | `nvidia-smi` CSV | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| AMD (Linux, amdgpu driver) | sysfs + hwmon | ✅* | ✅ | ✅* | ✅* | ✅* | via `rocm-smi` |
| Intel (Linux, i915/xe) | sysfs + hwmon | ✅* | ❌ | ✅* | ✅* | ✅* | ❌ |
`✅*` = depends on card/driver; unavailable sensors are reported with the
driver's own error, not guessed.
## Connecting an MCP client
Generic stdio configuration (any MCP client):
```json
{
"mcpServers": {
"gpu-manager": {
"command": "/path/to/.venv/bin/gpu-manager-mcp",
"args": ["stdio"]
}
}
}
```
Hermes Agent (`~/.hermes/config.yaml`):
```yaml
mcp_servers:
gpu-manager:
command: /path/to/.venv/bin/gpu-manager-mcp
args: ["stdio"]
timeout: 60
```
Claude Desktop / Cursor / Cline: same `command` + `args` shape as above.
## Tools
Discovery: `list_gpus`, `get_gpu_info`, `get_system_gpu_summary`
Monitoring: `get_gpu_utilization`, `get_gpu_memory`, `get_gpu_temperature`,
`get_gpu_power`, `get_gpu_clocks`, `get_gpu_processes`,
`get_all_gpu_metrics`
History: `get_gpu_history`, `get_gpu_peak_usage`, `get_gpu_health`
AI planning: `estimate_model_fit`, `recommend_gpu_for_model`,
`find_available_gpu`, `compare_gpus`, `detect_gpu_bottleneck`
Always call `list_gpus()` first — every other tool takes a `gpu_id` from it.
### Example
`estimate_model_fit(gpu_id="amd-0000:03:00.0", model_size_b=7,
quantization="q4", context_length=4096, parallel_requests=1,
architecture="qwen2-7b")` — real output from an 8 GiB RX 6600 XT:
```json
{
"gpu_id": "amd-0000:03:00.0",
"available": true,
"weights_gib": 3.26,
"runtime_overhead_gib": 0.5,
"kv_cache_gib_per_request": 0.22,
"total_gib": 3.98,
"vram_total_gib": 7.98,
"vram_free_gib": 7.97,
"fits": true,
"headroom_gib": 3.99,
"assumptions": ["runtime overhead = max(0.5 GiB, 5% of weights)",
"KV cache from architecture 'qwen2-7b'"],
"warnings": []
}
```
A metric that the hardware cannot provide looks like:
```json
{
"available": false,
"reason": "sensor busy — the GPU power management interface refused the read (common when the card is in a low-power state)",
"source": "amd-sysfs"
}
```
## Configuration
Environment variables (all optional):
| Variable | Default | Meaning |
|---|---|---|
| `GPU_MANAGER_SAMPLE_INTERVAL` | `2.0` | background sampling period (s) |
| `GPU_MANAGER_HISTORY_RETENTION_HOURS` | `24` | history window kept |
| `GPU_MANAGER_HISTORY_MAX_ROWS` | `200000` | hard row cap (bounded storage) |
| `GPU_MANAGER_DB_PATH` | `~/.local/share/gpu-manager-mcp/history.sqlite3` | SQLite location |
| `GPU_MANAGER_CACHE_TTL` | `1.0` | telemetry cache TTL (s) for <250 ms repeat queries |
| `GPU_MANAGER_COMMAND_TIMEOUT` | `10` | timeout for allowlisted helper CLIs |
| `GPU_MANAGER_HTTP_ENABLED` | `false` | enable Streamable HTTP transport |
| `GPU_MANAGER_HTTP_HOST` / `_PORT` | `127.0.0.1` / `8940` | loopback-only HTTP bind |
## Security guidance
- The server exposes **monitoring only**. There is no tool that executes
arbitrary commands, changes clocks/fans/voltages, or kills processes.
- Helper CLIs (`nvidia-smi`, `rocm-smi`, `intel_gpu_top`) are invoked from a
fixed allowlist with argument arrays and timeouts — never via a shell and
never with user-supplied strings.
- `gpu_id` values are validated against discovered devices; unknown or
crafted ids are rejected with a clean error.
- The optional HTTP transport binds to loopback by default and refuses
non-loopback hosts unless you explicitly change it — and you should not,
without adding authentication in front of it. Do not expose this server to
the public internet.
- History is local SQLite with a bounded row cap; nothing leaves the machine.
## Known limitations
- **Windows**: AMD telemetry via sysfs is Linux-only; a Windows backend is
planned (AMD-ADL / PDH or `amdsmi` bindings). The server runs on Windows
but will report no AMD devices.
- **AMD hwmon reads can return EBUSY** when the card is in a low-power
state; the reading is reported as unavailable with that explanation.
- **Intel VRAM** is not exposed by i915/xe sysfs; memory metrics are
reported unavailable rather than estimated.
- **KV-cache estimates** are architecture-dependent. Without an
`architecture` hint the server uses documented default assumptions and
flags them. Treat all fit numbers as engineering estimates.
- Per-process VRAM requires NVML or `rocm-smi`; plain sysfs cannot provide it.
## Troubleshooting
- **No GPUs found on Linux** — check `/sys/class/drm/card*/device/vendor`
exists and the driver is `amdgpu`/`i915`/`xe`; NVIDIA needs the proprietary
driver + `nvidia-ml-py` or `nvidia-smi` on PATH.
- **`sensor busy` on AMD** — normal at idle on some cards; retry under load
or check `power_state` in sysfs.
- **Permission denied** — NVML on some setups needs root or
`CAP_SYS_ADMIN`; sysfs sensors are world-readable on standard distros.
- **History empty** — the sampler runs inside the server process; give it a
few sample intervals, or call `get_all_gpu_metrics()` to force samples.
## Development
```bash
pip install -e ".[dev]"
pytest # unit + MCP client tests (mocked hardware)
ruff check src tests
mypy src
python -m build # package validation
```
## License
MIT — see [LICENSE](LICENSE).
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues