Skip to content

Exec and shell#

Four commands work inside a sandbox. All of them need the project ADMIN role.

Command Use it to
nexusctl sandbox exec Run a command in a running sandbox, with optional stdin and TTY.
nexusctl sandbox shell Open an interactive shell in a running sandbox.
nexusctl sandbox run Create a sandbox, run one command in it, and exit with its exit code.
nexusctl sandbox cp Copy files between this machine and a sandbox.

Exec into an agent sandbox#

nexusctl sandbox exec nightly-refactor --project production -- ls -la /workspace

-- separates the remote command from the CLI's own flags. stdout and stderr stream back as they are produced, and the remote command's exit code becomes the exit code of nexusctl, so this composes in scripts:

if ! nexusctl sandbox exec nightly-refactor --project production \
     -- test -f /workspace/report.md; then
  echo "agent has not produced a report yet"
fi

The sandbox must be in started state with its supervisor connected. Exec against a stopped or error sandbox fails rather than starting it.

Passing stdin#

echo '{"task":"summarize"}' | nexusctl sandbox exec nightly-refactor \
  --project production -i -- /usr/local/bin/handle-task

When your stdin ends, the remote stdin is closed too, so a command that reads until end-of-input — a bare cat, for example — finishes.

Interactive TTY#

nexusctl sandbox exec nightly-refactor --project production -t -- top

-t allocates a TTY: raw mode locally, a PTY remotely, and terminal resizes forwarded as the window changes. It implies -i.


Open a shell#

nexusctl sandbox shell nightly-refactor --project production

This is sugar for sandbox exec <slug> -it -- bash. Pass --shell sh when the image has no bash; the binary has to exist on $PATH inside the image.


Run one command in a new sandbox#

sandbox run creates a sandbox, waits until it is started, runs one command in it, and exits with that command's exit code. It is the shape of a CI step or a script that needs the project's policy and connections for a single job.

nexusctl sandbox run --project production -f task.yaml --rm -- ./task.sh
  • run takes the same spec flags as sandbox create, including -f for a spec file. The command after -- runs next to the sandbox's main command, which defaults to sleep infinity when the spec does not set one.
  • The wait for started lasts at most five minutes. A sandbox that goes to error stops the run at once with the reason.
  • --rm deletes the sandbox when the command exits, fails, or is interrupted. Ctrl-C exits with code 130, except under -t, where it goes to the remote process.
  • -i and -t work as they do on exec.
  • Status lines go to stderr, so stdout carries only the command's output. A job can stream results back as a tar archive:
nexusctl sandbox run --project production -f task.yaml --rm -- sh -c '
  ./task.sh >&2 || exit $?
  tar -C /workspace/out -cf - .
' > out.tar

The sandbox runs under the policy its spec attaches, so kubectl and aws in the image reach only the connections that policy grants, with credentials injected on the way out and never readable inside.


Copy files#

nexusctl sandbox cp --project production ./inputs nightly-refactor:/workspace
nexusctl sandbox cp --project production nightly-refactor:/workspace/out results

Exactly one side is <sandbox>:<path>. SOURCE is copied into the directory DEST and keeps its name, so the first command makes /workspace/inputs and the second makes results/out. DEST is created if it is missing.

The copy is a tar stream over exec, as with kubectl cp, so both this machine and the sandbox image need tar.


Over MCP#

Interactive exec into a sandbox is a WebSocket, and there is no MCP tool for it. An agent connected to the MCP endpoint manages sandboxes with the platform tools, but does not get a terminal inside one.


What is audited#

Creating, starting, stopping, and deleting a sandbox, the one sandbox run creates included, is written to the audit trail with the actor, the project, and the result. That applies whether the caller was a person at a terminal or an API token in CI.