Skip to content

OpenCode v1 on Codex Pooler

OpenCode is an open-source coding agent that brings project-aware assistance to your terminal. Connect it to Codex Pooler to use your Pool’s models for code changes, questions and tool-driven tasks. This guide covers v1 and its optional OMO integration; the OpenCode v2 guide covers the newer configuration.

Codex Pooler OpenCode integration

  • Install OpenCode v1 and check opencode --version.
  • Have a Codex Pooler URL reachable from the client.
  • Create a Pool API key and choose a model available to that Pool.

Keep the provider id as openai for this setup so OpenCode retains its OpenAI provider-family behavior.

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.

Provider settings

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

OMO settings (optional)

OS Default config file
macOS ~/.config/opencode/oh-my-openagent.jsonc
Linux ~/.config/opencode/oh-my-openagent.jsonc
Windows %USERPROFILE%\.config\opencode\oh-my-openagent.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.

Merge the provider settings into opencode.jsonc at the path for your system. If you already use opencode.json, edit that file instead. Store the Pool API key outside the config and read it through environment expansion:

macOS / Linux / WSL

Terminal window
export CODEX_POOLER_API_KEY="<pool-api-key>"

Windows PowerShell

Terminal window
$env:CODEX_POOLER_API_KEY = "<pool-api-key>"
opencode.jsonc
{
"$schema": "https://opencode.ai/config.json",
"small_model": "openai/gpt-6-luna",
"compaction": {
"auto": true,
"reserved": 41420
},
"provider": {
"openai": {
"npm": "@ai-sdk/openai",
"name": "Codex Pooler",
"options": {
"baseURL": "https://codex-pooler.example.com/v1",
"apiKey": "{env:CODEX_POOLER_API_KEY}"
},
"models": {
"gpt-6-luna": {
"id": "gpt-6-luna",
"name": "GPT-6 Luna via Codex Pooler",
"family": "gpt",
"attachment": true,
"reasoning": true,
"tool_call": true,
"temperature": false,
"options": {
"reasoningEffort": "high",
"reasoningSummary": "auto",
"textVerbosity": "medium",
"include": ["reasoning.encrypted_content"],
// Optional: priority processing may cost more than the default tier.
// "serviceTier": "priority"
},
"modalities": {
"input": ["text", "image"],
"output": ["text"]
},
"limit": {
"context": 828400,
"input": 828400,
"output": 64000
}
},
"gpt-6-sol": {
"id": "gpt-6-sol",
"name": "GPT-6 Sol via Codex Pooler",
"family": "gpt",
"attachment": true,
"reasoning": true,
"tool_call": true,
"temperature": false,
"options": {
"reasoningEffort": "high",
"reasoningSummary": "auto",
"textVerbosity": "medium",
"include": ["reasoning.encrypted_content"],
// Optional: priority processing may cost more than the default tier.
// "serviceTier": "priority"
},
"modalities": {
"input": ["text", "image"],
"output": ["text"]
},
"limit": {
"context": 828400,
"input": 828400,
"output": 64000
}
},
"gpt-6-astra": {
"id": "gpt-6-astra",
"name": "GPT-6 Astra via Codex Pooler",
"family": "gpt",
"attachment": true,
"reasoning": true,
"tool_call": true,
"temperature": false,
"options": {
"reasoningEffort": "high",
"reasoningSummary": "auto",
"textVerbosity": "medium",
"include": ["reasoning.encrypted_content"],
// Optional: priority processing may cost more than the default tier.
// "serviceTier": "priority"
},
"modalities": {
"input": ["text", "image"],
"output": ["text"]
},
"limit": {
"context": 828400,
"input": 828400,
"output": 64000
}
}
}
}
}
}

Define only model ids your assigned Pool can serve. If you run Codex Pooler locally, set baseURL to http://localhost:4000/v1.

Select an openai/ model configured below the openai provider and available to your Pool.

OpenCode uses small_model for background helpers such as automatic session titles. Without an explicit override, it may infer a nano model that Codex Pools do not serve. Point small_model at a lightweight model assigned to your Pool. The setting remains effective when OMO is loaded.

Request-time OpenAI options belong under each model’s options block. Keep only connection settings such as baseURL and apiKey in provider-level options. Use serviceTier: "priority" for priority processing. fast is an accepted equivalent request spelling, but priority is the canonical spelling for new configuration. Enable it only when your Pool and upstream offer it and you intentionally accept the potentially higher cost; leave it commented to use the default tier. This /v1 route translates the request shape, while any projected provider service_tier response value keeps the provider’s literal vocabulary. Do not add store: Codex Pooler sets store: false on its upstream streaming request.

OpenCode subtracts its compaction reserve from limit.input before declaring the session full. The 828400 values above are long-profile examples for models whose selected Pool catalog source reports an 872000-token raw ceiling. Provider accounts can temporarily report different ceilings for the same model; a selected 272000-token profile exposes 258400 through /v1/models instead. Use each model’s /v1/models.context_length as the authoritative value for limit.context and limit.input. With the long-profile example and reserved: 41420, OpenCode starts compaction at 786980 tokens. limit.input is the local pre-compaction boundary, not a simultaneous input-plus-output envelope. OpenCode caps request output at 32k by default; set OPENCODE_EXPERIMENTAL_OUTPUT_TOKEN_MAX=64000 only when you want OpenCode to request the full 64k cap.

Start a new conversation with the configured model and send a short request. In Codex Pooler’s request logs, match the request time, API key, model, and final status to your test. A reply alone does not confirm that the client used your Pooler instance.

If you automate OpenCode from scripts, use OpenCode’s own documented headless command shape for your installed version and verify both the final response and the expected file changes. The examples on this page focus on configuration, not a full automation workflow.

If you use Oh My OpenAgent, keep the native openai provider configuration above and add model overrides in oh-my-openagent.jsonc in the same config folder. Keep the openai/ prefix on every OMO model so delegated agents continue to use the same Codex Pooler provider.

This example assigns Luna to lightweight and background work, Sol to daily agent work, and Astra to planning and deep-reasoning roles. Each explicit fallback stays inside the model ids assigned to the Pool and preserves the primary reasoning variant.

oh-my-openagent.jsonc
{
"agents": {
"sisyphus": {
"model": "openai/gpt-6-sol",
"variant": "high",
"fallback_models": [{ "model": "openai/gpt-6-astra", "variant": "high" }]
},
"hephaestus": {
"model": "openai/gpt-6-astra",
"variant": "xhigh",
"fallback_models": [{ "model": "openai/gpt-6-sol", "variant": "xhigh" }]
},
"oracle": {
"model": "openai/gpt-6-astra",
"variant": "high",
"fallback_models": [{ "model": "openai/gpt-6-sol", "variant": "high" }]
},
"librarian": {
"model": "openai/gpt-6-luna",
"variant": "low",
"fallback_models": [{ "model": "openai/gpt-6-sol", "variant": "low" }]
},
"explore": {
"model": "openai/gpt-6-luna",
"variant": "low",
"fallback_models": [{ "model": "openai/gpt-6-sol", "variant": "low" }]
},
"multimodal-looker": {
"model": "openai/gpt-6-sol",
"variant": "medium",
"fallback_models": [{ "model": "openai/gpt-6-astra", "variant": "medium" }]
},
"prometheus": {
"model": "openai/gpt-6-astra",
"variant": "high",
"fallback_models": [{ "model": "openai/gpt-6-sol", "variant": "high" }]
},
"metis": {
"model": "openai/gpt-6-astra",
"variant": "high",
"fallback_models": [{ "model": "openai/gpt-6-sol", "variant": "high" }]
},
"momus": {
"model": "openai/gpt-6-astra",
"variant": "xhigh",
"fallback_models": [{ "model": "openai/gpt-6-sol", "variant": "xhigh" }]
},
"atlas": {
"model": "openai/gpt-6-sol",
"variant": "medium",
"fallback_models": [{ "model": "openai/gpt-6-astra", "variant": "medium" }]
},
"sisyphus-junior": {
"model": "openai/gpt-6-sol",
"variant": "medium",
"fallback_models": [{ "model": "openai/gpt-6-astra", "variant": "medium" }]
}
},
"categories": {
"visual-engineering": {
"model": "openai/gpt-6-sol",
"variant": "high",
"fallback_models": [{ "model": "openai/gpt-6-astra", "variant": "high" }]
},
"ultrabrain": {
"model": "openai/gpt-6-astra",
"variant": "xhigh",
"fallback_models": [{ "model": "openai/gpt-6-sol", "variant": "xhigh" }]
},
"deep": {
"model": "openai/gpt-6-astra",
"variant": "medium",
"fallback_models": [{ "model": "openai/gpt-6-sol", "variant": "medium" }]
},
"artistry": {
"model": "openai/gpt-6-astra",
"variant": "xhigh",
"fallback_models": [{ "model": "openai/gpt-6-sol", "variant": "xhigh" }]
},
"quick": {
"model": "openai/gpt-6-luna",
"variant": "low",
"fallback_models": [{ "model": "openai/gpt-6-sol", "variant": "low" }]
},
"unspecified-low": {
"model": "openai/gpt-6-luna",
"variant": "low",
"fallback_models": [{ "model": "openai/gpt-6-sol", "variant": "low" }]
},
"unspecified-high": {
"model": "openai/gpt-6-sol",
"variant": "high",
"fallback_models": [{ "model": "openai/gpt-6-astra", "variant": "high" }]
},
"writing": {
"model": "openai/gpt-6-sol",
"variant": "medium",
"fallback_models": [{ "model": "openai/gpt-6-astra", "variant": "medium" }]
}
}
}

OMO tries configured fallback_models before its built-in model chains. Define only model ids your assigned Pool can serve; if one tier is unavailable, replace it in both primary and fallback entries instead of leaving an unreachable model in the routing map.

Validate the OMO configuration after editing the routing map:

Terminal window
bunx oh-my-openagent doctor --platform=opencode --json

The doctor validates plugin loading, schema, and model resolution, but it does not prove that an upstream can serve the selected model. Send one bounded request through the installed OpenCode headless workflow for every model tier assigned to OMO before relying on the routing map.

Add Codex Pooler as a remote MCP server only when the OpenCode host should inspect metadata that the operator can already see in the admin UI.

opencode.jsonc
{
"mcp": {
"codex_pooler": {
"type": "remote",
"url": "https://codex-pooler.example.com/mcp",
"oauth": false,
"headers": {
"Authorization": "Bearer <operator-mcp-token>"
},
"enabled": true,
"timeout": 30000
}
}
}

Use a dedicated operator MCP token for hosts that persist remote MCP headers. Don’t use a Pool API key for /mcp.

Codex Pooler provides narrow OpenAI-compatible /v1 support for selected SDK routes. Supported OpenCode traffic should stay on /v1/responses or /v1/chat/completions, depending on the OpenAI provider path OpenCode uses.

GET /v1/responses is narrow Responses websocket compatibility, not /v1/realtime support. /v1/realtime and OpenAI Realtime SDK websocket or session routes are unsupported.

Continuity headers such as session-id, x-session-id, and x-session-affinity are local routing inputs only and are not forwarded upstream.

Unsupported /v1 routes return deterministic OpenAI-shaped unsupported endpoint errors when explicitly routed. Don’t treat Codex Pooler as full OpenAI API parity.