ENGINEERING
OpenCode with your own gateway: config-first, no lock-in
Why config-first clients change the calculus
This isn't an announcement. It's what "open-source" is supposed to buy you: the ability to point the tool at infrastructure you own, without asking anyone's permission or waiting on a feature request.
OpenCode was built for custom providers from the start — not retrofitted onto a single vendor's API after the fact. That difference shows up the moment you want to run it against your own gateway instead of a vendor endpoint directly. You get the usual list of reasons teams do this, plus one that only an open client gives you:
- Data containment. Requests terminate at your gateway before going upstream.
- Predictable cost. Per-key budgets instead of one shared vendor invoice nobody can attribute.
- Model swaps without touching the client. Change the gateway's routing config; nobody's OpenCode setup changes.
- No lock-in on the client itself. OpenCode is open-source. If the maintainers ship something you don't want — telemetry you didn't ask for, a feature gated behind an account — you can fork it, patch it, or replace it. Pair that with a gateway you also operate and there's no single piece of this stack you can't swap out.
That last point is the real pitch. A closed client plus your own gateway still leaves you dependent on the vendor keeping the client's behavior stable and its pricing sane. An open client plus your own gateway means every layer between "developer types a prompt" and "model answers" is something you could, in principle, run yourself end to end — and something you can audit rather than take on faith.
The config block that matters
OpenCode reads provider configuration from opencode.json. Add a provider entry pointing at your gateway:
{
"provider": {
"my-gateway": {
"npm": "@ai-sdk/openai-compatible",
"options": {
"baseURL": "https://gateway.your-company.com/v1",
"apiKey": "sk-your-gateway-key"
},
"models": {
"team-default": {}
}
}
}
}
@ai-sdk/openai-compatible is the piece doing the work — the same Vercel AI SDK adapter used for any OpenAI-shaped endpoint, which your gateway already is if it speaks /v1/chat/completions. baseURL and apiKey point at your infrastructure instead of a vendor's; the models block lets you name whatever the gateway exposes — team-default, fast, reasoning, whatever names fit your routing. Commit this file to the repo (pulling the key from an environment variable, not hardcoding it) and every developer who clones the project gets the same provider config without editing anything by hand.
Why this beats a wrapper script
Some tools need a shim or a forked binary to redirect their traffic — a maintenance burden that breaks on every upstream release and has to be re-patched by hand. OpenCode's provider system means there's no shim to maintain: the config file is the interface the maintainers actually support, so it survives version bumps instead of fighting them. That's a small detail until the sixth time a tool's update silently breaks your wrapper, and then it's the whole reason you picked the open client in the first place.
Verify it's working
Don't just trust that the config parsed. Run a prompt through OpenCode with my-gateway/team-default selected as the active model, then check your gateway's request log for a matching entry — model name, timestamp, and token count should line up with what you just sent. If OpenCode falls back silently to a different provider instead of erroring, the most common cause is a typo in the provider key or a models entry that doesn't match what you selected in the client; both fail quietly rather than loudly, so the log is the only place you'll actually catch it.
Gotchas we hit in production
- Same SSE and timeout requirements as any OpenAI-compatible client. Streaming has to reach OpenCode unbuffered, and tool-use turns can run past a default reverse-proxy timeout — raise
proxy_read_timeoutor the equivalent on your gateway's front end. - Per-key budgets still matter. Nothing about an open client changes the failure mode of a runaway agent loop; cap the key the same way you would for any other tool.
- Keep the key out of the committed config. Reference an environment variable in
opencode.jsonrather than pasting the key into a file that ends up in git history the first time someone forgets.
Try it on ours
Our gateway (iSol API) runs exactly this setup on sovereign infrastructure — US$ 99/month, 14-day trial.