# stereos.ai > AI-friendly documentation for stereos.ai *Complete documentation content below* # stereOS > Purpose built Linux OS for agents—isolating agent execution in secure sandboxes with cryptographic attestation and compliance-ready audit trails for enterprise deployment. stereOS runs AI coding agents inside sandboxed Linux VMs. Instead of giving an agent access to your host machine, stereOS boots a disposable VM, injects credentials, and launches the agent — isolated from everything else. [masterblaster](https://github.com/papercomputeco/masterblaster) (`mb`) is the CLI that manages everything. ## Install ```bash curl -fsSL https://mb.stereos.ai/install | bash ``` ## Run In a separate terminal, start the daemon: ```bash mb serve ``` The daemon manages VM processes. Keep it running. ## Use Mixtapes are pre-built VM images with agents included. Pull one to get started: ```bash mb pull opencode-mixtape ``` Create a `jcard.toml` in your working directory: ```toml mixtape = "opencode-mixtape:latest" [[agents]] harness = "opencode" prompt = "Hello world!" ``` The jcard tells mb which mixtape to boot and which agents to run. See the [jcard.toml reference](/reference/jcard-schema) for all options. Then: ```bash mb up # boot the VM mb ssh # connect to it ``` You’re inside a sandboxed VM with OpenCode running your prompt. When you’re done, clean up: ```bash mb down mb destroy ``` ## Why a VM? stereOS uses full virtual machines — not containers, not microvms. This is a deliberate design choice: - **Full isolation** — each agent gets its own kernel, RAM, disk, and network. Nothing is shared with the host. - **Hardware access** — secure boot, FIPS compliance, and GPU passthrough for running local models via ollama or vLLM. - **Bare metal ready** — runs on real hardware, not just KVM. Critical for self-hosted enterprise deployments. - **Self-healing infrastructure** — agents can run k8s, docker compose, or kick other agents inside their own VM with no platform needed. Microvms (Firecracker, Cloud Hypervisor) strip virtual hardware, which means no secure boot, no FIPS, no GPU passthrough, no bare metal support, and broken security boundaries for nested virtualization. Full VMs avoid all of that. --- # stereOS > Development workflow and contribution guidelines stereOS welcomes contributions. ## Development setup ### Prerequisites - **Nix** with flakes enabled — Add `experimental-features = nix-command flakes` to `~/.config/nix/nix.conf`. - **direnv** — See [Local Build](/development/local-build) for installation. ### Getting started ```bash git clone https://github.com//stereos cd stereos direnv allow make help make build make test ``` The Nix dev shell provides Go, linters, and all other tools. ## Testing ```bash make test ``` Follow existing test patterns. Use standard Go tests: ```go func TestConfigParsing(t *testing.T) { cfg, err := config.Load("testdata/valid.toml") if err != nil { t.Fatalf("unexpected error: %v", err) } if cfg.VM.Name != "test-vm" { t.Errorf("expected name 'test-vm', got '%s'", cfg.VM.Name) } } ``` ## Linting and formatting ```bash gofmt -w . go vet ./... ``` Code that doesn’t pass these will be flagged during review. ## Code style - **Error handling** — Return errors, don’t panic. Wrap with context: `fmt.Errorf("loading config: %w", err)`. - **Naming** — Clear, descriptive. Avoid abbreviations except common ones (`ctx`, `err`, `cfg`). - **Package structure** — Single responsibility per package. No circular dependencies. - **Comments** — Doc comments on exported types and functions. Focus on _what_, not _how_. - **Constructor pattern** — Use `New*` functions. Return pointers. Initialize maps and slices. ```go func NewVMManager(imagePath string) *VMManager { return &VMManager{ imagePath: imagePath, vms: make(map[string]*VM), } } ``` ## Pull request process ### Branch naming ```bash git checkout -b feat/my-feature # or: fix/issue-description, docs/page-name, refactor/component-name ``` ### Before submitting 1. `make build` — compiles without errors 1. `make test` — all tests pass 1. `gofmt -w .` and `go vet ./...` 1. One logical change per commit ### PR description Cover **what** the change does, **why** it’s needed, and **testing** beyond the automated suite. ### Review process All PRs need at least one review. Reviewers check correctness, test coverage, code style, docs updates, and regressions. ## Project structure ```plaintext stereos/ ├── flake.nix # Entry point — delegates to flake/ modules (flake-parts) ├── flake/ # flake-parts modules (split flake.nix logic) │ ├── devshell.nix # Developer shell for direnv │ ├── images.nix # Image build targets (raw, qcow2, kernel-artifacts) │ └── checks.nix # CI verification builds ├── modules/ # NixOS modules — the core of the OS │ ├── default.nix # Aggregator (imports all sub-modules) │ ├── base.nix # Core OS: filesystem, SSH, nix settings, hardening │ ├── boot.nix # Boot config + boot-time optimizations │ ├── services/ # Service overrides (stereosd, agentd) │ └── users/ # User definitions (agent, admin) ├── profiles/ # Composable configuration presets │ ├── base.nix # Shared foundation (imports image formats) │ └── dev.nix # Dev-only: SSH key injection, debug tools ├── mixtapes/ # Mixtapes — spins with specific AI agents │ ├── claude-code/ │ ├── opencode/ │ ├── gemini-cli/ │ └── full/ ├── formats/ # Image format definitions (raw, qcow2, kernel) ├── lib/ # Shared Nix helpers (mkMixtape, SSH key logic) ├── cmd/ # CLI entry points (mb) ├── internal/ # Private Go packages ├── Makefile # Build and test targets ├── .envrc # direnv integration └── go.mod # Go module definition ``` --- # stereOS > Build instructions for the mb CLI The mb CLI uses **Nix flakes** for reproducible builds, **direnv** for automatic environment setup, and a **Makefile** for common tasks. ## Prerequisites - **Nix** with flakes enabled — Install from [nixos.org](https://nixos.org/download). Add `experimental-features = nix-command flakes` to `~/.config/nix/nix.conf`. - **direnv** — Auto-loads the Nix dev shell when you enter the project directory. ```bash # macOS brew install direnv # Add to ~/.zshrc or ~/.bashrc eval "$(direnv hook zsh)" # or bash ``` ## Build ```bash git clone https://github.com/papercomputeco/stereOS cd stereos # direnv auto-enters the Nix dev shell direnv allow # first time only make help # list targets make build # build the binary make test # run tests ``` For a production binary without the dev shell: ```bash nix build ``` Output goes to `./result/bin/mb`. ## Runtime dependency mb requires **QEMU**. On macOS it uses HVF; on Linux, KVM. ```bash # macOS (Intel & Apple Silicon) brew install qemu # Linux x86_64 (Fedora / RHEL) sudo dnf install qemu-system-x86 # Linux x86_64 (Ubuntu / Debian) sudo apt install qemu-system-x86 # Linux ARM64 (Fedora / RHEL) sudo dnf install qemu-system-aarch64 # Linux ARM64 (Ubuntu / Debian) sudo apt install qemu-system-arm ``` mb automatically selects the correct QEMU binary and configuration for your platform. ## Testing ```bash make test ``` Uses standard Go tests. ## Troubleshooting ### direnv not loading Run `direnv allow` in the project directory. Check that the direnv hook is in your shell profile. ### Nix build fails with network error All dependencies are vendored. Run `go mod vendor` and check that `vendor/` is up to date. --- # stereOS > Set up OpenCode as your AI agent ## Providers stereOS runs OpenCode as a normal install inside the VM, so any provider that OpenCode supports works out of the box. You are not limited to Anthropic API keys. **Supported options include:** - **Anthropic** — pass your API key via the jcard - **OpenAI** — pass your API key via the jcard - **GitHub Copilot (OAuth)** — run `opencode auth` inside the VM to authenticate interactively - **Ollama** — run a local Ollama instance and point OpenCode at it - **Any OpenAI-compatible endpoint** — set the base URL in your OpenCode config The jcard `[agent.env]` section is a convenience for injecting API keys. If your provider uses OAuth or a locally running model, you can omit it entirely and configure OpenCode directly inside the VM. ## jcard.toml ### With an API key ```toml mixtape = "opencode-mixtape:latest" [[agents]] harness = "opencode" prompt = "Analyze the project structure and write missing unit tests." workdir = "/workspace" restart = "on-failure" max_restarts = 3 [agents.env] ANTHROPIC_API_KEY = "${ANTHROPIC_API_KEY}" ``` Export your API key on the host before booting: ```bash export ANTHROPIC_API_KEY="sk-ant-..." ``` For OpenAI, swap in `OPENAI_API_KEY` instead. ### Without an API key (OAuth, Ollama, etc.) If you are using GitHub Copilot OAuth or a local model, you don’t need to pass an API key through the jcard: ```toml mixtape = "opencode-mixtape:latest" [agent] harness = "opencode" workdir = "/workspace" ``` After booting, attach to the tmux session and configure your provider directly (e.g., `opencode auth` for Copilot). ## Boot The VM name defaults to your current folder name. For example, if your `jcard.toml` is in `~/projects/my-app/`, the VM will be named `my-app`. ```bash mb up mb ssh my-app ``` You can check for the session with `tmux`: ```bash sudo -u agent -- tmux -S /run/agentd/tmux.sock ls ``` The agent starts automatically in a tmux session. Attach to it: ```bash sudo -u agent -- tmux -S /run/agentd/tmux.sock a ``` Detach without stopping: `Ctrl-b` then `d`. ## Interactive mode Omit `prompt` for an interactive OpenCode session: ```toml mixtape = "opencode-mixtape:latest" [[agents]] harness = "opencode" workdir = "/workspace" ``` ## Clean up ```bash mb down my-app && mb destroy my-app ``` --- # stereOS > Sandboxed Linux VMs for AI coding agents stereOS runs AI coding agents inside sandboxed Linux VMs. Instead of giving an agent access to your host machine, stereOS boots a disposable VM, injects credentials, and launches the agent — isolated from everything else. [masterblaster](https://github.com/papercomputeco/masterblaster) (`mb`) is the CLI that manages everything. ## Install ```bash curl -fsSL https://mb.stereos.ai/install | bash ``` ## Run In a separate terminal, start the daemon: ```bash mb serve ``` The daemon manages VM processes. Keep it running. ## Use Mixtapes are pre-built VM images with agents included. Pull one to get started: ```bash mb pull opencode-mixtape ``` Create a `jcard.toml` in your working directory: ```toml mixtape = "opencode-mixtape:latest" [[agents]] harness = "opencode" prompt = "Hello world!" ``` The jcard tells mb which mixtape to boot and which agents to run. See the [jcard.toml reference](/reference/jcard-schema) for all options. Then: ```bash mb up # boot the VM mb ssh # connect to it ``` You’re inside a sandboxed VM with OpenCode running your prompt. When you’re done, clean up: ```bash mb down mb destroy ``` ## Why a VM? stereOS uses full virtual machines — not containers, not microvms. This is a deliberate design choice: - **Full isolation** — each agent gets its own kernel, RAM, disk, and network. Nothing is shared with the host. - **Hardware access** — secure boot, FIPS compliance, and GPU passthrough for running local models via ollama or vLLM. - **Bare metal ready** — runs on real hardware, not just KVM. Critical for self-hosted enterprise deployments. - **Self-healing infrastructure** — agents can run k8s, docker compose, or kick other agents inside their own VM with no platform needed. Microvms (Firecracker, Cloud Hypervisor) strip virtual hardware, which means no secure boot, no FIPS, no GPU passthrough, no bare metal support, and broken security boundaries for nested virtualization. Full VMs avoid all of that. --- # stereOS > Remove a sandbox and all its resources Destroy a sandbox by first attempting a graceful shutdown and then removing all on-disk resources (disk image, EFI vars, state, etc.) from `~/.mb/vms/`. This is a destructive operation and will prompt for confirmation unless `--yes` is provided. Use `--force` to forcibly kill a hung VM before removing. ## Usage ```bash mb destroy [name] [flags] ``` ## Examples ```bash mb destroy my-sandbox mb destroy --yes mb destroy --force --yes ``` ## Flags Flag | Description --force | Force kill a hung VM before removing -h, --help | Help for destroy --yes | Skip confirmation prompt --- # stereOS > Gracefully stop a running sandbox Gracefully stop a running stereOS sandbox. Sends a shutdown command to `stereosd` inside the VM, allowing it to unmount shared directories and sync filesystems before powering off. If no name is given and only one sandbox is running, that sandbox is stopped. Use `--force` to immediately terminate the VM process. ## Usage ```bash mb down [name] [flags] ``` ## Examples ```bash mb down mb down my-sandbox mb down --force ``` ## Flags Flag | Description --force | Force kill the VM process -h, --help | Help for down --- # stereOS > Initialize a new sandbox configuration Initialize a new Masterblaster sandbox configuration by creating a `jcard.toml` file in the current directory. This file defines the mixtape, resources, network, shared directories, and agent configuration. Edit the generated `jcard.toml` to customize the sandbox, then run `mb up` to boot it. ## Usage ```bash mb init [flags] ``` ## Examples ```bash mb init ``` ## Flags Flag | Description -h, --help | Help for init --- # stereOS > List all sandbox instances Show all known sandbox instances with their current state, mixtape, resources, and SSH address. ## Usage ```bash mb list [flags] ``` ## Aliases ```bash mb list mb ls ``` ## Examples ```bash mb list mb ls ``` ## Flags Flag | Description -h, --help | Help for list --- # stereOS > Manage stereOS mixtapes Manage stereOS mixtapes (bootable VM images). Mixtapes are pre-configured stereOS images bundled with agent harnesses and workflows. Use `mb mixtapes list` to see what’s available in the registry, `mb mixtapes local` to see what’s downloaded, and `mb mixtapes pull ` to download new ones. ## Usage ```bash mb mixtapes [command] ``` ## Examples ```bash mb mixtapes list # List mixtapes in the registry mb mixtapes list coder # List tags for a specific mixtape mb mixtapes local # List locally downloaded mixtapes mb mixtapes pull coder mb mixtapes rm coder:latest # Remove a local mixtape ``` ## Subcommands Command | Description mb mixtapes list \[name] | List mixtapes available in the remote registry. With a name argument, lists all tags for that mixtape. mb mixtapes local | List locally downloaded mixtapes. mb mixtapes pull \ | Pull a mixtape from the registry. Alias for mb pull . mb mixtapes rm \ | Remove a locally downloaded mixtape. With just a name, removes all tags. --- # stereOS > Command reference for the Masterblaster CLI Masterblaster (`mb`) is an AI agent sandbox management, build, and infrastructure tool for operators embracing safe, sandboxed agentic workflows. It manages stereOS virtual machines, bootstraps agent environments, and provides the foundation for the Paper Compute ecosystem. ## Usage ```bash mb [command] ``` ## Commands ### Sandbox Lifecycle Command | Description mb init | Create a jcard.toml configuration file mb up | Create and start a sandbox mb down | Stop a running sandbox mb destroy | Remove a sandbox and all its resources ### Inspection Command | Description mb list | List all sandboxes mb status | Show the status of a sandbox mb ssh | SSH into a running sandbox ### Mixtapes Command | Description mb pull | Pull a mixtape from the registry mb mixtapes | Manage stereOS mixtapes ### Daemon & Other Command | Description mb serve | Start the Masterblaster daemon mb version | Display version information ## Global Flags Flag | Description --config-dir string | Config directory (default: $XDG\_CONFIG\_HOME/mb ) --disable-telemetry | Disable anonymous telemetry -h, --help | Help for mb -v, --verbose | Enable verbose output ## Quick Start ```bash # Initialize a new sandbox configuration mb init # Pull a mixtape image mb pull coder # Boot the sandbox mb up # SSH into it mb ssh # When done, stop and destroy mb down mb destroy ``` --- # stereOS > Pull a mixtape image from the registry Pull a stereOS mixtape image from the Paper Compute registry. Downloads an OCI artifact containing the VM disk image (zstd-compressed), kernel artifacts (`bzImage`, `initrd`, `cmdline`, `init`), and mixtape manifest, then stores them locally in `~/.config/mb/mixtapes///`. The registry hosts an OCI index with both raw and qcow2 format manifests. The raw format is preferred (for Apple Virtualization.framework); qcow2 is used as a fallback (for QEMU). The argument is a mixtape reference in the form `name[:tag]`. Short names are resolved against the default registry (`download.stereos.ai/mixtapes/`). Full OCI references are also accepted. ## Usage ```bash mb pull [flags] ``` ## Examples ```bash mb pull coder mb pull coder:0.1.0 mb pull download.stereos.ai/mixtapes/coder:latest ``` ## Flags Flag | Description -h, --help | Help for pull --- # stereOS > Start the Masterblaster daemon Start the long-lived Masterblaster daemon that manages sandbox VMs. The daemon listens on `~/.mb/mb.sock` for CLI commands and manages all VM lifecycle operations. Other `mb` commands communicate with this daemon. Each VM gets its own `vmhost` child process that holds the hypervisor handle and survives daemon restarts. The daemon acts as a multiplexer, spawning and monitoring `vmhost` processes. If the daemon is already running, this command exits with an error. ## Usage ```bash mb serve [flags] ``` ## Flags Flag | Description -h, --help | Help for serve --- # stereOS > Connect to a running sandbox via SSH Connect to a running sandbox via SSH. Replaces the current process with the `ssh` binary for a clean interactive experience. If no name is given and only one sandbox is running, connects to that one. The default user is `admin` (the operator account in stereOS). ## Usage ```bash mb ssh [name] [flags] ``` ## Examples ```bash mb ssh mb ssh my-sandbox mb ssh --user agent my-sandbox ``` ## Flags Flag | Description -u, --user string | SSH user (default: admin ) -h, --help | Help for ssh --- # stereOS > Display the current state of a sandbox Display the current state of a sandbox, including its name, state, mixtape, resources, and SSH address. Use `--all` to show all sandboxes. ## Usage ```bash mb status [name] [flags] ``` ## Examples ```bash mb status mb status my-sandbox mb status --all ``` ## Flags Flag | Description --all | Show all sandboxes -h, --help | Help for status --- # stereOS > Boot a new stereOS sandbox VM Boot a new stereOS sandbox VM using the `jcard.toml` in the current directory (or the path given with `--config`). Communicates with the Masterblaster daemon to create, configure, and start the VM. If the daemon is not running, it will be automatically started in the background. ## Usage ```bash mb up [flags] ``` ## Examples ```bash mb up mb up --config /path/to/jcard.toml ``` ## Flags Flag | Description --config string | Path to jcard.toml (default: ./jcard.toml ) -h, --help | Help for up --- # stereOS > Display the Masterblaster CLI version Display the version of the Masterblaster CLI. ## Usage ```bash mb version [flags] ``` ## Flags Flag | Description -h, --help | Help for version --- # stereOS > jcard.toml configuration reference The `jcard.toml` tells mb which mixtape to boot and which agents to run. ## Minimal example ```toml mixtape = "opencode-mixtape:latest" [[agents]] harness = "opencode" prompt = "Hello world!" ``` ## Top-level fields Field | Type | Required | Description mixtape | string | yes | Mixtape image and tag to boot. ## \[\[agents]] section Multiple agents can run concurrently inside a single sandbox. Each `[[agents]]` entry defines an independent agent managed by agentd. Field | Type | Default | Description name | string | auto-generated | Unique identifier for this agent. If omitted, auto-generated from harness (e.g. "claude-code" , "claude-code-1" ). harness | string | — | Agent runner: "claude-code" , "opencode" , "gemini-cli" , or "custom" . Required. type | string | "sandboxed" | Execution mode: "sandboxed" (gVisor container) or "native" (tmux session). prompt | string | "" | Prompt passed to the agent at startup. Empty starts interactive mode. prompt\_file | string | — | Path to a prompt file inside the VM. Overrides prompt if set. workdir | string | "/workspace" | Working directory for the agent process. restart | string | "no" | Restart policy: "no" , "on-failure" , or "always" . max\_restarts | int | 0 | Max restart attempts. 0 = unlimited. timeout | string | — | Max run duration ( "30m" , "1h" , "2h" ). Unset = no limit. grace\_period | string | "30s" | Time between SIGTERM and SIGKILL on shutdown. session | string | agent name | tmux session name. extra\_packages | string\[] | \[] | Additional Nix packages to install. Only valid for type = "sandboxed" . replicas | int | 1 | Number of identical agents to launch. See Replicas . ## \[\[shared]] section Mount host directories into the sandbox. Each `[[shared]]` entry maps a host path to a guest mount point using virtio-fs. Paths are relative to the `jcard.toml` location. Field | Type | Default | Description host | string | — | Directory on the host machine. Required. guest | string | — | Mount point inside the VM. Required. readonly | bool | false | Prevent the agent from modifying host files. ```toml [[shared]] host = "./" guest = "/workspace" readonly = false ``` Multiple shared directories are supported: ```toml [[shared]] host = "./" guest = "/workspace" [[shared]] host = "/tmp/data" guest = "/data" readonly = true ``` The agent’s `workdir` typically points to a shared mount so that agents can read and write files on the host. ## \[agents.env] Extra environment variables for the agent process. ```toml [[agents]] harness = "opencode" [agents.env] ANTHROPIC_API_KEY = "${ANTHROPIC_API_KEY}" ``` ## Restart policies Policy | Behavior no | Run once, never restart. on-failure | Restart only on non-zero exit. always | Restart on any exit, up to max\_restarts . ## Replicas The `replicas` field launches multiple identical agents from a single spec. Each replica gets a unique name suffixed with its index. ```toml [[agents]] name = "reviewer" harness = "claude-code" prompt = "Review the code for bugs." replicas = 5 ``` This creates 5 agents: `reviewer-0`, `reviewer-1`, `reviewer-2`, `reviewer-3`, `reviewer-4`. If `replicas = 1` (the default), no suffix is added — the agent keeps its original name. Replicas share the same configuration but run independently. Useful for launching swarms of agents performing the same task. ## Examples **Shared workspace with an agent:** ```toml mixtape = "opencode-mixtape:latest" [[shared]] host = "./" guest = "/workspace" [[agents]] harness = "claude-code" prompt = "Fix the failing tests." workdir = "/workspace" ``` **Single agent with restart and timeout:** ```toml mixtape = "opencode-mixtape:latest" [[agents]] harness = "opencode" prompt = "Fix the failing tests." workdir = "/workspace" restart = "on-failure" max_restarts = 3 timeout = "1h" [agents.env] ANTHROPIC_API_KEY = "${ANTHROPIC_API_KEY}" ``` **Multiple agents in one sandbox:** ```toml mixtape = "opencode-mixtape:latest" [[agents]] name = "reviewer" harness = "claude-code" prompt = "Review the PR for security issues." [[agents]] name = "coder" harness = "opencode" prompt = "Implement the feature described in TASK.md." ``` **Agent swarm with replicas:** ```toml mixtape = "opencode-mixtape:latest" [[agents]] name = "worker" harness = "claude-code" prompt = "Process items from the work queue." replicas = 10 ``` **Interactive session (no prompt):** ```toml mixtape = "opencode-mixtape:latest" [[agents]] harness = "opencode" workdir = "/workspace" ``` **Sandboxed agent with extra packages:** ```toml mixtape = "opencode-mixtape:latest" [[agents]] harness = "claude-code" type = "sandboxed" extra_packages = ["ripgrep", "fd", "python311"] ```