> ## Documentation Index
> Fetch the complete documentation index at: https://docs.boxd.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Commands

> The full boxd CLI command reference, grouped by task.

Every machine operation is available from the CLI, and all commands accept `--json` for scripting. This page is the full reference.

## The command tree

The surface is a nested tree. This is the full first level:

| Command       | Alias  | What it does                                                                                                                 |
| ------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------- |
| `machine`     | `m`    | Machines end to end: create, fork, state control, exec, files, proxies, domains, checkpoints, networks, per-machine settings |
| `new`         |        | Create a machine, from scratch, a fork, or a snapshot (shortcut for `machine new`)                                           |
| `connect`     |        | Open an interactive shell in a machine (shortcut for `machine connect`)                                                      |
| `list`        | `ls`   | List your machines (shortcut for `machine list`)                                                                             |
| `snapshots`   | `snap` | Reusable snapshots of memory and disk                                                                                        |
| `auth`        |        | [Login](/cli/authentication), identity, org context, [API keys](/cli/authentication#api-keys)                                |
| `manage`      |        | Org-level management: billing, integrations, wildcard domains                                                                |
| `env`         |        | Env vars and secrets                                                                                                         |
| `config`      |        | Laptop-side CLI settings                                                                                                     |
| `docs`        |        | Open the boxd documentation in your browser                                                                                  |
| `completions` |        | Set up shell tab-completion                                                                                                  |
| `version`     |        | Show the CLI version                                                                                                         |

The three shortcuts exist because creating, connecting, and listing are what you do all day: `boxd new myapp` and `boxd machine new myapp` are the same command.

`remove` is the delete verb everywhere (alias `rm`), and the common aliases are `ls` for `list`, `info` for `get`, and `ssh` for `connect`.

<Tip>
  `boxd <cmd> --help` is the always-current reference for flags and subcommands, straight from your installed binary. Running bare `boxd` in a terminal drops into an interactive REPL (`boxd (org)>`) where you type the same commands without the `boxd` prefix, with tab completion and arrow-key pickers for missing arguments.
</Tip>

## Managing machines

```bash theme={"theme":"github-dark"}
boxd machine new myapp                              # create a machine
boxd machine new                                    # auto-named
boxd machine new myapp --auto-suspend-timeout=60    # idle secs before auto-suspend (0 disables)
boxd machine new myapp --auto-hibernate-timeout=0   # never hibernate this machine
boxd machine new myapp --shared                     # in an org context: shared with the whole org from birth
boxd machine new myapp --networks=backend,cache     # join these networks instead of the default one
boxd machine new myapp --isolated                   # sandbox, see Networks below
boxd machine list                                   # list your machines (alias: ls)
boxd machine get myapp                              # detailed info (status, image, auto-suspend; alias: info)
boxd machine fork myapp myapp-v2                    # fork with a full disk copy
boxd machine fork myapp --auto-suspend-timeout=0    # fork with auto-suspend disabled
boxd machine fork shared-vm --shared                # keep a fork of a shared machine shared (default: private to you)
boxd machine fork myapp --networks=backend          # fork onto different networks (default: inherit the source's)
boxd machine rename myapp myapp2 -y                 # rename (reboots to apply the hostname unless stopped)
boxd machine remove myapp -y                        # destroy (requires -y or --confirm; alias: rm)
```

`boxd new myapp` and `boxd m ls` are the top-level and short forms. `machine new` folds in fork (`--fork`) and snapshot restore (`--from-snapshot`):

```bash theme={"theme":"github-dark"}
boxd machine new myapp-v2 --fork myapp              # same as `machine fork myapp myapp-v2`
boxd machine new fresh --from-snapshot my-workspace # create from a snapshot (fast; restores memory + disk)
```

See [Suspend, resume, and hibernate](/guides/suspend-resume) for how the idle timers work.

### State control

Three categories of state transition, all `boxd machine <verb> <machine>`:

```bash theme={"theme":"github-dark"}
boxd machine start myapp       # start a stopped machine
boxd machine stop myapp        # stop (disk persists; running processes lost)
boxd machine pause myapp       # standby (warm: memory preserved, sub-ms resume)
boxd machine resume myapp      # resume a paused machine
boxd machine hibernate myapp   # cold snapshot to disk now (frees host RAM)
boxd machine wake myapp        # wake a hibernated machine
boxd machine reboot myapp      # reboot (cold: memory lost, ~2s)
```

* **pause / resume** are warm. They freeze the VMM process and keep memory, running processes, and open sockets intact. Resume is sub-millisecond. This is the same mechanism as auto-suspend, only user-triggered. Status becomes `standby`.
* **reboot** and **stop** + **start** are cold. They kill the VMM process, so memory is lost and the restart takes \~2s.

Use `pause` for cost savings without losing state. Use `reboot` when you need a cold restart.

## Running commands

```bash theme={"theme":"github-dark"}
boxd machine exec myapp -- uname -a                        # run a command
boxd machine exec myapp -- 'cd /app && npm start'          # shell constructs work
boxd machine exec myapp -e API_KEY=secret -e DEBUG=1 -- CMD  # env vars
boxd machine exec myapp --timeout 30 -- CMD                # timeout in seconds
boxd machine exec myapp --tty -- htop                      # allocate a pseudo-TTY (for interactive tools)
boxd machine exec myapp --json -- echo hello               # JSON: {"output":"hello\n","exit_code":0}
```

Exit codes are forwarded, so a remote command that exits 42 makes `boxd machine exec` exit 42.

The remote command's stdout and stderr are surfaced separately on the local side, so shell redirects work as you'd expect:

```bash theme={"theme":"github-dark"}
boxd machine exec myapp -- gcc -v 2>/dev/null              # drop the version banner (it's on stderr)
boxd machine exec myapp -- cargo build 2>build.log         # only warnings/errors land in build.log
```

PTY execs (`--tty`) are the exception. The kernel TTY layer merges stderr into stdout, as terminals do, so everything arrives on local stdout and `2>` filters won't separate them.

<Note>
  The `--` separator between the machine name and the command is optional, since everything after the machine name is treated as the command. Put exec's own flags (`-e`, `--timeout`, `--tty`) before the command, and use `--` or quotes when your command starts with a dash.
</Note>

## Interactive access

`boxd connect` drops you straight into an interactive shell on the machine over the boxd API. It needs neither SSH config nor host keys, auto-resumes paused or hibernated machines on demand, and forwards exit codes. Type `exit` or Ctrl-D to come back to your local shell.

```bash theme={"theme":"github-dark"}
boxd connect myapp             # drops you into a shell (top-level shortcut)
boxd machine connect myapp     # the full path
boxd machine ssh myapp         # `ssh` is the alias of connect
```

`connect` requires an interactive terminal and refuses to run in scripts, pipes, or other non-TTY contexts. For automation, use `boxd machine exec` instead:

```bash theme={"theme":"github-dark"}
boxd machine exec myapp -- uptime    # one-shot, scriptable
```

## Editor & SSH integration

The CLI keeps a managed block of `Host` entries in `~/.ssh/config` **automatically**. Every `machine new`, `fork`, `list`, `remove`, and `rename` refreshes it, and a background agent re-syncs it periodically, so your SSH config stays current as machines come and go. There is no separate command to run.

After the first sync, `<vmname>.boxd` is reachable to plain `ssh`, `scp`, `rsync`, Cursor / VS Code Remote-SSH, JetBrains Gateway, Zed Remote, and anything else that reads SSH config:

```bash theme={"theme":"github-dark"}
ssh myapp.boxd                                      # plain SSH (alias carries HostName + Port)
cursor --remote ssh-remote+myapp.boxd /home/boxd    # Cursor (Remote-SSH)
code   --remote ssh-remote+myapp.boxd /home/boxd    # VS Code
# JetBrains Gateway / Zed: pick `myapp.boxd` from their host picker
```

Each machine is reachable on a dedicated SSH **port** (10000-30000 range) on the shared proxy IP, so each stanza carries a `HostName`, a `Port`, a `User`, and a managed `IdentityFile`. The CLI also pre-trusts the proxy's host key in `~/.ssh/known_hosts`, so the first connect never prompts. Connecting to the bare `<vmname>.boxd.sh` hostname on port 22 reaches the proxy rather than the machine, so always use the `<vmname>.boxd` alias. The managed block is bracketed with `# BEGIN boxd` / `# END boxd`, and nothing outside the markers is ever modified.

## Copying files

Paths after `:` are relative to `/home/boxd` unless starting with `/`. Uploads stream automatically, with no inherent file-size cap.

```bash theme={"theme":"github-dark"}
boxd machine cp ./local.txt myapp:/home/boxd/remote.txt    # upload
boxd machine cp myapp:/home/boxd/remote.txt ./local.txt    # download
boxd machine cp myapp:/path/file -                         # download to stdout
echo data | boxd machine cp - myapp:/path/file             # upload from stdin
boxd machine cp -r ./dir myapp:dir                         # recursive
```

## Proxy management

Every machine gets `https://name.boxd.sh` forwarding to its default port. Publish more ports, either HTTPS subdomains or raw TCP/UDP forwards, all under `boxd machine proxy`.

```bash theme={"theme":"github-dark"}
boxd machine proxy list --vm myapp                       # list published ports (alias: ls)
boxd machine proxy add api --vm myapp --port 3001        # HTTPS subdomain: api.myapp.boxd.sh → 3001
boxd machine proxy set-port --vm myapp --port 3000       # change the default proxy's target port
boxd machine proxy set-port --vm myapp --port auto       # auto-detect the listening port
boxd machine proxy remove api --vm myapp                 # remove a subdomain proxy (alias: rm)
```

Subdomain proxies are HTTPS-only. To expose a database, an SSH daemon, or any non-HTTP service, use a raw port forward (below).

## Custom domains

Bring your own domain instead of `name.boxd.sh`. See [Custom domains](/guides/custom-domains) for the full walkthrough (DNS records, confirmation step, gotchas).

```bash theme={"theme":"github-dark"}
boxd machine domain add app.example.com --vm myapp   # prints DNS records, then waits for Enter (or pass -y/--confirm)
boxd machine domain list                             # domain, machine, status, error (alias: ls)
boxd machine domain remove app.example.com            # unbind (alias: rm)
```

Org admins can delegate a wildcard to the whole org instead of binding machines one at a time:

```bash theme={"theme":"github-dark"}
boxd manage domain set preview.mysaas.com    # prints NS records to delegate, then waits for Enter (or -y/--confirm)
boxd manage domain get                       # any org member can read it
boxd manage domain clear                     # admin only
```

## Raw TCP and UDP ports

Raw forwards live under the same `machine proxy` group, selected with `--raw`. boxd opens a raw TCP or UDP port on the machine's public proxy and forwards it straight to a port inside the machine, for anything that isn't HTTP (databases, game servers, custom protocols). The public port is allocated for you. Connect on the machine's existing `name.boxd.sh` endpoint at that port. See [Port forwarding](/guides/port-forwarding) for the concept.

```bash theme={"theme":"github-dark"}
boxd machine proxy add --vm myapp --port 5432 --raw            # forward a public port -> :5432 (TCP)
boxd machine proxy add --vm myapp --port 9999 --raw --udp      # UDP instead
boxd machine proxy add --vm myapp --port 7777 --raw --tcp --udp # both protocols on one allocated public port
boxd machine proxy list --vm myapp                            # raw forwards show as kind tcp/udp
boxd machine proxy remove 5432 --vm myapp                     # remove a raw forward by its machine port
```

Up to **3** raw forwards per machine. Re-adding a port you already forwarded keeps the same public port and just updates the protocol set. Forwards are owner-only and removed automatically when the machine is destroyed.

## Snapshots

A snapshot captures a running machine's memory and disk at a moment in time, replicated across a few workers. Create a machine from it near-instantly with `machine new --from-snapshot`.

```bash theme={"theme":"github-dark"}
boxd snapshots save myapp my-workspace              # save memory + disk as a named snapshot (machine keeps running)
boxd snapshots list                                 # name, version, status, size, used (alias: ls)
boxd snapshots remove my-workspace -y               # delete a snapshot and its replicas (alias: rm)
boxd snap save myapp my-workspace                   # `snap` is the short alias
```

Re-saving an existing name captures a new version, and the latest version is what new machines get. Snapshots are fenced to the org context that created them and never cross an org boundary.

## Checkpoints

A checkpoint captures a running machine's memory and disk on the machine's own worker, restorable **in place**: the machine reboots into that exact state with the same name, URL, and ports. Checkpoints are per-machine, live and die with the machine, and never become a reusable image. Use them as quick save points before a risky change.

```bash theme={"theme":"github-dark"}
boxd machine checkpoint save myapp before-migration    # capture memory + disk (machine keeps running)
boxd machine checkpoint list myapp                     # name, status, size, created, available (alias: ls)
boxd machine checkpoint restore myapp before-migration # reboot the machine into the checkpoint (-y to skip confirm)
boxd machine checkpoint remove myapp before-migration  # delete a checkpoint (-y; alias: rm)
```

Up to 10 checkpoints per machine. `available: no` means the checkpoint's worker is no longer the machine's worker (for example after a migration), so it can't be restored until they line up again.

## Integrations

Connect third-party accounts (**GitHub**, **Linear**, and **Slack**) under `boxd manage integrations`, and every personal machine in that org can use them. See [Integrations](/guides/integrations/overview) for the full model.

```bash theme={"theme":"github-dark"}
boxd manage integrations                       # list connected integrations + what you can connect (alias: ls)
boxd manage integrations connect linear        # connect via browser OAuth: prints a URL, polls until you approve
boxd manage integrations disconnect linear     # revoke at the provider + remove from boxd
boxd manage integrations mcp linear            # install Linear's MCP into all agents (claude, codex, opencode)
boxd manage integrations mcp slack claude      # ...or only specific agents
boxd manage integrations mcp linear --disable  # remove the MCP from every agent
boxd manage integrations --shared connect slack # connect the ORG's shared credential (org admin)
```

`connect` prints an authorize URL for you to open in a browser, and a human has to approve it. Integrations are fenced to one org. Your own connection serves your private machines in the active org, while `--shared` addresses the org's connection for its shared machines (admin only).

## Env vars & secrets

Set environment variables and secrets once, and boxd injects them into every machine you own in that org. Plain vars are cleartext and readable back. `--secret` seals a value at rest, write-only. See [Env vars & secrets](/guides/env-secrets) for the full model (scopes, naming, injection).

```bash theme={"theme":"github-dark"}
boxd env set DATABASE_URL postgres://…   # cleartext env var
boxd env set OPENAI_API_KEY sk-… --secret # sealed, write-only, never readable back
boxd env list                            # NAME / VALUE / SCOPE; secrets show (sealed) (alias: ls)
boxd env remove DATABASE_URL             # delete (alias: rm; --scope disambiguates in an org context)
boxd env scope OPENAI_API_KEY shared --from private  # move a secret to another org scope (value preserved)
```

To put a literal **.env file** on **one** machine, rather than an account-wide var, use `boxd env push`:

```bash theme={"theme":"github-dark"}
boxd env push myapp --file .env --dest ~/myapp/.env   # upload + chmod 600
```

`--file` defaults to `.env`, `--dest` to the file's name in the machine's home directory, and `--mode` to `600`.

## Billing

Every machine is 2 vCPU / 8 GiB RAM / 100 GB disk. Your balance, usage, and payment live under `boxd manage billing`.

```bash theme={"theme":"github-dark"}
boxd manage billing              # your (or the active org's) balance and usage
boxd manage billing --open       # open the billing portal in your browser
```

See [boxd.sh/pricing](https://boxd.sh/pricing) for the rate card.

## Organizations

Every account works in an org context, and your personal account counts as an organization of its own. Your active **context** decides which org a new machine is billed to and which machines `list` and `connect` see. Switching context is covered in [Org context](/cli/authentication#org-context). Sharing a machine opens it to every member of the org.

```bash theme={"theme":"github-dark"}
boxd auth switch acme            # work in the "acme" org context
boxd machine share myapp         # share a machine with the whole org (every member can reach it)
boxd machine unshare myapp       # stop sharing: private to you again (org keeps paying)
```

* In an org context, `boxd machine new` creates a machine **billed to the org but private to you**. Add `--shared` to make it visible to the whole org from birth.
* `boxd manage billing` follows the active context, so in an org it shows the org's balance and usage.
* **Share and unshare are owner-only.** Any member can `connect` to a *shared* machine. A private machine, personal or org-billed, is reachable only by its owner.
* An org has three roles: **owner**, **admin**, and **member**. Owners and admins invite and remove members at [`/app/organizations`](https://boxd.sh/app/organizations).

<Warning>
  Sharing a machine **wipes its in-VM agent logins** (Claude Code, Codex, OpenCode) the instant it goes shared, so a teammate with a shell can never read your personal tokens. Unsharing restores Claude automatically, while Codex and OpenCode need a one-time re-login. Forking a shared machine gives you a **private** fork with your logins intact. See [VM sharing](/guides/share-a-vm) for the full handoff.
</Warning>

## Networks

Machines reach each other when they **share at least one network**, or when **neither has any**. Machines with no networks form your default network, so naming a network opts a machine out of that pool. The same rule governs direct connections, the `<name>.boxd` DNS name, and `machine exec` / `cp` between machines.

```bash theme={"theme":"github-dark"}
boxd machine networks myapp                    # show current networks
boxd machine networks myapp backend,cache      # replace the whole set (not a merge)
boxd machine networks myapp --clear            # remove them all → the default network
```

Networks are labels you pick, with nothing to create first, and they never cross an organization. Changes take effect immediately, without a reboot. Set them at creation with `machine new --networks`.

`machine new --isolated` sandboxes a machine. It never joins the default network and never reaches another isolated machine, and boxd strips everything that could reach into the rest of your account from it: the in-VM `boxd` CLI, your connected integrations, your saved agent logins, and the bridge to your laptop. Outbound internet, its HTTPS domain, and inbound SSH still work. Isolation is fixed at creation and always inherited by forks and snapshot restores, while its `--networks` remain editable and are the only thing it can reach through. See [Sandboxes](/use-cases/sandboxes).

## Per-machine settings

Auto-suspend and auto-hibernate timeouts live under `boxd machine config`. You can also set them at creation with `--auto-suspend-timeout` / `--auto-hibernate-timeout`.

```bash theme={"theme":"github-dark"}
boxd machine config list myapp                        # all settings for a machine
boxd machine config get myapp auto-suspend.timeout    # read one
boxd machine config set myapp auto-suspend.timeout 300    # suspend after 5 min idle (0 = off)
boxd machine config set myapp auto-hibernate.timeout 0    # never hibernate
```

## CLI settings

`boxd config` persists laptop-side CLI settings (kept in `config.toml`).

```bash theme={"theme":"github-dark"}
boxd config list                              # api-url, client-utils.enable, daemon.enable
boxd config get api-url                       # read one
boxd config set api-url https://boxd.sh       # persist the API server (flag/env still override)
boxd config set client-utils.enable true      # enable the clipboard/files/browser bridge for this device
```

Shell completions are covered in [Installation](/cli/installation#shell-completions).

## Open the docs

```bash theme={"theme":"github-dark"}
boxd docs                        # opens https://docs.boxd.sh in your browser
```

## Global flags

| Flag                         | Description                                                                            |
| ---------------------------- | -------------------------------------------------------------------------------------- |
| `--json`                     | Output as JSON (the only visible global besides `--help`)                              |
| `--api-url` / `BOXD_API_URL` | API server URL (hidden; default `https://boxd.sh`)                                     |
| `--token` / `BOXD_TOKEN`     | Auth token, overrides stored credentials (hidden)                                      |
| `--org`                      | Run one invocation in a specific org context (hidden; persist with `boxd auth switch`) |
