Single-binary AI router for AI coding tools.
Embedded dashboard · OpenAI-compatible API · auto-fallback across 40+ providers · ~20–40% input-token savings via RTK.
Install · Connect a CLI · Providers · Combos · For AI Agents · Configuration
OpenProxy runs as one binary on 127.0.0.1:4623. Point any tool that speaks the OpenAI Chat Completions API at it (Claude Code, Codex, Cursor, Cline, OpenClaw, Copilot, ...) and OpenProxy:
- routes the request to a provider you've configured (OAuth, API key, or free)
- falls back to the next provider in your combo when one is rate-limited or errors
- compresses tool-call results via RTK before they hit the LLM (typical −20–40% input tokens on tool-heavy turns)
- tracks per-account quota so you can use subscription tiers fully before paying for API calls
- serves a local dashboard at
/for configuration, monitoring, and account management
There is no cloud component required. All state lives in ~/.openproxy/db.json.
# Linux / macOS — x86_64 + aarch64
curl -fsSL "https://raw.githubusercontent.com/quangdang46/openproxy/main/install.sh" | bash
# Or via npm (any platform with Node 18+)
npm install -g @openprx/openproxyBoth pull the same prebuilt binary from the same GitHub release. The curl path drops the binary at ~/.local/bin/openproxy. The npm path uses optionalDependencies to install only the platform binary that matches your machine.
openproxyThe server binds to 127.0.0.1:4623 and the dashboard auto-opens in your browser. Use --no-open for headless / SSH / container contexts.
Other install options
# Pin a version
curl -fsSL "https://raw.githubusercontent.com/quangdang46/openproxy/main/install.sh" | bash -s -- --version v0.1.0
# Install system-wide (may need sudo)
curl -fsSL "https://raw.githubusercontent.com/quangdang46/openproxy/main/install.sh" | bash -s -- --system
# Add to PATH automatically (~/.bashrc / ~/.zshrc)
curl -fsSL "https://raw.githubusercontent.com/quangdang46/openproxy/main/install.sh" | bash -s -- --easy-mode
# Build from source (requires cargo + Node 20 + pnpm)
curl -fsSL "https://raw.githubusercontent.com/quangdang46/openproxy/main/install.sh" | bash -s -- --from-source
# Uninstall
curl -fsSL "https://raw.githubusercontent.com/quangdang46/openproxy/main/install.sh" | bash -s -- --uninstallManual download: https://github.com/quangdang46/openproxy/releases
Most tools ask for an OpenAI base URL and an API key.
| Tool | Setting | Value |
|---|---|---|
| Cursor / Cline / Continue / Roo / Kilo | OpenAI base URL | http://127.0.0.1:4623/v1 |
| Codex CLI | OPENAI_BASE_URL |
http://127.0.0.1:4623 |
| Claude Code | ~/.claude/config.json anthropic_api_base |
http://127.0.0.1:4623/v1 |
| OpenClaw | dashboard → CLI Tools → OpenClaw | one-click apply |
The API key comes from the dashboard. Visit http://127.0.0.1:4623, create an API key, paste it into the tool's settings.
Tested CLIs: Claude Code, Codex, Cursor, Cline, Continue, Roo, Kilo, Copilot, OpenClaw, OpenCode, Antigravity, Droid.
OpenProxy is built to be driven by AI agents (Devin, Claude Code, Codex, Cursor, OpenClaw, …) end-to-end — install, init, configure, and verify without any browser interaction.
A ready-to-use agent skill ships in this repo:
.agents/skills/openproxy/SKILL.md— install,server init,server start --detach, declarativeprovider apply, and wiring CLI tools.
The install.sh one-shot installer automatically drops the same file at ~/.agents/skills/openproxy/SKILL.md so agents that scan the home directory (Devin, Claude Code, …) pick it up the moment you install openproxy. The installer preserves any user-edited skill file (detected via the name: openproxy frontmatter marker) and exposes two flags:
--no-skill— skip the auto-install entirely.--skill-dest <dir>— write to a custom skills root (default:~/.agents/skills).
The CLI is agent-friendly by design:
--robotemits stable line-delimited JSON envelopes (openproxy.v1.*, frozen contract — additive only).openproxy schema list/schema show <resource>exposes the JSON shape for everyapply-able resource.openproxy provider apply --from-file -is declarative and idempotent (--pruneto reconcile).openproxy doctorself-tests the install, data dir, and server reachability.
Minimal autonomous bootstrap (no TTY, no browser, no prompts):
# 1. Install (drops binary at ~/.local/bin/openproxy)
curl -fsSL "https://raw.githubusercontent.com/quangdang46/openproxy/main/install.sh" | bash
export PATH="$HOME/.local/bin:$PATH"
# 2. Initialize data dir; capture the admin API key from the JSON envelope
openproxy --robot server init | tee /tmp/op-init.json
APIKEY=$(jq -r '.data.admin_key.key' /tmp/op-init.json)
# 3. Start server detached + headless, then self-test
openproxy server start --detach --no-open
openproxy --robot doctor
openproxy --robot server status
# 4. Configure a provider declaratively (idempotent)
cat > /tmp/providers.json <<JSON
{ "providers": [{ "name": "openai", "provider": "openai", "apiKey": "sk-...", "isActive": true }] }
JSON
OPENPROXY_API_KEY="$APIKEY" openproxy --robot provider apply --from-file /tmp/providers.json
# 5. End-to-end smoke test against the running server
curl -sS http://127.0.0.1:4623/health
curl -sS http://127.0.0.1:4623/v1/models -H "Authorization: Bearer $APIKEY"Full walkthrough — including failure modes, OAuth provider notes, and post-install verification — lives in .agents/skills/openproxy/SKILL.md.
Paste the block below into Devin, Claude Code, Codex, Cursor, OpenClaw, or any agent chat. It's a single self-contained instruction set — the agent will install OpenProxy, start it, and verify it works without asking further questions.
You are setting up OpenProxy (https://github.com/quangdang46/openproxy) on this
machine. OpenProxy is a single-binary AI router exposing an OpenAI-compatible
API on http://127.0.0.1:4623. Follow these steps exactly, stop on the first
error, and report the captured admin API key back to me at the end.
1. Check whether `openproxy` is already on PATH:
command -v openproxy && openproxy --version || echo "not installed"
If already installed, skip to step 3.
2. Install the binary. Pick ONE path:
a) Linux / macOS, x86_64 or aarch64 (preferred):
curl -fsSL "https://raw.githubusercontent.com/quangdang46/openproxy/main/install.sh" | bash
export PATH="$HOME/.local/bin:$PATH"
b) Any platform with Node >= 18 (use if (a) fails or on Windows):
npm install -g @openprx/openproxy
3. Initialize a data dir and capture the admin API key. Use --robot so the
output is JSON; never re-run with --force without my explicit approval:
openproxy --robot server init | tee /tmp/op-init.json
APIKEY=$(jq -r '.data.admin_key.key' /tmp/op-init.json)
export OPENPROXY_API_KEY="$APIKEY"
If `server init` reports `db.json already exists`, STOP and tell me — the
data dir is pre-populated and I need to decide whether to overwrite.
4. Start the server detached and headless, then self-test:
openproxy server start --detach --no-open
openproxy --robot server status
openproxy --robot doctor
5. Verify end-to-end:
curl -sS http://127.0.0.1:4623/health
curl -sS http://127.0.0.1:4623/v1/models \
-H "Authorization: Bearer $OPENPROXY_API_KEY"
6. Report back to me:
- The exact `openproxy --version` output.
- The admin API key (value of $OPENPROXY_API_KEY).
- Result of step 4's `server status` and `doctor`.
- Any non-2xx response from step 5.
Do NOT run `openproxy server init --force`, do NOT delete ~/.openproxy/, and
do NOT add provider API keys unless I gave you values explicitly. If you hit
the failure modes documented in
https://github.com/quangdang46/openproxy/blob/main/.agents/skills/openproxy/SKILL.md
("Common failure modes & fixes"), apply the listed fix; otherwise stop and ask.
The same instructions in machine-readable form live at .agents/skills/openproxy/SKILL.md — agents that auto-discover .agents/skills/ (Devin, etc.) will pick them up without any copy-paste.
| Tier | Provider | Auth | Notes |
|---|---|---|---|
| OAuth subscription | Claude Code, Codex, GitHub Copilot, Cursor, Antigravity | OAuth (PKCE) | Use your existing subscription quota. Auto-refresh. |
| API key | OpenAI, Anthropic, Gemini, OpenRouter, GLM, Kimi, MiniMax, DeepSeek, Groq, xAI, Mistral, Perplexity, Together, Fireworks, Cerebras, Cohere, NVIDIA, SiliconFlow, Nebius, Chutes, Hyperbolic, custom OpenAI/Anthropic-compatible endpoints | API key | 40+ supported. |
| Free | Kiro AI (Claude 4.5 + GLM-5 + MiniMax), OpenCode Free, Vertex AI ($300 trial credits) | OAuth / no auth / GCP service account | Best for fallback tiers. |
Configure providers from the dashboard (Providers tab) or via openproxy provider CLI subcommands. Each provider supports multiple accounts; OpenProxy round-robins between them.
A combo is an ordered list of models. OpenProxy tries them in order, falling back when one is rate-limited or errors. Models are addressed as <provider-prefix>/<model-id>:
combo: my-stack
1. cc/claude-opus-4-7 # Claude Pro/Max subscription
2. glm/glm-4.7 # paid backup ($0.6/1M)
3. kr/claude-sonnet-4.5 # Kiro free fallback
Created from Combos in the dashboard or openproxy combo create. Use the combo name as the model field in your CLI tool — OpenProxy resolves it.
Most operators only set JWT_SECRET and INITIAL_PASSWORD and leave the rest at defaults.
| Variable | Default | Purpose |
|---|---|---|
JWT_SECRET |
openproxy-default-secret-change-me |
Sign the dashboard session cookie. Change in production. |
INITIAL_PASSWORD |
123456 |
First-login password (one-time, replaced on first save). |
DATA_DIR |
~/.openproxy |
Where db.json, usage.json, log.txt live. |
PORT |
4623 |
HTTP listen port. |
HOSTNAME |
127.0.0.1 |
Bind host. Set 0.0.0.0 to expose on LAN. |
BASE_URL |
http://localhost:4623 |
Internal base URL for cloud-sync jobs. |
CLOUD_URL |
unset | Cloud-sync endpoint. Leave unset to disable cloud sync. |
API_KEY_SECRET |
endpoint-proxy-api-key-secret |
HMAC secret for generated API keys. |
MACHINE_ID_SALT |
endpoint-proxy-salt |
Salt for the stable machine-ID hash. |
AUTH_COOKIE_SECURE |
false |
Force Secure flag on the auth cookie. Set true behind HTTPS. |
REQUIRE_API_KEY |
false |
Reject /v1/* requests without Authorization: Bearer …. Recommended for any internet-exposed deploy. |
ENABLE_REQUEST_LOGS |
false |
Write per-request logs under logs/. |
HTTP_PROXY, HTTPS_PROXY, NO_PROXY |
unset | Forward outbound provider calls through an HTTP proxy. Lowercase variants also honored. |
openproxy [FLAGS] # default: start server + open browser
openproxy --port 4623 --no-open # foreground, no browser
openproxy --web-dir ./web/dist # serve dashboard from disk (UI dev)
openproxy --dashboard-sidecar-url http://127.0.0.1:4624
# reverse-proxy dashboard requests to a dev server
openproxy --version
openproxy provider list
openproxy provider add <name> '<json-config>'
# e.g. openproxy provider add openai-paid \
# '{"provider":"openai","apiKey":"sk-..."}'
openproxy combo create --name <name> --models cc/opus,glm/glm-5
openproxy key list
openproxy key add <name> <secret> # provide your own secret
openproxy key add <name> --auto # let openproxy mint a fresh `op-…` secret
openproxy quota list # subcommands: list / get / reset / refresh
openproxy usage summary # subcommands: summary / daily / chart / history / …
openproxy doctor # diagnose common config issues
openproxy server start [--detach] [--no-open] [--port P]
openproxy server status
openproxy server stop
openproxy server init # mint the first admin API key
openproxy --help prints the full reference. Subcommands have their own --help.
Output formats: human (default), --robot (line-delimited JSON for agent/automation use), --quiet.
OpenAI-compatible chat completions:
POST /v1/chat/completions
Authorization: Bearer <api-key>
Content-Type: application/json
{
"model": "cc/claude-opus-4-6",
"messages": [{"role": "user", "content": "..."}],
"stream": true
}List available models and combos:
GET /v1/models
Authorization: Bearer <api-key>Health probe (no auth):
GET /health → 200 OKThe dashboard at / is the same authenticated API surface in HTML form. Admin endpoints live under /api/* and use the dashboard session cookie.
┌─────────────────────────────────────────────┐
│ openproxy (single binary, port 4623) │
│ │
│ / embedded web dashboard │
│ (Astro static via rust-embed)│
│ │
│ /v1/* OpenAI-compatible API │
│ /api/* admin / dashboard data │
│ /codex/* Codex OAuth helper │
│ │
│ RTK token compression ─┐ │
│ format translation ─┤ │
│ quota tracking ─┼─→ provider HTTP │
│ account fallback ─┘ │
└─────────────────────────────────────────────┘
│
↓
[ provider APIs: Anthropic, OpenAI, GLM, ... ]
Stack: Rust 1.76+, axum 0.8, hyper 1, rusqlite (bundled), Astro 4 (static, embedded), React 19, Tailwind. Storage: db.json + SQLite.
Requires Node ≥ 20.3 and pnpm (corepack enable && corepack prepare pnpm@10.33.2 --activate, or npm i -g pnpm).
git clone https://github.com/quangdang46/openproxy.git
cd openproxy
pnpm --dir web install
pnpm --dir web run build
cargo build --release --locked
./target/release/openproxyUI iteration without rebuilding the binary:
pnpm --dir web run build
cargo run -- --web-dir ./web/distUI live-reload via the Astro dev server:
# Terminal 1
pnpm --dir web run dev # → http://127.0.0.1:4624
# Terminal 2
cargo run -- --dashboard-sidecar-url http://127.0.0.1:4624Headless build (no embedded dashboard, smaller binary):
cargo build --release --locked --no-default-features
# Requires --web-dir or --dashboard-sidecar-url at runtime.Pull the prebuilt image (published to GHCR by the release pipeline):
docker run -d \
--name openproxy \
-p 4623:4623 \
-v openproxy-data:/app/data \
ghcr.io/quangdang46/openproxy:latestOr build locally:
docker build -t openproxy .
docker run -d \
--name openproxy \
-p 4623:4623 \
--env-file ./.env \
-v openproxy-data:/app/data \
openproxyContainer defaults: HOSTNAME=0.0.0.0, PORT=4623, DATA_DIR=/app/data. The dashboard is embedded — no separate volume needed for it. Mount /app/data to persist db.json, usage.json, and request logs across container restarts.
First-time pulls from GHCR for this repo may require the package to be set to public at https://github.com/quangdang46/openproxy/pkgs/container/openproxy.
For internet-exposed deploys: set REQUIRE_API_KEY=true, AUTH_COOKIE_SECURE=true, terminate TLS at the proxy, and forward only /v1/* if you don't need the dashboard accessible publicly.
| Symptom | Cause | Fix |
|---|---|---|
EADDRINUSE on 4623 |
Port in use | openproxy --port 4624 or openproxy server stop |
| Dashboard shows blank page | Embedded asset not hashed correctly | Hard reload (Ctrl+Shift+R); check /health returns 200 |
| OAuth "callback failed" | Browser blocked the redirect | Retry from the dashboard's Providers → Reconnect |
401 on /v1/chat/completions |
Wrong API key | Copy fresh from dashboard. Header: Authorization: Bearer <key> |
| Quota exhausted message | Subscription / API limit hit | Combo fallback handles this — add a cheaper or free tier as the next entry |
cargo build fails with "web/dist not built" |
Embedded build needs the dashboard | (cd web && pnpm install --frozen-lockfile && pnpm run build) first |
| First login password rejected | INITIAL_PASSWORD not what you set |
Default is 123456 if unset; check .env is sourced |
Logs: enable with ENABLE_REQUEST_LOGS=true, then watch logs/ (or stderr).
Built on the work of others:
- CLIProxyAPI — Go implementation that inspired the architecture.
- RTK — token compression pipeline. OpenProxy's
tool_resultcompression is a port. - Caveman — caveman-speak prompt that trims output tokens by reframing the system instruction.
MIT — see LICENSE.