Make the docs and help text unapologetically teach as the product path for Claude Code, Codex, and OpenCode on Linux KVM.
Rewrite the README, install/first-run/integration guides, public contract, vision, and use-case docs around the zero-to-hero chat flow, and explicitly note that there are no users yet so breaking changes are acceptable while the interface is still being shaped.
Update package metadata, CLI help, and the docs/help expectation tests to match the new positioning. Validate the reframe with usage: pyro [-h] [--version] COMMAND ...
Validate the host and serve disposable MCP workspaces for chat-based coding agents on supported Linux x86_64 KVM hosts.
positional arguments:
COMMAND
env Inspect and manage curated environments.
mcp Run the MCP server.
run Run one command inside an ephemeral VM.
workspace Manage persistent workspaces.
doctor Inspect runtime and host diagnostics.
demo Run built-in demos.
options:
-h, --help show this help message and exit
--version show program's version number and exit
Suggested zero-to-hero path:
pyro doctor
pyro env list
pyro env pull debian:12
pyro run debian:12 -- git --version
pyro mcp serve
Connect a chat host after that:
claude mcp add pyro -- uvx --from pyro-mcp pyro mcp serve
codex mcp add pyro -- uvx --from pyro-mcp pyro mcp serve
If you want terminal-level visibility into the workspace model:
pyro workspace create debian:12 --seed-path ./repo --id-only
pyro workspace sync push WORKSPACE_ID ./changes
pyro workspace exec WORKSPACE_ID -- cat note.txt
pyro workspace diff WORKSPACE_ID
pyro workspace snapshot create WORKSPACE_ID checkpoint
pyro workspace reset WORKSPACE_ID --snapshot checkpoint
pyro workspace shell open WORKSPACE_ID --id-only
pyro workspace service start WORKSPACE_ID app --ready-file .ready -- sh -lc 'touch .ready && while true; do sleep 60; done'
pyro workspace export WORKSPACE_ID note.txt --output ./note.txt, usage: pyro mcp serve [-h] [--profile {vm-run,workspace-core,workspace-full}]
Expose pyro tools over stdio for an MCP client. Bare `pyro mcp serve` now starts `workspace-core`, the recommended first profile for most chat hosts.
options:
-h, --help show this help message and exit
--profile {vm-run,workspace-core,workspace-full}
Expose only one model-facing tool profile. `workspace-
core` is the default and recommended first profile for
most chat hosts; `workspace-full` is the larger opt-in
profile. (default: workspace-core)
Default and recommended first start:
pyro mcp serve
Profiles:
workspace-core: default for normal persistent chat editing
vm-run: smallest one-shot-only surface
workspace-full: larger opt-in surface for shells, services,
snapshots, secrets, network policy, and disk tools
Use --profile workspace-full only when the host truly needs those
extra workspace capabilities., and uv run ruff check .
All checks passed!
uv run mypy
Success: no issues found in 61 source files
uv run pytest -n auto
============================= test session starts ==============================
platform linux -- Python 3.12.10, pytest-9.0.2, pluggy-1.6.0
rootdir: /home/thales/projects/personal/pyro
configfile: pyproject.toml
testpaths: tests
plugins: anyio-4.12.1, xdist-3.8.0, cov-7.0.0
created: 32/32 workers
32 workers [393 items]
........................................................................ [ 18%]
........................................................................ [ 36%]
........................................................................ [ 54%]
........................................................................ [ 73%]
........................................................................ [ 91%]
................................. [100%]
=============================== warnings summary ===============================
../../../.local/share/uv/python/cpython-3.12.10-linux-x86_64-gnu/lib/python3.12/importlib/metadata/__init__.py:467: 32 warnings
/home/thales/.local/share/uv/python/cpython-3.12.10-linux-x86_64-gnu/lib/python3.12/importlib/metadata/__init__.py:467: DeprecationWarning: Implicit None on return values is deprecated and will raise KeyErrors.
return self.metadata['Version']
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
================================ tests coverage ================================
_______________ coverage: platform linux, python 3.12.10-final-0 _______________
Name Stmts Miss Cover Missing
-------------------------------------------------------------------------
src/pyro_mcp/__init__.py 25 0 100%
src/pyro_mcp/api.py 307 7 98% 37-38, 63, 69, 72, 75, 548
src/pyro_mcp/cli.py 1132 141 88% 288-289, 332-333, 336, 344, 367-368, 394-395, 398, 406, 450, 460-461, 464, 477, 483-484, 498-499, 502, 566-575, 592-593, 596, 635, 2180, 2182, 2226, 2236, 2280, 2284-2285, 2295, 2302, 2344-2351, 2392, 2409-2414, 2459-2461, 2470-2472, 2483-2485, 2494-2496, 2503-2505, 2510-2512, 2523-2528, 2530, 2541-2546, 2567-2572, 2574, 2589-2594, 2596, 2608, 2623, 2637, 2655-2660, 2669-2674, 2676, 2683-2688, 2690, 2701-2706, 2708, 2719-2724, 2726, 2737-2742, 2764, 2787, 2806, 2824, 2841, 2899, 3017
src/pyro_mcp/contract.py 52 0 100%
src/pyro_mcp/demo.py 16 0 100%
src/pyro_mcp/doctor.py 12 0 100%
src/pyro_mcp/ollama_demo.py 245 6 98% 289, 294, 299, 318, 439, 550
src/pyro_mcp/runtime.py 142 14 90% 80, 84, 88, 92, 120, 130, 144, 173, 182, 194, 230-232, 262
src/pyro_mcp/runtime_boot_check.py 33 0 100%
src/pyro_mcp/runtime_build.py 546 47 91% 92, 127, 181, 189, 238-240, 263-265, 300, 325, 331, 340-341, 343, 392, 396, 413, 416, 492-494, 497-499, 522, 525, 578, 615, 620, 646-647, 649, 686, 688, 694, 697, 725, 765, 779, 791, 805, 808, 1002, 1009, 1198
src/pyro_mcp/runtime_bundle/__init__.py 0 0 100%
src/pyro_mcp/runtime_network_check.py 15 0 100%
src/pyro_mcp/server.py 8 0 100%
src/pyro_mcp/vm_environments.py 386 55 86% 128, 131, 267, 274, 281, 304-306, 329-331, 352-353, 355, 380, 382, 392-394, 415, 418, 421, 429, 431, 436-437, 446-448, 488, 495-496, 502, 515, 526, 539, 546, 549, 570, 596, 599, 608-609, 613, 617, 626, 629, 636, 644, 647, 659, 667, 676, 682, 685
src/pyro_mcp/vm_firecracker.py 47 0 100%
src/pyro_mcp/vm_guest.py 206 22 89% 139, 142, 173, 176, 202, 205, 208, 211, 217, 239, 262-279, 291, 313, 633-634, 643
src/pyro_mcp/vm_manager.py 2846 355 88% 625, 642, 650-657, 677, 684, 688, 712-715, 795-796, 818, 828, 830, 845, 853-855, 858, 870, 872, 881, 889, 892, 901-902, 910, 913, 919, 926, 929, 933, 951-955, 1010-1011, 1050, 1096, 1102, 1114, 1150, 1156, 1159, 1168, 1170, 1173-1177, 1230, 1236, 1239, 1248, 1250, 1253-1257, 1268, 1277, 1280, 1284-1290, 1319, 1322-1324, 1326, 1333, 1335, 1345, 1347, 1349, 1352-1353, 1361, 1377, 1379, 1381, 1391, 1403-1404, 1408, 1424, 1440-1441, 1443, 1447, 1450-1451, 1469, 1476, 1488, 1505, 1508-1509, 1511, 1582-1583, 1586-1588, 1599, 1602, 1605, 1617, 1638, 1649-1650, 1657-1658, 1669-1671, 1781, 1792-1798, 1808, 1860, 1870, 1891, 1894-1895, 1901-1904, 1910, 1922-1962, 1991-1993, 2034, 2046-2047, 2077, 2146, 2175, 2524-2528, 2598-2602, 2614, 2720, 3563, 3577, 3580, 3583, 3648-3653, 3720, 3802, 3842-3843, 3846-3847, 3862-3863, 3914, 4194, 4229, 4232, 4237, 4250, 4254, 4263, 4277, 4316, 4349, 4444, 4472-4473, 4477-4478, 4504, 4530-4531, 4576, 4578, 4600-4601, 4629, 4631, 4661-4662, 4681-4682, 4734, 4738, 4741-4743, 4745, 4747, 4776-4777, 4809-4845, 4863-4864, 4903, 4905, 4934, 4954-4955, 4977, 4988-4990, 5036, 5049-5050, 5059-5061, 5104-5105, 5171-5178, 5189-5192, 5203, 5208, 5216-5230, 5240, 5473-5476, 5485-5490, 5498-5503, 5513, 5557, 5577, 5601-5602, 5678-5680, 5706-5725, 5784, 5789, 5804, 5832, 5836, 5848, 5884-5886, 5946, 5950, 6079, 6111, 6155, 6170, 6189, 6201, 6242, 6251, 6256, 6269, 6274, 6296, 6394, 6422-6423
src/pyro_mcp/vm_network.py 134 22 84% 65-66, 139, 201, 203, 205, 226, 317-331, 350-351, 360, 362, 372-384
src/pyro_mcp/workspace_disk.py 164 0 100%
src/pyro_mcp/workspace_files.py 293 0 100%
src/pyro_mcp/workspace_ports.py 79 1 99% 116
src/pyro_mcp/workspace_shell_output.py 88 2 98% 16, 61
src/pyro_mcp/workspace_shells.py 235 26 89% 105-118, 193-194, 226-227, 230-235, 251, 257-259, 263, 270-271, 299, 301, 303, 306-307
src/pyro_mcp/workspace_use_case_smokes.py 216 8 96% 131, 134-135, 423-426, 490
-------------------------------------------------------------------------
TOTAL 7227 706 90%
Required test coverage of 90% reached. Total coverage: 90.23%
======================= 393 passed, 32 warnings in 5.60s =======================.
4.5 KiB
Public Contract
This document describes the chat way to use pyro-mcp in 4.x.
pyro-mcp currently has no users. Expect breaking changes while this chat-host
path is still being shaped.
This document is intentionally biased. It describes the path users are meant to follow today:
- prove the host with the terminal companion commands
- serve disposable workspaces over MCP
- connect Claude Code, Codex, or OpenCode
- use the recipe-backed workflows
This page does not try to document every building block in the repo. It documents the chat-host path the project is actively shaping.
Package Identity
- distribution name:
pyro-mcp - public executable:
pyro - primary product entrypoint:
pyro mcp serve
pyro-mcp is a disposable MCP workspace for chat-based coding agents on Linux
x86_64 KVM hosts.
Supported Product Path
The intended user journey is:
pyro doctorpyro env listpyro env pull debian:12pyro run debian:12 -- git --versionpyro mcp serve- connect Claude Code, Codex, or OpenCode
- run one of the documented recipe-backed workflows
- validate the whole story with
make smoke-use-cases
Evaluator CLI
These terminal commands are the documented companion path for the chat-host product:
pyro doctorpyro env listpyro env pullpyro runpyro demo
What to expect from that path:
pyro run <environment> -- <command>defaults to1 vCPU / 1024 MiBpyro runfails if guest boot or guest exec is unavailable unless--allow-host-compatis setpyro run,pyro env list,pyro env pull,pyro env inspect,pyro env prune, andpyro doctorare human-readable by default and return structured JSON with--json- the first official environment pull downloads from public Docker Hub into the local environment cache
pyro demoproves the one-shot create/start/exec/delete VM lifecycle end to end
These commands exist to validate and debug the chat-host path. They are not the main product destination.
MCP Entry Point
The product entrypoint is:
pyro mcp serve
What to expect:
- bare
pyro mcp servestartsworkspace-core workspace-coreis the default product path for chat hostspyro mcp serve --profile workspace-fullexplicitly opts into the larger tool surfacepyro mcp serve --profile vm-runexposes the smallest one-shot-only surface
Host-specific setup docs:
Chat-Facing Workspace Contract
workspace-core is the normal chat path. It exposes:
vm_runworkspace_createworkspace_listworkspace_updateworkspace_statusworkspace_sync_pushworkspace_execworkspace_logsworkspace_file_listworkspace_file_readworkspace_file_writeworkspace_patch_applyworkspace_diffworkspace_exportworkspace_resetworkspace_delete
That is enough for the normal persistent editing loop:
- create one workspace
- sync or seed repo content
- inspect and edit files without shell quoting
- run commands repeatedly in one sandbox
- diff and export results
- reset and retry
- delete the workspace when the task is done
Move to workspace-full only when the chat truly needs:
- persistent PTY shell sessions
- long-running services and readiness probes
- secrets
- guest networking and published ports
- stopped-workspace disk inspection
Recipe-Backed Workflows
The documented product workflows are:
| Workflow | Recommended profile | Doc |
|---|---|---|
| Cold-start repo validation | workspace-full |
use-cases/cold-start-repo-validation.md |
| Repro plus fix loop | workspace-core |
use-cases/repro-fix-loop.md |
| Parallel isolated workspaces | workspace-core |
use-cases/parallel-workspaces.md |
| Unsafe or untrusted code inspection | workspace-core |
use-cases/untrusted-inspection.md |
| Review and evaluation workflows | workspace-full |
use-cases/review-eval-workflows.md |
Treat this smoke pack as the trustworthy guest-backed verification path for the advertised product:
make smoke-use-cases
The chat-host MCP path above is the thing the docs are intentionally shaping around.