keyrouter
Health Warn
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 5 GitHub stars
Code Fail
- child_process — Shell command execution capability in .github/workflows/docker-publish.yml
- exec() — Shell command execution in .github/workflows/docker-publish.yml
- process.env — Environment variable access in .github/workflows/docker-publish.yml
- fs module — File system access in .github/workflows/docker-publish.yml
- process.env — Environment variable access in .github/workflows/publish-cli.yml
- fs module — File system access in .github/workflows/tray-binaries.yml
- child_process — Shell command execution capability in cli/cli.js
- execSync — Synchronous shell command execution in cli/cli.js
- exec() — Shell command execution in cli/cli.js
- fs.rmSync — Destructive file system operation in cli/cli.js
- os.homedir — User home directory access in cli/cli.js
- process.env — Environment variable access in cli/cli.js
- fs module — File system access in cli/cli.js
- process.env — Environment variable access in cli/hooks/postinstall.js
- child_process — Shell command execution capability in cli/hooks/sqliteRuntime.js
- spawnSync — Synchronous process spawning in cli/hooks/sqliteRuntime.js
- os.homedir — User home directory access in cli/hooks/sqliteRuntime.js
- process.env — Environment variable access in cli/hooks/sqliteRuntime.js
- fs module — File system access in cli/hooks/sqliteRuntime.js
- child_process — Shell command execution capability in cli/hooks/trayRuntime.js
- spawnSync — Synchronous process spawning in cli/hooks/trayRuntime.js
- fs.rmSync — Destructive file system operation in cli/hooks/trayRuntime.js
- os.homedir — User home directory access in cli/hooks/trayRuntime.js
- fs module — File system access in cli/hooks/trayRuntime.js
- child_process — Shell command execution capability in cli/scripts/build-cli.js
- execSync — Synchronous shell command execution in cli/scripts/build-cli.js
- exec() — Shell command execution in cli/scripts/build-cli.js
- fs.rmSync — Destructive file system operation in cli/scripts/build-cli.js
- process.env — Environment variable access in cli/scripts/build-cli.js
- fs module — File system access in cli/scripts/build-cli.js
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
One endpoint for every AI you already pay for — self-hosted router for Claude Code, Codex, Cursor & 40+ providers.
KeyRouter
One endpoint. Every AI you already pay for. Zero wasted tokens.
⚡ Quick Start · 🎯 Which install path? · 🔌 Connect a tool · ✨ Features · 🛠 CLI · ❓ FAQ
📌 At a glance
| What it is | A self-hosted router that sits between your AI coding tools and 40+ providers (100+ models) |
| Install | npm i -g keyrouter — no account, no signup, no cloud lock-in |
| Endpoint | http://localhost:20131/v1 — speaks OpenAI and Claude API |
| Runs on | Node.js ≥ 22.23 (24 LTS recommended) · Linux · macOS · Windows · Docker amd64/arm64 |
| Data | 100% local in ~/.keyrouter (SQLite) — keys, logs, usage never leave your machine |
| Cost for the router itself | Free, MIT-licensed. You keep paying (or not paying — free tiers work) your providers |
[!TIP]
60-second try:npx keyrouter→ dashboard opens → Providers → Kiro AI (free Claude, no login) → point Claude Code athttp://localhost:20131/v1. That's it — you're routing.
# 1. route-all-the-things in one line
npx keyrouter
# 2. wire the CLI tools on this machine to it (backs up configs once as *.bak-keyrouter)
npx keyrouter connect http://localhost:20131 --tools claude,codex,cline
# 3. see what it changed
keyrouter show claude
🚀 Quick Start
Option 1 · npm (desktop, recommended)
npm install -g keyrouter
keyrouter
# → dashboard at http://localhost:20131 (default password: 123456 — change it)
Or skip the install entirely: npx keyrouter
Option 2 · Docker (server / VPS)
docker run -d --name keyrouter \
-p 20131:20131 \
-v "$HOME/.keyrouter:/app/data" \
-e DATA_DIR=/app/data \
keyzakyy/keyrouter:latest
Images for amd64 + arm64 on Docker Hub and GHCR. Version pinning, tags, and upgrades: DOCKER.md.
Option 3 · from source
git clone https://github.com/keyzakyy-dev/keyrouter.git
cd keyrouter && cp .env.example .env
npm install && npm run build
npm run start
Full contributor setup (tests, lint, dev server on :20127): docs/ARCHITECTURE.md.
🤔 Which install path do I need?
| You are… | Use | Why |
|---|---|---|
| Coding on a laptop/desktop | npm (Option 1) | Auto-updates itself, tray icon, zero config |
| Deploying on a VPS/homelab | Docker (Option 2) | Persistent volume, restart policy, arm64 OK |
| Hacking on the router itself | source (Option 3) | Dev server, hot reload, tests |
| Just testing once | npx keyrouter |
Nothing installed, throwaway |
🔌 Connect a tool in 3 lines
Every tool that speaks the OpenAI or Claude API works out of the box:
Endpoint : http://localhost:20131/v1
API Key : (copy from the dashboard → API Keys)
Model : kr/claude-sonnet-4.5
Or let KeyRouter write the configs for you — it backs up each tool's file once as *.bak-keyrouter:
npx keyrouter connect http://localhost:20131 # pick tools interactively
npx keyrouter connect http://localhost:20131 --tools claude,codex # choose in advance
npx keyrouter connect --reset --tools claude,codex # undo
Supported tools for keyrouter connect (click to expand)
claude · codex · opencode · droid · crush · kilo · cline · pi · omp · all
Cursor and other GUI tools: paste the endpoint + key manually per the table above.
🧠 Why KeyRouter?
The problem you already have:
- Subscription quotas expire monthly, even unused.
- Rate limits hit mid-task; you wait or switch manually.
git diff/grep/lsoutput burns input tokens on every turn.- Every provider = another key, endpoint and config to babysit.
KeyRouter's answers:
| 🔥 RTK Token Saver | Compresses tool output before it reaches the model — 20–40% fewer input tokens per request |
| 🪜 3-tier fallback | Subscription → cheap (GLM, MiniMax) → free (Kiro, OpenCode Free), automatically, mid-request |
| 📊 Quota tracking | Know what's left on every subscription; drain it before it resets |
| 👥 Multi-account | Several accounts per provider, load-spread |
| 🔁 Auto token refresh | OAuth stays alive in the background; no re-login marathons |
| 🎛 Custom combos | Unlimited kr/* model mixes with your own routing strategy |
📸 Screenshots
| Endpoint — base URL, remote access tunnel & API keys | Providers — 40+ providers, multi-account with live status |
![]() |
![]() |
CLI — one-shot keyrouter connect wires 9 coding tools |
Prompt Injection — global, per-key, and chat-script variants |
![]() |
![]() |
🗺 How it works
┌──────────────────┐
│ Your CLI tool │ Claude Code, Codex, Cursor, Cline, Droid, Crush…
└────────┬─────────┘
│ http://localhost:20131/v1
▼
┌─────────────────────────────────────────────┐
│ KeyRouter (router) │
│ 1. Auth your API key (+ per-key access) │
│ 2. RTK Token Saver compresses tool output │
│ 3. Translate format: OpenAI ↔ Claude ↔ │
│ Gemini ↔ Kiro ↔ Vertex ↔ Cursor │
│ 4. Log, meter and fall back as needed │
└────────┬────────────────────────────────────┘
│
├─→ Tier 1: subscription (Claude, Codex, Copilot)
├─→ Tier 2: cheap (GLM, MiniMax, …)
└─→ Tier 3: free (Kiro, OpenCode Free, Vertex, …)
Deep dive (executors, streaming, OAuth flows, DB schema): docs/ARCHITECTURE.md. Full docs site: gitbook/content/en/.
✨ Features
| Area | What it does | Why it matters |
|---|---|---|
| RTK Token Saver | Compresses git diff, grep, ls and friends in-place |
20–40% cheaper requests, fail-open (never breaks your call) |
| Format translation | OpenAI ↔ Claude ↔ Gemini ↔ Kiro ↔ Vertex ↔ Cursor | One endpoint into any CLI tool |
| Usage analytics | Tokens, cost, latency per request — filterable, exportable | See exactly where money goes |
| Per-key model access | Restrict each API key to specific combos and models | Share the endpoint without exposing every provider |
| Prompt injection | System prompts / chat scripts per key, model or global | Router-level personas, no tool config needed |
| Proxy pools | Health checks, rotation, dead-pool cleanup | Keeps big key fleets alive |
| Request log | Live console with per-request detail and redaction | Debug any call in seconds |
| Update button | In-dashboard "update available" with copy-install command | No surprise versions |
🛠 CLI
keyrouter # start with defaults
keyrouter --port 8080 # custom port
keyrouter --no-browser # don't open the dashboard
keyrouter --skip-update # skip the auto-update check
keyrouter show claude # inspect a tool's config (try --json)
keyrouter connect --help # remote-connect options
keyrouter --help # everything else
⚙️ Environment & Data
Environment variables (click to expand — defaults are fine for local use)| Variable | Required | Description |
|---|---|---|
JWT_SECRET |
Yes | Long random secret for session signing |
INITIAL_PASSWORD |
Yes | First dashboard password — change after login |
DATA_DIR |
Yes | Data directory (default ~/.keyrouter) |
PORT |
No | Server port (default 20131) |
API_KEY_SECRET |
No | Secret for API keys issued by the endpoint proxy |
MACHINE_ID_SALT |
No | Salt for machine identity |
CLOUD_URL |
No | Cloud sync endpoint — off unless you set it |
BASE_URL |
No | Public base URL of this instance |
HTTP_PROXY / HTTPS_PROXY |
No | Outbound proxy for upstream calls |
Full list + examples: .env.example
- macOS / Linux:
~/.keyrouter/db/data.sqlite - Windows:
%APPDATA%/keyrouter/db/data.sqlite - Docker:
/app/data/db/data.sqlite— mount$HOME/.keyrouterto persist it - Everything (keys, logs, usage, settings) is in that one SQLite file. Back it up = back up KeyRouter.
The CLI and web assets update via src/lib/updater/ — when a new version exists, the dashboard shows an Update available button with a copy-install command; nothing auto-installs without your click. Docker users: pull the new tag and recreate the container (data stays in the mounted volume).
🩹 Troubleshooting
| Symptom | Fix |
|---|---|
Port 20131 already in use |
keyrouter --port 8080 (and update the endpoint in your tools) |
401 from KeyRouter |
Key mismatch — re-copy the API key from the dashboard |
| Tool can't connect after upgrade | npx keyrouter connect --reset --tools <tools> then reconnect |
| OAuth token expired mid-use | Shouldn't happen (auto-refresh); force reconnect the provider in Providers |
| Docker: data gone after recreate | You didn't mount -v "$HOME/.keyrouter:/app/data" — data lives in the volume, not the image |
More: gitbook/content/en/troubleshooting.md · Discussions
❓ FAQ
Do my API keys / prompts leave my machine?No. KeyRouter is fully self-contained — requests go from your tools to your local (or your own VPS's) KeyRouter process straight to the provider. No telemetry, no middleman. The only network calls are the ones you configure: providers, optional proxy pools, and the optional CLOUD_URL sync (off by default).
kr/<model> special syntax?
Yes — kr/ prefixes a combo: a KeyRouter-defined model mix with its own fallback strategy (e.g. kr/claude-sonnet-4.5 → falls back to a cheaper Claude, then a subscription Codex, then a free tier). Build your own in the dashboard → Combos.
Yes — that's exactly what per-key model access + INITIAL_PASSWORD + BASE_URL + HTTPS (put it behind nginx/Caddy) are for. Authentication is session-based for the dashboard and API-key-based for /v1.
Yes — Kiro AI (free Claude) and OpenCode Free work without any login, as Tier-3 fallback or standalone. The dashboard marks every provider free/paid/subscription so the router picks in the right order.
🗺 Roadmap
-
keyrouter connectone-shot tool config - Per-key model access control
- Trusted publishing (releases are provenance-signed from CI)
- Cloud sync dashboard for multi-instance deployments (
CLOUD_URL) - Request replay / diff between two providers for the same payload
🤝 Contributing
npm install
npm run dev # hot-reload dev server on :20127
npm run build # production standalone build
npm run cli:pack # build the publishable CLI tarball
npm run release:dry # preview the next version bump (no writes)
node tests/__baseline__/verify-no-regression.mjs # regression check vs baseline
# lint the files you touched (repo-wide eslint has pre-existing failures):
npx eslint path/to/changed-file.js
The test suite is intentionally not all-green on a bare checkout (~938 pass / ~64 known-fail, tracked in tests/__baseline__/known-fails.txt) — use verify-no-regression.mjs to judge your change, not the raw count. Unit tests for the embeddings endpoint live in tests/ (own package.json). Full conventions: CLAUDE.md & AGENTS.md.
Please read gitbook/content/en/faq.md for common questions before opening an issue, and docs/ARCHITECTURE.md before touching routing, fallback, OAuth or DB code. PRs that touch auth, keys, headers or SSRF surfaces will get extra scrutiny.
For bugs → Issues · Questions → Discussions
⚖️ KeyRouter vs 9Router vs 9Router Pro
| 9Router | 9Router Pro | KeyRouter | |
|---|---|---|---|
| Positioning | Origin — free AI router & token saver | Pro fork — prompts & quotas | Development fork — 9Router base + Pro features + extras |
| Token savers | RTK, Headroom, Caveman, Ponytail | Same | Same + PXPIPE image compression |
| Prompt injection (global / per-key / per-model) | ❌ | ✅ | ✅ |
| Per-key control | ❌ | ✅ quotas & rate limits | ✅ model access |
| Modalities | Chat, image, speech, embeddings | Same | Same + video, search, web fetch |
| Extra tooling | Proxy pools | Proxy pools + health checks | Proxy pools, MITM proxy, remote access, MCP plugins |
📚 Documentation
| Doc | What's in it |
|---|---|
DOCKER.md |
Docker & docker-compose, image tags, verified digests, publishing |
docs/ARCHITECTURE.md |
Executors, streaming pipeline, OAuth, DB schema, env matrix |
gitbook/content/en/index.md |
Full documentation site (EN, plus JA / ZH / ES / PT / FA) |
CHANGELOG.md |
Every release, auto-generated from commits |
| npm | https://www.npmjs.com/package/keyrouter |
🙏 Acknowledgments
KeyRouter is a derivative and rebrand of 9Router by decolua, with ideas from 9Router Pro by Gienetic. Both released under the MIT license. The original copyright notice and license terms are preserved in LICENSE.
The token-saving pipeline builds on ideas from RTK (Rust token saver) and CLIProxyAPI (the Go implementation that inspired this JavaScript port). Many thanks to their authors.
📄 License
MIT — see LICENSE.
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found



