gateway.config.{ts,mts,cts,js,mjs,cjs,json} from the current directory, or a path passed with --config. See Config file discovery for every location it reads. Embedders skip the file entirely and pass a config object straight to createGateway. Every key the object accepts is listed in Config options.
Write a config file
UsedefineConfig for autocomplete and compile-time checking of the providers map.
baseURL (see Providers). A config with no providers at all fails validation on startup.
Restrict built-in models
Setmodels on a built-in provider to allow only those models. IDs are unprefixed, exact, per-provider model names.
404 model_not_found on every HTTP and in-process path. Friendly aliases are canonicalized before comparison, and GET /v1/models omits blocked models. Without models, the provider’s full catalog is allowed and uncatalogued IDs return 404 model_not_found.
Auto-discover from env
Running the CLI with no config file discovers providers from environment variables — each built-in provider defines its own list, checked in order.
Every built-in provider has an equivalent list; see Built-in provider options. If none resolve, the CLI exits with an error naming every env var it checked. A config file merges on top of env-discovered providers rather than replacing them — the file wins on conflicts.
Custom OpenAI-compatible endpoints are never auto-discovered — there’s no reasonable way to derive a base URL from env alone, so they always need an explicit
providers entry.
CLI flags
Any other argument exits with
unknown flag or unknown command.
The CLI also reads these environment variables:
On
SIGTERM or SIGINT, the server stops accepting connections, waits up to 25 seconds for open requests to finish, flushes telemetry, and exits.
npx @frogbotai/gateway init scaffolds a standalone project — src/server.ts, package.json, tsconfig.json, .env.example, .gitignore, and a README.md — for embedding the gateway behind your own Hono server instead of running the bundled CLI server.
Config file discovery
The CLI builds one config from these layers. Each later layer merges on top of the earlier ones:- Providers discovered from environment variables.
- Global files in
$XDG_CONFIG_HOME/frogbotai/(or~/.config/frogbotai/): everygateway.*andgateway.config.*file there, with any of the extensions below. - Project files: the first
gateway.config.*file in each directory from the project root down to the current directory. The project root isGATEWAY_CONFIG_ROOT, or the nearest directory above the current one that holds.gitorpackage.json. Without either, only the current directory is searched. - The file passed with
--configorGATEWAY_CONFIG. - The JSON object in
GATEWAY_CONFIG_JSON.
.ts, .mts, .cts, .js, .mjs, .cjs, and .json. A file can export the config as default or as a named config export, or export a function, optionally async, that returns it. Loading a TypeScript file needs a runtime that imports .ts directly, such as Bun or Node with --import tsx.
JSON files and GATEWAY_CONFIG_JSON can reference {env:NAME} to insert an environment variable, or {file:path} to insert a file’s trimmed contents. A file path resolves from the config file’s directory (or the current directory for GATEWAY_CONFIG_JSON), may start with ~/, and must stay inside that directory. A missing variable or file stops startup.
When layers merge, each providers entry merges key by key, so a later layer can add models to a provider an earlier layer configured. tracing and logger options merge one level deep; a logger instance replaces the earlier logger. Other keys are replaced by the later layer.
Every config option works in a config file. JSON files and GATEWAY_CONFIG_JSON hold only JSON values, so options that take a function, a Map, or an object instance need a .ts or .js file: hooks, catalog, tracer, a logger instance, pre-built provider instances, and function provider options such as azure.tokenProvider. A JSON catalog fails validation on startup.
Allow and deny lists
Filter the merged provider set without removing entries from the config itself.enabled_providers is an allow list — when set and non-empty, only those names survive. disabled_providers is a deny list, evaluated after the allow list. Both apply to built-in and custom provider names alike. An unknown name in either list fails validation.
Config options
createGateway, defineConfig, and config files accept these keys: