# Run OpenCode in a sandbox
URL: https://docs.munito.ai/harnesses/opencode

OpenCode (`opencode`) is installed in the `ubuntu` template. Choose how it signs in, then run a task with `opencode run`.

## Sign in [#sign-in]

### With the API key of a provider [#with-the-api-key-of-a-provider]

OpenCode reads the key of each provider from its usual variable, such as `ANTHROPIC_API_KEY` or `OPENAI_API_KEY`. Put it in the `env` of the sandbox:

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

`opencode models` lists the models that your keys reach. `-m provider/model` picks one for a run.

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

Sign in inside the sandbox, over [SSH](https://docs.munito.ai/sandboxes#ssh):

- **GitHub Copilot** (Pro, Pro+, Business or Enterprise): run `opencode auth login`, choose GitHub Copilot, and enter the code that it prints at github.com/login/device.
- **OpenCode Zen or OpenCode Go**: create a key at [opencode.ai/auth](https://opencode.ai/auth), and put it in the `env` of the sandbox as `OPENCODE_API_KEY`.

OpenCode keeps a sign-in in `~/.local/share/opencode/auth.json`, and a [persistent sandbox](https://docs.munito.ai/sandboxes#persistent-sandboxes) keeps it across pauses. A Claude subscription does not work in OpenCode, because Anthropic does not allow it. For a ChatGPT plan, use [Codex](https://docs.munito.ai/harnesses/codex). See the [providers](https://opencode.ai/docs/providers) in the OpenCode docs.

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

Put your Munito AI key in the `env` of the sandbox as `MUNITO_API_KEY`, and write this configuration to `~/.config/opencode/opencode.json` in the sandbox, with the files API or a command:

```json
{
  "$schema": "https://opencode.ai/config.json",
  "model": "munito/zai-org/glm-5.3-flash",
  "provider": {
    "munito": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "Munito",
      "options": {
        "baseURL": "https://api.munito.ai/inference/v1",
        "apiKey": "{env:MUNITO_API_KEY}"
      },
      "models": {
        "zai-org/glm-5.3-flash": {
          "name": "GLM-5.3-Flash",
          "limit": { "context": 1048576, "output": 943718 }
        }
      }
    }
  }
}
```

`{env:MUNITO_API_KEY}` reads the key from the environment, so the file holds no key. [OpenCode with open models](https://docs.munito.ai/opencode) explains the provider, the reasoning effort 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 && opencode run --auto \"Write a Python script that prints the first 10 primes, and run it\"", "timeout": 1800}'
```

- `opencode run` runs one task with the `build` agent and exits. It writes the answer to standard output.
- `--auto` approves each permission that no rule denies, so OpenCode runs commands and changes files without asking. Without it, `opencode run` rejects each permission that would ask.
- `-m provider/model` picks the model for one run. Without it, OpenCode uses `model` from its configuration.
- A command runs for at most 30 minutes. For a longer task, run `opencode run` in the background with `nohup` and read its 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 `opencode` in `/workspace`. For a session that outlives your connection, install `tmux` (`apt-get install -y tmux`) and start OpenCode inside it.
