# Connect with the CLI
URL: https://metorial.com/docs/build/sandboxes/connect-cli

Open a shell, run commands, and move files from your terminal.

---

The CLI gives you a terminal in any running machine and copies files in both directions. Use it to debug a machine, seed it with data, or script work against it.

<PageIntro>
  <Learn>
    * How to open a shell and run one-off commands
    * How to list, read, and transfer files
    * How to open a port in your browser
  </Learn>

  <Reading title="Before you start">
    * A running machine, saved as `MACHINE` ([quickstart](/docs/build/sandboxes/quickstart))
  </Reading>
</PageIntro>

<Note>
  Connections need a running machine. Run `metorial-admin sandbox machines start $MACHINE` first if the machine is paused or hibernated.
</Note>

## Open a shell [#open-a-shell]

```bash
metorial-admin sandbox machines shell $MACHINE
```

You get an interactive terminal with full TTY support, so editors, `top`, and Ctrl+C work as usual. If your network drops, the CLI reconnects and resumes the same session. Type `exit` to close it.

## Run commands [#run-commands]

Put the command after `--`. Output streams to your terminal, and the CLI exits with the command's exit code, so it works in scripts and CI.

```bash
# Run a single command
metorial-admin sandbox machines shell $MACHINE -- python --version

# Set the working directory and environment variables
metorial-admin sandbox machines shell $MACHINE --cwd /app -e NODE_ENV=production -- npm test

# Pipe a local script into the machine
cat setup.sh | metorial-admin sandbox machines shell $MACHINE -- bash -s
```

Pass `-t` to force a TTY, for example to get colored output, or `-T` to turn it off. Repeat `-e` for each variable.

## Work with files [#work-with-files]

Remote paths are always absolute. Use `-` as the local path to read from stdin or write to stdout.

```bash
# Browse
metorial-admin sandbox machines files ls $MACHINE /app -r --max-depth 2
metorial-admin sandbox machines files stat $MACHINE /app/package.json
metorial-admin sandbox machines files cat $MACHINE /app/package.json

# Copy a directory in and results out
metorial-admin sandbox machines files upload $MACHINE ./src /app/src -r
metorial-admin sandbox machines files download $MACHINE /app/output ./output -r

# Manage files
metorial-admin sandbox machines files mkdir $MACHINE /app/logs
metorial-admin sandbox machines files mv $MACHINE /app/old.txt /app/new.txt
metorial-admin sandbox machines files rm $MACHINE /app/tmp -r
```

Uploads create missing parent directories. Recursive transfers copy files in parallel, keep file modes, and recreate symlinks.

Useful options:

* `upload --mode 0755`: sets the mode of uploaded files.
* `upload --no-overwrite`: fails instead of replacing an existing file.
* `rm -f`: ignores paths that don't exist.
* `mv --overwrite`: replaces the destination if it exists.
* `ls --limit`: caps the number of entries (10,000 by default).

## Open a port [#open-a-port]

Generate a temporary URL for a port the machine listens on:

```bash
metorial-admin sandbox machines access ports $MACHINE --ports '[3000]' --ttl-seconds 3600
```

The output contains the URL for each port and a token. Send the token in the `Metorial-Sandbox-Token` header. [Networking](/docs/build/sandboxes/networking) covers public ports, which need no token.