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

# OpenCode

> Run OpenCode through a Dari Router.

Install the [Dari CLI](/install-cli.md), then launch OpenCode through your organization's default router:

```bash theme={null}
dari opencode
```

On first use, Dari signs you in if needed, creates and privately caches a Routing key, and offers to connect a ChatGPT or Claude Code subscription or use Dari managed billing. It then starts the installed `opencode` executable with session-local configuration. Your OpenCode config files are left intact.

On first launch, setup opens an **Accounts** page where you can connect one or more ChatGPT or Claude Code subscriptions or choose Dari managed billing. Later launches go straight to the agent; run `dari opencode --connect` to open the page again. Without the Autorouting plan, OpenCode starts on your router's first model and `/models` switches between them; run `dari opencode --connect` and choose **Get Autorouting** to subscribe so Dari picks for you.

Every following argument is forwarded to OpenCode:

```bash theme={null}
dari opencode run "Explain this repository"
dari opencode run -f screenshot.png "What is wrong with this layout?"
dari opencode ./my-project
```

The launcher supplies its configuration through `OPENCODE_CONFIG_CONTENT`, replacing any value you set for that variable. It adds a Dari provider with the `dari/routing` model, a one-million-token context window, and image input, and pins OpenCode's built-in agents (including Scout), subagents, and title, summary, and compaction tasks to `dari/routing`. OpenCode sends its session ID as the `x-session-affinity` header, so requests from one session group under the same conversation in **Activity**. Subagents appear in that conversation's **Subagents** view, each with its own routing lease. The launcher's plugin also labels title generation as **Auxiliary** and context compaction as **Compaction**, both served by the cheapest routable model. Dari chooses the model and reasoning level per request.

OpenCode normally connects to a shared background service, which would not see session-local configuration. Interactive, `run`, `mini`, `api`, `models`, and `stats` launches therefore add `--standalone` to start a private server. `--server` and `pair` are rejected because they use a server Dari cannot configure; run `dari opencode serve` to connect other clients. Management commands such as `service`, `session`, and `auth` run without Dari's configuration, so OpenCode's long-lived background service never picks it up. `--help` and `--version` skip sign-in and onboarding.

A launcher plugin shows the routing state in OpenCode's prompt footer: the model that served the turn, its thinking level when one is enabled, how many turns remain on the current routing lease, and whether the last response read from the provider's prompt cache. Routing values come from the `X-Dari-Selected-Model`, `X-Dari-Thinking-Level`, and `X-Dari-Lease-Turns-Remaining` response headers; cache status comes from response usage and expires after five minutes.

Set `DARI_ROUTING_API_KEY` before launching to use an existing Routing key instead of the CLI-managed key. Set `DARI_OPENCODE_PATH` when `opencode` is not on `PATH`.

## Manual Configuration

If you do not want to use the launcher, create a [Routing API key](/api-keys.md#create-a-routing-key):

```bash theme={null}
export DARI_ROUTING_API_KEY="dari_..."
```

Add this provider to `~/.config/opencode/opencode.json`:

```json theme={null}
{
  "$schema": "https://opencode.ai/config.json",
  "model": "dari/routing",
  "small_model": "dari/routing",
  "provider": {
    "dari": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "Dari",
      "options": {
        "baseURL": "https://routing.dari.dev/v1",
        "apiKey": "{env:DARI_ROUTING_API_KEY}"
      },
      "models": {
        "routing": {
          "id": "dari/routing",
          "name": "Dari Router",
          "attachment": true,
          "reasoning": false,
          "tool_call": true,
          "limit": { "context": 1000000, "output": 128000 },
          "modalities": { "input": ["text", "image"], "output": ["text"] }
        }
      }
    }
  }
}
```

`"reasoning": false` keeps OpenCode from sending a fixed reasoning level; Dari still chooses one per request. The routing status footer is available only through the launcher.

To use a different model set, edit the default router or [Create A Router](/router/create-a-router.md). For a specific router, point `baseURL` at `https://routing.dari.dev/{router_id}/v1` and set `limit.context` to the smallest window among its enabled models.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.