> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ns.rocks/llms.txt
> Use this file to discover all available pages before exploring further.

# OpenCode

> Run OpenCode in a secure Nullspace machine.

The `opencode` template supports `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, or
`OPENCODE_API_KEY`.

## Run OpenCode

Create a machine from the `opencode` template, run OpenCode headlessly, and
clean up. The SDK and CLI paths are equivalent — use the one that matches your
workflow.

<CodeGroup>
  ```python Python SDK theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  import json
  import os
  from nullspace import Machine

  model = os.environ.get("OPENCODE_OPENAI_MODEL", "openai/gpt-5.2")
  config = json.dumps({
      "$schema": "https://opencode.ai/config.json",
      "model": model,
      "small_model": model,
      "provider": {
          "openai": {
              "options": {"apiKey": "{env:OPENAI_API_KEY}"}
          }
      },
  })

  with Machine.create(
      template="opencode",
      envs={
          "OPENAI_API_KEY": os.environ["OPENAI_API_KEY"],
          "OPENCODE_CONFIG_CONTENT": config,
          "OPENCODE_DISABLE_AUTOUPDATE": "true",
      },
      timeout=600,
  ) as machine:
      result = machine.commands.run(
          'opencode run --model openai/gpt-5.2 --dangerously-skip-permissions "Create a hello world HTTP server in Go"',
          shell=True,
          cwd="/workspace",
          timeout=600,
      )
      print(result.stdout)
  ```

  ```bash CLI theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  nullspace machine create \
    --template opencode \
    --env "OPENAI_API_KEY=${OPENAI_API_KEY}" \
    --env "OPENCODE_DISABLE_AUTOUPDATE=true" \
    --timeout 600
  # machine create prints the id used below as mch_123
  nullspace machine exec mch_123 \
    --cwd /workspace \
    --timeout 600 \
    --shell 'opencode run --model openai/gpt-5.2 --dangerously-skip-permissions "Create a hello world HTTP server in Go"'
  nullspace machine kill mch_123
  ```
</CodeGroup>

### Interactive terminal

Open a PTY instead of a headless run to drive OpenCode interactively:

```bash theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
nullspace machine pty create mch_123 --cols 120 --rows 30
nullspace machine pty connect mch_123 --session-id ses_123
# then, inside the PTY:
opencode
```

Use the `session_id` from `machine pty create` with `--session-id`.

## Provider models

| Provider  | API key env         | Default model env          |
| --------- | ------------------- | -------------------------- |
| Anthropic | `ANTHROPIC_API_KEY` | `OPENCODE_ANTHROPIC_MODEL` |
| OpenAI    | `OPENAI_API_KEY`    | `OPENCODE_OPENAI_MODEL`    |
| OpenCode  | `OPENCODE_API_KEY`  | `OPENCODE_ZEN_MODEL`       |

## Work on a cloned repository

```python theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
machine.git.clone("https://github.com/your-org/your-repo.git", path="/workspace/repo", depth=1)
machine.commands.run(
    'opencode run --dangerously-skip-permissions "Add tests for the auth module"',
    shell=True,
    cwd="/workspace/repo",
    timeout=600,
    on_stdout=lambda data: print(data, end=""),
)
print(machine.git.diff(path="/workspace/repo"))
```

## Serve OpenCode

OpenCode can run a headless HTTP server inside the machine. Start it on
`0.0.0.0`, then use `machine.get_url(port)` to connect through Nullspace's
preview URL routing.

```python theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
server = machine.commands.run(
    "opencode serve --hostname 0.0.0.0 --port 4096",
    shell=True,
    background=True,
)
print(machine.get_url(4096))
```

## Related

* [Preview URLs](../networking/preview-urls)
* [Git helpers](../reference/git)
* [Templates](../templates/overview)
