# vmcluster-mcp

## What This Is

vmcluster-mcp is a general-purpose MCP server that defines and manages multi-VM clusters on libvirt/QEMU for autonomous test workflows.
It provides topology-driven lifecycle management, artifact distribution and installation, snapshot control, node execution, kernel observability, and fault injection.
v1.0 ships as a complete infrastructure orchestration layer for solo developer use, enabling agents to prepare and reset test clusters end-to-end without manual intervention.

## Core Value

Agents can provision and reset realistic multi-node VM clusters end-to-end without requiring human intervention.

## Requirements

### Validated

- ✓ Server starts, accepts MCP stdio connections, and routes all tool calls through a structured `ToolResult[T]` error contract — v1.0
- ✓ Server configuration loadable from file or environment variables; YAML topology files validated with schema errors — v1.0
- ✓ Agent can define, start, inspect, and destroy topology-declared multi-node VM clusters — v1.0 (CLUS-01..07, all idempotent)
- ✓ Agent can run commands and collect structured output from individual nodes or all nodes in parallel — v1.0 (EXEC-01..03, auto-reconnect after reboot)
- ✓ Agent can create and revert cluster-wide snapshots for reliable test reset points — v1.0 (SNAP-01..04, atomic across all nodes)
- ✓ Agent can register, sync, and install content-addressed build artifacts across cluster nodes — v1.0 (ART-01..05, dedup via sha256)
- ✓ Agent can bracket kernel operations with dmesg markers and collect classified kernel log output — v1.0 (OBS-01..03, oops/panic/KASAN/UBSAN)
- ✓ Agent can inject and heal network and node faults for distributed-system testing — v1.0 (FAULT-01..07, survives MCP restart)

### Active

- User can install vmcluster-mcp from PyPI with a single command (INST-01)
- User can run `vmcluster-mcp setup` wizard to validate host deps and generate config (INST-02, INST-03)
- Setup wizard provides distro-specific install guidance for missing host dependencies (INST-04)
- Setup wizard downloads a known-good base VM image and verifies checksum (INST-05)
- Setup wizard writes MCP server entry into the user's MCP client config (INST-06)
- PyPI releases are published automatically via GitHub Actions on git tag push (INST-07)

### Out of Scope

- Application-specific cluster configuration beyond infrastructure orchestration — downstream consumers handle app/domain setup via ClusterHandle
- Runtime orchestration after ClusterHandle handoff — downstream tools SSH directly; no callback into this server at runtime
- Full RDMA / o2ib provisioning — implementation complexity; deferred to v2
- In-memory SSH connection pooling — v1 correctness-first; pooling deferred until performance data justifies it
- Multi-user RBAC — v1 targets solo developer use; team features deferred
- `artifact_build` (local build trigger) — agents build externally and register via `artifact_register`; deferred to v2
- Memory-state snapshots as default — external disk-only snapshots are the baseline
- Web UI or dashboard — pure MCP stdio interface; no GUI in v1

## Context

- **Shipped:** v1.0 MVP — 2026-03-24
- **Codebase:** ~11,972 Python LOC, 10 phases, 30 plans
- **Tech stack:** Python (uv), FastMCP, Pydantic v2, libvirt-python, asyncssh, iptables/tc-netem
- **Architecture:** Stateless MCP stdio server; all tool results via `ToolResult[T]`; single `ThreadPoolExecutor(max_workers=1)` for all libvirt calls; asyncio fan-out via `asyncio.gather` for multi-node ops
- **Test coverage:** ~800+ tests across phases (124 cluster, 188 snapshot, 228 artifact, 361 fault injection)
- **Primary user:** Project author; solo developer workflow with autonomous agent cluster setup validated end-to-end

## Key Decisions

| Decision | Rationale | Outcome |
|----------|-----------|---------|
| Topology-as-data in YAML | Agent workflows stay declarative and reproducible across runs | ✓ Good — clean separation between topology and orchestration |
| ClusterHandle handoff boundary | Decouples infrastructure provisioning from downstream app logic | ✓ Good — keeps server interface general-purpose |
| Structured tool outputs via Pydantic v2 | Enables deterministic agent behavior and error handling | ✓ Good — `ToolResult[T]` + `@structured_tool_handler` validated as the correct pattern |
| Stateless server architecture | Allows safe process restarts and simpler operational recovery | ✓ Good — fault registry persisted to disk proves out the pattern |
| Single `ThreadPoolExecutor(max_workers=1)` for libvirt | Thread-unsafe C library; concurrent use causes non-deterministic segfaults | ✓ Good — must be in `libvirt_client.py` from first commit |
| asyncssh over paramiko | Pure asyncio; trivial parallel multi-node fan-out via asyncio.gather | ✓ Good — no threading overhead for parallel exec |
| Destroy-all-before-revert for `snapshot_revert` | No atomic multi-domain revert in libvirt; partial reverts fatal | ✓ Good — deterministic state guarantees |
| Atomic artifact registry writes (tmp-rename) | Prevents registry corruption on crash | ✓ Good — not retrofittable without risk |
| External disk-only snapshots (default) | Simpler code path; memory dumps not required for v1 | ✓ Good — sufficient for test-reset use case |
| v1 optimized for autonomous single-user workflow | Fastest path to validating core value before widening scope | ✓ Good — entire v1.0 built and validated in 3 days |

## Constraints

- **Platform**: Linux host with libvirt/QEMU and reachable SSH networking — required for VM lifecycle and remote execution
- **Protocol**: MCP stdio server with structured JSON responses — agents must consume typed outputs, not free-text parsing
- **Automation**: Zero-human-intervention cluster setup in v1 — this is the core success criterion
- **Scope**: Infrastructure orchestration only, not app-specific runtime control — keeps the interface general-purpose and reusable
- **State Model**: No critical in-memory runtime state — restart safety and reproducibility (fault registry persisted to disk)

## Current Milestone: v1.1 Installation Ease-of-Use

**Goal:** Users can go from zero to a fully operational vmcluster-mcp setup with a single command.

**Target features:**
- PyPI package publishing with GitHub Actions CI/CD (tag → auto-publish)
- `vmcluster-mcp setup` interactive wizard: host dep check + distro-specific guidance, config file generation
- Base image helper: download known-good cloud image, verify checksum, place at expected path
- MCP client auto-configuration: detect and write MCP server entry into claude-code / Claude Desktop config

## Evolution

This document evolves at phase transitions and milestone boundaries.

**After each phase transition** (via `/gsd:transition`):
1. Requirements invalidated? → Move to Out of Scope with reason
2. Requirements validated? → Move to Validated with phase reference
3. New requirements emerged? → Add to Active
4. Decisions to log? → Add to Key Decisions
5. "What This Is" still accurate? → Update if drifted

**After each milestone** (via `/gsd:complete-milestone`):
1. Full review of all sections
2. Core Value check — still the right priority?
3. Audit Out of Scope — reasons still valid?
4. Update Context with current state

---
*Last updated: 2026-03-24 — v1.1 milestone started — installation ease-of-use*
