OpenCode
OpenCode is a terminal coding assistant. It talks to any OpenAI-compatible endpoint through a custom provider entry, which is what LowRouter exposes.
Verified against OpenCode 1.18.32. The config below is re-run against that release every week; if you are on a much newer version and it stops working, check the OpenCode provider docs for a schema change and let us know.
Configure
OpenCode reads ~/.config/opencode/opencode.json (or an
opencode.json in the project directory; the two are merged).
Declare LowRouter as a provider, list the models you want to use, and
set the default model:
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"lowrouter": {
"npm": "@ai-sdk/openai-compatible",
"name": "LowRouter",
"options": {
"baseURL": "https://api.lowrouter.ai/v1",
"apiKey": "sk-lr-..."
},
"models": {
"auto/mistralai/mistral-large-2512": {
"name": "Mistral Large (auto-routed)",
"tool_call": true,
"limit": { "context": 256000, "output": 16384 }
}
}
}
},
"model": "lowrouter/auto/mistralai/mistral-large-2512"
}Restart OpenCode after editing the file. Four things in this block are easy to get wrong:
- Models must be declared. OpenCode does not discover models from
GET /v1/models; a model that is not listed undermodelsdoes not exist as far as OpenCode is concerned. Each key is a LowRouter model ID, exactly as the model browser shows it.tool_call: truetells OpenCode the model can drive its file and shell tools; check the function-calling tag on the model’s page, or filter the model browser to models that have it, before setting it. - Declare
limit. OpenCode asks for 32,000 output tokens unless the model entry says otherwise, and a model that caps lower rejects the request outright (max_tokens is too large: 32000. This model supports at most 16384…ongpt-4o-mini, for instance). Copycontextand the max output from the model’s page; when the page shows no max output, 16384 is a safe ceiling for the models listed today. - The model is addressed as
lowrouter/<model id>. The first segment is the provider key you chose above (lowrouter), the rest is the LowRouter ID. That applies to themodelfield, to/modelinside the TUI and toopencode run -m .... baseURLends in/v1, with no trailing slash. OpenCode appends/chat/completionsitself. This is the opposite of Goose, whose host must not include/v1. Each tool decides for itself how much of the path it adds.
To check the wiring without opening the TUI:
opencode run -m lowrouter/auto/mistralai/mistral-large-2512 "Reply with the single word pong"Picking a model
Any model on the model browser is routable. Add it under
models first, then pick it with /model in the TUI. For coding
tasks, name a capable model and let LowRouter pick where it runs, as
with auto/mistralai/mistral-large-2512. You still choose the model:
- For long contexts: a model with ≥128K context window. The model browser tags context length per model.
- For latency-sensitive iteration: an
*-minior*-haiku-*variant. - For careful reasoning: a top-tier reasoning model.
- For agentic work: a model whose page carries the function-calling tag (filtered list). Without it OpenCode’s tools cannot be invoked.
Recommended setup
- Use a dedicated key. OpenCode is interactive and it’s easy to lose track of how many tokens you spent in an afternoon; a key of its own shows that on the Activity page.
- Disable shell-execution tools by default. OpenCode supports letting the model run shell commands; turn that off until you’ve reviewed the prompts the agent sends. Enable it per-session for the workflow that needs it.
- Keep streaming on. It is the default in OpenCode.
Troubleshooting
Unexpected server error… ref err_…on the first prompt, and nothing in your Activity: the request never left your machine. This is what a legacy config looks like: older guides (including an earlier version of this page) used aproviders/defaultModelblock that OpenCode 1.18 silently drops, leaving it with no provider at all. Replace it with the block above. If the request is not in Activity, LowRouter never saw it.- Model “not found”: it is not declared under
models. There is no autocomplete from the gateway; add the ID and restart. 404on every request:baseURLis missing/v1, or has a trailing slash.401: confirm the key underoptions.apiKey.
If tool calls are auto-rejected
OpenCode asks before each file read or edit, and in a non-interactive run
(opencode run) there is nobody to ask, so it rejects and reports the
tool call as failed. That is OpenCode’s sandbox, not a routing problem.
Grant the permissions in the same config file:
{
"permission": { "read": "allow", "edit": "allow", "bash": "allow" }
}Verified with the real CLI against LowRouter, agentic loop included: it
reads a file, edits it, and the change lands on disk. Works with both an
explicit {provider}/{creator}/{model} id and an auto/ id.
