Models
Choose a model for the current session with /models:
/models
OpenCode lists models from models.dev, provider integrations, and your configuration. The selector only shows enabled models whose provider is available in the current project. Connect providers in Providers.
Select
Pick an entry from /models instead of guessing its provider or model ID. The selection applies to the current session
and does not change your configuration.
anthropic/claude-sonnet-5-5
Availability is project-specific:
- The model must be enabled.
- Its provider must be available in the current project.
- Credentials and configuration from another project do not carry over automatically.
Runs
Use --model to choose a model for one command-line run without changing the configured default:
opencode run --model anthropic/claude-sonnet-5-5 "Refactor parseToken"
Agents and commands can also choose their own model. See Agents and Commands.
Defaults
Set model in opencode.json or opencode.jsonc to choose the default for new work:
{
"$schema": "https://opencode.ai/config.json",
"model": "anthropic/claude-sonnet-5-5",
}The configured model becomes the catalog default when it is enabled and its provider is available. Otherwise, OpenCode falls back to the newest available supported model.
- A model already selected for a session takes precedence over the configured default.
- Switching a session’s model does not rewrite the config file.
- The root
modelcurrently retains only the default provider and model, not a variant.
See Config for configuration locations and precedence.
Free models
Set OPENCODE_DISABLE_FREE_MODELS=1 (or true) on the server process to hide free OpenCode models:
OPENCODE_DISABLE_FREE_MODELS=1 opencode serve
For the shared background server:
opencode service set env OPENCODE_DISABLE_FREE_MODELS 1
Free means an opencode or opencode-go model with no input price. These models disappear from the catalog and defaults;
explicitly selecting one fails with Model unavailable. Signed out, the opencode provider is absent until you connect
an OpenCode Console account or set OPENCODE_API_KEY, which restores its paid models.
Variants
Variants are named options for one model, often used for reasoning effort or token budgets. Add #variant when selecting
one for a run, session, agent, or command:
opencode run --model openai/gpt-6.1-sol#high "Review this migration plan"
Variant names come from the selected model’s current catalog metadata. Names such as low, high, and max are not
available for every model, and an unknown variant produces a model-resolution error.
Define new variants, or replace catalog variants with the same ID, in the model’s variants array:
{
"$schema": "https://opencode.ai/config.json",
"providers": {
"openai": {
"models": {
"gpt-6.1-sol": {
"settings": {
"reasoningEffort": "medium",
},
"variants": [
{
"id": "fast",
"settings": {
"reasoningEffort": "low",
},
},
{
"id": "deep",
"settings": {
"reasoningEffort": "high",
"reasoningSummary": "auto",
},
},
],
},
},
},
},
}Each variant can contain settings, headers, and body. Its values are applied after provider and model values.
To replace a model’s reasoning variants, describe its reasoning controls in capabilities.reasoning, using the
models.dev v2 shape. OpenCode builds the variants for the model’s package from them:
{
"providers": {
"openai": {
"models": {
"gpt-6.1-sol": {
"capabilities": {
"reasoning": {
"supported": true,
"effort": ["low", "medium", "high"],
},
},
},
},
},
},
}| Field | Purpose |
|---|---|
supported | Whether the model reasons. false, or true without controls, adds no variants. |
toggle | Adds a none variant that turns reasoning off. |
effort | Effort levels to offer. default keeps the provider default and adds no variant. |
budget | Optional min and max thinking tokens. Ignored when effort is set. |
Variants listed in variants are applied on top of the ones built from capabilities.reasoning.
Options
Provider and model entries can customize requests with settings, headers, and body:
{
"providers": {
"openai": {
"settings": {
"baseURL": "https://api.example.com/v1",
},
"headers": {
"X-Team": "platform",
},
"models": {
"gpt-6.1-sol": {
"settings": {
"reasoningEffort": "high",
},
"body": {
"store": false,
},
},
},
},
},
}| Field | Purpose |
|---|---|
settings | Provider-package options such as baseURL or reasoningEffort. |
headers | Additional HTTP request headers. |
body | Provider-specific request body fields. |
OpenCode applies provider values first, model values second, and the selected variant last.
- Nested
settingsandbodyobjects are merged. - Later arrays and scalar values replace earlier values.
- Header names are matched case-insensitively.
- Options are provider-specific and may be ignored or rejected by another provider package.
Aliases
Use modelID to give an API model a friendlier catalog ID:
{
"$schema": "https://opencode.ai/config.json",
"model": "openai/coding-default",
"providers": {
"openai": {
"models": {
"coding-default": {
"modelID": "gpt-6.1-sol",
"name": "Coding default",
"capabilities": {
"tools": true,
"input": ["text", "image"],
"output": ["text"],
},
"limit": {
"context": 200000,
"output": 32000,
},
},
},
},
},
}Here, openai/coding-default is the selectable reference and gpt-6.1-sol is sent to the provider. For a model that is not
already in the catalog, OpenCode assumes:
- Tool support, text and image input, and text output.
- A 200,000-token context limit and 32,000-token output limit.
- An unspecified input limit.
These are fallback assumptions, not detected capabilities. Set accurate capabilities and limit values when known;
explicit values replace the fallbacks. Add disabled: true to hide a model from the available catalog:
{
"providers": {
"openai": {
"models": {
"legacy-model": {
"disabled": true,
},
},
},
},
}Reasoning
For an OpenAI-compatible model that streams reasoning in a custom assistant-message field, set
compatibility.reasoningField:
{
"providers": {
"local": {
"models": {
"reasoner": {
"compatibility": {
"reasoningField": "reasoning_content",
},
},
},
},
},
}OpenCode recognizes reasoning, reasoning_content, and reasoning_text, and also accepts another provider-specific
string. It reads streamed reasoning from that field and restores the field when sending prior assistant messages back to
the model. See Compatibility for the related requireReasoning field.
Prompt caching
OpenCode places prompt-cache breakpoints automatically on routes that are known to need them, such as Anthropic. When
Claude models are served through an OpenAI-compatible proxy such as LiteLLM, OpenCode cannot tell that they need
Anthropic-style cache_control breakpoints. Set compatibility.cacheFormat on those Claude models:
{
"providers": {
"litellm": {
"package": "@opencode/ai/providers/openai-compatible",
"settings": { "baseURL": "https://litellm.example.com/v1" },
"models": {
"claude-sonnet-5-5": {
"compatibility": { "cacheFormat": "anthropic" },
},
"claude-opus-5-5": {
"compatibility": { "cacheFormat": "anthropic" },
},
// Other models on the same proxy cache automatically and need no setting.
"gpt-6.1-sol": {},
},
},
},
}OpenCode then marks the last tool definition, the system prompt, and the latest message with
cache_control: { "type": "ephemeral" }, which uses the endpoint’s default five-minute cache lifetime. Use "alibaba"
for Alibaba Model Studio models, which accept the same markers but ignore them on tool definitions. Set
compatibility.cacheFormat on the provider instead when every model it serves accepts the same format. See
Compatibility for the other fields.
Compatibility
compatibility describes request and response quirks of the API a model is served through, such as which field carries
reasoning or whether the endpoint accepts prompt_cache_key. Each model is served through one API, and a field only
takes effect when that API reads it. Other fields are ignored.
{
"providers": {
"local": {
"compatibility": { "streamUsage": false },
"models": {
"reasoner": {
"compatibility": { "reasoningField": "reasoning_content", "maxTokensField": "max_tokens" },
},
},
},
},
}Provider compatibility applies to every model of that provider. A model’s own compatibility overrides it field by
field: OpenCode starts from the values models.dev publishes for the model’s API (reasoningField,
maxTokensField, and mediaInput), then applies the model’s configuration. Unset fields keep the provider package’s
built-in default or detection. supportsThinkingBlockBinding and supportsEffortUpdates are model-only.
| Field | What it does | Read by | Values and default |
|---|---|---|---|
reasoningField | Assistant-message field that carries reasoning. Checked first when reading streamed reasoning and used when sending prior reasoning back. | OpenAI Chat | Any field name except role, content, refusal, or tool_calls. Unset uses the field seen in the stream, else reasoning_content. |
requireReasoning | Sends the reasoning field on every prior assistant message, as an empty string when there was no reasoning. | OpenAI Chat | true or false. Defaults to true when reasoningField is set or the model is DeepSeek, otherwise false. |
maxTokensField | Body field that carries the output token limit. | OpenAI Chat | max_completion_tokens or max_tokens. Unset detects max_tokens for providers that need it, such as DeepSeek, Moonshot, Together AI, Z.AI, and Cerebras, otherwise max_completion_tokens. |
requireFinishReason | Treats a stream that ends without finish_reason as an incomplete response error. false accepts it as finished. | OpenAI Chat | true or false. Defaults to true. |
requireAssistantAfterTool | Inserts an assistant message between a tool result and the next user message, for endpoints that reject that order. | OpenAI Chat | true or false. Defaults to true for Mistral-family model IDs, otherwise false. |
supportsPromptCacheKey | Whether the endpoint accepts the prompt_cache_key body field. | OpenAI Chat, OpenAI Responses, Mistral | true or false. OpenAI Chat only sends the key when true, which some provider packages set by default. Other APIs send it unless false. |
streamUsage | Requests token usage in the stream with stream_options.include_usage. | OpenAI Chat | true or false. Defaults to true. |
cacheFormat | Prompt-cache marker syntax the endpoint accepts. Overrides the provider’s automatic breakpoint placement. alibaba skips tool definitions. | Every API with prompt-cache markers, including OpenAI Chat, Anthropic Messages, and Bedrock Converse | anthropic or alibaba. Unset uses the provider default. See Prompt caching. |
supportsThinkingBlockBinding | Asks the API to drop thinking blocks whose earlier context changed instead of rejecting the request. | Anthropic Messages, Bedrock Converse | true or false. Unset detects Claude 5.1 and later. |
supportsEffortUpdates | Sends reasoning effort changes as per-message updates, which keep the prompt cache. Otherwise the effort changes for the whole request. | Anthropic Messages, OpenAI Responses | true or false. Unset detects Claude Opus 5, Claude 5.1 and later, and GPT-6 and later. |
mediaInput | Where images and other media go in a decision request. | System One | assets (images referenced from the state), state (inline in the state), or root (top-level images, audio, and videos lists). Unset uses the provider default. |
Local
OpenCode automatically discovers models from Ollama, LM Studio, and vLLM at their default local addresses. You can also configure any OpenAI-compatible server manually.
ollama/gemma3:4b
lmstudio/google/gemma-4-26b-a4b
vllm/Qwen/Qwen3-Coder-30B-A3B-Instruct
Ollama
With Ollama listening at http://127.0.0.1:11434, select a discovered model with the ollama provider ID:
{
"$schema": "https://opencode.ai/config.json",
"model": "ollama/gemma3:4b",
}OpenCode refreshes the inventory in the background and reads context, vision, and tool-use capabilities from Ollama. Embedding-only models are excluded.
For another host or port, set Ollama’s OpenAI-compatible URL. Discovery still uses the native Ollama API at the same path prefix:
{
"providers": {
"ollama": {
"settings": {
"baseURL": "http://127.0.0.1:5678/v1",
"apiKey": "{env:OLLAMA_API_KEY}",
},
},
},
}- Omit
apiKeywhen the endpoint does not require bearer authentication. - Disable discovery with
"plugins": ["-opencode.provider.ollama"].
LMStudio
With an unauthenticated LM Studio server at http://127.0.0.1:1234, select a discovered model with the lmstudio
provider ID:
{
"$schema": "https://opencode.ai/config.json",
"model": "lmstudio/google/gemma-4-26b-a4b",
}OpenCode refreshes the inventory in the background and reads context, vision, and tool-use capabilities from LM Studio. Embedding models are excluded.
For another host or port, set the OpenAI-compatible URL. Models are still discovered automatically:
{
"providers": {
"lmstudio": {
"settings": {
"baseURL": "http://127.0.0.1:5678/v1",
"apiKey": "{env:LMSTUDIO_API_KEY}",
},
},
},
}- Omit
apiKeywhen LM Studio authentication is disabled. - Disable discovery with
"plugins": ["-opencode.provider.lmstudio"].
vLLM
With vLLM listening at http://127.0.0.1:8000, select a discovered model with the vllm provider ID:
{
"$schema": "https://opencode.ai/config.json",
"model": "vllm/Qwen/Qwen3-Coder-30B-A3B-Instruct",
}OpenCode checks /health, refreshes /v1/models in the background, uses the reported max_model_len as the context
limit, and includes only model cards owned by vllm.
Discovered models advertise text input and output, but not vision or tools. vLLM enables tool calling with server flags
such as --enable-auto-tool-choice and --tool-call-parser, which discovery does not report.
For another endpoint or an authenticated server, set its OpenAI-compatible URL:
{
"providers": {
"vllm": {
"settings": {
"baseURL": "http://127.0.0.1:9000/v1",
"apiKey": "{env:VLLM_API_KEY}",
},
},
},
}- Omit
apiKeywhen authentication is disabled. - Disable discovery with
"plugins": ["-opencode.provider.vllm"]. - Path-prefixed proxies are supported. For example,
https://example.com/vllm/v1checks/vllm/healthand discovers/vllm/v1/models.
Compatible
For another OpenAI-compatible server, define its provider package, endpoint, and at least one model:
{
"$schema": "https://opencode.ai/config.json",
"model": "local/coder",
"providers": {
"local": {
"name": "Local server",
"package": "@opencode/ai/providers/openai-compatible",
"settings": {
"baseURL": "http://127.0.0.1:1234/v1",
},
"models": {
"coder": {
"modelID": "model-name-on-server",
"capabilities": {
"tools": true,
"input": ["text"],
"output": ["text"],
},
"limit": {
"context": 32768,
"output": 8192,
},
},
},
},
},
}Use the server’s real model name, limits, input and output types, and tool support. OpenCode cannot detect whether the
custom-model fallback values are accurate. If the endpoint requires a key, add apiKey to settings with an environment
substitution such as "apiKey": "{env:LOCAL_API_KEY}"; do not commit secrets.
References
Model selectors use provider/model with an optional #variant:
openai/gpt-6.1-sol
openai/gpt-6.1-sol#high
openrouter/anthropic/claude-sonnet-5.5#high
| Part | Rule |
|---|---|
| Provider | Ends at the first /; cannot contain / or #. |
| Model | May contain additional / characters; cannot contain #. |
| Variant | Follows # when present. |
| Casing | Provider and model IDs are case-sensitive. |
Use catalog IDs rather than provider display names. Root, agent, and command model fields accept the string form above
or an expanded object:
{
"model": {
"providerID": "openrouter",
"model": "anthropic/claude-sonnet-5.5",
},
}
The expanded form is useful for generated or programmatic configuration.
Caveats
Keep these rules in mind when configuring models:
{
"model": "openai/gpt-6.1-sol"
}
- A selector object uses
model; a provider catalog entry usesmodelIDfor the ID sent to the provider. - Although the root selection shape accepts a variant, the V2 catalog default does not retain it. Select variants for a session, run, agent, or command instead.
- Model options are provider-specific. Another provider package may ignore or reject them.
- Catalog data, credentials, and configuration are location-scoped. A model available in one project may be unavailable in another.
- Configuration files normally reload automatically. A model request already in progress keeps the settings it started with.