mirror of
https://github.com/anomalyco/opencode.git
synced 2026-07-14 04:38:28 +00:00
272 lines
7.8 KiB
Text
272 lines
7.8 KiB
Text
---
|
|
title: "Providers"
|
|
description: "Connect LLM providers and configure endpoints, packages, models, and variants."
|
|
---
|
|
|
|
OpenCode builds its provider and model catalog from [Models.dev](https://models.dev), then applies the `providers`
|
|
overlays from your [configuration](/config). A provider needs both a usable runtime package and, when required, an
|
|
active connection.
|
|
|
|
## Connect a provider
|
|
|
|
Run `/connect` in the TUI, choose an integration, and complete one of the methods it offers:
|
|
|
|
```text
|
|
/connect
|
|
```
|
|
|
|
An integration may support an API key, OAuth, environment variables, or a combination of them. API keys and OAuth
|
|
tokens entered through `/connect` are stored by the OpenCode service in its database. Run `/connect` again to replace
|
|
or remove a stored credential.
|
|
|
|
Providers from Models.dev also declare their standard environment variables. A non-empty declared variable is exposed
|
|
as an environment connection automatically, so common providers usually need no config:
|
|
|
|
```bash
|
|
export ANTHROPIC_API_KEY="your-key"
|
|
```
|
|
|
|
For a custom provider, `env` declares the variables that can supply its key:
|
|
|
|
```jsonc title="opencode.jsonc"
|
|
{
|
|
"$schema": "https://opencode.ai/config.json",
|
|
"providers": {
|
|
"acme": {
|
|
"env": ["ACME_API_KEY"]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
When several credential sources exist, OpenCode uses the stored credential first, then the first non-empty variable in
|
|
`env`, then `settings.apiKey`. Use config substitution instead of committing a literal key:
|
|
|
|
```jsonc title="opencode.jsonc"
|
|
{
|
|
"$schema": "https://opencode.ai/config.json",
|
|
"providers": {
|
|
"acme": {
|
|
"settings": {
|
|
"apiKey": "{env:ACME_API_KEY}"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
<Warning>Do not commit API keys or authorization headers to your repository.</Warning>
|
|
|
|
## Configure providers
|
|
|
|
The `providers` object is keyed by provider ID. Each provider accepts these fields:
|
|
|
|
| Field | Purpose |
|
|
| --- | --- |
|
|
| `name` | Display name. |
|
|
| `env` | Ordered environment variable names that provide a connection. |
|
|
| `package` | Runtime provider package. |
|
|
| `settings` | JSON settings passed to the runtime package, such as `baseURL`. |
|
|
| `headers` | String-valued HTTP headers added to requests. |
|
|
| `body` | JSON fields merged into request bodies. |
|
|
| `models` | Models to add or override, keyed by catalog model ID. |
|
|
|
|
Configuration files are applied from lowest to highest precedence. `settings` and `body` are deep-merged. Headers are
|
|
merged case-insensitively. At request time, provider values are inherited by the model, model values override them, and
|
|
the selected variant is applied last.
|
|
|
|
### Custom endpoint
|
|
|
|
Override `settings.baseURL` to send an existing provider through a proxy or compatible endpoint. Its existing package,
|
|
models, and connection continue to apply:
|
|
|
|
```jsonc title="opencode.jsonc"
|
|
{
|
|
"$schema": "https://opencode.ai/config.json",
|
|
"providers": {
|
|
"anthropic": {
|
|
"settings": {
|
|
"baseURL": "https://llm-proxy.example.com/anthropic"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
`settings` is package-specific. A field only has an effect when the selected package supports it.
|
|
|
|
### Custom headers and body
|
|
|
|
Headers and body fields can be set at provider, model, or variant scope:
|
|
|
|
```jsonc title="opencode.jsonc"
|
|
{
|
|
"$schema": "https://opencode.ai/config.json",
|
|
"providers": {
|
|
"openai": {
|
|
"headers": {
|
|
"X-Gateway-Tenant": "engineering"
|
|
},
|
|
"body": {
|
|
"metadata": {
|
|
"application": "opencode"
|
|
}
|
|
},
|
|
"models": {
|
|
"gpt-5.2": {
|
|
"headers": {
|
|
"X-Model-Policy": "coding"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
These are request overlays, not a generic authentication scheme. Prefer `/connect`, `env`, or `settings.apiKey` for
|
|
provider credentials unless the endpoint explicitly requires a custom header.
|
|
|
|
## Custom providers and packages
|
|
|
|
For an OpenAI-compatible service, use the V2 native compatible package. The model map is explicit because a custom
|
|
provider has no Models.dev catalog entries:
|
|
|
|
```jsonc title="opencode.jsonc"
|
|
{
|
|
"$schema": "https://opencode.ai/config.json",
|
|
"model": "acme/qwen3-coder",
|
|
"providers": {
|
|
"acme": {
|
|
"name": "Acme Gateway",
|
|
"env": ["ACME_API_KEY"],
|
|
"package": "@opencode-ai/llm/providers/openai-compatible",
|
|
"settings": {
|
|
"baseURL": "https://llm.acme.example/v1"
|
|
},
|
|
"models": {
|
|
"qwen3-coder": {
|
|
"name": "Qwen 3 Coder",
|
|
"capabilities": {
|
|
"tools": true,
|
|
"input": ["text"],
|
|
"output": ["text"]
|
|
},
|
|
"limit": {
|
|
"context": 131072,
|
|
"output": 32768
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
Omit `env` for an endpoint that does not require authentication. The native compatible package requires
|
|
`settings.baseURL` and uses bearer authentication when a key is available.
|
|
|
|
The `package` field supports two runtime contracts:
|
|
|
|
| Form | Contract |
|
|
| --- | --- |
|
|
| `"@opencode-ai/llm/providers/openai-compatible"` | A V2 native package exporting `model(modelID, settings)`. An npm specifier or absolute `file://` URL may use the same contract. |
|
|
| `"aisdk:@ai-sdk/openai-compatible"` | An AI SDK provider package. The `aisdk:` prefix is required. |
|
|
|
|
Native packages receive the merged `settings` plus the resolved `apiKey`, `headers`, `body`, and `limits`. AI SDK
|
|
packages receive their merged provider options. Use a package's own documentation for accepted settings; OpenCode does
|
|
not validate package-specific keys.
|
|
|
|
`package` may also be set on one model to override the provider package for that model.
|
|
|
|
## Models
|
|
|
|
`models` adds a model or overlays an existing catalog model. The object key is the model ID used in OpenCode. Set
|
|
`modelID` when the upstream API expects a different ID:
|
|
|
|
```jsonc title="opencode.jsonc"
|
|
{
|
|
"$schema": "https://opencode.ai/config.json",
|
|
"model": "openai/coding",
|
|
"providers": {
|
|
"openai": {
|
|
"models": {
|
|
"coding": {
|
|
"modelID": "gpt-5.2",
|
|
"name": "GPT-5.2 Coding",
|
|
"family": "gpt-5",
|
|
"limit": {
|
|
"context": 200000,
|
|
"input": 180000,
|
|
"output": 32000
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
A model supports `modelID`, `family`, `name`, `package`, `settings`, `headers`, `body`, `capabilities`, `variants`,
|
|
`cost`, `disabled`, and `limit`. If supplied, `capabilities` requires `tools`, `input`, and `output`. `limit` may set
|
|
`context`, `input`, and `output`. Cost values are USD per million tokens:
|
|
|
|
```jsonc
|
|
{
|
|
"cost": {
|
|
"input": 3,
|
|
"output": 15,
|
|
"cache": {
|
|
"read": 0.3,
|
|
"write": 3.75
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
Set `disabled: true` on a model to remove it from the available model list. V2 does not define provider-level
|
|
whitelist or blacklist fields.
|
|
|
|
## Variants
|
|
|
|
Variants are named request overlays for one model. They can override `settings`, `headers`, and `body`; the selected
|
|
package determines which values are meaningful.
|
|
|
|
```jsonc title="opencode.jsonc"
|
|
{
|
|
"$schema": "https://opencode.ai/config.json",
|
|
"providers": {
|
|
"openai": {
|
|
"models": {
|
|
"gpt-5.2": {
|
|
"variants": [
|
|
{
|
|
"id": "fast",
|
|
"settings": {
|
|
"reasoningEffort": "low"
|
|
}
|
|
},
|
|
{
|
|
"id": "deep",
|
|
"settings": {
|
|
"reasoningEffort": "high",
|
|
"reasoningSummary": "auto"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
Choose a variant with the TUI variant picker or `/variants`. Explicit CLI, agent, and command model references use
|
|
`provider/model#variant`; for example:
|
|
|
|
```bash
|
|
opencode2 run --model openai/gpt-5.2#deep "Review this project"
|
|
```
|
|
|
|
The current V2 top-level `model` default does not retain a `#variant` selection, so choose the variant separately.
|
|
Selecting an ID that is not defined for the model fails instead of silently using the default request settings.
|