OpenCode reads providers from ~/.config/opencode/opencode.json. Add a provider keyed continuum with npm set to @ai-sdk/openai-compatible, options.baseURL set to https://continuumcode.ai/v1, options.apiKey set to a cont_sk_ key created in the Continuum web app under Settings, then Account, then Inference API, and a models map. The models map is not optional and not advisory: OpenCode shows exactly the entries it contains, so a model the gateway serves but the map omits does not appear anywhere in the picker. Run opencode models to list what is registered and pick one with /models in the TUI. Responses are capped at 8,192 output tokens. Personal Continuum API keys are a paid-plan feature: Plus is $25/mo, Max 100 is $100/mo, Max 200 is $200/mo, and Ultra is $500/mo as of August 2026.
- One provider block in
~/.config/opencode/opencode.jsondoes the whole job. - The adapter is
@ai-sdk/openai-compatible, and the base URL carries the/v1:https://continuumcode.ai/v1. - Every model you want must be listed in the
modelsmap. A served model missing from the map simply does not exist as far as OpenCode is concerned. - The key lives in the file in plaintext. Rotating it means editing the file, so treat
opencode.jsonas a secret. opencode modelslists what is registered;/modelspicks one inside the TUI.- Standalone OpenCode works fine. It is T3 Code’s OpenCode driver that breaks this setup, and that is a bug in T3 Code.
What the provider block does
OpenCode treats providers as data. A key under provider in opencode.json names an adapter package, an endpoint, a credential, and a set of models; anything that speaks a shape one of its adapters understands can be added without OpenCode knowing the vendor exists. @ai-sdk/openai-compatible is the generic adapter for the OpenAI request shape, which is what Continuum serves at https://continuumcode.ai/v1.
Adding the provider does not remove anything. Whatever you had configured before — a subscription-backed provider, another API key, a local server — stays registered and stays in the picker, and Continuum joins the list rather than replacing it. That makes this a low-commitment change: you can switch models mid-session and compare.
What you need first
Setting OpenCode up this way requires Continuum Plus or higher. Inference keys do not mint on the Free tier, so the Create key button stays disabled until you subscribe, and the provider block below needs one to authenticate.
- OpenCode installed. Any recent version; the custom-provider mechanism is long-standing.
- A Continuum account on a paid plan. Personal API keys are a paid-plan feature: Plus at $25/mo, Max 100 at $100/mo, Max 200 at $200/mo, or Ultra at $500/mo as of August 2026. See pricing for what each includes.
- An editor and valid JSON. That is genuinely all.
Register Continuum in opencode.json
Create a Continuum API key
In the Continuum web app at continuumcode.ai/app, open Settings, then Account, then Inference API. Create your key under Your keys. The same panel is on the Usage tab. Copy it when it appears: it starts with cont_sk_ and the full value is shown exactly once.
Keys mint on Plus and above, so on the Free tier Create key stays disabled until you subscribe.
Add the provider block
Open ~/.config/opencode/opencode.json, creating it if it is not there. If the file already exists, merge the continuum key into your existing provider object rather than replacing the object.
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"continuum": {
"npm": "@ai-sdk/openai-compatible",
"name": "Continuum",
"options": {
"baseURL": "https://continuumcode.ai/v1",
"apiKey": "cont_sk_..."
},
"models": {
"claude-opus-5": { "name": "claude-opus-5" }
}
}
}
}
List the models you actually want
The single-entry map above is the minimum that proves the plumbing. Add an entry per model you intend to use — the IDs are in the next section — because OpenCode will show exactly these and nothing else.
"models": {
"claude-opus-5": { "name": "claude-opus-5" },
"claude-sonnet-5": { "name": "claude-sonnet-5" },
"gpt-5.6-sol": { "name": "gpt-5.6-sol" },
"grok-4.6": { "name": "grok-4.6" },
"gemini-3.5-flash": { "name": "gemini-3.5-flash" }
}
Confirm registration, then pick a model
From a terminal, opencode models prints everything registered. Your entries should appear under the Continuum provider; if they do not, the file did not parse or the map is empty, and no amount of work inside the TUI will help. Once they are listed, start opencode and run /models to select one.
opencode models
opencode
The models map is the whole trick
Most OpenAI-compatible clients discover models: they call /v1/models, and whatever comes back is what you can pick. OpenCode does not work that way for a custom provider. The models map is the list, full stop. A model your plan serves, that curl confirms, that appears in every other client you have configured, will not appear in OpenCode unless it has an entry here.
These IDs were read from the live gateway on 17 August 2026. Each one needs its own entry in the map to be selectable.
Paid lane, drawn from your plan’s inference allowance.
| Model ID | What it is |
|---|---|
claude-opus-5 | The flagship, and the recommended default |
claude-fable-5 | Claude 5 family |
claude-sonnet-5 | Claude 5 family |
gpt-5.6-sol | GPT-5.6 family |
gpt-5.6-terra | GPT-5.6 family |
gpt-5.6-luna | GPT-5.6 family |
grok-4.6 | xAI |
gemini-3.5-flash | |
deepseek-v4-flash | DeepSeek |
glm-5.3 | Z.ai, via OpenCode Go |
muse-spark-1.2 | Muse |
The free lane
These models do not draw down your plan’s weekly inference allowance. Listing one in the map still needs a paid key, because that is what minting a key requires. They are chat-grade rather than agent-grade: useful for questions and small edits, and not what you want driving a long OpenCode run against a real repository. Note that these IDs contain slashes and a :free suffix, both of which must be reproduced exactly in the map key.
On a paid key, these :free models do not draw your weekly budget.
| Model ID | Provider |
|---|---|
google/gemma-4-26b-a4b-it:free | |
nvidia/nemotron-3-ultra-550b-a55b:free | NVIDIA |
nvidia/nemotron-3-super-120b-a12b:free | NVIDIA |
cohere/north-mini-code:free | Cohere |
poolside/laguna-m.1:free | Poolside |
tencent/hy3:free | Tencent |
curl -s https://continuumcode.ai/v1/models \
-H "Authorization: Bearer cont_sk_..."
When it does not work
| Symptom | Cause | Fix |
|---|---|---|
| The provider does not appear at all | The file did not parse | Validate the JSON; a trailing comma is the usual culprit |
| The provider appears, but a model is missing | That model has no entry in the models map | Add it; OpenCode shows exactly what the map contains |
| 401 or an authentication failure | Key mistyped, truncated on paste, or revoked | Mint a new key and edit the file; the original is unrecoverable |
| 404 on every request | The /v1 is missing from baseURL, or a path was appended | Set it to exactly https://continuumcode.ai/v1 |
| Unknown or invalid model at request time | The map key does not match a served ID | Compare it against GET /v1/models, character for character |
| A long answer stops mid-sentence | The 8,192-token output cap | Ask for the work in parts; agent turns iterate and rarely hit it |
| It all works standalone but not inside T3 Code | T3 Code clobbers the OpenCode config | Not fixable from here — see below |
On credential handling: unlike the Codex and Claude Code setups, which read a key from an environment variable, this one puts the key in a file in plaintext. Rotating means editing opencode.json, and the file deserves the same care as any other file holding a live credential — including keeping it out of a dotfiles repository you push somewhere.
Questions people ask
~/.config/opencode/opencode.json. Create it if it does not exist, and merge the continuum key into an existing provider object rather than replacing the object.
Because OpenCode shows exactly the entries in a custom provider’s models map rather than discovering them from the endpoint. A model the gateway serves but the map omits does not appear anywhere in the picker, and produces no error.
Yes. https://continuumcode.ai/v1, with no trailing slash. OpenAI-shaped clients append their own route. Anthropic-shaped clients such as Claude Code take the bare origin instead, which is the opposite rule.
@ai-sdk/openai-compatible, the generic adapter for the OpenAI request shape. It is what OpenCode uses for any endpoint that is not one of its built-in providers.
Run opencode models from a terminal. It lists every registered provider and model. If your entries are not there, the problem is in the file, and nothing inside the TUI will reveal it.
Create a replacement in the web app under Settings, then Account, then Inference API, under Your keys, then edit opencode.json and replace the apiKey value. The key is stored in that file in plaintext, so treat the file as a secret and keep it out of any dotfiles repository you publish.
No. Providers are additive. Everything already configured stays registered and stays in the picker, so you can switch between them mid-session.
Responses are capped at 8,192 output tokens. Long single generations can truncate; agent turns iterate across several responses, so in practice they are unaffected.
T3 Code sets OPENCODE_CONFIG_CONTENT to an empty object in the OpenCode child environment, which clobbers your config. It is tracked as t3code#4239 and was open on 13 August 2026. Standalone OpenCode is unaffected.
Sources
Every figure above was read from these pages on August 2026. Vendors reprice without notice; if you find a stale number, tell us.
- OpenCode configuration schema the provider, npm, options, and models shape used above
- OpenCode documentation custom providers, the models command, and the /models picker
- t3code#4239: opencode subprocess forced to an empty config the OPENCODE_CONFIG_CONTENT clobber that hides custom providers inside T3 Code; open when read on 13 August 2026
- Continuum pricing plan names, prices, and which tiers include personal API keys
- Continuum hosted inference the model lanes and the gateway surfaces, read 13 August 2026; the live /v1/models endpoint itself needs a cont_sk_ bearer