pyro-mcp/docs/install.md
Thales Maciel 9e11dcf9ab Add task sync push milestone
Tasks could start from host content in 2.2.0, but there was still no post-create path to update a live workspace from the host. This change adds the next host-to-task step so repeated fix or review loops do not require recreating the task for every local change.

Add task sync push across the CLI, Python SDK, and MCP server, reusing the existing safe archive import path from seeded task creation instead of introducing a second transfer stack. The implementation keeps sync separate from workspace_seed metadata, validates destinations under /workspace, and documents the current non-atomic recovery path as delete-and-recreate.

Validation:
- uv lock
- UV_CACHE_DIR=.uv-cache uv run pytest --no-cov tests/test_cli.py tests/test_vm_manager.py tests/test_api.py tests/test_server.py tests/test_public_contract.py
- UV_CACHE_DIR=.uv-cache make check
- UV_CACHE_DIR=.uv-cache make dist-check
- real guest-backed smoke: task create --source-path, task sync push, task exec to verify both files, task delete
2026-03-11 22:20:55 -03:00

5 KiB

Install

Support Matrix

Supported today:

  • Linux x86_64
  • Python 3.12+
  • uv
  • /dev/kvm

Optional for outbound guest networking:

  • ip
  • nft or iptables
  • privilege to create TAP devices and configure NAT

Not supported today:

  • macOS
  • Windows
  • Linux hosts without working KVM at /dev/kvm

If you do not already have uv, install it first:

python -m pip install uv

Use these command forms consistently:

  • published package without install: uvx --from pyro-mcp pyro ...
  • installed package: pyro ...
  • source checkout: uv run pyro ...

Fastest Evaluation Path

Use either of these equivalent evaluator paths:

# Package without install
uvx --from pyro-mcp pyro doctor
uvx --from pyro-mcp pyro env list
uvx --from pyro-mcp pyro env pull debian:12
uvx --from pyro-mcp pyro run debian:12 -- git --version
# Already installed
pyro doctor
pyro env list
pyro env pull debian:12
pyro run debian:12 -- git --version

If you are running from a repo checkout instead, replace pyro with uv run pyro.

1. Check the host first

uvx --from pyro-mcp pyro doctor

Expected success signals:

Platform: linux-x86_64
Runtime: PASS
KVM: exists=yes readable=yes writable=yes
Environment cache: /home/you/.cache/pyro-mcp/environments
Capabilities: vm_boot=yes guest_exec=yes guest_network=yes
Networking: tun=yes ip_forward=yes

If Runtime: FAIL, stop here and use troubleshooting.md.

2. Inspect the catalog

uvx --from pyro-mcp pyro env list

Expected output:

Catalog version: 2.3.0
debian:12 [installed|not installed] Debian 12 environment with Git preinstalled for common agent workflows.
debian:12-base [installed|not installed] Minimal Debian 12 environment for shell and core Unix tooling.
debian:12-build [installed|not installed] Debian 12 environment with Git and common build tools preinstalled.

3. Pull the default environment

uvx --from pyro-mcp pyro env pull debian:12

The first pull downloads an OCI environment from public Docker Hub, requires outbound HTTPS access to registry-1.docker.io, and needs local cache space for the guest image. See host-requirements.md for the full host requirements.

Expected success signals:

[pull] phase=install environment=debian:12
[pull] phase=ready environment=debian:12
Pulled: debian:12
...

4. Run one command in a guest

uvx --from pyro-mcp pyro run debian:12 -- git --version

Expected success signals:

[run] phase=create environment=debian:12
[run] phase=start vm_id=...
[run] phase=execute vm_id=...
[run] environment=debian:12 execution_mode=guest_vsock exit_code=0 duration_ms=...
git version ...

The guest command output and the [run] ... summary are written to different streams, so they may appear in either order in terminals or capture tools. Use --json if you need a deterministic structured result.

If guest execution is unavailable, the command fails unless you explicitly pass --allow-host-compat.

5. Optional demo proof point

uvx --from pyro-mcp pyro demo

pyro demo proves the one-shot create/start/exec/delete VM lifecycle works end to end.

Example output:

{
  "cleanup": {
    "deleted": true,
    "reason": "post_exec_cleanup",
    "vm_id": "..."
  },
  "command": "git --version",
  "environment": "debian:12",
  "execution_mode": "guest_vsock",
  "exit_code": 0,
  "stdout": "git version ...\n"
}

For a fuller copy-pasteable transcript, see first-run.md. When you are done evaluating and want to remove stale cached environments, run pyro env prune.

Installed CLI

If you already installed the package, the same evaluator path works with plain pyro ...:

uv tool install pyro-mcp
pyro --version
pyro doctor
pyro env list
pyro env pull debian:12
pyro run debian:12 -- git --version

After the CLI path works, you can move on to:

  • persistent workspaces: pyro task create debian:12 --source-path ./repo
  • live task updates: pyro task sync push TASK_ID ./changes
  • MCP: pyro mcp serve
  • Python SDK: from pyro_mcp import Pyro
  • Demos: pyro demo or pyro demo --network

Persistent Task Workspace

Use pyro task ... when you need repeated commands in one sandbox instead of one-shot pyro run.

pyro task create debian:12 --source-path ./repo
pyro task sync push TASK_ID ./changes --dest src
pyro task exec TASK_ID -- cat src/note.txt
pyro task logs TASK_ID
pyro task delete TASK_ID

Task commands default to the persistent /workspace directory inside the guest. If you need the task identifier programmatically, use --json and read the task_id field. Use --source-path when the task should start from a host directory or a local .tar / .tar.gz / .tgz archive. Use pyro task sync push for later host-side changes to a started task. Sync is non-atomic in 2.3.0; if it fails partway through, delete and recreate the task from its seed.

Contributor Clone

git lfs install
git clone <repo>
cd pyro
git lfs pull
make setup