setup-gateway: point Claude Code, OpenCode and Codex CLI at any OpenAI-compatible endpoint
Konfigurator gateway OpenAI-compatible untuk Claude Code, OpenCode, dan Codex CLI. Zero-dependency, interaktif + CI, backup atomik + restore, config preservation, selftest built-in.
At a glance
- What is it?
- A zero-dependency Node script that rewrites three AI coding clients' config files against a gateway you supply, with atomic backups and a restore command. The catch is Codex, which now expects the Responses API.
- Who is it for?
- Adopt setup-gateway if you already run a gateway that exposes /v1 and you are tired of hand-editing three different config formats; the atomic backup plus restore pair is the reason to prefer it over a shell script you wrote yourself. Skip it if your gateway only speaks classic Chat Completions and you are targeting Codex, since the README states Codex needs wire_api = "responses" and a translation proxy in front.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 44 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 16, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem: three clients, three config formats, one gateway
If you route coding agents through a company LiteLLM instance, an OpenRouter account, or a local 9Router, you configure that endpoint once per client. Claude Code reads ~/.claude/settings.json. OpenCode reads ~/.config/opencode/opencode.json. Codex CLI reads ~/.codex/config.toml. Three file formats, three naming conventions for the same three values: base URL, API key, model id.
The README frames setup-gateway as a generic configurator: no provider, base URL or model is hardcoded, and you supply base URL, key and model on every run. That genericity is the whole product. It is not a proxy and it does not sit between your client and the network; it edits files, then exits. Anyone who has hand-edited a TOML provider block, then had to remember which JSON key Claude Code wanted, is the intended user. So is a CI job that has to provision a fresh machine with a known gateway before tests run.
How it works: fetch the model list, then write only the gateway keys
The interactive flow is documented in five steps. You pick a tool from an arrow-key menu (space to toggle, a for all), paste a base URL such as https://gw.example.com or http://127.0.0.1:8080, paste an API key, then pick a model. For the model step the tool attempts GET <baseURL>/v1/models with the key as a Bearer token. If that succeeds you get a filterable list; if it fails or times out, you type the model id by hand. That fallback matters, because plenty of internal gateways expose /v1/chat/completions without a working /v1/models.
After the model step, config is written, a backup is made first, and for Claude Code the key suffix is approved in ~/.claude.json so the client does not prompt about a custom API key.
The write targets differ per tool. Claude Code gets env.ANTHROPIC_BASE_URL, env.ANTHROPIC_API_KEY and model in settings.json. OpenCode gets a provider.<name> block plus model = <name>/<model> in opencode.json. Codex gets model, model_provider, model_catalog_json, a [model_providers.<name>] block, and an extra gateway-catalog.json file. Every path honors an environment override: CLAUDE_CONFIG_DIR, OPENCODE_CONFIG_DIR, CODEX_HOME.
The preservation claim is the part worth checking in your own diff. The README lists what is left alone: other settings and env entries such as ANTHROPIC_AUTH_TOKEN and ANTHROPIC_DEFAULT_*_MODEL, previous providers, agent blocks, TOML comments, and top-level Codex keys like model_reasoning_effort. That is a narrower blast radius than a script that regenerates a config from a template, and it is the reason to prefer this over a dotfile you sync by hand.
Install and first run: clone, then one command per tool
There is no npm install step. The README requires Node >= 18, which package.json confirms under engines, and the project declares zero dependencies, relying on built-in fetch, readline and AbortController. The package exposes a bin entry named setup-gateway plus npm scripts setup, selftest and help.
The quick start is a clone followed by the interactive entry point. Running it with no arguments gives you the tool menu.
node bin/setup-gateway.mjs
# alias: node setup-gateway.mjs (shim, setara)
# alias: npm run setupThe README notes the shim at the repository root is equivalent to the bin script. To configure a single client without the menu, pass the tool name; cc, oc and cx are documented aliases.
node bin/setup-gateway.mjs claude # Claude Code
node bin/setup-gateway.mjs opencode # OpenCode
node bin/setup-gateway.mjs codex # Codex CLIFor a headless run, the README gives a Claude Code example with all three values supplied as flags and --yes to skip prompts. This is the shape a provisioning script would use.
node bin/setup-gateway.mjs claude \
--base-url https://gw.example.com \
--api-key sk-... \
--model deepseek-v4 \
--yesTwo read-only or recovery commands are documented. status prints the active base URL, model and a masked API key; restore takes an optional tool name and, on a TTY, offers a menu of backups in the config directory.
node setup-gateway.mjs status # lihat config aktif (key termask)
node setup-gateway.mjs restore codex # pulihkan backup terakhir CodexThe generated Codex TOML is shown in the README and is worth reading before you run anything, because it tells you what your gateway has to support.
model = "deepseek-v4"
model_provider = "gateway"
model_catalog_json = "C:/Users/you/.codex/gateway-catalog.json"
[model_providers.gateway]
name = "Gateway"
base_url = "https://gw.example.com/v1"
wire_api = "responses"
experimental_bearer_token = "sk-..."The Codex constraint that decides whether this tool fits you
Codex is where setup-gateway stops being a convenience and starts having requirements. The README states that since early 2026 Codex only supports the OpenAI Responses API at /v1/responses, and that wire_api = "responses" is mandatory in the generated provider block. A gateway that only serves classic Chat Completions will not work directly; the README suggests a translation proxy such as LiteLLM in front.
That single sentence splits the audience. If you are already behind LiteLLM, the tool is a clean fit. If your gateway is a thin shim over /v1/chat/completions and Codex is one of the three clients you care about, you are adding a proxy before setup-gateway becomes useful.
Two more Codex-specific limits come from the README. The provider ids openai, ollama and lmstudio are reserved and rejected as --provider-name values, so you must choose something else (the default is gateway). And project-scoped config at .codex/config.toml cannot override provider or auth by Codex's own design, so the tool always writes to the user-level file under ~/.codex or $CODEX_HOME. If your workflow depends on per-repository Codex providers, this tool will not deliver it.
The model catalog is the compensating feature. Setup writes gateway-catalog.json in the config directory and points model_catalog_json at it, which makes gateway models appear in Codex's built-in /model picker. In interactive mode you multi-select extra models; with --yes the catalog contains only the main model. Two constraints: Codex must be restarted once after setup for the catalog to take effect, and the catalog key requires Codex >= 0.105.0. On an older Codex, expect the picker integration to do nothing.
API key handling: a deliberate departure from Codex's own advice
The README is unusually candid here. Codex officially recommends env_key, meaning the key lives in an environment variable rather than the config file, but setup-gateway writes the key directly through experimental_bearer_token. The stated justification is consistency with Claude Code and OpenCode, which also write the key into their configs, and that direct writing is supported.
That is a real trade-off, not a bug. It means the secret sits in plaintext in ~/.codex/config.toml, exactly as it sits in ~/.claude/settings.json. Anyone who can read those files has the key. If your threat model requires the key to stay out of on-disk config, this tool's default behavior is the wrong one, and the env_key route would be a manual edit after each run. The README does not document a flag to switch to env_key, so treat that as a gap rather than a supported mode.
One mitigation is built in: status masks the key when printing. The README does not describe encryption at rest or a keyring integration, so the plaintext property stands.
Alternatives and how they differ
The obvious alternative is a shell script or Ansible template that writes the same three files. The difference is preservation and recovery. A template regenerates a file, so anything not in the template is lost; setup-gateway edits the specific keys and, per the README, leaves comments, unknown keys, agent blocks and prior providers intact. It also backs up before each write and ships a restore subcommand, which a hand-rolled script usually does not.
A second alternative is to skip client-side configuration and put the gateway behind whatever base URL each client already expects, for example by running a local proxy on 127.0.0.1:8080 and pointing clients there once. That avoids rewriting configs on every gateway change, but it adds a process to keep alive and does not help with Codex's Responses API requirement unless the proxy does translation.
A third is to use each vendor's own configuration command or environment variables. That keeps you on supported paths, and for Codex it keeps the key in an env var as the vendor recommends, but it means three separate procedures and no shared backup or restore story. setup-gateway's value is precisely that it collapses those three procedures into one binary with one recovery path.
Maintenance, licence and what to verify before trusting it
The repository is not archived and the last push was on 2026-08-05, which is recent enough that the project has not gone quiet. There are no retrieved releases, so version 1.0.0 in package.json is the only version signal available; distribution appears to be clone-and-run rather than a published npm package, and the README gives no install-from-registry path.
The licence is MIT, declared in both package.json and the LICENSE file at the repository root. MIT permits commercial use and modification with the copyright notice retained; it offers no patent grant and no warranty. That is a standard permissive posture, and nothing in the README suggests additional terms. This is a description of the licence text, not legal advice.
Upgrade cost is low by design. There is no dependency tree to audit, so a new Node version is the main external variable. The README does not document a changelog, a migration path between versions, or a rollback other than the restore command, which recovers a config file rather than the tool itself. The built-in --selftest exercises pure functions without touching real config, and the README recommends it for CI, which is the cheapest way to confirm a fresh checkout behaves before it writes anything. Note that --selftest does not validate your gateway; it validates the tool.
Editorial conclusion
Adopt setup-gateway if you already run a gateway that exposes /v1 and you are tired of hand-editing three different config formats; the atomic backup plus restore pair is the reason to prefer it over a shell script you wrote yourself. Skip it if your gateway only speaks classic Chat Completions and you are targeting Codex, since the README states Codex needs wire_api = "responses" and a translation proxy in front. Before trusting it on a working machine, run node bin/setup-gateway.mjs status to see what it reads today, then run --selftest, then do one tool and inspect the backup directory it created next to the config file.
Frequently asked questions
Does setup-gateway need npm install or any dependencies?
No. package.json declares no dependencies and the README states Node >= 18 is the only requirement, using built-in fetch, readline and AbortController. You clone the repository and run the script directly.
Which config files does setup-gateway modify?
Claude Code's ~/.claude/settings.json, OpenCode's ~/.config/opencode/opencode.json, and Codex CLI's ~/.codex/config.toml, plus a gateway-catalog.json for Codex. Each path can be redirected with CLAUDE_CONFIG_DIR, OPENCODE_CONFIG_DIR or CODEX_HOME.
Can I undo a setup-gateway run?
Yes, through the restore subcommand, which recovers the last backup in the config directory and offers a backup menu on a TTY. A backup is written before every config write, and status is read-only if you only want to inspect the current values.
Does setup-gateway work with a gateway that only supports Chat Completions?
For Claude Code and OpenCode it should, since you supply the base URL and model yourself. For Codex the README states wire_api = "responses" is mandatory and a Chat Completions-only gateway will not work directly, so a translation proxy such as LiteLLM is needed.
Community notes