Skip to main content
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

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

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.
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.
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 are installed on the user’s machine, the internal CLI can access files and a browser on the user’s local machine:
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:
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.