Skip to content

CLI Reference

One binary, one MCP server — both thin adapters over a single service layer.

nexus exposes one binary (nexus) and one MCP server (nexus mcp). Every operation reachable from the CLI is backed by internal/core/service; CLI and MCP share the same service layer, so capabilities are identical.

Help partial

The target is help on every verb and group, on stdout, exiting zero. Today: running nexus with no arguments lists all commands with one-line descriptions, and verbs that parse flags with Go's flag package (exec, attach, ssh, …) respond to --help. Three things fall short:

  • nexus --help, nexus help and nexus -h are all rejected as unknown (they still print the command list, but exit non-zero).
  • Commands with hand-rolled parsing have no help: the groups sandbox, snapshot, image, auth (at any depth — including create --help, ps --help), and the leaf verbs fork, restore, forward. nexus mcp --help starts the stdio server instead of printing anything.
  • The command list goes to stderr and exits 2, so nexus | less shows nothing.

For per-flag detail, generate the extractor inventory: scripts/docs/extract-surface.sh.

Invocation

nexus [global-flags] <verb> [verb-flags] [args...]

Global flags precede the verb:

FlagTypeDefaultDescription
--jsonboolfalseEmit machine-readable output (see Response envelopes)

Verb index

VerbReferencePurpose
create/ps/rm/start/stop/pause/resume partialLifecycle commandsSandbox lifecycle management (built today as sandbox <verb>)
runLifecycle commandsOne-shot ephemeral exec; sandbox removed on exit
execExec, SSH and forwardRun a command inside a sandbox; auto-detects TTY for interactive use
attachExec, SSH and forwardReattach to an existing guest session
cpExec, SSH and forwardCopy files between host and guest
forwardExec, SSH and forwardForward a host TCP port to a guest port over vsock
log builtExec, SSH and forwardPrint a sandbox's supervisor log (--tail <N> for the last N lines, --follow to stream)
sshExec, SSH and forwardDial a sandbox's sshd over vsock
ssh config partialExec, SSH and forwardPrint an SSH ProxyCommand configuration snippet (built today as config-ssh)
snapshot create/list/rmSnapshot, fork and restoreManage retained snapshots
forkSnapshot, fork and restoreFork a running sandbox into a new copy-on-write child
restoreSnapshot, fork and restoreRestore a retained snapshot into a new running sandbox
volume create/ls/rm/pruneVolume commandsManage named volumes that persist across sandboxes
image build/ls/pruneImage commandsBuild and manage guest images
authAuth, MCP and reapAuthenticate your coding agent (Claude Code, Codex, opencode, …)
secret not builtAuth, MCP and reapNamed secret store: set, ls, rm
mcpAuth, MCP and reapRun an MCP server over stdio
reapAuth, MCP and reapReport (and optionally delete) orphaned host resources
disk usageAuth, MCP and reapReport host disk usage by category, reclaimable space, and free space vs the builder floor
recoverAuth, MCP and reapReconcile persisted sandbox records against the live substrate
doctorAuth, MCP and reapReport substrate availability and capability checks
versionPrint version and build information
--context config partialConfigurationSelf-contained Dockerfile-based image build (built today as --file)

Command grouping partial

Today's implementation groups the lifecycle verbs under a sandbox noun: sandbox create, sandbox list, sandbox start, and so on. The target spells them flat: create, ps, rm, start, stop, pause, resume. The Lifecycle commands page carries the full target-to-implementation mapping.

Response envelopes

There are two envelope shapes, deliberately kept separate.

CLI --json emits newline-delimited JSON, one object per event:

json
{ "schema_version": 1, "kind": "sandbox.created", "data": {  } }
{ "schema_version": 1, "kind": "error", "error": { "code": "sandbox_not_found", "message": "" } }

kind identifies the event (sandbox.created, exec.done, reap.report). Error code values are stable within a schema_version; changes inside a version are additive only.

MCP uses a uniform shape across all tools:

json
{ "ok": true, "data": {  }, "truncated": null }

truncated is non-null only when a response was cut; currently wired for sandbox_list only (64 KiB cap). The two shapes are kept separate because shell and CI pipelines need kind routing and forward-compatible versioning, while MCP tool-call handlers need a minimal success/failure shape with truncation signalling.

MCP scope covers lifecycle and execution. The MCP server exposes 9 tools: the 7 lifecycle tools (sandbox_create, sandbox_list, sandbox_start, sandbox_stop, sandbox_pause, sandbox_resume, sandbox_remove) plus sandbox_exec (run a command in an existing sandbox) and sandbox_run (ephemeral create+boot+exec+remove in one call). Snapshot, fork, restore, forward, image build, and auth operations remain CLI-only. The sandbox_ prefix is kept across all tool names because MCP tool names live in a single flat namespace shared with every other MCP server an orchestrator may load; namespacing by noun avoids collisions without requiring a per-server prefix convention.

Target surface gaps

These capabilities have no implementation today. An unbadged entry in the verb index means built-and-matching.

SurfaceStateWhat the target is
metricsnot builtReport CPU and memory as effective / max. The data exists — auto-resize computes it — but nothing surfaces it.
Label mutationnot builtAdd and remove labels on an existing sandbox.
Fleet lifecycle selectorsnot built--label as a selector for stop and rm, not only for list.
Full helppartialHelp on every verb and group, on stdout, exit zero. See the note at the top of this page for exactly what is missing.

Eleven things are deliberately excluded from the target:

  • Fleet exec — retracted. Fan-out is a host-side loop.
  • A pr verb — pushing pull requests stays host-side so no GitHub credential ever needs to reach a guest.
  • harvest — superseded by live virtiofs mounts; the verb exists in source but is slated for removal once the mounts path ships.
  • up — removed from the target. Bringing up N sandboxes is a host-side loop over create.
  • fork --count/restore --count — built today, removed from the target. Each invocation creates one child; fan-out is the orchestrator looping the verb.
  • create --workspace <host-path> — working-tree capture superseded by named volumes. Use --mount-named to attach a named volume into the sandbox instead.
  • create --capture-max <size> — capture size limit; removed alongside --workspace.
  • shell — built today, retired in the target. exec subsumes it: without a trailing command, or when stdin is a terminal, exec opens an interactive PTY session automatically.
  • Reserved-label convention and git-driven branch naming — nexus is git-unaware. --label carries arbitrary key-value metadata only; no label key has special semantics, and branch names are chosen by the user or orchestrator, not by nexus.
  • Bundle-export and host-side push by nexus — removed. In-guest git push via the MITM GitHub credential path (placeholder-swap + per-repo allowlist) is the supported flow; the host user pushes from the host with their own tools.
  • Preview-release publisher — building and distributing release artifacts is outside the nexus target surface.