pyro-mcp/README.md

255 lines
5.5 KiB
Markdown

# pyro-mcp
`pyro-mcp` is a Firecracker-backed sandbox for coding agents.
It exposes the same runtime in two public forms:
- a `pyro` CLI
- a Python SDK via `from pyro_mcp import Pyro`
It also ships an MCP server so LLM clients can use the same VM runtime through tools.
## Start Here
- Install: [docs/install.md](/home/thales/projects/personal/pyro/docs/install.md)
- Host requirements: [docs/host-requirements.md](/home/thales/projects/personal/pyro/docs/host-requirements.md)
- Public contract: [docs/public-contract.md](/home/thales/projects/personal/pyro/docs/public-contract.md)
- Troubleshooting: [docs/troubleshooting.md](/home/thales/projects/personal/pyro/docs/troubleshooting.md)
## Public UX
Primary install/run path:
```bash
uvx --from pyro-mcp pyro mcp serve
```
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.
Check the installed CLI version:
```bash
pyro --version
```
## Repository Storage
This repository uses Git LFS for the packaged runtime images under
`src/pyro_mcp/runtime_bundle/`.
Fresh contributor setup:
```bash
git lfs install
git clone <repo>
cd pyro
git lfs pull
make setup
```
The large files tracked through LFS are:
- `src/pyro_mcp/runtime_bundle/**/rootfs.ext4`
- `src/pyro_mcp/runtime_bundle/**/vmlinux`
If you are working from an older clone created before the LFS migration, reclone or realign your branch to the rewritten history before doing more work.
## 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+
- host privilege for TAP/NAT setup when using guest networking
The current implementation uses `sudo -n` for `ip`, `nft`, and `iptables` when networked runs are requested.
## CLI
Start the MCP server:
```bash
pyro mcp serve
```
Run one command in an ephemeral VM:
```bash
pyro run --profile debian-git --vcpu-count 1 --mem-mib 1024 -- git --version
```
Run with outbound internet enabled:
```bash
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"
```
Show runtime and host diagnostics:
```bash
pyro doctor
```
Run the deterministic demo:
```bash
pyro demo
pyro demo --network
```
Run the Ollama demo:
```bash
ollama serve
ollama pull llama:3.2-3b
pyro demo ollama
```
Verbose Ollama logs:
```bash
pyro demo ollama -v
```
## Integration Examples
- Python one-shot SDK example: [examples/python_run.py](/home/thales/projects/personal/pyro/examples/python_run.py)
- Python lifecycle example: [examples/python_lifecycle.py](/home/thales/projects/personal/pyro/examples/python_lifecycle.py)
- MCP client config example: [examples/mcp_client_config.md](/home/thales/projects/personal/pyro/examples/mcp_client_config.md)
- Agent-ready `vm_run` example: [examples/agent_vm_run.py](/home/thales/projects/personal/pyro/examples/agent_vm_run.py)
## Python SDK
```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"])
```
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"])
```
The recommended agent-facing default is still one-shot execution through `run_in_vm(...)` / `vm_run`.
Use lifecycle methods only when the agent needs VM state to persist across multiple calls.
## 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
make dist-check
```
Runtime build and validation helpers remain available through `make`, including:
- `make runtime-bundle`
- `make runtime-materialize`
- `make runtime-boot-check`
- `make runtime-network-check`
Space cleanup after runtime work:
```bash
rm -rf build
git lfs prune
```
Recreating `.venv/` is also a straightforward way to reclaim local disk if needed.