# setup-gateway rewrites three agent configs without touching the rest

> Sinholms/setup-gateway is a zero-dependency Node CLI that points Claude Code, OpenCode and Codex CLI at any OpenAI-compatible gateway you paste in. Its whole argument is restraint: only the gateway block is written, every write is preceded by a timestamped backup, and a built-in selftest runs without touching disk.

**Sinholms/setup-gateway** — Konfigurator gateway OpenAI-compatible untuk Claude Code, OpenCode, dan Codex CLI. Zero-dependency, interaktif + CI, backup atomik + restore, config preservation, selftest built-in.

- Repository: https://github.com/Sinholms/setup-gateway
- Stars: 440 · Forks: 0
- Language: JavaScript
- License: MIT
- Published: 2026-09-17 · Updated: 2026-09-17 · Language: en
- Canonical page: https://hysenlabs.com/projects/sinholms-setup-gateway

## Nothing is hardcoded except the three config files

The neutrality is the design constraint. setup-gateway is a generic CLI that configures an OpenAI-compatible API gateway into three popular AI coding clients, and it works with anything exposing a `/v1` path: LiteLLM, OpenRouter, a company internal proxy, a local 9Router instance and so on.

There is no provider, base URL or model baked in. You supply the base URL, the API key and the model on every run. That sounds like a missing feature until you consider the alternative: a tool that knows a default provider is a tool that is wrong the first time you use a different one.

The three targets are named with their config files, which is the real scope of the tool. Claude Code uses a settings file under the home directory or an override directory. OpenCode uses a JSON file under the user config directory. Codex CLI uses a TOML file under the Codex home, and that one gets extra handling for reasons covered later.

Node 18 or newer is the only requirement, and the zero-dependency claim is specific rather than aspirational: the built-in `fetch`, `readline` and `AbortController` do the work, so there is no install step.

## Two modes, one binary

The interactive path is a five-step flow, and the details of step four are where the work is.

You pick a tool with arrow keys and space, entering `a` for all. You paste the base URL, which the example shows as either a normal https endpoint or a loopback address such as `http://127.0.0.1:8080`. You paste the key. Then you pick a model, and this is where the tool earns its keep: it tries `GET <baseURL>/v1/models` with the key as a bearer token. On success you get a filterable list where typing searches it. On failure or timeout, it falls back to asking you to type a model identifier manually.

That fallback matters more than the happy path, because a gateway that is up but slow, or up but strict about the models endpoint, would otherwise block the whole setup.

For a single tool you skip the menu:

```bash
node bin/setup-gateway.mjs claude
```

And for CI there are flags that replace every prompt:

```bash
node bin/setup-gateway.mjs claude \
  --base-url https://gw.example.com \
  --api-key sk-... \
  --model deepseek-v4 \
  --yes
```

The `--yes` flag does two things worth knowing: it accepts all defaults and skips the menus, and it also skips the http warning, so it is the flag that turns the tool into a silent writer.

## Only the gateway block is written

The preservation claim is stated as a list of what survives, and that list is the argument against corrupting a working setup.

Unrelated settings are kept. Other environment entries stay, including an existing auth token variable and the default model variables. Old providers are kept. The agent block is kept. TOML comments are kept, which is the detail most config writers get wrong, because a rewrite that drops comments loses information nobody backed up. And unknown keys are left intact.

Three commands exist around this. `status` is read-only and prints the base URL, the model and the masked API key from the active config. `restore` puts back the most recent backup in the config directory, and in an interactive terminal it offers a menu of backups rather than taking the latest automatically.

The backup behaviour is described as atomic, and the framing is the right one: a mistake while typing is not a problem, because every write is preceded by a labelled timestamped backup. That is a different posture from a config tool that validates before writing and refuses on error. This one assumes you will get it wrong and gives you the undo.

There is also a flag to skip the backup, with the risk explicitly left to you.

## Codex needs the Responses API and writes a key in plain sight

Codex gets a separate section because it has three constraints the other two do not, and two of them are things the tool cannot work around.

The first is that the wire protocol value is mandatory. Since early 2026 Codex only supports the OpenAI Responses API, so the generated config sets the wire API to `responses`. A gateway that offers only classic Chat Completions will not work directly, and the advice is to put a translation proxy in front of it, with LiteLLM named as one.

The second is the key. Codex officially recommends an environment variable reference rather than a key in the config file, but setup-gateway writes the key directly through an experimental bearer token field, and the reason given is consistency with the Claude and OpenCode paths, which also write the key into config. So the tool knowingly departs from the upstream recommendation, and says why.

The third is scope. A project-scoped config inside a repository cannot override the provider or auth settings by Codex's own design, so this tool always writes to the user-level config. That is a documented limit rather than a bug, and it matters if you were expecting the tool to configure a repo on a shared machine.

Three provider identifiers are reserved and rejected as errors if you try them: `openai`, `ollama` and `lmstudio`. The default name is `gateway`.

## The model catalog makes /model work after setup

There is one feature that goes beyond writing a default model, and it changes how you use Codex afterwards.

Besides setting the default model, the tool writes a catalog file into the config directory and points at it from a top-level catalog key. The effect is that the gateway's models appear in Codex's built-in model picker, so switching models afterwards happens inside Codex with a slash command rather than by re-running setup-gateway.

The generated TOML is the clearest illustration of the whole output shape:

```toml
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-..."
```

Two behaviours differ by mode. Interactively you get a multi-select for additional models, with space to tick, `a` for all, and the main model ticked by default. Under CI with `--yes` the catalog contains only the main model, which is the right trade for a non-interactive run.

There are two costs. Codex needs a restart once after setup for the catalog to take effect, and the catalog requires Codex 0.105.0 or newer, since that is when the catalog key became official. On an older Codex the extra file is written and ignored.

## A selftest that never touches your config

There is a flag whose purpose is worth naming on its own: it verifies the pure functions without touching real files, and it is described as suitable for CI.

```bash
node bin/setup-gateway.mjs --selftest
```

That is the feature that makes this tool reviewable. A config writer that rewrites three files in three formats is hard to trust from reading alone, and a test mode that exercises the transformation logic without an output path gives you something to run on every build.

The package file wires it up as a script named `selftest`, alongside a setup alias and a help alias that run the same binary with the equivalent flag.

The rest of the package is minimal in a way that matches the zero-dependency claim. It is an ES module at version 1.0.0, MIT licensed, requiring Node 18 or newer. One binary is declared, and the published files are the binary directory, the source directory and the readme. The two aliases are worth noting because they are what a person will actually type: the setup script runs the binary, and the repository also carries a top-level shim so the shorter invocation works.

## Three readme languages, and no releases yet

Two repository facts are worth noting for anyone deciding how much weight to put on this.

The first is the language situation. The project documentation is in Indonesian, with an English version and a Japanese version alongside it, and the navigation at the top of the readme links to quick start, how it works, commands, flags and environment, security, and troubleshooting. Three maintained translations of a configuration tool aimed at coding agents is more localisation effort than most projects of this size attempt.

The second is the release state. There are no GitHub releases, and the last push to the default branch landed on 5 August 2026. The package version in the project file is 1.0.0, so the code declares itself stable while the repository publishes no tagged artefact for it.

For a tool whose entire job is rewriting files in your home directory, that combination is the thing to weigh. A stable version number with no release history means you have no published artefact to verify against, so pinning is done against a commit rather than a tag, and the backup plus restore commands are the practical substitute for trusting the version.

## Conclusion

Fit for someone running two or three coding CLIs against one gateway and tired of hand-editing three config formats, since the model picker, the backup and the restore are the parts that would otherwise be repeated by hand. A poor fit if your gateway only speaks classic Chat Completions, because Codex now requires the Responses API and the tool will not paper over that. Before running it, note two things it is explicit about: it writes the API key into the config file rather than an environment variable, and a Codex project-scoped config cannot be overridden, so it always writes to your user-level config.

## FAQ

### What does setup-gateway actually configure?

It writes an OpenAI-compatible gateway into three coding agent clients: Claude Code, OpenCode and Codex CLI. Nothing is hardcoded, so you supply the base URL, API key and model on every run, and the tool will discover available models from the gateway's `/v1/models` endpoint when it can, falling back to a manual identifier.

### Does setup-gateway overwrite my existing agent config?

Only the gateway section. Other environment entries, an existing auth token, the default model variables, old providers, the agent block, TOML comments and unknown top-level keys are all preserved. Every write is preceded by a timestamped backup, and a restore command puts the most recent one back, with a menu of backups when run in a terminal.

### Does setup-gateway need any npm packages?

No. It requires Node 18 or newer and relies on the built-in fetch, readline and AbortController, so there is no install step. The package declares one binary, ships the binary directory, the source directory and the readme, and exposes a selftest mode that exercises the pure functions without writing to real config files.

## Sources

- [Issues](https://github.com/Sinholms/setup-gateway/issues)
- [License: MIT](https://github.com/Sinholms/setup-gateway/blob/main/LICENSE)
- [README](https://github.com/Sinholms/setup-gateway/blob/main/README.md)
- [Sinholms/setup-gateway on GitHub](https://github.com/Sinholms/setup-gateway)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/sinholms-setup-gateway
