# Run Claude Code in a sandbox
URL: https://docs.munito.ai/harnesses/claude-code

Claude Code (`claude`) is installed in the `ubuntu` template. Choose how it signs in, then run a task with `claude -p`.

## Sign in [#sign-in]

### With an Anthropic API key [#with-an-anthropic-api-key]

Put the key in the `env` of the sandbox:

```json
{ "ANTHROPIC_API_KEY": "sk-ant-..." }
```

Claude Code bills the usage to that key. See [authentication](https://code.claude.com/docs/en/authentication) in the Claude Code docs.

### With a Claude subscription [#with-a-claude-subscription]

Sign in inside the sandbox, so that the sign-in never passes through the API:

1. Connect over [SSH](https://docs.munito.ai/sandboxes#ssh) and run `claude`.
2. Type `/login` and choose your Claude account. Claude Code prints a link.
3. Open the link on any device, sign in with your Pro or Max plan, and paste the code back into the terminal.

Claude Code keeps the sign-in in the sandbox, and each later `claude -p` in the same sandbox uses it. A [persistent sandbox](https://docs.munito.ai/sandboxes#persistent-sandboxes) keeps it across pauses. Claude Code then uses the usage limits of your plan.

Anthropic sets the limits of a plan for the usual work of one person, and it does not allow a third party to collect or store the tokens of a Claude account ([legal and compliance](https://code.claude.com/docs/en/legal-and-compliance)). So do not put such a token in an API request, and use an API key to run many agents at the same time.

### With the open models of Munito AI [#with-the-open-models-of-munito-ai]

```json
{
  "ANTHROPIC_BASE_URL": "https://api.munito.ai/inference",
  "ANTHROPIC_AUTH_TOKEN": "munitoai_...",
  "ANTHROPIC_MODEL": "zai-org/glm-5.3-flash[1m]",
  "ANTHROPIC_DEFAULT_OPUS_MODEL": "zai-org/glm-5.3-flash[1m]",
  "ANTHROPIC_DEFAULT_SONNET_MODEL": "zai-org/glm-5.3-flash[1m]",
  "ANTHROPIC_DEFAULT_HAIKU_MODEL": "qwen/qwen3.8-27b"
}
```

One Munito AI key with the **Inference** permission serves the sandboxes API and the models. [Claude Code with open models](https://docs.munito.ai/claude-code) explains each variable, the models and the regional hosts.

## Run a task [#run-a-task]

```bash
curl -sS --fail-with-body "https://api.munito.ai/sandboxes/v1/sandboxes/$SANDBOX/exec" \
  -H "Authorization: Bearer $MUNITO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"command": "cd /workspace && claude -p \"Write a Python script that prints the first 10 primes, and run it\" --allowedTools Bash Edit Write Read --output-format json", "timeout": 1800}'
```

- `claude -p` runs one task and exits. `--output-format json` returns the result and the `session_id`.
- `--allowedTools Bash Edit Write Read` lets Claude Code run commands and change files without asking. As root, Claude Code refuses `--dangerously-skip-permissions`, and `--allowedTools` does the same work.
- To follow the work while it runs, use `--output-format stream-json --verbose` with `"stream": true` in the command: each event of Claude Code comes as it happens.
- `claude -p "..." --resume <session_id>` continues a session in a later command.
- A command runs for at most 30 minutes. For a longer task, run `nohup claude -p "..." --allowedTools Bash Edit Write Read > /workspace/claude.log 2>&1 &` and read the log with later commands.

## Use the terminal UI over SSH [#use-the-terminal-ui-over-ssh]

Add your public key with [SSH](https://docs.munito.ai/sandboxes#ssh), connect with the command that `GET /sandboxes/{sandbox_id}/ssh` answers, and run `claude`. A shell starts in `/workspace`, with the variables of the sandbox. For a session that outlives your connection, install `tmux` (`apt-get install -y tmux`) and start Claude Code inside it.
