Unify public UX around pyro CLI and Pyro facade
This commit is contained in:
parent
d16aadd03f
commit
23a2dfb330
19 changed files with 936 additions and 407 deletions
264
README.md
264
README.md
|
|
@ -1,170 +1,200 @@
|
|||
# pyro-mcp
|
||||
|
||||
`pyro-mcp` is an MCP-compatible tool package for running ephemeral development environments with a VM lifecycle API.
|
||||
`pyro-mcp` is a Firecracker-backed sandbox for coding agents.
|
||||
|
||||
## v0.1.0 Capabilities
|
||||
It exposes the same runtime in two public forms:
|
||||
|
||||
- Split lifecycle tools for coding agents: `vm_list_profiles`, `vm_create`, `vm_start`, `vm_exec`, `vm_stop`, `vm_delete`, `vm_status`, `vm_network_info`, `vm_reap_expired`.
|
||||
- Standard environment profiles:
|
||||
- `debian-base`: minimal Debian shell/core Unix tools.
|
||||
- `debian-git`: Debian base with Git preinstalled.
|
||||
- `debian-build`: Debian Git profile with common build tooling.
|
||||
- Explicit sizing contract for agents (`vcpu_count`, `mem_mib`) with guardrails.
|
||||
- Strict ephemerality for command execution (`vm_exec` auto-deletes VM on completion).
|
||||
- Ollama demo that asks an LLM to clone a small public Git repository through lifecycle tools.
|
||||
- a `pyro` CLI
|
||||
- a Python SDK via `from pyro_mcp import Pyro`
|
||||
|
||||
## Runtime
|
||||
It also ships an MCP server so LLM clients can use the same VM runtime through tools.
|
||||
|
||||
The package includes a bundled Linux x86_64 runtime payload:
|
||||
- Firecracker binary
|
||||
- Jailer binary
|
||||
- Profile artifacts for `debian-base`, `debian-git`, and `debian-build`
|
||||
## Public UX
|
||||
|
||||
No system Firecracker installation is required for basic usage.
|
||||
Primary install/run path:
|
||||
|
||||
Current status:
|
||||
- The bundled runtime is real, not shim-based.
|
||||
- `doctor` reports real guest capability flags for VM boot, guest exec, and guest networking.
|
||||
- `vm_exec` now runs in `guest_vsock` mode when the VM is started from the bundled runtime.
|
||||
- Networking still requires host privileges for TAP/NAT setup; see the networking section below.
|
||||
```bash
|
||||
uvx --from pyro-mcp pyro mcp serve
|
||||
```
|
||||
|
||||
Host requirements still apply:
|
||||
- Linux host
|
||||
- `/dev/kvm` available for full virtualization mode
|
||||
Installed package path:
|
||||
|
||||
```bash
|
||||
pyro mcp serve
|
||||
```
|
||||
|
||||
The public user-facing interface is `pyro` and `Pyro`.
|
||||
`Makefile` targets are contributor conveniences for this repository and are not the primary product UX.
|
||||
|
||||
## Capabilities
|
||||
|
||||
- Firecracker microVM execution with bundled runtime artifacts
|
||||
- standard profiles:
|
||||
- `debian-base`
|
||||
- `debian-git`
|
||||
- `debian-build`
|
||||
- high-level one-shot execution via `vm_run` / `Pyro.run_in_vm(...)`
|
||||
- low-level lifecycle control when needed:
|
||||
- `vm_create`
|
||||
- `vm_start`
|
||||
- `vm_exec`
|
||||
- `vm_stop`
|
||||
- `vm_delete`
|
||||
- `vm_status`
|
||||
- `vm_network_info`
|
||||
- `vm_reap_expired`
|
||||
- outbound guest networking with explicit opt-in
|
||||
|
||||
## Requirements
|
||||
|
||||
- Linux host
|
||||
- `/dev/kvm`
|
||||
- Python 3.12+
|
||||
- `uv`
|
||||
- Optional for Ollama demo: local Ollama server and `llama:3.2-3b` model.
|
||||
- host privilege for TAP/NAT setup when using guest networking
|
||||
|
||||
## Setup
|
||||
The current implementation uses `sudo -n` for `ip`, `nft`, and `iptables` when networked runs are requested.
|
||||
|
||||
## CLI
|
||||
|
||||
Start the MCP server:
|
||||
|
||||
```bash
|
||||
make setup
|
||||
pyro mcp serve
|
||||
```
|
||||
|
||||
## Build runtime bundle
|
||||
Run one command in an ephemeral VM:
|
||||
|
||||
```bash
|
||||
make runtime-bundle
|
||||
pyro run --profile debian-git --vcpu-count 1 --mem-mib 1024 -- git --version
|
||||
```
|
||||
|
||||
This builds the packaged runtime bundle from `runtime_sources/` and syncs the result into `src/pyro_mcp/runtime_bundle/`.
|
||||
For real artifacts, first materialize upstream sources into `build/runtime_sources/`.
|
||||
|
||||
Available staged targets:
|
||||
- `make runtime-binaries`
|
||||
- `make runtime-kernel`
|
||||
- `make runtime-rootfs`
|
||||
- `make runtime-agent`
|
||||
- `make runtime-validate`
|
||||
- `make runtime-manifest`
|
||||
- `make runtime-sync`
|
||||
- `make runtime-clean`
|
||||
|
||||
Available real-runtime targets:
|
||||
- `make runtime-fetch-binaries`
|
||||
- `make runtime-build-kernel-real`
|
||||
- `make runtime-build-rootfs-real`
|
||||
- `make runtime-materialize`
|
||||
- `make runtime-boot-check`
|
||||
- `make runtime-network-check`
|
||||
|
||||
Notes:
|
||||
- the real-source path depends on `docker`, outbound access to GitHub and Debian snapshot mirrors, and enough disk for kernel/rootfs builds
|
||||
- `make runtime-boot-check` validates that the bundled runtime can boot a real microVM
|
||||
- `make runtime-network-check` validates outbound internet access from inside the guest by cloning `https://github.com/octocat/Hello-World.git`
|
||||
|
||||
## Run deterministic lifecycle demo
|
||||
Run with outbound internet enabled:
|
||||
|
||||
```bash
|
||||
make demo
|
||||
pyro run --profile debian-git --vcpu-count 1 --mem-mib 1024 --network -- \
|
||||
"git clone --depth 1 https://github.com/octocat/Hello-World.git hello-world && git -C hello-world rev-parse --is-inside-work-tree"
|
||||
```
|
||||
|
||||
The demo creates a VM, starts it, runs a command, and returns structured output.
|
||||
If the VM was started with networking enabled, it uses an internet probe.
|
||||
Otherwise it runs `git --version`.
|
||||
|
||||
To run the deterministic demo with guest networking enabled:
|
||||
Show runtime and host diagnostics:
|
||||
|
||||
```bash
|
||||
make network-demo
|
||||
pyro doctor
|
||||
```
|
||||
|
||||
## Runtime doctor
|
||||
Run the deterministic demo:
|
||||
|
||||
```bash
|
||||
make doctor
|
||||
pyro demo
|
||||
pyro demo --network
|
||||
```
|
||||
|
||||
This prints bundled runtime paths, profile availability, checksum validation status, runtime capability flags, KVM host checks, and host networking diagnostics.
|
||||
|
||||
## Networking
|
||||
|
||||
- Host-side network allocation and diagnostics are implemented.
|
||||
- The MCP server exposes `vm_network_info` for per-VM network metadata.
|
||||
- Primary network-enabled entrypoints:
|
||||
|
||||
```bash
|
||||
make network-demo
|
||||
make ollama-demo
|
||||
```
|
||||
|
||||
- Network setup requires host privilege to manage TAP/NAT state.
|
||||
- The current implementation auto-uses `sudo -n` for `ip`, `nft`, and `iptables` commands when available.
|
||||
- Manual opt-in for other commands is still available with:
|
||||
|
||||
```bash
|
||||
PYRO_VM_ENABLE_NETWORK=1 make demo
|
||||
```
|
||||
|
||||
- To validate real guest egress directly:
|
||||
|
||||
```bash
|
||||
make runtime-network-check
|
||||
```
|
||||
|
||||
## Run Ollama lifecycle demo
|
||||
Run the Ollama demo:
|
||||
|
||||
```bash
|
||||
ollama serve
|
||||
ollama pull llama:3.2-3b
|
||||
make ollama-demo
|
||||
pyro demo ollama
|
||||
```
|
||||
|
||||
Defaults are configured in `Makefile`.
|
||||
The demo streams lifecycle progress logs and ends with a short text summary.
|
||||
`make ollama-demo` now enables guest networking by default.
|
||||
The command it asks the model to run is a small public repository clone:
|
||||
Verbose Ollama logs:
|
||||
|
||||
```bash
|
||||
rm -rf hello-world && git clone --depth 1 https://github.com/octocat/Hello-World.git hello-world >/dev/null && git -C hello-world rev-parse --is-inside-work-tree
|
||||
```
|
||||
By default it omits log values; to include prompt content, tool args, and tool results use:
|
||||
|
||||
```bash
|
||||
make ollama-demo OLLAMA_DEMO_FLAGS=-v
|
||||
pyro demo ollama -v
|
||||
```
|
||||
|
||||
## Run MCP server
|
||||
## Python SDK
|
||||
|
||||
```bash
|
||||
make run-server
|
||||
```python
|
||||
from pyro_mcp import Pyro
|
||||
|
||||
pyro = Pyro()
|
||||
result = pyro.run_in_vm(
|
||||
profile="debian-git",
|
||||
command="git --version",
|
||||
vcpu_count=1,
|
||||
mem_mib=1024,
|
||||
timeout_seconds=30,
|
||||
network=False,
|
||||
)
|
||||
print(result["stdout"])
|
||||
```
|
||||
|
||||
## Quality checks
|
||||
Lower-level lifecycle control remains available:
|
||||
|
||||
```python
|
||||
from pyro_mcp import Pyro
|
||||
|
||||
pyro = Pyro()
|
||||
created = pyro.create_vm(
|
||||
profile="debian-git",
|
||||
vcpu_count=1,
|
||||
mem_mib=1024,
|
||||
ttl_seconds=600,
|
||||
network=True,
|
||||
)
|
||||
vm_id = created["vm_id"]
|
||||
pyro.start_vm(vm_id)
|
||||
result = pyro.exec_vm(vm_id, command="git --version", timeout_seconds=30)
|
||||
print(result["stdout"])
|
||||
```
|
||||
|
||||
## MCP Tools
|
||||
|
||||
Primary agent-facing tool:
|
||||
|
||||
- `vm_run(profile, command, vcpu_count, mem_mib, timeout_seconds=30, ttl_seconds=600, network=false)`
|
||||
|
||||
Advanced lifecycle tools:
|
||||
|
||||
- `vm_list_profiles()`
|
||||
- `vm_create(profile, vcpu_count, mem_mib, ttl_seconds=600, network=false)`
|
||||
- `vm_start(vm_id)`
|
||||
- `vm_exec(vm_id, command, timeout_seconds=30)`
|
||||
- `vm_stop(vm_id)`
|
||||
- `vm_delete(vm_id)`
|
||||
- `vm_status(vm_id)`
|
||||
- `vm_network_info(vm_id)`
|
||||
- `vm_reap_expired()`
|
||||
|
||||
## Runtime
|
||||
|
||||
The package ships a bundled Linux x86_64 runtime payload with:
|
||||
|
||||
- Firecracker
|
||||
- Jailer
|
||||
- guest kernel
|
||||
- guest agent
|
||||
- profile rootfs images
|
||||
|
||||
No system Firecracker installation is required.
|
||||
|
||||
Runtime diagnostics:
|
||||
|
||||
```bash
|
||||
pyro doctor
|
||||
```
|
||||
|
||||
The doctor report includes:
|
||||
|
||||
- runtime integrity
|
||||
- component versions
|
||||
- capability flags
|
||||
- KVM availability
|
||||
- host networking prerequisites
|
||||
|
||||
## Contributor Workflow
|
||||
|
||||
For work inside this repository:
|
||||
|
||||
```bash
|
||||
make help
|
||||
make setup
|
||||
make check
|
||||
```
|
||||
|
||||
Includes `ruff`, `mypy`, and `pytest` with coverage threshold.
|
||||
Runtime build and validation helpers remain available through `make`, including:
|
||||
|
||||
## Pre-commit
|
||||
|
||||
```bash
|
||||
make install-hooks
|
||||
```
|
||||
|
||||
Hooks execute the same lint/type/test gates.
|
||||
- `make runtime-bundle`
|
||||
- `make runtime-materialize`
|
||||
- `make runtime-boot-check`
|
||||
- `make runtime-network-check`
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue