Tested · v2
Why v2 needs different instructions

OpenCode 2 changed provider to providers, npm to package, and options to settings. Its background service also owns provider credentials. The protected key-file method below avoids stale saved credentials and service-environment mismatches.

1. Create a SafetyRouter identity

In the tenant portal, create an API key named for the employee and client—for example Steele-OpenCode2-Mac. Add project tags for reporting and Duplicate Guard.

2. Store the key in a protected file

First place the new key in your current shell:

export SAFETYROUTER_API_KEY='sr_live_...'

Then create a key file on macOS or Linux without adding a trailing newline:

mkdir -p ~/.config/opencode
umask 077
printf '%s' "$SAFETYROUTER_API_KEY" > ~/.config/opencode/safetyrouter.key
chmod 600 ~/.config/opencode/safetyrouter.key

On Windows PowerShell:

$env:SAFETYROUTER_API_KEY = 'sr_live_...'
$keyDirectory = Join-Path $HOME '.config/opencode'
New-Item -ItemType Directory -Force -Path $keyDirectory | Out-Null
[System.IO.File]::WriteAllText(
  (Join-Path $keyDirectory 'safetyrouter.key'),
  $env:SAFETYROUTER_API_KEY
)

3. Add the v2 provider

Create or update opencode.jsonc. Use a provider ID such as safetyrouter-v2 that has never been connected to a saved OpenCode account. Replace the hostname and modelID with values enabled by your tenant.

{
  "$schema": "https://opencode.ai/config.json",
  "model": "safetyrouter-v2/company-model",
  "providers": {
    "safetyrouter-v2": {
      "name": "SafetyRouter V2",
      "package": "@opencode/ai/providers/openai-compatible",
      "settings": {
        "baseURL": "https://your-company.safetyrouter.io/v1",
        "apiKey": "{file:~/.config/opencode/safetyrouter.key}",
        "headerTimeout": 900000,
        "chunkTimeout": 900000,
        "encoding": "none"
      },
      "models": {
        "company-model": {
          "name": "Model through SafetyRouter",
          "modelID": "provider/model-name",
          "capabilities": {
            "tools": true,
            "input": ["text"],
            "output": ["text"]
          },
          "limit": {
            "context": 128000,
            "output": 8192
          }
        }
      }
    }
  }
}
Do not connect this provider with /connect

Do not run /connect for safetyrouter-v2. An active saved account can override the apiKey configured above. If you previously used the ID safetyrouter, keep the new safetyrouter-v2 ID so OpenCode cannot reuse that older credential.

4. Reload and test

opencode service restart
opencode reload
opencode run --model safetyrouter-v2/company-model \
  "Reply with exactly: SafetyRouter connected"

For diagnostic logs, the level must be lowercase:

opencode --print-logs --log-level debug
Buffered-safe streaming

OpenCode may pause while SafetyRouter reviews the input, generates the answer, and inspects the output. Approved content is then emitted as a compatible stream.

OpenCode v2 provider fields, file substitution, service behavior, and credential precedence are documented in the official provider guide, configuration reference, and credential guide.

Buffered-safety timeout

Allow up to 15 minutes

SafetyRouter intentionally waits for input review, model generation, and output review before releasing model content. Where your client exposes request, response-header, socket-read, or stream-idle timeouts, set them to at least 900000 ms or 900 seconds. Keep streaming enabled. A longer timeout preserves the safety boundary; it does not bypass inspection.