# Overview Source: https://docs.boxd.sh/index Instant cloud computers you can fork. SSH in, build, it's live. If you are an agent reading this doc, visit [llms.txt](https://docs.boxd.sh/llms.txt) or [llms-full.txt](https://docs.boxd.sh/llms-full.txt) instead. boxd gives you full Linux computers in the cloud that boot in milliseconds. Every machine gets its own public IP, persistent disk, and HTTPS domain. Whatever you build is immediately live on the internet. Create your first machine in under 5 seconds. Install the boxd CLI. Token auth, shell completions, best for automation. No install needed. Manage machines and connect directly. Automatic domains, configurable proxies. ## What makes boxd different? **Real VMs, not containers.** Each machine is a KVM microVM with its own Linux kernel, network stack, and persistent disk. Run systemd, Docker, install kernel modules -- no restrictions. **Fork entire machines.** Copy a running machine -- full disk state, installed packages, running services -- into a new machine in seconds. Fork before risky changes, fork to test in parallel, destroy the fork when done. **Instant HTTPS.** Every machine gets `name.boxd.sh` with TLS terminated at the proxy. Create additional subdomain proxies pointing to different ports. No certs, no DNS, no config. **Built for agents.** Claude Code and Codex are pre-installed. The in-VM `boxd` CLI works without SSH keys. Every command outputs JSON. Agents can create, fork, and destroy machines autonomously. **Sub-10ms suspend and resume.** Machines freeze in place and wake instantly when traffic arrives. Built on [Ignition](/primitives/suspend-resume), our open-source microVM engine. No cold starts, no wasted compute. 🇪🇺 **European sovereign infrastructure.** Hosted on EU hardware with no US cloud dependency. Your data stays in Europe. ## Use cases **AI agent sandboxes.** Give each agent its own isolated machine with full root, persistent disk, and internet access. Agents manage their own VMs via the `boxd` CLI -- no SSH keys, JSON output, fully autonomous. Fork a known-good state before each task, destroy after. Unlike container-based sandboxes, agents get real hardware isolation with their own kernel. **Autonomous coding agents.** Claude Code and Codex are pre-installed with a `boxd` skill that teaches agents the full platform. Agents can spin up machines, deploy apps, configure HTTPS proxies, fork for safe experimentation, and tear down -- all without human intervention. **Development environments.** A full Ubuntu 24.04 machine with Docker, Go, Python, and your editor of choice. Unlike traditional CDEs that take minutes to start, boxd machines boot in milliseconds and persist across sessions. SSH in from anywhere, pick up where you left off. **Live demos and prototypes.** Deploy an app and share the HTTPS link. No CI/CD pipeline, no hosting config. Your code is live the moment it listens on a port. **Parallel testing.** Spin up multiple machines to test different configurations, library versions, or approaches simultaneously. Each is fully isolated with its own IP and HTTPS domain. **Safe experimentation.** Fork your production-like environment, break things, learn, destroy the fork. The original is untouched. This is how agents should work -- cheap, disposable branches of entire computers. ## Every machine includes * **Ubuntu 24.04** (unminimized, with man pages) -- Python 3, Go, Docker, build-essential * **Claude Code and Codex** pre-installed with a built-in `boxd` skill and `CLAUDE.md`/`AGENTS.md` so agents understand the environment out of the box * **HTTPS domain** at `name.boxd.sh` with configurable proxy routing * **Public IPv4** -- direct SSH, SCP, VS Code Remote, port forwarding * 🇪🇺 **European infrastructure** -- hosted on sovereign EU hardware, no US cloud dependency * **2 vCPUs, 8 GiB RAM, 100 GB disk** per machine (extendable on request) # Claude Code Source: https://docs.boxd.sh/integrations/claude-code Use Claude Code on your machines with persistent authentication across resets. [Claude Code](https://claude.ai/code) is pre-installed on every boxd machine. Launch it from any directory: ```bash theme={"theme":"github-dark"} ssh myapp.boxd.sh cd my-project claude ``` Use it with a Claude subscription (e.g., Claude Max) or by setting an API key. ## Persistent auth When you authenticate Claude Code on a boxd machine, your credentials are saved to your boxd account. If your machine is reset, destroyed, or you create a new one, Claude Code is already authenticated -- no need to sign in again. This happens automatically. There's nothing to configure. ## AGENTS.md Every machine includes an `CLAUDE.md` that gives Claude Code context about the boxd environment -- how to create machines, manage proxies, and use the `boxd` CLI from inside a VM. It's picked up by default. This means Claude Code can help you manage your boxd infrastructure directly from conversation. ## Codex [Codex](https://openai.com/index/codex/) is also pre-installed on every machine. It gets an `AGENTS.md` file with similar context. Authentication is not yet automated for Codex, so you'll need to login on every new machine. # Client Utilities Source: https://docs.boxd.sh/integrations/client-utilities Access files and a browser on your local machine from inside a boxd VM. boxd client tools run on your Mac (Linux support coming soon) and bridge local resources into your VMs. Once installed, you can paste images into Claude Code, read files from your local filesystem, and control a local Chrome browser — all from inside a VM. ## Install ```bash theme={"theme":"github-dark"} curl -fsSL https://boxd.sh/downloads/install.sh | sh ``` This installs the `boxd-clientd` daemon and configures SSH to start it automatically when you connect to boxd. Currently available for macOS (Apple Silicon) only. ## How it works When you SSH into a boxd machine, the client daemon starts on your Mac and an SSH tunnel is established. Inside the VM, the `boxd local` commands communicate with the daemon through this tunnel. No configuration needed — it works automatically after install. ## Clipboard and image pasting With client tools installed, you can paste images from your Mac's clipboard directly into Claude Code running inside a VM. This works via an `xclip` shim that intercepts clipboard reads and routes them through the SSH tunnel to your Mac's clipboard. This is especially useful for sharing screenshots, diagrams, or UI mockups with Claude Code without manually transferring files. ## Reading local files List and read files on your local machine from inside a VM: ```bash theme={"theme":"github-dark"} boxd local ls # List your home directory boxd local ls Documents # Relative to home boxd local ls /Users/you/Desktop # Absolute path boxd local read ~/notes.txt # Read a file boxd local read ~/app.log --tail=50 # Last 50 lines boxd local read ~/app.log --head=20 # First 20 lines boxd local read ~/app.log --range=10:30 # Lines 10 through 30 ``` Output from `ls` shows absolute paths with type and size: ``` dir /Users/you/Documents file /Users/you/.bashrc (1234 bytes) ``` All commands accept `--json` for structured output. ### Path access For security, only files under your home directory and macOS temporary directories (e.g. `/var/folders/`) are accessible. System files outside these areas are blocked. ### Full Disk Access Some macOS temporary directories (like `TemporaryItems` used for screenshots) are protected by TCC permissions. If you get "Operation not permitted" errors reading files in `/var/folders/`, you need to grant Full Disk Access to `boxd-clientd`. This is **optional** -- only needed if you want to read screenshots or other TCC-protected files from your VM. Go to **System Settings → Privacy & Security → Full Disk Access**. Click the **+** button. In the Finder dialog, navigate to: ``` ~/Applications/boxd-clientd.app ``` If you don't see it, press **Cmd+Shift+G** and paste the path above. Click **Open**. Toggle `boxd-clientd` **on** in the list. ```bash theme={"theme":"github-dark"} launchctl stop sh.boxd.clientd ``` launchd will automatically restart it with the new permissions. ## Browser Launch and control a Chrome instance on your Mac, with the Chrome DevTools Protocol (CDP) forwarded into the VM. This lets tools like Puppeteer or Playwright running inside a VM control a real browser on your local machine. ```bash theme={"theme":"github-dark"} boxd local browser open # Launch Chrome boxd local browser open --headless # Launch headless boxd local browser info # Check status and CDP URL boxd local browser close # Close the browser ``` ### Connecting via CDP The CDP WebSocket URL is always the same: ``` ws://$BOXD_CLIENTD_ADDR/browser/ws ``` Connect from Puppeteer: ```javascript theme={"theme":"github-dark"} const puppeteer = require('puppeteer-core'); const browser = await puppeteer.connect({ browserWSEndpoint: `ws://${process.env.BOXD_CLIENTD_ADDR}/browser/ws` }); const page = await browser.newPage(); await page.goto('https://example.com'); await page.screenshot({ path: 'screenshot.png' }); ``` Or from Playwright: ```javascript theme={"theme":"github-dark"} const { chromium } = require('playwright-core'); const browser = await chromium.connectOverCDP( `ws://${process.env.BOXD_CLIENTD_ADDR}/browser/ws` ); ``` Or straight from chrome using the pre-installed and pre-configured [chrome-devtools-mcp](https://github.com/ChromeDevTools/chrome-devtools-mcp): ```bash theme={"theme":"github-dark"} claude # open my local browser and search for cat pictures on google ``` ### Session persistence The browser uses a fixed session directory on your Mac (`~/.boxd/browser-sessions/default/`). Cookies, localStorage, and login state persist across `open`/`close` cycles. Only one browser instance runs at a time. Calling `open` when a browser is already running returns the existing session. ## Updating To update to the latest version, re-run the install command: ```bash theme={"theme":"github-dark"} curl -fsSL https://boxd.sh/downloads/install.sh | sh ``` The installer automatically restarts the daemon with the new version. If `boxd local` commands inside a VM show a message about updating, it means the daemon on your Mac is missing features available in the latest version. # GitHub Source: https://docs.boxd.sh/integrations/github Connect your GitHub account to clone and push to private repos from any machine. boxd can connect to your GitHub account so your machines can access your private repositories -- no SSH keys or personal access tokens to manage. ## Connecting your account From the [boxd console](https://boxd.sh/app), click **Connect GitHub repos**. This redirects you to GitHub to authorize repository access. Once connected, every machine automatically has access to your repos. ## Using git in your machine After connecting, `git clone` and `git push` work with your private repos out of the box: ```bash theme={"theme":"github-dark"} ssh myapp.boxd.sh git clone https://github.com/you/private-repo.git cd private-repo # make changes... git push ``` No credentials to enter. boxd injects a git credential helper that handles authentication transparently. Git SSH URLs (`git@github.com:...`) are automatically rewritten to HTTPS, so both URL styles work. ## Disconnecting From the console, click **Disconnect** next to your GitHub connection. Future machines won't have repo access. Existing running machines lose access on their next git operation. ## What's authorized When you connect GitHub repos, boxd requests the `repo` scope -- this grants read/write access to your repositories. Your token is never exposed inside the machine. The credential helper fetches it on demand for git operations only. GitHub CLI (`gh`) is also pre-installed (and authenticated) on every machine if you prefer using it directly. # Fork Source: https://docs.boxd.sh/primitives/fork Copy a machine with its full disk state. `fork` creates a new machine that is an exact copy of an existing one -- same filesystem, same installed packages, same data. The new machine gets its own name, IP, and HTTPS domain. ## Usage ```bash theme={"theme":"github-dark"} ssh boxd.sh fork myapp ``` ``` forking myapp-fork... name: myapp-fork id: 7a3f8c12-bb41-4e09-a5d2-91c3e4f0d678 url: myapp-fork.boxd.sh forked from: myapp boot: 1.8s ``` Specify a custom name: ```bash theme={"theme":"github-dark"} ssh boxd.sh fork myapp --name=myapp-v2 ``` With `--json`: ```json theme={"theme":"github-dark"} { "name": "myapp-fork", "vm_id": "7a3f8c12-bb41-4e09-a5d2-91c3e4f0d678", "url": "myapp-fork.boxd.sh", "image": "default", "status": "running", "boot_time_ms": 1800, "forked_from": "myapp" } ``` The fork gets its own 100 GB disk, copied from the source machine. The fork is placed on the same worker as the source machine. If the default name `{source}-fork` is already taken, the command fails. Use `--name` to pick a different name. ## Use cases ### Rollback Fork before a risky change: ```bash theme={"theme":"github-dark"} ssh boxd.sh fork myapp --name=myapp-backup # make changes to myapp... # something broke? ssh boxd.sh destroy myapp # myapp-backup still has the working state ``` ### Experimentation Try things without affecting your working machine: ```bash theme={"theme":"github-dark"} ssh boxd.sh fork myapp --name=experiment # break things freely ssh boxd.sh destroy experiment ``` ### Scaling Need another instance of the same app: ```bash theme={"theme":"github-dark"} ssh boxd.sh fork myapp --name=myapp-2 ``` Both machines run the same code and data from the moment of the fork. Changes after the fork are independent. # Machines Source: https://docs.boxd.sh/primitives/machines Create, list, and destroy machines. A machine is a KVM microVM with its own kernel, network stack, persistent disk, public IP, and HTTPS domain. ## Create ```bash theme={"theme":"github-dark"} ssh boxd.sh new --name=myapp ``` | Flag | Default | Description | | ----------- | ----------------- | ----------------------------------------------------------------------- | | `--name` | auto-generated | Machine name. Must be unique across the cluster. Becomes the subdomain. | | `--image` | `computer:latest` | Container image for the root filesystem. | | `--restart` | `always` | Restart policy: `always` or `never`. | If you omit `--name`, boxd generates a random name like `blue-river`. Output: ``` creating myapp... name: myapp id: 9645b1e8-193d-4d11-86b1-f91deff5bbfb url: myapp.boxd.sh boot: 1.3s Connect via SSH: ssh myapp.boxd.sh Or from your browser: https://myapp.boxd.sh ``` With `--json`: ```json theme={"theme":"github-dark"} { "name": "myapp", "vm_id": "9645b1e8-193d-4d11-86b1-f91deff5bbfb", "url": "myapp.boxd.sh", "image": "default", "status": "running", "boot_time_ms": 1300 } ``` ## List ```bash theme={"theme":"github-dark"} ssh boxd.sh list ``` ``` name status url image myapp running myapp.boxd.sh default test running test.boxd.sh default ``` Returns `no VMs` if you have none. ## Destroy ```bash theme={"theme":"github-dark"} ssh boxd.sh destroy myapp ``` ``` destroyed myapp ``` The name and IP are reserved -- recreating a machine with the same name reuses the same IP when possible. ## What's inside The default image is Ubuntu 24.04 (unminimized, with man pages and full documentation): **Languages and runtimes:** * Python 3 with pip, `uv` package manager, and `pipx` * Go (`golang-go`) * `build-essential` (gcc, g++, make) **Coding agents:** * Claude Code (`claude`) -- Anthropic's CLI coding agent * Codex (`codex`) -- OpenAI's CLI coding agent Use them with a subscription (e.g., Claude Max) or by setting an API key inside your machine. Each machine includes an `AGENTS.md` at `~/.config/boxd/AGENTS.md` that gives agents context about the boxd environment. It's symlinked to `~/.claude/CLAUDE.md` and `~/.codex/AGENTS.md` automatically. **Containers:** * Docker and Docker Compose * Docker Buildx **Editors:** * vim, neovim **Tools:** * git, curl, wget, jq, ripgrep, sqlite3, rsync, tree, file, unzip * GitHub CLI (`gh`) **Monitoring:** * btop, atop, iotop, ncdu **Media:** * ffmpeg, ImageMagick **Network:** * mitmproxy, socat, netcat * Headless Chrome (via `headless-shell`) **System:** * nginx (configured on port 8000, disabled by default) * systemd (full init system) * openssh-server, openssh-client Node.js is not pre-installed. Install it with `sudo apt install -y nodejs npm` or use a version manager like nvm. The `boxd` user has passwordless sudo and is a member of the `docker` group. # Proxies Source: https://docs.boxd.sh/primitives/proxies Every machine gets an HTTPS proxy with its own domain. Create subdomain proxies for additional ports. ## How proxies work A proxy is an HTTPS endpoint paired with a domain. It terminates TLS and forwards traffic to a port on your machine. No certificate setup required. Every machine automatically gets a **default proxy** at `name.boxd.sh`, forwarding to port 8000: ``` https://myapp.boxd.sh -> your machine, port 8000 (default) ``` You can create additional **subdomain proxies**, each with its own domain, pointing to different ports: ``` https://api.myapp.boxd.sh -> your machine, port 3001 https://ws.myapp.boxd.sh -> your machine, port 8080 ``` DNS records are created automatically when the machine boots. Records have a 60-second TTL. ## View your proxies ```bash theme={"theme":"github-dark"} ssh boxd.sh proxy list ``` Filter by machine: ```bash theme={"theme":"github-dark"} ssh boxd.sh proxy list --vm=myapp ``` Each proxy shows its paired domain: ```json theme={"theme":"github-dark"} [ { "name": "default", "vm": "myapp", "domain": "myapp.boxd.sh", "port": 8000 }, { "name": "api", "vm": "myapp", "domain": "api.myapp.boxd.sh", "port": 3001 } ] ``` ## Create a subdomain proxy Each subdomain proxy gets its own domain at `subdomain.vmname.boxd.sh`: ```bash theme={"theme":"github-dark"} ssh boxd.sh proxy new api --vm=myapp --port=3001 ``` This creates the domain `api.myapp.boxd.sh` and forwards HTTPS traffic to port 3001 on your machine. From inside the VM: ```bash theme={"theme":"github-dark"} boxd proxy new api --port=3001 ``` ## Remove a proxy ```bash theme={"theme":"github-dark"} ssh boxd.sh proxy delete api --vm=myapp ``` This removes the proxy and its associated subdomain. Alias: `proxy rm`. ## Change the default port ```bash theme={"theme":"github-dark"} ssh boxd.sh proxy set-port --vm=myapp --port=3000 ``` Or from inside the VM: ```bash theme={"theme":"github-dark"} boxd proxy set-port --port=3000 ``` ## Custom domains Custom domain binding is not yet available. Contact the Azin team if you need a custom domain mapped to your machine. # Suspend & resume Source: https://docs.boxd.sh/primitives/suspend-resume Freeze a machine and wake it in milliseconds. Suspend and resume is **coming soon** to boxd. This page describes how it will work. The underlying technology is already built — boxd is based on [Ignition](https://github.com/lttle-cloud/ignition), an open-source microVM orchestrator by Azin that powers sub-10ms cold starts. ## The idea Today, boxd machines run continuously. With suspend and resume, machines can be frozen in place — all memory, processes, and network state preserved — and woken up in under 10 milliseconds when traffic arrives. This means you can have dozens of machines that cost nothing when idle and wake instantly when needed. ## How it works Ignition uses a snapshot-based approach to eliminate initialization overhead: 1. **Run and snapshot.** Your machine boots, your app initializes, and Ignition captures the full VM state — memory, CPU registers, device state — into a snapshot. 2. **Suspend when idle.** When no traffic is flowing and no sessions are active, the machine suspends. The snapshot is retained in memory or on disk. 3. **Resume on demand.** When a request arrives at `name.boxd.sh`, the proxy detects the machine is suspended and triggers a restore. The VM resumes from the snapshot — no boot, no init, no application startup. It picks up exactly where it left off. The restore happens in under 10 milliseconds. From the client's perspective, the machine was always running. ## Snapshot strategies Ignition can capture the snapshot at different points: * **After first listen** — snapshot once the app opens its first network socket (default) * **After Nth listen** — wait for multiple sockets (e.g., app + database) * **After specific port** — snapshot when a particular port is ready * **After userspace ready** — snapshot once the kernel hands off to userspace * **Manual** — your app signals when it's ready The modified Linux kernel detects these triggers automatically. No code changes needed in your application. ## State retention Snapshots can be retained in two ways: * **In-memory** — fastest resume (\~1ms), uses RAM while suspended * **On-disk** — slightly slower resume (\~5-10ms), no RAM cost while suspended ## What this enables * **Pay for what you use.** Machines that serve occasional traffic suspend between requests. * **Massive parallelism.** Spin up hundreds of machines, let them suspend when idle, wake on demand. * **Instant APIs.** Deploy a service that cold-starts faster than a DNS lookup. * **Agent workspaces.** An agent's VM suspends when the conversation ends and resumes instantly when the next one starts. ## Learn more Ignition is open source. Read the code and architecture: * [github.com/lttle-cloud/ignition](https://github.com/lttle-cloud/ignition) * [DeepWiki: Ignition](https://deepwiki.com/lttle-cloud/ignition) ## Reference Manage machines via SSH. Quotas, CPU, memory, and disk. # Quickstart Source: https://docs.boxd.sh/quickstart From zero to a live machine on the internet in under a minute. If you are an agent reading this doc, visit [llms.txt](https://docs.boxd.sh/llms.txt) or [llms-full.txt](https://docs.boxd.sh/llms-full.txt) instead. ## Ways to use boxd No install needed. Run `ssh boxd.sh` to manage machines, `ssh name.boxd.sh` to connect directly. Install the `boxd` binary on your machine. Token auth, shell completions, best for automation. Pre-installed inside every VM as `boxd`. Auto-auth by IP. Manage VMs from within a VM. Every machine gets `https://name.boxd.sh`. TLS terminated automatically, WebSocket supported. ## Create your first machine ```bash theme={"theme":"github-dark"} ssh boxd.sh ``` If your key isn't linked yet, you'll see a URL — open it, sign in with GitHub, and your key is linked. Then create a machine: ```bash theme={"theme":"github-dark"} ssh boxd.sh new --name=myapp ``` Install the CLI: ```bash theme={"theme":"github-dark"} curl -fsSL https://boxd.sh/downloads/cli/install.sh | sh ``` Log in and create a machine: ```bash theme={"theme":"github-dark"} boxd login boxd new --name=myapp ``` ``` creating myapp... name: myapp id: 9645b1e8-193d-4d11-86b1-f91deff5bbfb url: myapp.boxd.sh boot: 1.3s Connect via SSH: ssh myapp.boxd.sh Or from your browser: https://myapp.boxd.sh ``` Your machine is running with its own HTTPS domain. ## Make it live nginx is pre-installed on port 8000 (the default proxy port). Start it: ```bash theme={"theme":"github-dark"} ssh boxd.sh exec myapp -- sudo systemctl start nginx ``` ```bash theme={"theme":"github-dark"} boxd exec myapp -- sudo systemctl start nginx ``` Visit `https://myapp.boxd.sh` — your machine is live on the internet. ## What's next Create, configure, and manage VMs. Branch an entire machine in seconds. Automatic and subdomain proxy routing. # Resources and limits Source: https://docs.boxd.sh/reference/resources What each account gets. ## Per-machine resources | Resource | Per machine | | ------------------------ | ----------- | | vCPUs | 2 | | Memory | 8 GiB | | Disk | 100 GB | | Max machines per account | 10 | Every machine gets the same fixed resources. Need more? [Contact us](https://azin.run) to increase your quota. ## CPU Each machine gets 2 CPU cores. ## Memory Each machine gets 8 GiB of RAM. ## Disk Each machine gets a 100 GB disk. Disks use copy-on-write -- actual storage usage grows only as you write data. # External CLI Source: https://docs.boxd.sh/using-boxd/external-cli Install the boxd CLI to manage machines from your local terminal. The boxd CLI lets you manage VMs from your local terminal without SSH keys. Recommended for automation and coding agents. ## Install ```bash theme={"theme":"github-dark"} curl -fsSL https://boxd.sh/downloads/cli/install.sh | sh ``` Installs to `~/.local/bin/boxd`. Supports macOS (arm64) and Linux (x86\_64, arm64). The installer also adds a Claude Code skill to `~/.claude/skills/boxd-cli/` so Claude Code knows how to use the CLI on your behalf. ## Authentication ```bash theme={"theme":"github-dark"} boxd login # opens browser for OAuth login boxd logout # remove stored credentials boxd whoami # show your user ID and SSH keys ``` You can also authenticate via token: ```bash theme={"theme":"github-dark"} boxd --token= list # pass token directly BOXD_TOKEN= boxd list # or via env var ``` ## Managing machines ```bash theme={"theme":"github-dark"} boxd new --name=myapp # create a machine boxd list # list your machines boxd fork myapp --name=myapp-v2 # fork with full disk copy boxd reboot myapp # reboot boxd destroy myapp -y # destroy (requires -y or --confirm) ``` All commands accept `--json` for structured output. ## Running commands ```bash theme={"theme":"github-dark"} boxd exec myapp -- uname -a # run a command boxd exec myapp -- 'cd /app && npm start' # shell constructs work boxd exec myapp -e API_KEY=secret -e DEBUG=1 -- CMD # env vars boxd exec myapp --timeout 30 -- CMD # timeout boxd exec myapp --json -- echo hello # JSON: {"output":"hello\n","exit_code":0} ``` ## Interactive access ```bash theme={"theme":"github-dark"} boxd connect myapp # open interactive SSH session ``` ## Copying files Paths after `:` are relative to `/home/boxd` unless starting with `/`. Max 100 MB. ```bash theme={"theme":"github-dark"} boxd cp ./local.txt myapp:/home/boxd/remote.txt # upload boxd cp myapp:/home/boxd/remote.txt ./local.txt # download boxd cp myapp:/path/file - # download to stdout echo data | boxd cp - myapp:/path/file # upload from stdin ``` ## Proxy management Every machine gets `https://name.boxd.sh` forwarding to port 8000 by default. ```bash theme={"theme":"github-dark"} boxd proxy list --vm=myapp # list proxies boxd proxy new api --vm=myapp --port=3001 # create subdomain boxd proxy set-port --vm=myapp --port=3000 # change port boxd proxy set-port --vm=myapp --port=auto # auto-detect boxd proxy delete api --vm=myapp # remove ``` ## Shell completions ```bash theme={"theme":"github-dark"} boxd completions bash >> ~/.bashrc boxd completions zsh >> ~/.zshrc ``` ## Global flags | Flag | Description | | ----------- | ------------------------------------------- | | `--json` | Output as JSON | | `--api-url` | API server URL (default: `https://boxd.sh`) | | `--token` | Auth token (overrides stored credentials) | # HTTPS Source: https://docs.boxd.sh/using-boxd/https Every machine gets an HTTPS domain automatically. Every machine gets a domain at `name.boxd.sh`. The boxd proxy terminates TLS and forwards HTTP requests to your machine. ``` https://myapp.boxd.sh -> your machine, port 8000 (default) ``` ## Getting started nginx is pre-installed and configured on port 8000, but disabled by default. Start it: ```bash theme={"theme":"github-dark"} ssh boxd.sh exec myapp -- sudo systemctl start nginx ``` Visit `https://myapp.boxd.sh` -- you will see a welcome page. ## Running your own app Any process that listens on the proxy's target port (8000 by default) is reachable via HTTPS. No configuration needed. ```bash theme={"theme":"github-dark"} # Python ssh boxd.sh exec myapp -- python3 -m http.server 8000 # Go ssh boxd.sh exec myapp -- "/home/boxd/app/server -port 8000" ``` Node.js is not pre-installed. Install it first: `sudo apt install -y nodejs npm` or use [nvm](https://github.com/nvm-sh/nvm). ## Changing the port The default proxy forwards to port 8000, but you can change it: ```bash theme={"theme":"github-dark"} # From outside ssh boxd.sh proxy set-port --vm=myapp --port=3000 # From inside the VM boxd proxy set-port --port=3000 # Auto-detect the listening port boxd proxy set-port --port=auto ``` ## Subdomain proxies Create additional subdomains pointing to different ports: ```bash theme={"theme":"github-dark"} # api.myapp.boxd.sh -> port 3001 ssh boxd.sh proxy new api --vm=myapp --port=3001 # List all proxies ssh boxd.sh proxy list --vm=myapp # Remove a proxy ssh boxd.sh proxy delete api --vm=myapp ``` ## WebSockets WebSocket connections work transparently. The proxy detects the `Upgrade: websocket` header and forwards the connection. ## HTTP to HTTPS Plain HTTP requests to `http://name.boxd.sh` are redirected to HTTPS automatically. HSTS headers are included in the response. ## DNS A DNS record is created automatically when your machine boots. The record has a 60-second TTL. ``` myapp.boxd.sh -> A record -> machine's public IP ``` # Internal CLI Source: https://docs.boxd.sh/using-boxd/internal-cli Manage VMs from inside a VM using the pre-installed boxd command. Every machine has the `boxd` command pre-installed. Authentication is automatic by source IP — no SSH keys or tokens needed. This lets agents and scripts running inside a VM manage other VMs directly. ## Commands ```bash theme={"theme":"github-dark"} boxd info # current VM info boxd list # list all your VMs boxd new --name=NAME # create a VM boxd fork # fork current VM boxd fork SOURCE --name=NAME # fork a specific VM boxd destroy NAME # destroy a VM (cannot destroy self) boxd exec NAME -- CMD # run command in another VM boxd connect NAME # interactive shell in another VM boxd cp ./file.txt NAME:path # upload file to another VM boxd cp NAME:path ./local # download file from another VM ``` Aliases: `list`/`ls`, `destroy`/`rm`, `connect`/`ssh`. All commands accept `--json` for structured output. ## Running commands in other VMs ```bash theme={"theme":"github-dark"} boxd exec other-vm -- uname -a boxd exec other-vm -e KEY=VAL -- CMD # env vars boxd exec other-vm --timeout 30 -- CMD # timeout cat script.sh | boxd exec other-vm -- 'cat > /tmp/script.sh && bash /tmp/script.sh' # pipe stdin ``` ## Copying files between VMs Paths after `:` are relative to `/home/boxd` unless they start with `/`. Max 100 MB. ```bash theme={"theme":"github-dark"} boxd cp ./config.json backend:config.json # upload boxd cp backend:output.log ./output.log # download boxd cp backend:/etc/nginx/nginx.conf ./nginx.conf # absolute path ``` ## Proxy management Defaults to the current VM when `--vm` is omitted. ```bash theme={"theme":"github-dark"} boxd proxy list # proxies for this VM boxd proxy list --all # proxies for all VMs boxd proxy new api --port=3001 # create subdomain proxy boxd proxy set-port --port=3000 # change default proxy port boxd proxy set-port --port=auto # auto-detect port boxd proxy rm api # remove proxy ``` The internal CLI uses `proxy remove` (alias `proxy rm`) while the SSH CLI uses `proxy delete`. Both do the same thing. ## Local machine access When [client tools](/integrations/client-utilities) are installed on the user's machine, the internal CLI can access files and a browser on the user's local machine: ```bash theme={"theme":"github-dark"} boxd local ls # list user's home directory boxd local ls Documents # relative to home boxd local read ~/notes.txt # read a local file boxd local read ~/log.txt --tail=50 # last 50 lines boxd local read ~/log.txt --range=10:30 # lines 10-30 boxd local browser open # launch Chrome on user's Mac boxd local browser open --headless # headless mode boxd local browser info # status + CDP WebSocket URL boxd local browser close # close browser ``` These commands require the `BOXD_CLIENTD` environment variable to be set, which happens automatically when client tools are installed. ## How it works The internal CLI communicates over HTTP to a metadata server on the bridge gateway (port 9002). For `exec` and `connect`, it uses a binary TCP protocol on port 9003. Authentication is implicit — the metadata server maps your VM's source IP to your user account. Do NOT try to `ssh name.boxd.sh` from inside a VM — VMs don't have your SSH keys. Always use the `boxd` CLI for VM-to-VM communication. ## Delegating work to agents Claude Code is pre-installed in every VM. Start it non-interactively and capture the session ID for follow-ups: ```bash theme={"theme":"github-dark"} RESULT=$(boxd exec myvm -- 'claude -p --output-format json "Build a Flask API on port 8000" --dangerously-skip-permissions 2>/dev/null') SESSION_ID=$(echo "$RESULT" | jq -r .session_id) # Follow up on the same session boxd exec myvm -- "claude -p --resume $SESSION_ID \"Add a /health endpoint\" --dangerously-skip-permissions" ``` The session ID is the handoff mechanism between orchestrator, in-VM agent, and human user. # SSH Source: https://docs.boxd.sh/using-boxd/ssh Manage machines and access them directly via SSH. SSH is the most direct way to use boxd. No install needed — just an SSH key. ## Getting started ```bash theme={"theme":"github-dark"} ssh boxd.sh ``` If your key isn't linked yet, you'll get a URL to sign in with GitHub. Once linked, you're in. To skip host key prompts, add this to `~/.ssh/config`: ```bash theme={"theme":"github-dark"} Host boxd.sh *.boxd.sh StrictHostKeyChecking no UserKnownHostsFile /dev/null ``` ## Managing machines Pass commands directly to `ssh boxd.sh`: ```bash theme={"theme":"github-dark"} ssh boxd.sh new --name=myapp # create a machine ssh boxd.sh list # list your machines ssh boxd.sh fork myapp --name=copy # fork with full disk copy ssh boxd.sh reboot myapp # reboot ssh boxd.sh destroy myapp # destroy ``` Or use the interactive `boxd>` prompt: ```bash theme={"theme":"github-dark"} ssh boxd.sh ``` ``` boxd -- your cloud, your rules Type 'help' for available commands. boxd> list name status url image myapp running myapp.boxd.sh default boxd> exit goodbye ``` ## Running commands inside machines Use `exec` to run commands inside a machine: ```bash theme={"theme":"github-dark"} ssh boxd.sh exec myapp -- ls /home ssh boxd.sh exec myapp -- sudo apt install -y nodejs ssh boxd.sh exec myapp -- 'cd /app && python3 server.py' ``` Wrap commands containing shell metacharacters (`&&`, `|`, `>`, `$`, etc.) in single quotes so your local shell passes them through unchanged. Commands run as the `boxd` user with passwordless sudo. Working directory is `/home/boxd`. Additional flags: ```bash theme={"theme":"github-dark"} ssh boxd.sh exec myapp -e API_KEY=secret -- CMD # set env vars ssh boxd.sh exec myapp --timeout 30 -- CMD # timeout ssh boxd.sh exec myapp --tty -- bash # interactive TTY cat config.json | ssh boxd.sh exec myapp -- 'cat > /home/boxd/config.json' # pipe stdin ``` ## Copying files Downloads write to stdout, uploads read from stdin. Paths after `:` are relative to `/home/boxd` unless they start with `/`. ```bash theme={"theme":"github-dark"} ssh boxd.sh cp myapp:output.log > output.log # download ssh boxd.sh cp myapp:/etc/nginx/nginx.conf > nginx.conf # absolute path cat config.json | ssh boxd.sh cp myapp:config.json # upload ``` Max file size: 100 MB. ## Direct SSH into a machine SSH directly into any machine using its domain: ```bash theme={"theme":"github-dark"} ssh myapp.boxd.sh ``` You land in a shell as the `boxd` user. All standard SSH features work: * **SCP** -- copy files to/from the machine * **Port forwarding** -- tunnel ports through SSH * **VS Code Remote SSH** -- develop remotely * **rsync** -- sync files over SSH Direct SSH only works for the machine owner. Your SSH key must match the key registered to your account. ## Connecting interactively `connect` opens a shell session inside a machine via the control plane: ```bash theme={"theme":"github-dark"} ssh boxd.sh connect myapp ``` This is an alternative to direct SSH (`ssh myapp.boxd.sh`). Use whichever you prefer. ## Managing proxies Every machine gets a default proxy at `name.boxd.sh` forwarding to port 8000. ```bash theme={"theme":"github-dark"} ssh boxd.sh proxy list --vm=myapp # list ssh boxd.sh proxy set-port --vm=myapp --port=3000 # change port ssh boxd.sh proxy set-port --vm=myapp --port=auto # auto-detect ssh boxd.sh proxy new api --vm=myapp --port=3001 # subdomain ssh boxd.sh proxy delete api --vm=myapp # remove ``` ## JSON output Add `--json` to any command for structured output: ```bash theme={"theme":"github-dark"} ssh boxd.sh list --json ``` ```json theme={"theme":"github-dark"} [ { "name": "myapp", "vm_id": "9645b1e8-...", "status": "running", "url": "myapp.boxd.sh", "image": "default" } ] ``` ## Identity ```bash theme={"theme":"github-dark"} ssh boxd.sh whoami ``` ## Adding more SSH keys SSH from a different machine with a new key and go through the same link flow. The new key gets linked to your existing account (matched by GitHub identity).