Skip to main content
The sail CLI manages sailboxes and apps from the terminal. It is a single native binary with no runtime dependencies. Run sail --help or sail <command> --help for the same information at the prompt, and see the Sailboxes guide for what you can do with it.

Install

The CLI and the SDKs are separate products. If you only want to drive Sail from code, install an SDK. If you already use the Python SDK, you have the CLI too: pip install sail puts sail on your PATH.

macOS and Linux

This installs the latest sail into ~/.sail/bin, a directory only sail writes to. If that directory is not on your PATH, the installer adds it to your shell startup files and prints the line to run in the current shell.

Windows

This installs sail.exe into %LOCALAPPDATA%\sail\bin and puts that directory at the front of your user PATH. Restart your shell afterward.

Verify

Installer options

Both installers read a few environment variables. Pin a version, substituting the release you want for X.Y.Z:

Update

This downloads the latest release and replaces the binary you ran, which is normally the standalone install. Re-running the installer does the same thing, and it works the same however you first got the CLI, including through pip install sail. sail update updates the CLI itself. Upgrading a Sailbox is a different operation: sail box upgrade <sailbox>. The Sail API warns when your CLI version is nearing the end of its support window. The warning includes update instructions. A version past the end of its support window is rejected with an update error before any operation runs.

One binary, many channels

There is one real sail CLI per user: the standalone install at ~/.sail/bin/sail (%LOCALAPPDATA%\sail\bin\sail.exe on Windows). The installer writes it, sail update replaces it, and upgrading the SDK with pip install -U sail keeps it current too. pip install sail does not add another copy: in a Python environment, the sail command is a small launcher that runs the standalone install, completing the setup automatically the first time you run it, with no separate download. Installing the SDK into any number of Python environments still leaves exactly one CLI to keep current. sail --version prints the path of the binary that ran.

Interactive shell

For interactive use, sail shell is usually the most convenient option. It opens a REPL on your machine that accepts every command below without the leading sail (so box list, box create ...), and adds touches the one-shot commands do not: line editing and history, a picker menu when you omit a sailbox id, and confirmation prompts.
The individual sail <command> subcommands are non-interactive and take their arguments up front, which suits scripts and agents (add --json for machine-readable output). Mind the naming: sail shell is a shell for managing sailboxes from your machine. It is not a shell inside a box. To open a shell inside a running sailbox, use sail box shell (below).

Global options

These work on any command. sail --version prints the CLI version and the path of the binary that answered (top-level only). Authentication comes from SAIL_API_KEY, falling back to the credential stored by sail auth login. See Configuration.

Authentication

Apps

Sailbox lifecycle

sail box create

sail box list

Run commands and connect

sail box exec

Run a command in a sailbox, streaming its output.

sail box run

Create an ephemeral sailbox, run a command, then terminate it. A shortcut for create + exec + terminate; for workflows that reuse a sailbox, use those directly.
Takes the same create sizing/port flags plus --name (default run-<hex>), --cwd, --timeout, --env, and --keep (leave the sailbox running instead of terminating it).

sail box shell

Open an interactive shell inside a running sailbox. This is the simplest and preferred way in: it runs a PTY over exec, so it opens no port and does not count against your org’s raw-TCP endpoint limit. (Not to be confused with sail shell, the local REPL for managing boxes.) While the shell is open, the session forwards to your machine:
  • Browser opens. When a program in the box opens a browser, the page opens in your local browser instead. This covers logins like claude login, codex login, and gh auth login. A login that redirects to a localhost callback completes end to end.
  • Localhost servers. A server the box starts on localhost (say a dev server on port 3000) becomes reachable at http://localhost:3000 on your machine. The same port is used on your machine, so if it is already in use locally that server is not forwarded.
  • Paste and drag-and-drop. Files dragged onto the terminal upload to /tmp/sail-drops in the box and paste as their guest paths. Press Ctrl+V to forward your clipboard. On devbox images an image or text lands on the box’s clipboard, so pasting a screenshot into claude or codex works as it does locally, and text copied inside the box is copied back to yours. On other images a Ctrl+V image uploads as a file and pastes its path, while text uses your terminal’s own paste. Large uploads show a progress line; press Esc to cancel one.
Pass --no-forward to turn all of it off, for example for an untrusted or automated session, or --no-forward-browser to keep everything but the box’s browser opens. sail box exec --tty forwards the same way (and takes both flags too).

sail box cp

Copy a file to or from a sailbox; <id>:<path> denotes the remote side.

Networking

--tcp exposes raw TCP instead of HTTP. --allowlist restricts sources to an address or a range (e.g. 203.0.113.0/24), or, for HTTP listeners, a Sail app name. Re-exposing a port replaces its whole list; omitting --allowlist reopens the port. See Networking for the full model.

Custom domains

sail box domain serves a Sailbox HTTP listener on a hostname you own, with TLS certificates obtained and renewed for you.
attach requires --port naming an exposed HTTP listener, and checks that your DNS record points at your target first. See Custom domains for the DNS setup, apex-domain options, and certificate behavior.

SSH

sail box ssh sets up SSH access so you can reach a box as ssh <name>.sail. For a quick interactive shell, prefer sail box shell: it needs no open port. Reach for SSH when you need a real SSH endpoint rather than a PTY over exec, such as scp/rsync, an editor’s remote mode, or a devbox you work in day to day. Enabling it exposes port 22 as a TCP ingress port, which counts against your org’s raw-TCP endpoint limit.
  • enable: turn on SSH for a box (expose port 22, install your org’s CA, start sshd), certify your key on this machine, and add the <name>.sail shortcut. --allowlist <addr> restricts the sources allowed to reach port 22 to an address or a range (repeatable).
  • alias: add ssh <name>.sail shortcuts for boxes already SSH-enabled elsewhere (e.g. from the SDK), without waking them.
  • disable: stop SSH on a box and drop its local shortcut.
Only the public half of your key is certified; the private key is referenced in your SSH config, never read.

Configuration

Manage ~/.sail/config.toml.