Skip to content

quangdang46/openproxy

Repository files navigation

OpenProxy

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.

CI GitHub release npm License: MIT Install

Install · Connect a CLI · Providers · Combos · For AI Agents · Configuration


What it does

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.


Install

# 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/openproxy

Both 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.

openproxy

The 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 -- --uninstall

Manual download: https://github.com/quangdang46/openproxy/releases


Connect a CLI tool

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.


For AI Agents

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:

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:

  • --robot emits stable line-delimited JSON envelopes (openproxy.v1.*, frozen contract — additive only).
  • openproxy schema list / schema show <resource> exposes the JSON shape for every apply-able resource.
  • openproxy provider apply --from-file - is declarative and idempotent (--prune to reconcile).
  • openproxy doctor self-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.

Copy-paste prompt for your AI agent

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.


Supported providers

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.


Combos: build a fallback chain

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.


Configuration

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.

CLI reference

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.


API

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 OK

The dashboard at / is the same authenticated API surface in HTML form. Admin endpoints live under /api/* and use the dashboard session cookie.


Architecture

┌─────────────────────────────────────────────┐
│ 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.


Build from source

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/openproxy

UI iteration without rebuilding the binary:

pnpm --dir web run build
cargo run -- --web-dir ./web/dist

UI 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:4624

Headless build (no embedded dashboard, smaller binary):

cargo build --release --locked --no-default-features
# Requires --web-dir or --dashboard-sidecar-url at runtime.

Deployment

Docker

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:latest

Or build locally:

docker build -t openproxy .
docker run -d \
  --name openproxy \
  -p 4623:4623 \
  --env-file ./.env \
  -v openproxy-data:/app/data \
  openproxy

Container 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.

Behind a reverse proxy

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.


Troubleshooting

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).


Acknowledgments

Built on the work of others:

  • CLIProxyAPI — Go implementation that inspired the architecture.
  • RTK — token compression pipeline. OpenProxy's tool_result compression is a port.
  • Caveman — caveman-speak prompt that trims output tokens by reframing the system instruction.

License

MIT — see LICENSE.

About

Smart AI proxy router that connects Claude Code, Cursor, Codex, Copilot, and 50+ coding tools to 40+ AI providers with 100+ models. Saves 20-40% tokens via RTK compression, auto-fallback from subscription to cheap to free providers, multi-account round-robin, and a local dashboard.

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors