# OpenCode Configuration Reference

OpenCode (formerly "OpenCode Go" / CommandCode) — multi-agent coding tool.
This reference covers server setup, credential management, model config, and known issues.

## Installation & Version

- Installed via npm: `npm install -g @opencode/opencode`
- Binary: typically at `~/.local/share/npm-global/bin/opencode`
- Current version in this environment: **1.17.4** (CLI), **1.17.3** (web UI bundle)
- Debian server at `/home/rurouni/.local/share/npm-global/bin/opencode`
- CachyOS Desktop at `/opt/OpenCode/ai.opencode.desktop` (AUR package `opencode-desktop-bin`)

## Config File Layout

OpenCode uses THREE separate storage locations — editing one doesn't affect the others:

### 1. Provider/Model Config — `~/.config/opencode/opencode.json`

Defines which providers exist, their API endpoints, and which models each exposes.

```json
{
  "provider": {
    "openrouter": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "OpenRouter",
      "options": {
        "baseURL": "https://openrouter.ai/api/v1",
        "apiKey": "sk-or-...3f12"
      },
      "models": {
        "qwen/qwen3-coder:free": { "name": "Qwen Coder (Free)", "limit": { "context": 131072, "output": 8192 } }
      }
    }
  }
}
```

**WARNING:** Keys in this file get **sanitized to `***` on server restart** — OpenCode rewrites the file from its auth store on startup. This file is NOT the source of truth for credentials.

### 2. Credential Store — `~/.local/share/opencode/auth.json`

This is the actual credential store. Keys set here persist across restarts.

```json
{
  "openrouter": { "type": "api", "key": "sk-or-v1-..." },
  "deepseek": { "type": "api", "key": "sk-..." }
}
```

**CLI commands to manage credentials:**
- `opencode providers list` — shows configured providers
- `opencode providers login [url]` — interactive login flow
- `opencode providers logout [name]` — removes credentials

### 3. Desktop Electron Store — `~/.config/ai.opencode.desktop/`

The Desktop app (Electron) stores its OWN config independently:
- Local Storage: `~/.config/ai.opencode.desktop/Local Storage/leveldb/`
- Workspace configs: `opencode.workspace.*.dat` files
- Global config: `opencode.global.dat`
- The Desktop **does not read** `~/.config/opencode/opencode.json` — it has its own internal store

## Server Mode

```bash
opencode serve --port 4096 --hostname 0.0.0.0
```

- Serves an SPA web UI **and** accepts Desktop client connections
- Auth: HTTP Basic Auth — credentials set via `OPENCODE_SERVER_PASSWORD` env or defaults
- The web UI has a **React context crash bug** in 1.17.x — "Settings context must be used within a context provider" error on load. This is a known issue, not a misconfiguration.
- `opencode web` starts the same server + opens browser — same crash bug

### Systemd Unit

```
/etc/systemd/system/opencode-server.service
[Service]
ExecStart=/home/rurouni/.local/share/npm-global/bin/opencode serve --port 4096 --hostname 0.0.0.0
Environment=OPENCODE_SERVER_PASSWORD=password
User=rurouni
```

## Desktop ↔ Server Connection

The Desktop on CachyOS connects to the Debian server at `http://192.168.1.50:4096`. When connected:
- The server provides **compute backend** (runs code)
- The model list comes from the **Desktop's local config**, NOT the server config
- To add models, edit BOTH the server config (for server-mode ACP clients) AND the Desktop's auth/opencode.json

Connection settings in Desktop:
- Server address: `http://192.168.1.50:4096`
- Username: `opencode`
- Password: `password`

## Adding Models (Free OpenRouter Models)

Query OpenRouter's API to get current free models:

```bash
curl -s https://openrouter.ai/api/v1/models \
  | python3 -c "import sys,json; ms=json.load(sys.stdin)['data']; [print(m['id']) for m in ms if m['id'].endswith(':free')]"
```

As of June 2026, there are 23 free models. Add them to `opencode.json` under the openrouter provider → models section with appropriate `limit` (context/output from the API response).

Current working model aliases (for `opencode.json` → `models` section):
```json
"or-nex": { "provider": "openrouter", "model": "nex-agi/nex-n2-pro:free" },
"or-free": { "provider": "openrouter", "model": "openrouter/free" },
"or-gemma-free": { "provider": "openrouter", "model": "google/gemma-4-31b-it:free" },
"or-nemotron-free": { "provider": "openrouter", "model": "nvidia/nemotron-3-ultra-550b-a55b:free" }
```

## Troubleshooting

### Keys show as `***` in config file
Check `~/.local/share/opencode/auth.json` — that's the real store. Re-add via `opencode providers login` or write auth.json directly.

### Desktop doesn't see models from server
The Desktop uses its own local config. Copy the models to CachyOS's `~/.config/opencode/opencode.json` AND `~/.local/share/opencode/auth.json`. Restart the Desktop app.

### Web UI shows "Something went wrong" / React context error
Known crash in OpenCode 1.17.x. The server is functional — connect via the Desktop client instead.

### "401 Account suspended" when using a bearer token
The token was revoked/burned. Generate a new one via `opencode providers login` or the provider's API key dashboard.

### Keys were truncated (stored as `sk-or-...e437` instead of full key)
OpenCode's UI or display masking truncated the key input. Length check: real keys are 30-72+ chars. A 13-char key with `...` in the middle is always truncated. Get the full key from the provider dashboard and write it directly to auth.json.
