Providers and models in opencode
BeginnerLast updated: Oct 21, 2026
opencode is provider-agnostic. Through the AI SDK and models.dev it supports 75+ LLM providers, including local models. You bring the API keys; opencode handles the rest.
Connect a provider
Inside the TUI run /connect, pick a provider, follow the auth flow, and paste the API key. Credentials live in ~/.local/share/opencode/auth.json — not in your project files; opencode auth list shows what’s there. Some providers authenticate through environment variables instead — Amazon Bedrock reads AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY, AWS_PROFILE, or AWS_BEARER_TOKEN_BEDROCK.
OpenCode Zen
If you don’t want to juggle provider accounts, OpenCode Zen is the team’s curated list of models tested and verified to work well with opencode — the docs recommend it for new users.
- Run
/connect, selectOpenCode Zen, and head to opencode.ai/auth. - Sign in, add billing details, and copy your API key.
- Paste it into the prompt, then run
/modelsto pick a model.
Zen is charged per request and completely optional — it behaves like any other provider. (The v2 docs call this surface OpenCode Console; the flow is the same.) OpenCode Go is the alternative: a low-cost subscription covering popular open coding models.
Pick a model
/models in the TUI lists every model your connected providers expose — switch any time mid-session. The docs call out a few that handle both code generation and tool calling well: GPT 5.2, GPT 5.1 Codex, Claude Opus 4.5, Claude Sonnet 4.5, Minimax M2.1, Gemini 3 Pro.
Set defaults in opencode.json:
{
"$schema": "https://opencode.ai/config.json",
"model": "anthropic/claude-sonnet-4-5",
"small_model": "anthropic/claude-haiku-4-5"
}
model— the default, inprovider_id/model_idform. For Zen’s GPT 5.1 Codex that’sopencode/gpt-5.1-codex.small_model— a cheaper model for lightweight tasks like title generation. Unset, opencode tries a cheaper provider model and falls back to the main one.
When several sources set a model, startup resolves in this order:
| Priority | Source |
|---|---|
| 1 | --model / -m CLI flag |
| 2 | model in config |
| 3 | Last used model |
| 4 | Internal priority |
Tune a provider
The provider block customizes each provider — keys are provider ids from the models.dev catalog (or your custom id):
provider.<id>.options.baseURL— custom endpoint; useful behind proxies or gateways.provider.<id>.blacklist/.whitelist— hide models from the/modelspicker.whitelistnarrows the set,blacklistremoves entries from it; they combine.provider.<id>.options.apiKey— set the key inline;{env:VAR}substitution keeps secrets in env vars.options.headersadds custom request headers.
Variants and reasoning effort
Many models ship variants — same model, different settings. Built-in defaults cover popular providers: Anthropic gets high/max thinking budgets, OpenAI gets none through xhigh reasoning effort, Google gets low/high. Override or add your own:
{
"provider": {
"openai": {
"models": {
"gpt-5": {
"variants": {
"thinking": { "reasoningEffort": "high" },
"fast": { "disabled": true }
}
}
}
}
}
}
Cycle variants in the TUI with the variant_cycle keybind. Global per-model options also live under provider.<id>.models.<id>.options — e.g. Anthropic’s thinking.budgetTokens — and agents can override them.
Custom providers
Any OpenAI-compatible endpoint works:
- Run
/connect, scroll to Other, enter a provider id, and paste the API key. - Define it in
opencode.json—npmis the AI SDK package (@ai-sdk/openai-compatiblefor/v1/chat/completions,@ai-sdk/openaifor/v1/responses):
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"myprovider": {
"npm": "@ai-sdk/openai-compatible",
"name": "My Provider",
"options": {
"baseURL": "https://api.myprovider.com/v1",
"apiKey": "{env:MYPROVIDER_API_KEY}"
},
"models": {
"my-model": {
"name": "My Model",
"limit": { "context": 200000, "output": 65536 }
}
}
}
}
}
limit.context/limit.output tell opencode the token ceilings (known providers get these from models.dev). Run /models — the provider appears as myprovider/my-model. If it doesn’t, check that the /connect id matches the config key, the npm package matches the API shape, and options.baseURL is correct.