NAME
spawn — Spawn any agent, on any cloud
SYNOPSIS
INFO
DESCRIPTION
Spawn any agent, on any cloud
README
Spawn
Launch any AI agent on any cloud with a single command. Coding agents, research agents, self-hosted AI tools — Spawn deploys them all. All models powered by OpenRouter. (ALPHA software, use at your own risk!)
9 agents. 7 clouds. 63 working combinations. Zero config.
Install
macOS / Linux — and Windows users inside a WSL2 terminal (Ubuntu, Debian, etc.):
curl -fsSL https://openrouter.ai/labs/spawn/cli/install.sh | bash
Windows PowerShell (outside WSL):
irm https://openrouter.ai/labs/spawn/cli/install.ps1 | iex
Usage
spawn # Interactive picker
spawn <agent> <cloud> # Launch directly
spawn matrix # Show the full agent x cloud matrix
Examples
spawn # Interactive picker
spawn claude sprite # Claude Code on Sprite
spawn codex hetzner # Codex CLI on Hetzner
spawn claude sprite --prompt "Fix bugs" # Non-interactive with prompt
spawn codex sprite -p "Add tests" # Short form
spawn claude # Show clouds available for Claude
spawn delete # Delete a running server
spawn delete -c hetzner # Delete a server on Hetzner
Commands
| Command | Description |
|---|---|
spawn | Interactive agent + cloud picker |
spawn <agent> <cloud> | Launch agent on cloud directly |
spawn <agent> <cloud> --dry-run | Preview without provisioning |
spawn <agent> <cloud> --zone <zone> | Set zone/region for the cloud |
spawn <agent> <cloud> --size <type> | Set instance size/type for the cloud |
spawn <agent> <cloud> --prompt "text" | Non-interactive with prompt (or -p) |
spawn <agent> <cloud> --prompt-file <file> | Prompt from file (or -f) |
spawn <agent> <cloud> --headless | Provision and exit (no interactive session) |
spawn <agent> <cloud> --output json | Headless mode with structured JSON on stdout |
spawn <agent> <cloud> --model <id> | Set the model ID (overrides agent default) |
spawn <agent> <cloud> --config <file> | Load options from a JSON config file |
spawn <agent> <cloud> --steps <list> | Comma-separated setup steps to enable |
spawn <agent> <cloud> --custom | Show interactive size/region pickers |
spawn <agent> | Show available clouds for an agent |
spawn <cloud> | Show available agents for a cloud |
spawn matrix | Full agent x cloud matrix |
spawn list | Browse and rerun previous spawns |
spawn list <filter> | Filter history by agent or cloud name |
spawn list -a <agent> | Filter history by agent |
spawn list -c <cloud> | Filter history by cloud |
spawn list --flat | Show flat list (disable tree view) |
spawn list --json | Output history as JSON |
spawn list --clear | Clear all spawn history |
spawn tree | Show recursive spawn tree (parent/child relationships) |
spawn tree --json | Output spawn tree as JSON |
spawn history export | Dump history as JSON to stdout (used by parent VMs) |
spawn fix | Re-run agent setup on an existing VM (re-inject credentials, reinstall) |
spawn fix <spawn-id> | Fix a specific spawn by name or ID |
spawn link <ip> | Register an existing VM by IP |
spawn link <ip> --agent <agent> | Specify the agent running on the VM |
spawn link <ip> --cloud <cloud> | Specify the cloud provider |
spawn last | Instantly rerun the most recent spawn |
spawn agents | List all agents with descriptions |
spawn clouds | List all cloud providers |
spawn feedback "message" | Send feedback to the Spawn team |
spawn uninstall | Uninstall spawn CLI and optionally remove data |
spawn update | Check for CLI updates |
spawn delete | Interactively select and destroy a cloud server |
spawn delete -a <agent> | Filter servers to delete by agent |
spawn delete -c <cloud> | Filter servers to delete by cloud |
spawn delete --name <name> --yes | Headless delete by name (no prompts) |
spawn status | Show live state of cloud servers |
spawn status -a <agent> | Filter status by agent |
spawn status -c <cloud> | Filter status by cloud |
spawn status --prune | Remove gone servers from history |
spawn help | Show help message |
spawn version | Show version |
Config File
The --config flag loads options from a JSON file. CLI flags override config values.
{
"model": "openai/gpt-5.3-codex",
"steps": ["github", "browser", "telegram"],
"name": "my-dev-box",
"setup": {
"telegram_bot_token": "123456:ABC-DEF...",
"github_token": "ghp_xxxx"
}
}
spawn codex gcp --config setup.json --headless --output json
Setup Steps
Control which optional setup steps run with --steps:
spawn openclaw gcp --steps github,browser # Only GitHub + Chrome
spawn claude gcp --steps "" # Skip all optional steps
Available steps vary by agent:
| Step | Agents | Description |
|---|---|---|
github | All | GitHub CLI + git identity |
reuse-api-key | All | Reuse saved OpenRouter key |
browser | openclaw | Chrome browser (~400 MB) |
telegram | openclaw | Telegram bot (set TELEGRAM_BOT_TOKEN for non-interactive) |
whatsapp | openclaw | WhatsApp linking (interactive QR scan, skipped in headless) |
Fast Mode
Use --fast for significantly faster deploys. Enables all speed optimizations:
spawn claude hetzner --fast
What --fast does:
- Parallel boot: server creation runs concurrently with API key prompt and account checks
- Tarballs: installs agents from pre-built tarballs instead of live install
- Skip cloud-init: for lightweight agents (Claude, OpenCode, Hermes), skips the package install wait since the base OS already has what's needed
- Snapshots: uses pre-built cloud images when available (Hetzner, DigitalOcean)
Beta Features
Individual optimizations can be enabled separately with --beta <feature>. The flag is repeatable:
spawn claude gcp --beta tarball --beta parallel
| Feature | Description |
|---|---|
tarball | Use pre-built tarball for agent install (faster, skips live install) |
images | Use pre-built cloud images/snapshots (faster boot) |
parallel | Parallelize server boot with setup prompts |
recursive | Install spawn CLI on VM so it can spawn child VMs |
sandbox | Run local agents in a Docker container (sandboxed) |
--fast enables tarball, images, and parallel (not recursive or sandbox).
Recursive Spawn
Use --beta recursive to let spawned VMs create their own child VMs:
spawn claude hetzner --beta recursive
What this does:
- Installs spawn CLI on the remote VM
- Delegates credentials (cloud + OpenRouter) so child VMs can authenticate
- Injects parent tracking (
SPAWN_PARENT_ID,SPAWN_DEPTH) into the VM environment - Passes
--beta recursiveto children so they can also spawn recursively
View the spawn tree:
spawn tree
# spawn-abc Claude Code / Hetzner 2m ago
# ├─ spawn-def Codex CLI / Hetzner 1m ago
# └─ spawn-ghi OpenClaw / Hetzner 30s ago
# └─ spawn-jkl Claude Code / Hetzner 10s ago
Tear down an entire tree:
spawn delete --cascade <id> # Delete a VM and all its children
Sandboxed Local
Use --beta sandbox to run local agents inside a Docker container instead of directly on your machine:
spawn claude local --beta sandbox
What this does:
- Pulls the agent's Docker image from
ghcr.io/openrouterteam/spawn-<agent> - Runs the agent in a container with filesystem, network, and process isolation
- Auto-installs Docker if not present (OrbStack on macOS, docker.io on Linux)
- Cleans up the container automatically when the session ends
In the interactive picker, --beta sandbox adds a "Local Machine (Sandboxed)" option alongside the regular "Local Machine":
spawn --beta sandbox # Interactive picker shows both local options
spawn openclaw local --beta sandbox # Direct launch, sandboxed
Without the CLI
Every combination works as a one-liner — no install required:
bash <(curl -fsSL https://openrouter.ai/labs/spawn/{cloud}/{agent}.sh)
Non-Interactive Mode
Skip prompts by providing environment variables:
# OpenRouter API key (required for all agents) export OPENROUTER_API_KEY=sk-or-v1-xxxxxCloud-specific credentials (varies by provider)
Note: Sprite uses
sprite loginfor authenticationexport HCLOUD_TOKEN=... # For Hetzner export DIGITALOCEAN_ACCESS_TOKEN=... # For DigitalOcean
Run non-interactively
spawn claude hetzner
You can also use inline environment variables:
OPENROUTER_API_KEY=sk-or-v1-xxxxx spawn claude sprite
Get your OpenRouter API key at: https://openrouter.ai/settings/keys
For cloud-specific auth, see each cloud's README in this repository.
Troubleshooting
Installation issues
If spawn fails to install, try these steps:
Check bun version: spawn requires bun >= 1.2.0
bun --version bun upgrade # if neededManual installation: If auto-install fails, install bun first
curl -fsSL https://bun.sh/install | bash source ~/.bashrc # or ~/.zshrc for zsh curl -fsSL https://openrouter.ai/labs/spawn/cli/install.sh | bashPATH issues: If
spawncommand not found after install# Add to your shell config (~/.bashrc or ~/.zshrc) export PATH="$HOME/.local/bin:$PATH"
Windows (PowerShell)
Use the PowerShell installer — not the bash one:
irm https://openrouter.ai/labs/spawn/cli/install.ps1 | iexThe
.ps1extension is required. The defaultinstall.shis bash and won't work in PowerShell.Set credentials via environment variables before launching:
$env:OPENROUTER_API_KEY = "sk-or-v1-xxxxx" $env:DIGITALOCEAN_ACCESS_TOKEN = "dop_v1_xxxxx" # For DigitalOcean $env:HCLOUD_TOKEN = "xxxxx" # For Hetzner spawn openclaw digitaloceanLocal build failures during auto-update are normal on Windows — the CLI falls back to a pre-built binary automatically. You may see a brief build error followed by a successful update.
EISDIR or EEXIST errors on config files: If you see errors about
digitalocean.jsonbeing a directory, delete it:Remove-Item -Recurse -Force "$HOME\.config\spawn\digitalocean.json" -ErrorAction SilentlyContinue spawn openclaw digitalocean
Headless JSON mode — agent exits immediately
When using --headless --output json with Claude Code, you must also pass --prompt (or -p). Without it, Claude exits with Input must be provided through stdin or --prompt and the JSON output will show "status":"error":
# WRONG — Claude exits immediately spawn claude gcp --headless --output jsonRIGHT — provide a prompt
spawn claude gcp --headless --output json --prompt "Fix all linter errors"
Note: auto-update messages may appear before the JSON on older CLI versions. Run spawn update to get the fix.
Agent launch failures
If an agent fails to install or launch on a cloud:
Check credentials: Ensure cloud provider credentials are set
# Example for Hetzner export HCLOUD_TOKEN=your-token-here spawn claude hetznerTry a different cloud: Some clouds may have temporary issues
spawn <agent> # Interactive picker to choose another cloudUse --dry-run: Preview what spawn will do before provisioning
spawn claude hetzner --dry-runCheck cloud status: Visit your cloud provider's status page
- Many failures are transient (network timeouts, package mirror issues)
- Retrying often succeeds
Getting help
- View command history:
spawn listshows all previous launches - Rerun last session:
spawn lastorspawn rerun - Check version:
spawn versionshows CLI version and cache status - Update spawn:
spawn updatechecks for the latest version - Report bugs: Open an issue at https://github.com/OpenRouterTeam/spawn/issues
Matrix
| Local Machine | Hetzner Cloud | AWS Lightsail | DigitalOcean | GCP Compute Engine | Daytona | Sprite | |
|---|---|---|---|---|---|---|---|
| Claude Code | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| OpenClaw | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Codex CLI | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| OpenCode | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Kilo Code | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Hermes Agent | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Junie | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Cursor CLI | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Pi | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
How it works
Each cell in the matrix is a self-contained bash script that:
- Provisions a server on the cloud provider
- Installs the agent
- Injects your OpenRouter API key so every agent uses the same billing
- Drops you into an interactive session
Scripts work standalone (bash <(curl ...)) or through the CLI.
Development
git clone https://github.com/OpenRouterTeam/spawn.git
cd spawn
git config core.hooksPath .githooks
Structure
sh/{cloud}/{agent}.sh # Agent deployment script (thin bash → bun wrapper)
packages/cli/ # TypeScript CLI — all provisioning logic (bun)
manifest.json # Source of truth for the matrix
Adding a new cloud
- Add cloud-specific TypeScript module in
packages/cli/src/{cloud}/ - Add to
manifest.json - Implement agent scripts
- See CLAUDE.md for full contributor guide
Adding a new agent
- Add to
manifest.json - Implement on 1+ cloud by adapting an existing agent script
- Must support OpenRouter via env var injection
Contributing
The easiest way to contribute is by testing and reporting issues. You don't need to write code.
Test a cloud provider
Pick any agent + cloud combination from the matrix and try it out:
spawn claude hetzner # or any combination
If something breaks, hangs, or behaves unexpectedly, open an issue using the bug report template. Include:
- The exact command you ran
- The cloud provider and agent
- What happened vs. what you expected
- Any error output
Request a cloud or agent
Want to see a specific cloud provider or agent supported? Use the dedicated templates:
Requests with real-world use cases get prioritized.
Report auth or credential issues
Cloud provider APIs change frequently. If you hit authentication failures, expired tokens, or permission errors on a provider that previously worked, please report it — these are high-priority fixes.
Code contributions
See CLAUDE.md for the full contributor guide covering shell script rules, testing, and the shared library pattern.