Skip to content

MCP tools — the agent surface

rvmc exposes the workbench’s capabilities to an LLM agent through MCP (rvmc/mcp_tools.py, build_mcp(ctl, pid)), served via Open WebUI. This is how “the agent drives the VM the way a researcher would.” It is also the current area of refinement — the tools are stable; the analyst that orchestrates them is being sharpened.

Scoping & access

  • build_mcp(ctl, pid=None) returns a tool server. With a pid, every instance-scoped tool validates that the target VM belongs to that project, and listing/starting is bound to it — so a per-project endpoint only ever sees that project’s VMs. Open WebUI registers one endpoint per project, scoped to the project’s group.
  • Mutating tools honor a read-only token scope (a read-only access token may not call them).
  • Project access is checked (require_project) on every call.

The tool families

One MCP server is built per project, scoped to that project’s identity group — currently exposing over ninety project-scoped tools. The same server feeds every consumer (chat assistant, the code editor’s assistant, a researcher’s own external agent, and rvmc’s own analyst agent) without duplication.

FamilyTools (representative)
Catalog / lifecyclelist_catalog, list_instances, start_vm, power_vm, create_snapshot, revert_snapshot
Guest controlguest_run, guest_python, guest_read_file, guest_write_file, guest_list_dir, guest_send_keys, guest_click, guest_screenshot, guest_event_log, guest_process_list, guest_reg_read/write
Screen / inputsend_key, screenshot, list_resolutions, set_resolution
Media / capturecapture_start, capture_recent, capture_search, capture_summary, record_*
Discs / data-linklist_isos, insert_cd, eject_cd, datalink_*
Dead-web revivalwbc_* — point the guest’s browser at the per-project cache proxy, install the interception certificate, toggle archive replay
Analysis (autopsy bridge)analysis_start, analysis_status, analysis_report, analysis_confirm, analysis_cancel, autopsy_report

The shared wayback-mcp side-car

Separate from the per-project server, a shared wayback-mcp MCP server sits alongside the family as a common side-car over the Internet Archive’s Wayback Machine. Four read-only tools do the work: wayback_snapshots (the CDX index of every capture of a URL, with timestamp, status and content-type, era-scoped), wayback_available (the capture closest to a moment), wayback_fetch (the ground truth — the archived bytes and content-type), and wayback_prognosis (cheap triage over a cluster of dead URLs). The autopsy analyst drives it — through a wayback specialist sub-agent — to establish what each dead endpoint served, turning “endpoint gone” into a concrete revival contract; rvmc points its guest-side cache proxy at the same container to serve those captures back into the VM.

The autopsy ↔ agent loop

The analysis tools are what let the agent act on the autopsy, not just start VMs blind:

  • autopsy_report — a curated, action-oriented digest: the verdict, the suggested base VM plus the matching catalog goldens (catalog_matches, ready to feed start_vm), the network endpoints the work reaches (a dead host is something to serve from an archive, not ignore), and the runbook steps. Read this before start_vm to pick the right golden and know what to watch for.
  • analysis_status — surfaces the preflight pause (awaiting-confirmation) and its report.
  • analysis_confirm / analysis_cancel — let the agent drive the preflight gate: proceed (an installer can be the artwork) or decline. Both are mutating (read-only tokens can’t call them).

analysis_report returns the full deliverables; autopsy_report is the flattened “here’s what to do” version for an agent deciding its next move.

Adding a tool

  • Register with @m.tool() inside build_mcp; take ctx: Context and gate access (_guard/require_project, and _deny_read_only for mutating tools).
  • Keep the docstring operational — the model reads it to decide when to call the tool. Say what it returns and when to use it (e.g. “read this before start_vm”).
  • Return plain JSON-serializable data. Reuse the controller (ctl) methods the REST API uses, so the tool and the HTTP surface stay in lockstep.
  • Add it to the test that asserts the tool set registers.

Note: no from __future__ import annotations in this module — it stringifies annotations and breaks FastMCP’s tool introspection.