pyro-mcp/docs/public-contract.md
Thales Maciel f504f0a331 Add workspace service lifecycle with typed readiness
Make persistent workspaces capable of running long-lived background processes instead of forcing everything through one-shot exec calls.

Add workspace service start/list/status/logs/stop across the CLI, Python SDK, and MCP server, with multiple named services per workspace, typed readiness probes (file, tcp, http, and command), and aggregate service counts on workspace status. Keep service state and logs outside /workspace so diff and export semantics stay workspace-scoped, and extend the guest agent plus backends to persist service records and logs across separate calls.

Update the 2.7.0 docs, examples, changelog, and roadmap milestone to reflect the shipped surface.

Validation: uv lock; UV_CACHE_DIR=.uv-cache make check; UV_CACHE_DIR=.uv-cache make dist-check; real guest-backed Firecracker smoke for workspace create, two service starts, list/status/logs, diff unaffected, stop, and delete.
2026-03-12 05:36:28 -03:00

9.4 KiB

Public Contract

This document defines the supported public interface for pyro-mcp 2.x.

Package Identity

  • Distribution name: pyro-mcp
  • Public executable: pyro
  • Public Python import: from pyro_mcp import Pyro
  • Public package-level factory: from pyro_mcp import create_server

CLI Contract

Top-level commands:

  • pyro env list
  • pyro env pull
  • pyro env inspect
  • pyro env prune
  • pyro mcp serve
  • pyro run
  • pyro workspace create
  • pyro workspace sync push
  • pyro workspace exec
  • pyro workspace export
  • pyro workspace diff
  • pyro workspace service start
  • pyro workspace service list
  • pyro workspace service status
  • pyro workspace service logs
  • pyro workspace service stop
  • pyro workspace shell open
  • pyro workspace shell read
  • pyro workspace shell write
  • pyro workspace shell signal
  • pyro workspace shell close
  • pyro workspace status
  • pyro workspace logs
  • pyro workspace delete
  • pyro doctor
  • pyro demo
  • pyro demo ollama

Stable pyro run interface:

  • positional environment name
  • --vcpu-count
  • --mem-mib
  • --timeout-seconds
  • --ttl-seconds
  • --network
  • --allow-host-compat
  • --json

Behavioral guarantees:

  • pyro run <environment> -- <command> defaults to 1 vCPU / 1024 MiB.
  • pyro run fails if guest boot or guest exec is unavailable unless --allow-host-compat is set.
  • pyro run, pyro env list, pyro env pull, pyro env inspect, pyro env prune, and pyro doctor are human-readable by default and return structured JSON with --json.
  • pyro demo ollama prints log lines plus a final summary line.
  • pyro workspace create auto-starts a persistent workspace.
  • pyro workspace create --seed-path PATH seeds /workspace from a host directory or a local .tar / .tar.gz / .tgz archive before the workspace is returned.
  • pyro workspace sync push WORKSPACE_ID SOURCE_PATH [--dest WORKSPACE_PATH] imports later host-side directory or archive content into a started workspace.
  • pyro workspace export WORKSPACE_ID PATH --output HOST_PATH exports one file or directory from /workspace back to the host.
  • pyro workspace diff WORKSPACE_ID compares the current /workspace tree to the immutable create-time baseline.
  • pyro workspace service * manages long-running named services inside one started workspace with typed readiness probes.
  • pyro workspace exec runs in the persistent /workspace for that workspace and does not auto-clean.
  • pyro workspace shell * manages persistent PTY sessions inside a started workspace.
  • pyro workspace logs returns persisted command history for that workspace until pyro workspace delete.
  • Workspace create/status results expose workspace_seed metadata describing how /workspace was initialized.
  • pyro workspace status includes aggregate service_count and running_service_count fields.

Python SDK Contract

Primary facade:

  • Pyro

Supported public entrypoints:

  • create_server()
  • Pyro.create_server()
  • Pyro.list_environments()
  • Pyro.pull_environment(environment)
  • Pyro.inspect_environment(environment)
  • Pyro.prune_environments()
  • Pyro.create_vm(...)
  • Pyro.create_workspace(...)
  • Pyro.push_workspace_sync(workspace_id, source_path, *, dest="/workspace")
  • Pyro.export_workspace(workspace_id, path, *, output_path)
  • Pyro.diff_workspace(workspace_id)
  • Pyro.start_service(workspace_id, service_name, *, command, cwd="/workspace", readiness=None, ready_timeout_seconds=30, ready_interval_ms=500)
  • Pyro.list_services(workspace_id)
  • Pyro.status_service(workspace_id, service_name)
  • Pyro.logs_service(workspace_id, service_name, *, tail_lines=200, all=False)
  • Pyro.stop_service(workspace_id, service_name)
  • Pyro.open_shell(workspace_id, *, cwd="/workspace", cols=120, rows=30)
  • Pyro.read_shell(workspace_id, shell_id, *, cursor=0, max_chars=65536)
  • Pyro.write_shell(workspace_id, shell_id, *, input, append_newline=True)
  • Pyro.signal_shell(workspace_id, shell_id, *, signal_name="INT")
  • Pyro.close_shell(workspace_id, shell_id)
  • Pyro.start_vm(vm_id)
  • Pyro.exec_vm(vm_id, *, command, timeout_seconds=30)
  • Pyro.exec_workspace(workspace_id, *, command, timeout_seconds=30)
  • Pyro.stop_vm(vm_id)
  • Pyro.delete_vm(vm_id)
  • Pyro.delete_workspace(workspace_id)
  • Pyro.status_vm(vm_id)
  • Pyro.status_workspace(workspace_id)
  • Pyro.logs_workspace(workspace_id)
  • Pyro.network_info_vm(vm_id)
  • Pyro.reap_expired()
  • Pyro.run_in_vm(...)

Stable public method names:

  • create_server()
  • list_environments()
  • pull_environment(environment)
  • inspect_environment(environment)
  • prune_environments()
  • create_vm(...)
  • create_workspace(...)
  • push_workspace_sync(workspace_id, source_path, *, dest="/workspace")
  • export_workspace(workspace_id, path, *, output_path)
  • diff_workspace(workspace_id)
  • start_service(workspace_id, service_name, *, command, cwd="/workspace", readiness=None, ready_timeout_seconds=30, ready_interval_ms=500)
  • list_services(workspace_id)
  • status_service(workspace_id, service_name)
  • logs_service(workspace_id, service_name, *, tail_lines=200, all=False)
  • stop_service(workspace_id, service_name)
  • open_shell(workspace_id, *, cwd="/workspace", cols=120, rows=30)
  • read_shell(workspace_id, shell_id, *, cursor=0, max_chars=65536)
  • write_shell(workspace_id, shell_id, *, input, append_newline=True)
  • signal_shell(workspace_id, shell_id, *, signal_name="INT")
  • close_shell(workspace_id, shell_id)
  • start_vm(vm_id)
  • exec_vm(vm_id, *, command, timeout_seconds=30)
  • exec_workspace(workspace_id, *, command, timeout_seconds=30)
  • stop_vm(vm_id)
  • delete_vm(vm_id)
  • delete_workspace(workspace_id)
  • status_vm(vm_id)
  • status_workspace(workspace_id)
  • logs_workspace(workspace_id)
  • network_info_vm(vm_id)
  • reap_expired()
  • run_in_vm(...)

Behavioral defaults:

  • Pyro.create_vm(...) and Pyro.run_in_vm(...) default to vcpu_count=1 and mem_mib=1024.
  • Pyro.create_workspace(...) defaults to vcpu_count=1 and mem_mib=1024.
  • allow_host_compat defaults to False on create_vm(...) and run_in_vm(...).
  • allow_host_compat defaults to False on create_workspace(...).
  • Pyro.create_workspace(..., seed_path=...) seeds /workspace from a host directory or a local .tar / .tar.gz / .tgz archive before the workspace is returned.
  • Pyro.push_workspace_sync(...) imports later host-side directory or archive content into a started workspace.
  • Pyro.export_workspace(...) exports one file or directory from /workspace to an explicit host path.
  • Pyro.diff_workspace(...) compares the current /workspace tree to the immutable create-time baseline.
  • Pyro.start_service(...) starts one named long-running process in a started workspace and waits for its typed readiness probe when configured.
  • Pyro.list_services(...), Pyro.status_service(...), Pyro.logs_service(...), and Pyro.stop_service(...) manage those persisted workspace services.
  • Pyro.exec_vm(...) runs one command and auto-cleans that VM after the exec completes.
  • Pyro.exec_workspace(...) runs one command in the persistent workspace and leaves it alive.
  • Pyro.open_shell(...) opens a persistent PTY shell attached to one started workspace.
  • Pyro.read_shell(...) reads merged text output from that shell by cursor.
  • Pyro.write_shell(...), Pyro.signal_shell(...), and Pyro.close_shell(...) operate on that persistent shell session.

MCP Contract

Primary tool:

  • vm_run

Advanced lifecycle tools:

  • vm_list_environments
  • vm_create
  • vm_start
  • vm_exec
  • vm_stop
  • vm_delete
  • vm_status
  • vm_network_info
  • vm_reap_expired

Persistent workspace tools:

  • workspace_create
  • workspace_sync_push
  • workspace_exec
  • workspace_export
  • workspace_diff
  • service_start
  • service_list
  • service_status
  • service_logs
  • service_stop
  • shell_open
  • shell_read
  • shell_write
  • shell_signal
  • shell_close
  • workspace_status
  • workspace_logs
  • workspace_delete

Behavioral defaults:

  • vm_run and vm_create default to vcpu_count=1 and mem_mib=1024.
  • workspace_create defaults to vcpu_count=1 and mem_mib=1024.
  • vm_run and vm_create expose allow_host_compat, which defaults to false.
  • workspace_create exposes allow_host_compat, which defaults to false.
  • workspace_create accepts optional seed_path and seeds /workspace from a host directory or a local .tar / .tar.gz / .tgz archive before the workspace is returned.
  • workspace_sync_push imports later host-side directory or archive content into a started workspace, with an optional dest under /workspace.
  • workspace_export exports one file or directory from /workspace to an explicit host path.
  • workspace_diff compares the current /workspace tree to the immutable create-time baseline.
  • service_start, service_list, service_status, service_logs, and service_stop manage persistent named services inside a started workspace.
  • vm_exec runs one command and auto-cleans that VM after the exec completes.
  • workspace_exec runs one command in a persistent /workspace and leaves the workspace alive.
  • shell_open, shell_read, shell_write, shell_signal, and shell_close manage persistent PTY shells inside a started workspace.

Versioning Rule

  • pyro-mcp uses SemVer.
  • Environment names are stable identifiers in the shipped catalog.
  • Changing a public command name, public flag, public method name, public MCP tool name, or required request field is a breaking change.