OpenCode is an open-source terminal coding agent that supports any OpenAI-compatible provider. Because Tresor speaks the OpenAI Chat Completions protocol, you can route OpenCode through the Tresor router with a one-time config change.
1.x) and OpenCode 2 (2.x) are separate release lines that both run as opencode, and they use different config shapes and credential stores. Run opencode --version and follow the matching tab below.curl -fsSL https://opencode.ai/install | bash or npm install -g opencode-ai.curl -fsSL https://opencode.ai/v2/install | bash, brew install anomalyco/tap/opencode-v2, or npm install -g @opencode/cli.opencode command. Your OpenCode 1 config still loads in OpenCode 2, so migrating is optional, but the native OpenCode 2 shape is what the tabs below show.OpenCode 1 — start OpenCode with opencode, run /connect, and pick Other at the bottom of the provider list. Enter:
tresortr-)$ opencode
> /connect
┌ Add credential
│ ● Other
│ ◇ Enter provider id
│ tresor
│ ◇ Enter your API key
│ tr-...
└
OpenCode stores the key in ~/.local/share/opencode/auth.json.
OpenCode 2 — credentials live in a SQLite database rather than auth.json, and a custom provider reads its key from an environment variable instead of /connect. Export the variable on the server process that runs model requests:
export TRESOR_API_KEY="tr-..."
For the shared background server, add it to the managed environment with opencode service set env TRESOR_API_KEY tr-..., then confirm it with opencode auth list.
auth.json during its database migration, and stores new or updated credentials in ~/.local/share/opencode/opencode.db. Print the exact path with opencode debug paths db.OpenCode needs a tresor entry to know the base URL and which models to expose. Add it to either the project-local opencode.jsonc or the global ~/.config/opencode/opencode.jsonc. The field names differ between the two release lines:
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"tresor": {
"npm": "@ai-sdk/openai-compatible",
"name": "Tresor",
"options": {
"baseURL": "https://api.tresor.co/v1"
},
"models": {
"global/chutes/kimi-k2.6": { "name": "Kimi K2.6" },
"eu/privatemode/gpt-oss-120b": { "name": "GPT-OSS 120B (EU)" },
"global/tinfoil/deepseek-v4.1-flash": {
"name": "DeepSeek V4.1 Flash"
}
}
}
},
"model": "tresor/global/chutes/kimi-k2.6"
}
{
"$schema": "https://opencode.ai/config.json",
"providers": {
"tresor": {
"name": "Tresor",
"env": ["TRESOR_API_KEY"],
"package": "@opencode/ai/providers/openai-compatible",
"settings": {
"baseURL": "https://api.tresor.co/v1"
},
"models": {
"kimi-k2.6": {
"modelID": "global/chutes/kimi-k2.6",
"name": "Kimi K2.6"
},
"gpt-oss-120b": {
"modelID": "eu/privatemode/gpt-oss-120b",
"name": "GPT-OSS 120B (EU)"
},
"deepseek-v4.1-flash": {
"modelID": "global/tinfoil/deepseek-v4.1-flash",
"name": "DeepSeek V4.1 Flash"
}
}
}
},
"model": "tresor/kimi-k2.6"
}
The model ids must match those returned by GET /v1/models. Run curl https://api.tresor.co/v1/models -H "Authorization: Bearer $TRESOR_API_KEY" to list the current set.
models map works differently in each line. In OpenCode 1 the map key is the id sent to the provider, so it must be the full Tresor route. In OpenCode 2 the key is only OpenCode's local name and modelID is what gets sent to Tresor, which is why the OpenCode 2 example uses short keys.Alternatively, in OpenCode 2 you can drop the env array and set the key inline as "settings": { "baseURL": "...", "apiKey": "{env:TRESOR_API_KEY}" }.
@ai-sdk/openai-compatible on OpenCode 1, @opencode/ai/providers/openai-compatible on OpenCode 2) ship with OpenCode for any OpenAI-compatible endpoint that uses /v1/chat/completions. No extra install step is required.Inside OpenCode, run /models and select one of the entries you configured.
> /models
Tresor / Kimi K2.6
Tresor / GPT-OSS 120B (EU)
That's it — every prompt OpenCode sends now goes through the Tresor router and returns a verifiable receipt.