benes is a Go proxy on loopback. Codex, Claude Code, Claude Desktop, Grok Build, and other clients keep their own interfaces; the listener on 127.0.0.1:23100 accepts OpenAI Responses, Anthropic Messages, and Chat Completions, and internal/router decides which provider answers.
npm install -g @wibias/benes
benes start # data plane plus dashboard on 127.0.0.1:23100Default bind is 127.0.0.1:23100; state lives under ~/.benes unless BENES_HOME points elsewhere. The listener does not rewrite Codex config unless you ask it to: benes start leaves config.toml alone, --inject or benes sync writes the routing, and benes stop puts the native file back from the injection journal.
- Route anything you configured.
provider/modelselects a candidate up front; a bare id uses the default provider or a name match. Inner slashes in upstream ids are published with-as well, and the raw slash form still works. Model ids - Pool ChatGPT accounts. The
openaipreset can hold several accounts. A new session takes a healthy one and normally keeps it; quota pressure, fail-closed auth, and 401/403/429 recovery can rebind.openai-apikeynever joins the pool. - Combos are failover. A combo id expands to an ordered target list, and the projector walks it until one succeeds. Omitting the strategy means failover; anything else is rejected as
unsupported_strategy. Combos - OAuth or a pasted key.
benes loginruns the flows that need a browser. Key presets take a secret. Durable config writes are transactional, and the mutation log stores rows with secrets stripped. - Sidecars stay optional. Web search and vision live under
internal/sidecarand are off until a configuration enables them. Sidecars - Spawn roster.
benes agent subagentsandbenes v2decide which models Codex may spawn, including fallback chains. Sub-agents - Clients launch against the same port.
benes claude,benes grok,benes opencode(the third-party OpenCode client, not this project),benes mcode,benes zcode, plusbenes exportfor a client config. - Undo.
benes stopandbenes restoreput Codex back from the injection journal.
npm install -g @wibias/benes # Node 18+ and Go 1.27.0; the launcher execs the Go CLI
benes start # or `benes service` to keep it running in the backgroundOpen http://127.0.0.1:23100 and configure providers, models, and accounts in the dashboard. benes gui reopens it at any time, and starts the listener if it is not running.
Run from source
git clone https://github.com/Wibias/Benes.git
cd Benes
go run ./cmd/benes startThe same commands work on Windows in PowerShell. A source checkout runs the current tree; the npm tarball is the released CLI plus the built dashboard from gui/dist.
npm install -g @wibias/benes
benes start # or `benes service`
benes init # writes ~/.benes/config.json, may inject Codex, never starts the listenerbenes init and benes start can run in either order. Live verbs — benes provider add, benes combo set, and friends — talk to the running process and fail when it is unreachable. benes status, benes health, and benes ready --wait report liveness and post-sync readiness.
Installing or running benes as an agent? Read For agents first. An interactive
benes startmay print one dim line about starring this repository: that decision belongs to the user, and the CLI suppresses the prompt for agent-driven runs.POST /api/github/starwithout a dashboard session is403 consent_required.
Boards cover the fleet (providers and their access lanes), models and visibility, routing and combos, harnesses, sub-agents, sessions, usage, diagnostics, storage, and the API surface. Everything the dashboard shows comes from the same state the CLI uses, over loopback /api/*. Dashboard
benes sync (or benes start --inject) writes routing into the resolved Codex home, so Codex CLI, the TUI, the app, and SDK clients share one injected configuration, and the routed models appear in the model picker next to native ones. BENES_SKIP_CODEX_INJECT=1 skips injection even when --inject is passed. benes restore undoes the Codex side without a running proxy, and benes stop restores it as part of shutting down. Codex
codex -m "anthropic/claude-sonnet-4-6" "summarize this diff"
codex -m "google/gemini-2.5-pro" "write tests for auth.go"
codex -m "ollama/llama3" "refactor this function"GET /v1/models keeps the OpenAI list shape and adds capability metadata (context window, tool use, vision, reasoning ladders) from the same catalog state that routing uses. Unknown values are omitted rather than guessed. Model ids
internal/server/provider_presets.json ships 81 presets: OpenAI (ChatGPT login or API key), Anthropic, Google Gemini, xAI, Kimi, Azure OpenAI, Ollama local and Cloud, Cursor, and the OpenAI-compatible long tail. Any other endpoint can be added with its own base URL. Providers
GET /healthz answers immediately when the process is alive. GET /readyz answers with a sanitized identity (service, version, uptime, pid, port, status): 200 once status is ready, and 503 with Retry-After: 1 while it is pending or terminally failed. Neither route is authenticated, and neither exposes more than that.
benes ready probes once; --wait polls for up to 45 seconds by default and exits immediately on a terminal failed; --timeout <seconds> (1–300, requires --wait) bounds it. --json prints {ready, status, pid, port}.
| Exit | Meaning |
|---|---|
0 |
Ready |
1 |
Not ready: pending, failed, timeout, or unreachable |
64 |
Invalid arguments |
A listener too old to serve /readyz fails closed as unreachable with exit 1, while benes health keeps working.
benes service installs a listener that starts at login and restarts on crash — a launchd user agent on macOS, a systemd user unit on Linux, and Task Scheduler on Windows (benes service install --native uses WinSW instead). benes codex-shim install starts the listener the first time codex launches, with no daemon at all. Remove either with its uninstall verb. Install
127.0.0.1 is the default hostname. Setting "hostname": "0.0.0.0" makes the process refuse to start unless BENES_API_AUTH_TOKEN is set, and every client then sends that value as x-benes-api-key. Config
benes init # durable config, optional Codex routing and shim
benes start [--port] [--inject|--no-inject]
benes stop # pid-file stop, then restore native Codex
benes service [status|start|stop|install|uninstall|repair]
benes codex-shim [status|install|uninstall|remove]
benes status # proxy state and Codex routing, separately
benes health | ready [--wait] # liveness and post-sync readiness
benes gui | dev # dashboard, or Vite HMR on 23200
benes provider | models | agent | combo | alias | route | access | client | export
benes doctor # local snapshot
benes update # prints the update policy; never mutates the installAn unpinned start may hop to another free port when 23100 is taken; an explicit --port never hops. CLI reference
The public site is built from docs/; start at Install. Contributor setup is in CONTRIBUTING.md, the PR contract in docs/src/content/docs/contributing/pr-quality.md, and security reports go through private reporting as described in SECURITY.md.
git clone https://github.com/Wibias/Benes.git
cd Benes
go test ./...
go vet ./...
npm run build:guibenes is an independent project. OpenAI, Anthropic, and the other vendors it can route to did not build or endorse it.
Some vendors — Anthropic among them — may restrict accounts that send API traffic through another process. Read the terms that apply to your account before connecting it, and treat the decision as yours. The Benes maintainers are not responsible for actions an upstream provider takes against an account.
MIT