| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Original HTTPS Page] |
Prevent this user from interacting with your repositories and sending you notifications. Learn more about blocking users.
You must be logged in to block users.
Contact GitHub support about this user’s behavior. Learn more about reporting abuse.
Report abuseRun Claude Code (or any AI CLI) on any provider — a free, self-hosted LLM gateway in one binary that speaks four wire protocols, fails over across providers, pools upstream keys, and ships with a multi-user admin console.
English · 简体中文
Quick start · Protocols · Cost optimization · Documentation · Contributing
⚡ Low-overhead streaming proxy · 🔀 Any protocol in, any protocol out · 🆓 Free & open-source · 📦 Single binary, zero external deps · 🔁 Automatic failover + key pool · 👥 Multi-user with SSO · 💰 Cost analytics & optimization
Point your application at one endpoint and one API key. Yolorouter sits between your apps and your upstream providers, so the messy parts live in one place instead of scattered across every codebase: juggling provider accounts, rotating rate-limited keys, failing over when an account breaks, enforcing per-key budgets, and knowing what everything costs.
It accepts four wire protocols (OpenAI Chat Completions, OpenAI Responses, Anthropic Messages, and Gemini generateContent) and can translate any of them to any other on the way out. An OpenAI-only provider can serve Claude Code; an Anthropic-only provider can serve the OpenAI SDK. Streaming, tool calling, and reasoning/thinking blocks all survive the trip, as does image content on every ingress except Responses (see Protocols).
Everything ships as a single binary with the web console embedded. There is no Node runtime to install and no separate frontend deploy. SQLite works out of the box; switch to PostgreSQL when you want it.
Routing
Control & cost
docker run -d --name yolorouter --restart unless-stopped \
-p 8080:8080 -v "$PWD/yolorouter:/yolorouter" \
ghcr.io/yolorouter/yolorouter:latestOr grab docker-compose.yml and run docker compose up -d. Images are published for amd64 and arm64 with every release.
Everything the container writes lives in the one mounted folder: the generated configs/config.yaml (including the key that encrypts your upstream keys) and the SQLite database. Back up that folder and you have backed up the deployment.
Upgrading with docker compose:
docker compose pull # download the newest image; the running container is untouched
docker compose up -d # recreate the container on the new image (does nothing if already newest)Upgrading with plain docker run takes three steps. This is safe because a container's filesystem is disposable by design: none of your state lives inside the container — config and database sit in the mounted folder on the host and survive the container being deleted.
# 1. Download the newest image. The running container keeps serving meanwhile —
# this only fetches bytes to the local image store.
docker pull ghcr.io/yolorouter/yolorouter:latest
# 2. Stop and delete the old container. Your data is NOT in it: everything
# lives in the mounted folder on the host and stays put.
docker rm -f yolorouter
# 3. Start a new container — the exact same command as the first run, mounting
# the same folder. It picks up the image pulled in step 1.
docker run -d --name yolorouter --restart unless-stopped \
-p 8080:8080 -v "$PWD/yolorouter:/yolorouter" \
ghcr.io/yolorouter/yolorouter:latestTwo details worth knowing:
No Docker, or want the built-in self-updater? Install as a background service that starts on boot: systemd on Linux, launchd on macOS, a scheduled task on Windows.
# Linux / macOS
curl -fsSL https://get.yolorouter.com/install.sh | bash# Windows, PowerShell 5.1+
irm https://get.yolorouter.com/install.ps1 | iexOn Windows, an elevated PowerShell installs a system-wide service that starts at boot; a normal one installs under your account and starts at logon.
🇨🇳 China mirror: if GitHub is slow or unreachable from your network, swap get.yolorouter.com for gh.yolorouter.com. Same installers, routed through a Cloudflare proxy, and auto-updates keep using the mirror afterwards.
Re-run the same command to upgrade; configuration and database are preserved and the database is backed up first. Prefer a plain binary? Grab a release and run ./yolorouter serve (.\yolorouter.exe serve on Windows).
Whichever way you start it, the first run generates configs/config.yaml, applies migrations and starts the console on port 8080. Create the first admin account, then follow the guided flow: add a provider with its upstream key — the console then fetches that provider's model catalogue so you can import the models you want in one click. Each imported model is verified against the real upstream in the background and enabled automatically once it passes. Finally, issue an API key and start calling.
→ Full installation guide for every platform, including building from source: yolorouter.com/help?p=self-hosted/installation
Every ingress below authenticates with the same Yolorouter API key, supports streaming, and can be served by any configured provider, no matter which protocol that provider natively speaks.
| Ingress route | Protocol | Accepted auth headers |
|---|---|---|
| POST /v1/chat/completions | OpenAI Chat Completions | Authorization: Bearer, X-Api-Key |
| POST /v1/responses | OpenAI Responses | Authorization: Bearer, X-Api-Key |
| POST /v1/messages | Anthropic Messages | Authorization: Bearer, X-Api-Key |
| POST /v1beta/models/{model}:generateContent POST /v1beta/models/{model}:streamGenerateContent |
Gemini | x-goog-api-key, ?key=, Authorization: Bearer, X-Api-Key |
| GET /v1/models, GET /v1/models/{model} | Model discovery | Authorization: Bearer, X-Api-Key |
The model in every request is the public name you configured. Yolorouter picks a provider candidate, swaps in the real upstream model id, and keeps your public name in the response.
Known limitation: input_image entries on the Responses ingress are dropped when the request has to be translated to a different egress protocol; only text is forwarded. Same-protocol passthrough is unaffected, and image content translates correctly on the other three ingresses.
Because the ingresses are the real native protocols, official SDKs and agent tools need two settings changed and no adapter layer:
# OpenAI Python SDK
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8080/v1", api_key="sk-yr-your-key")
print(client.chat.completions.create(
model="smart",
messages=[{"role": "user", "content": "Hello!"}],
).choices[0].message.content)# Claude Code — routed through Yolorouter to whichever provider you configured
export ANTHROPIC_BASE_URL=http://localhost:8080
export ANTHROPIC_AUTH_TOKEN=sk-yr-your-key
claude→ Per-protocol request examples and setup guides for 19 agent tools (Claude Code, Cursor, Codex CLI, Cherry Studio, Gemini CLI, opencode …): yolorouter.com/help
Every model routes through an ordered list of provider candidates; its scheduling mode decides which candidate a request enters first.
Everything else — failure handling, key rotation, circuit breaking, budgets — is identical in both modes.
Known limitation: bindings live in process memory. A restart simply reassigns keys (converging back to the same even spread), and in a multi-instance deployment each instance computes its own spread — there is no cross-instance binding table. During a rolling upgrade from a version without scheduling modes, not-yet-upgraded instances run every model as failover — switch a model to balanced after the whole fleet is upgraded. The binding table holds up to 4096 (key, model) pairs across all models; beyond that, the least-recently-used binding is evicted and its key reassigned on its next request, so extremely wide deployments (hundreds of keys times dozens of balanced models) trade some stickiness at the margin.
Both features are off by default, configured globally in the console, and overridable per API key.
Custom system prompt injection. Append house rules to every request's system prompt without touching client code. The injection follows the caller's own protocol shape and is deterministic, so repeated requests produce byte-identical system content and still hit upstream prompt caches. The console's projected savings for this feature are backed by a published paired on/off benchmark — the method and all 150 raw measurement pairs live in docs/concise-output-benchmark.md.
Input compression. Coding agents send back huge, highly redundant tool output. Yolorouter recognizes what each content block is (go test output, git diffs, grep results, plain logs) and strips the noise while keeping the signal: failures, stack traces, and each distinct match all survive. It never touches the active edit region at the tail of the conversation, and only replaces a block when the compressed form is actually shorter.
Cache-read and cache-write tokens are metered and priced separately throughout the dashboard, so prompt-cache savings are a number you can see rather than a feeling.
→ Details and tuning: yolorouter.com/help?p=self-hosted/configuration
| Topic | Link |
|---|---|
| Installation (all platforms, from source) | Installation |
| Every config.yaml field and the CLI | Configuration |
| Upgrading, rolling back, uninstalling | Updating |
| Layering, protocol IR, storage | Architecture |
| API reference and model catalogue | Docs home |
Self-hosting means bringing your own upstream API keys. If you would rather not sign up with every provider separately, YoloRouter Cloud ships in the console's provider preset list as one more upstream you can select; see the hosted option.
Requires Go 1.25.7+ and Node.js 22.12+.
make build # backend only -> ./bin/yolorouter
make build-embed # full binary with the console embeddedOne script rebuilds everything, runs migrations, and restarts a local server:
./scripts/dev.sh # full rebuild + restart on http://localhost:8080
./scripts/dev.sh --backend # Go changes only; --frontend for console changes
tail -f logs/server.log # server log — the first place to look when debuggingConfiguration lives in configs/config.yaml and the SQLite database in data/yolorouter.db, both created on first run. For request-level debugging, the console's request-log detail page shows every relay's full client and upstream bodies plus the per-attempt routing chain.
For frontend work, skip the rebuild loop entirely. Vite serves the console with hot reload on port 5173 and proxies /api and /v1 to the backend:
cd frontend && npm run devmake test runs the Go tests, make gates the structural checks that CI enforces. Windows scripts (scripts/dev.ps1), lint, and cross-compilation targets are documented in CONTRIBUTING.md.
Issues and pull requests are welcome. Please read CONTRIBUTING.md and the Code of Conduct first. For security reports see SECURITY.md.
Licensed under the Apache License 2.0.
A self-hosted, OpenAI-compatible LLM gateway with multi-provider failover, key rotation, and a built-in admin console.
Transport-layer data masking for deepseek-harness (dsh): the model sees placeholders, you see real values restored live in the stream.
TypeScript 1
A Go library that masks PII/secrets before they reach an LLM and restores them in the response
Go
dualkit — Open-source Rust dual-mode application scaffolding: one codebase, two forms – desktop GUI and headless service.
Rust
A PHP library that masks sensitive data before it reaches an LLM, and restores it afterward — so the model, the network, and the vendor's logs never see the real values.
PHP
LLMasking TypeScript engine — mask sensitive data before it reaches an LLM, restore it after (SSE-safe). Zero runtime dependencies.
TypeScript
| Back | FazBrowse Home | New Git URL |