FUTURE PROOF MARKETER

Artificial IntelligenceMarketing

OpenCode Proxy: How to Route OpenCode Through a Gateway (One Toggle or Six Lines of JSON)

Illustration for: OpenCode Proxy: How to Route OpenCode Through a Gateway (One Toggle or Six Lines of JSON)

Some links below are affiliate links: if you buy through them we may earn a commission at no extra cost to you. It funds the testing budget and never changes a verdict — affiliate policy.

OpenCode was built to talk to any provider, and that makes it one of the easiest coding agents to put a gateway in front of. There is no hidden endpoint to trick: providers live in a JSON file and you can add one. Routing it through a proxy is a config change, and Gate now documents that change in its own OpenCode guide, with two ready configs.

This post gives you the one-toggle route, the two manual configs, the line that decides who pays, how to check it took, and how to undo it. First written on 18 September 2026; updated on 27 September 2026 to follow Gate's OpenCode guide exactly.

Why put a gateway in front of OpenCode

The case is the same as for Claude Code, and it gets stronger the more OpenCode does on its own. An agent that reads files, runs commands and reads tool output is an agent that can be handed instructions by any of them: indirect prompt injection, and the tool result is the carrier that is growing fastest. Right now, nothing sits between OpenCode and the model: nobody screens what goes out, nobody counts it until the bill, nobody keeps a record you could show anyone.

A gateway in the path gives you a meter, a screen and a record for one config change. A good one also sends less: OpenCode, like every coding agent, resends the whole conversation each turn, including files the model has already seen, and a gateway that strips the repeats before forwarding is money back every turn.

Where OpenCode keeps its providers

Two facts about OpenCode's config make everything below simple:

  • It lives in JSON. Global config is ~/.config/opencode/opencode.json; a project can have its own opencode.json; OPENCODE_CONFIG points at a custom file. They merge rather than replace, in that order (remote org defaults first, global, custom, project, managed last), so a project file can add a gateway without touching your global settings.
  • Providers are a map. Each entry has an npm package that speaks the provider's protocol (@ai-sdk/openai-compatible for anything OpenAI-shaped), options with baseURL, apiKey and optional headers, and a models map of what to show in the picker. Models are selected as provider/model. Credentials from opencode auth login (or /connect in the TUI) are kept separately in ~/.local/share/opencode/auth.json.

That is the entire surface you need.

Route OpenCode through Gate, the one-toggle way

Constellation Gate AI is the gateway we use (compared with six others here). It sits "between your agent and the model", screens every request and response for prompt injection, removes repeated content so 20% or more fewer tokens reach the model, tracks cost per request, and writes a tamper-evident audit log (Gate's own figures, checked 18 September 2026). Free plan, no card.

Gate Connect, its menu-bar app, treats OpenCode as a config integration: instead of running a proxy, it writes the provider into your OpenCode config and takes it out again when you disconnect. Its docs put it in one line: "Gate Connect adds Gate as a provider. The keys from opencode auth login stay in place."

  1. Create the free account at Gate and copy an API key from the dashboard (starts with sk-gw-).
  2. Install Gate Connect (macOS, Windows, Linux). It lives in the menu bar.
  3. Paste the key, click Connect. The key goes to your OS keychain, not a file.
  4. Open Routing, make sure Route through Gate is on, switch opencode on.
  5. Quit and reopen OpenCode. A running OpenCode keeps its old config until restarted.
  6. Pick a Gate model in OpenCode's model picker and send one message. It should appear on Gate's Messages page within seconds, with model, cost and security result.

From a terminal, or on a machine with no desktop, the same thing is:

gate-connect login --base-url https://gateway.constellationgate.ai --api-key sk-gw-...
gate-connect connect opencode
gate-connect status opencode      # not installed · detected · connected · drifted

Drifted means the config changed outside Gate Connect; connect again fixes it. disconnect opencode restores the original config.

Affiliate disclosure, where it belongs: we earn a commission on Pro seats that start from our link. It pays for the testing, not the verdict.

Route OpenCode through Gate, the manual way

If you would rather see the setting, add Gate as a provider yourself. Gate's OpenCode guide gives two configs; this is the first, pay through Gate: your Gate key is the only credential, Gate routes each request and bills your prepaid balance. The block below is Gate's, unchanged:

{
  "provider": {
    "gate": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "Constellation Gate",
      "options": {
        "baseURL": "https://gateway.constellationgate.ai/v1",
        "apiKey": "sk-gw-…your Gate key…"
      },
      "models": {
        "anthropic/claude-opus-4-8": { "name": "anthropic/claude-opus-4-8" }
      }
    }
  }
}

Four things to notice:

  • The base URL ends in /v1. The OpenAI-compatible package does not add it for you.
  • The key and the model are placeholders. Your key starts with sk-gw- (dashboard, API keys). Any Gate-catalog model works, written provider/model; browse the IDs on the dashboard's Models page or with GET /v1/models. In the picker the model appears as gate/anthropic/claude-opus-4-8, because OpenCode prefixes the provider key.
  • Keep the key out of committed files. Gate's example has the key inline. OpenCode's own config syntax also accepts "apiKey": "{env:GATE_API_KEY}", which reads it from your shell instead; use that the moment the block lands in a project's opencode.json that gets committed.
  • small_model is the second saving. It is an OpenCode setting, not part of Gate's block: add a small Gate-catalog model to models and set the top-level "small_model" to it (written gate/provider/model). OpenCode uses it for lightweight jobs such as titles and summaries, so the cheap tier is cheap and screened.

Put the block in ~/.config/opencode/opencode.json for every project, or in a project's opencode.json for one. Restart OpenCode.

The line that decides who pays

The block above bills through Gate. Gate's second config, use your own keys, keeps your own provider key as the credential: Gate forwards it and adds its screening and audit layer underneath, and your provider keeps billing you for the tokens. options.apiKey stays your upstream key, and Gate's two headers go in options.headers: your Gate key in X-Gate-Api-Key, and the upstream's base URL, without the /v1 OpenCode already sends, in X-Gate-Upstream-Url. Gate's example uses OpenRouter, again unchanged:

{
  "provider": {
    "openrouter-gate": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "OpenRouter through Gate",
      "options": {
        "baseURL": "https://gateway.constellationgate.ai/v1",
        "apiKey": "sk-or-…your OpenRouter key…",
        "headers": {
          "X-Gate-Api-Key": "sk-gw-…your Gate key…",
          "X-Gate-Upstream-Url": "https://openrouter.ai/api"
        }
      },
      "models": {
        "openrouter/auto": { "name": "openrouter/auto" }
      }
    }
  }
}

The provider ID is yours to choose. A fresh one such as openrouter-gate leaves OpenCode's own openrouter entry alone, which also makes undoing it a one-block delete.

Three honest limits on this route:

  • Model IDs are the upstream's, not Gate's. Gate passes the model field to your upstream untouched, so every ID under models must exist in that upstream's own catalog: openrouter/auto for OpenRouter, claude-opus-4-8 (not anthropic/claude-opus-4-8) for Anthropic direct. A model that shows in the picker but never answers is almost always a Gate-catalog ID sent to your own upstream; check that first.
  • An Anthropic key is the exception. Gate requires Claude traffic on Anthropic's /v1/messages wire, and @ai-sdk/openai-compatible only speaks the OpenAI wire. Gate's guide says to use a provider built on @ai-sdk/anthropic instead, with the same options.headers, the same https://gateway.constellationgate.ai/v1 as baseURL, and https://api.anthropic.com (no /v1) as X-Gate-Upstream-Url, so the call lands on https://api.anthropic.com/v1/messages. Keep the /v1 on the baseURL: a bare host there sends the call to /messages and gets a 404. Or route a Claude key through Claude Code instead.
  • Subscription logins are still a question mark. OpenCode can sign in with a Claude Pro/Max account through /connect. Gate documents the subscription-kept route for Claude Code, whose custom-header setting forwards the login untouched. Its OpenCode guide covers API keys only and says nothing about OAuth or subscription logins, and OpenCode's docs are silent too, so whether a Max login survives this route is undocumented. If a Max subscription is what you run OpenCode on, test it with one message before you rely on it, and treat the two key-based configs above as the documented paths. We will report what we find in the 30 September field-test post.

Check that it took

  1. The model picker. After a restart, a Gate-routed model shows under the provider you added (gate, or the ID you chose for your own keys). If it is missing, the config did not load: check the file path, the JSON, and that you restarted.
  2. Gate's Messages page. Send one message, look for it. Model, cost, screening verdict. Nothing after a minute means the request went straight to the provider.
  3. gate-connect status opencode if you used the app: connected is what you want; drifted means something rewrote the config.

Then write down two numbers with the date: requests recorded and tokens saved. That is the baseline the rest of the evaluation is measured against.

What changes and what does not

Stays the same: your project, your AGENTS.md, your MCP servers, your existing logins in auth.json, and the answers, since Gate keeps the first copy of everything and removes only the repeats.

Changes:

  • One more hop. Some latency; we are measuring it.
  • Free records, Pro blocks. The free plan (20,000 recorded requests a month, a basic pattern screen, basic compression, the audit trail, Gate Connect) shows you a flagged request; blocking it, redacting PII and credentials, spend caps and the full compression are Pro at $20 per user per month (checked September 2026). Run free until the first flag, then decide.
  • Your prompts pass through a third party. Gate says it does not train on them and stores fingerprints, not content, in the audit ledger. If a client contract forbids another processor, read Gate's terms first; the review goes through this.
  • A project config can carry the gateway with it. Useful for a team (everyone who clones the repo gets the provider; the team rollout guide covers the rest), risky if you ever put a raw key in it instead of {env:...}.

Your first fifteen minutes

Following the rule we apply to every tool: real input, one output, hard stop.

  1. Minutes 0 to 4. Free account, copy the key, Gate Connect, switch opencode on, quit, reopen. Start here.
  2. Minute 4. Open the model picker, pick the Gate model, send one line. Watch it land on the Messages page.
  3. Minutes 5 to 13. The task you were going to do anyway. Real files, real edits.
  4. Minutes 13 to 15. Requests recorded, tokens saved, date. Sticky note. Stop.

A week later, the same two numbers say whether the free plan stays. The first flagged request, or the first e-mail address you see in a log that should not be there, is the day Pro becomes a simple decision. The calculator on our Gate page does the arithmetic from your monthly spend.

How to undo it

Gate Connect: switch opencode off in Routing, or gate-connect disconnect opencode; restart OpenCode. Manual: delete the gate (or openrouter-gate) provider block, restart. auth.json was never touched, so there is nothing to sign back into.

That is all it is. OpenCode already lets you choose where its requests go; a gateway is one more entry in that list, and the only entry whose job is to watch the others.

We are running our own sessions through Gate, OpenCode included. Token numbers, latency and the subscription question go out in the newsletter and on the Gate page on 30 September 2026.

Questions we actually get

How do I set a proxy for OpenCode?→

Two ways. Gate Connect: install the menu-bar app, paste a Gate key, turn OpenCode on under Routing, quit and reopen OpenCode. Manual: add a provider block to ~/.config/opencode/opencode.json (or opencode.json in the project) with the gateway's baseURL and key, then select a model from that provider. Config files merge, so a project file can add the gateway without touching your global one.

Does routing OpenCode through a gateway change my existing provider logins?→

Not with Gate Connect: its docs say it adds Gate as a provider and the keys from opencode auth login stay in place. Who pays depends on which of the two documented configs you pick. The pay-through-Gate provider bills your prepaid Gate balance; the own-keys provider sends your upstream key as apiKey and your Gate key in the X-Gate-Api-Key header, so your own provider account keeps paying for the model. Gate's guide suggests a fresh provider ID for that, such as openrouter-gate, which leaves OpenCode's built-in entry alone.

What is the opencode provider config for an OpenAI-compatible endpoint?→

A provider entry with npm set to @ai-sdk/openai-compatible, options.baseURL pointing at the endpoint (ending in /v1), options.apiKey, optional options.headers, and a models map naming each model ID you want in the picker. Environment variables are referenced as {env:NAME}. OpenCode publishes a schema at https://opencode.ai/config.json so your editor can validate the block.

Which model names do I use through Gate?→

It depends on the mode. Paying through Gate, you use Gate's catalog IDs, written provider/model, for example anthropic/claude-opus-4-8; OpenCode shows it as gate/anthropic/claude-opus-4-8 because it prefixes the provider key. With your own key, Gate passes the model field to your upstream untouched, so the IDs must be the upstream's own (openrouter/auto for OpenRouter, claude-opus-4-8 for Anthropic direct). A model that shows in the picker but never answers is usually a Gate-catalog ID sent to your own upstream.

Does a gateway save tokens with OpenCode?→

Only if the gateway changes what it forwards. Gate removes duplicate content and repeated file reads before the request reaches the model, which it says cuts tokens 20% or more on agent workloads (vendor-published, September 2026). A plain proxy or a corporate network proxy just changes the route and saves nothing. Set small_model to a cheaper model for OpenCode's lightweight tasks and you save a second time.

How do I undo it?→

Gate Connect: turn OpenCode off in Routing, or run gate-connect disconnect opencode, which restores the original config; restart OpenCode. Manual: delete the provider block you added, restart. Nothing about your logins was changed, so there is nothing to sign back into.

FILED ON THE AI VIDEO & REPURPOSING SHELF — MORE FIELD-TESTED TOOLS AND GUIDES THERE →

#AI#AI security#Marketing Stack#productivity#Claude

Never miss a verdict

One tool tested, one workflow, one future signal, one deal — every week.

One email with the goods, then the weekly letter. Unsubscribe anytime.

Keep reading