ENGINEERING
OpenCode with your own gateway: config-first, no lock-in
Just activated iSol API? Your key lives in the customer portal, isollm.ai/account → API keys (the portal shows the raw sk-… value; store it in your secret manager). The endpoint for every guide on this blog is https://tokens.4clouders.com/v1, and per-key spend updates live on the same portal page. That is all you need to follow along.
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.
Step 1: The config block that matters
OpenCode reads provider configuration from opencode.json in the project root. This is the exact file we ran with, note the {env:…} syntax, which keeps the key out of git:
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"isol": {
"npm": "@ai-sdk/openai-compatible",
"name": "iSol API",
"options": {
"baseURL": "https://tokens.4clouders.com/v1",
"apiKey": "{env:ISOL_API_KEY}"
},
"models": { "isol-4.9": { "name": "iSol 4.9" } }
}
}
}
@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. The models block names whatever the gateway exposes; the active model becomes <provider>/<model>, here, isol/isol-4.9. Commit this file to the repo and every developer who clones the project gets the same provider config without editing anything by hand.
Step 2: Run it for real
One-shot mode is the quickest proof. This is a genuine session, OpenCode wrote the file with its own tool, through our sovereign gateway:
export ISOL_API_KEY=sk-your-gateway-key
opencode run -m isol/isol-4.9 "Write a Python function is_cnpj_valid(cnpj: str) -> bool"

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.
Step 3: Verify at the gateway, not at the client
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, both fail quietly, so the gateway ledger is the only place you'll catch it:
curl -s https://tokens.4clouders.com/key/info \
-H "Authorization: Bearer $ISOL_API_KEY" | jq .info.spend
# the session above shows up here, accounted per key
isol declarado escrevendo o arquivo com a própria ferramenta dele, pelo seu gateway.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.
Same gateway, rest of your stack: every guide with real sessions
The pattern: one gateway, every tool
WhatsApp
Telegram
GitHub Actions
Teams
Claude Code
Cursor
VS Code
aider
n8n
Zapier
Power Automate
Power BI
Google Sheets
Website chatbot
Hermes Agent