# OpenCode v2 on Codex Pooler

OpenCode v2 is an open-source coding agent for working on projects from the terminal. Connect it to Codex Pooler to use your Pool's models while OpenCode reads files, runs tools and maintains your coding sessions. This guide covers v2; use the [OpenCode v1 guide](/clients/opencode/) for the earlier configuration format and OMO integration.

![Codex Pooler OpenCode integration](/codex-pooler-opencode.webp)

## Before you start

- Install [OpenCode v2](https://opencode.ai/v2/docs/) and check `opencode --version`.
- Have a Codex Pooler URL reachable from the client.
- Create a [Pool API key](/getting-started/quick-start/) and choose a model available to that Pool.

Make the Pooler URL and key available to the OpenCode server process. V2 normally runs a shared background service; restarting a terminal alone may not refresh its environment.

V1 and v2 use the same executable name and configuration locations. Back up your existing configuration before replacing it. V1 plugins and server-API integrations require a separate migration.

## Configure the connection

Use the commands for the terminal that starts the client. Environment-variable assignments below apply to that terminal; desktop apps and services need the variables in their own launch environment.

### Config file paths

| OS | Default config file |
| --- | --- |
| macOS | `~/.config/opencode/opencode.jsonc` |
| Linux | `~/.config/opencode/opencode.jsonc` |
| Windows | `%USERPROFILE%\.config\opencode\opencode.jsonc` |

If you set `XDG_CONFIG_HOME` or a client-specific config override, use that location instead.

These are the default locations. On Windows, paste the `%USERPROFILE%`, `%APPDATA%` or `%LOCALAPPDATA%` path into File Explorer's address bar. For a client installed inside WSL, use the Linux paths and commands inside WSL. Keep any custom configuration folder or profile you already use.

Set the key in the environment used to start OpenCode:

**macOS / Linux / WSL**

```bash
export CODEX_POOLER_API_KEY="<pool-api-key>"
```

**Windows PowerShell**

```powershell
$env:CODEX_POOLER_API_KEY = "<pool-api-key>"
```

Merge this native v2 configuration into `opencode.jsonc` at the path for your system. The custom provider name keeps this connection separate from personal OpenAI credentials.

```jsonc title="opencode.jsonc" frame="code"
{
  "$schema": "https://opencode.ai/config.json",
  "model": "codex-pooler/gpt-6-sol",
  "agents": {
    "title": { "model": "codex-pooler/gpt-6-luna" }
  },
  "compaction": {
    "auto": true,
    "keep": { "tokens": 15000 },
    "buffer": 41420
  },
  "providers": {
    "codex-pooler": {
      "package": "@opencode/ai/providers/openai/responses",
      "settings": {
        "baseURL": "https://codex-pooler.example.com/v1",
        "apiKey": "{env:CODEX_POOLER_API_KEY}",
        "transport": "http",
        "compaction": { "type": "summary" }
      },
      "models": {
        "gpt-6-luna": {
          "modelID": "gpt-6-luna",
          "name": "GPT-6 Luna",
          "capabilities": { "tools": true, "input": ["text", "image"], "output": ["text"] },
          "limit": { "context": 828400, "input": 828400, "output": 32000 },
          "settings": { "reasoningEffort": "low", "reasoningSummary": "auto" }
        },
        "gpt-6-sol": {
          "modelID": "gpt-6-sol",
          "name": "GPT-6 Sol",
          "capabilities": { "tools": true, "input": ["text", "image"], "output": ["text"] },
          "limit": { "context": 828400, "input": 828400, "output": 32000 },
          "settings": { "reasoningEffort": "high", "reasoningSummary": "auto" }
        },
        "gpt-6-astra": {
          "modelID": "gpt-6-astra",
          "name": "GPT-6 Astra",
          "capabilities": { "tools": true, "input": ["text", "image"], "output": ["text"] },
          "limit": { "context": 828400, "input": 828400, "output": 32000 },
          "settings": { "reasoningEffort": "high", "reasoningSummary": "auto" }
        }
      }
    }
  }
}
```

For a local instance, use `http://localhost:4000/v1`. Define only models your Pool serves, and replace the example limits with the values described below. Keep the title agent on an available model so helper calls do not select an unavailable default.

## Choose a model

Read the authenticated catalog before copying a context budget:

**macOS / Linux / WSL**

```bash
curl -fsS https://codex-pooler.example.com/v1/models \
  -H "Authorization: Bearer $CODEX_POOLER_API_KEY"
```

**Windows PowerShell**

```powershell
Invoke-RestMethod -Uri "https://codex-pooler.example.com/v1/models" -Headers @{ Authorization = "Bearer $env:CODEX_POOLER_API_KEY" }
```

Luna, Sol and Astra are example model IDs, not an availability guarantee. Use the exact `data[].id` served by your Pool and its `context_length` for both `limit.context` and `limit.input`. A long account profile can expose **828,400** tokens; a smaller profile can expose **258,400** for the same model. V2 does not automatically replace a manually configured model limit with Pooler's catalog value.

`limit.output` is the configured output allowance, not extra input capacity. The example uses a conservative 32,000-token budget; `/v1/models.context_length` does not advertise an output-token maximum. Raise the allowance only when the selected upstream supports it. Reasoning effort goes under model `settings`, not the ignored v1 model boolean `reasoning`. Optional priority processing uses `settings.serviceTier: "priority"` when your Pool supports it and you accept the additional cost.

## Start a conversation

Start a standalone conversation with your configured model:

```bash
opencode run --standalone --model codex-pooler/gpt-6-sol "Reply with a short greeting"
```

Resume a conversation with `opencode run --standalone --session <session-id>`. Pooler's request logs show the model, time and final status of each request.

## Advanced configuration

### Compaction and context budgets

V2 defaults to **local summary checkpoints**: it sends a normal model request to summarize older history, retains recent context under `compaction.keep.tokens`, and keeps the earlier transcript in its own storage. It uses the selected session model and variant; there is no separate compaction model.

Automatic compaction starts when estimated context reaches:

```text
min(input limit - buffer, context limit - max(output reserve, buffer))
```

The output reserve used by this calculation is capped at 32,000 tokens. With the example's 828,400 input/context budget and 41,420 buffer, the threshold is **786,980**. `keep.tokens` controls retained recent history; it does not increase the context ceiling. For a smaller catalog profile, recalculate the buffer and threshold instead of keeping the long-profile values.

For **native provider checkpoints**, change the provider's `settings.compaction` to `{ "type": "native" }`. OpenCode sends a terminal `compaction_trigger` through `/v1/responses`; Pooler collects the upstream streamed checkpoint and returns the encrypted compaction item for the next turn. Both HTTP and Responses websocket transport support this mode. Keep the Responses provider package shown above: the standalone `/v1/responses/compact` endpoint is not part of this integration. See [OpenCode's compaction guide](https://opencode.ai/v2/docs/compaction/) for the client-side mechanisms.

Manual compaction uses OpenCode's own session controls or its server's `POST /api/session/{sessionID}/compact` API. That is an OpenCode server endpoint, not a Codex Pooler route. Manual compaction remains available when `compaction.auto` is false; completion is asynchronous, so wait for the session's completed checkpoint before treating it as successful.

### Protocol and continuity

The configuration explicitly selects the Responses protocol and HTTP streaming: `POST /v1/responses` with SSE replies. It is not Chat Completions or Realtime. Set provider `settings.transport: "websocket"` to use the narrow Responses websocket route at `GET /v1/responses`; connection failures may fall back to HTTP. Keep the explicit transport when using a custom provider ID, rather than assuming the built-in `openai` provider's defaults apply.

OpenCode supplies per-session continuity headers and a prompt cache key. Reusing the same OpenCode session preserves that identity; starting another session must not share it. Pooler may bridge an eligible HTTP SSE conversation onto an upstream websocket, so the client-to-Pooler and Pooler-to-provider transports are separate facts. A cache key is a locality hint, not proof of a cache hit.

### Images and tools

Local tools such as shell commands and file edits execute in OpenCode, with results sent back through Responses. They do not require operator MCP access. Keep OpenCode's permission rules appropriate for your workspace; `--auto` is not required by the connection configuration.

Image input uses `capabilities.input: ["text", "image"]`, not the ignored v1 `attachment` field. Attach local PNG, JPEG, GIF or WebP files; OpenCode's attachment interface does not accept remote HTTP image URLs.

Image input does not enable an image-generation tool in OpenCode's stock coding-agent toolset. For image generation through Pooler's separate Images API, see the [OpenAI-compatible guide](/clients/openai-compatible/).

### Migrating v1 settings

Use `providers`, `package`, `settings`, `capabilities` and `modelID` for native v2 configuration. `agents.title.model` replaces `small_model`; `compaction.buffer` replaces `reserved`, and `compaction.keep.tokens` replaces tail-turn/pruning settings.

V2 warns and ignores legacy fields including `logLevel`, `compaction.prune`, `compaction.tail_turns`, and model `reasoning`, `attachment` and `temperature`. Use `OPENCODE_LOG_LEVEL` for logging and `--print-logs` to display migration warnings. V1 plugins, including OMO integrations, require migration to the v2 plugin API. See the [migration guide](https://opencode.ai/v2/docs/migrate-v1/).