drip-auth
v5.8.1
Published
Universal AI router — OAuth + API Key providers (Claude, GitHub Copilot, Gemini, Kimi, Kiro, Qwen, Cursor, OpenRouter, Groq…) behind one OpenAI-compatible local proxy
Maintainers
Readme
██████╗ ██████╗ ██╗██████╗
██╔══██╗██╔══██╗██║██╔══██╗
██║ ██║██████╔╝██║██████╔╝
██║ ██║██╔══██╗██║██╔═══╝
██████╔╝██║ ██║██║██║
╚═════╝ ╚═╝ ╚═╝╚═╝╚═╝ Universal AI router — OAuth + API Key providers behind one OpenAI-compatible endpoint. Run Claude Code, GitHub Copilot, Gemini CLI, Kiro, Kimi, KiloCode, Cursor and 15+ more through a single local proxy. No certificates, no MITM.
Table of contents
- Install
- Quick start
- Providers
- Commands
- Per-provider ports
- Dashboard
- How it works
- Development
- Contributing
- Support
- Uninstall
- License
Install
bunx drip-auth setupOr install globally:
bun install -g drip-auth
drip setupRequires Bun ≥ 1.0
Quick start
# 1. Add a connection — wizard walks you through OAuth or API key per provider
drip add
# 2. Start the proxy daemon (router on 3099, providers on 3100+)
drip serve on
# 3. Wire your tool to it interactively
drip up openclaude # arrow-key picker → provider → modelOpen the dashboard at http://localhost:3099 to manage everything visually — add/remove connections, see live token usage per account, swap rotation strategy, tail logs.
Using it programmatically
Any OpenAI-compatible client works:
import OpenAI from 'openai'
const client = new OpenAI({
baseURL: 'http://localhost:3099/v1',
apiKey: 'any-value',
})
const res = await client.chat.completions.create({
model: 'claude-sonnet-4-6',
messages: [{ role: 'user', content: 'Hello!' }],
})Anthropic SDK clients (Claude Code, Cursor's anthropic mode, @anthropic-ai/sdk, etc.) work too via POST /v1/messages — same translation/rotation/retry pipeline, native Anthropic response shape:
import Anthropic from '@anthropic-ai/sdk'
const client = new Anthropic({
baseURL: 'http://localhost:3099',
apiKey: 'any-value',
})
const msg = await client.messages.create({
model: 'anthropic/claude-sonnet-4-6',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Hello!' }],
})Both endpoints (/v1/chat/completions and /v1/messages) are also available on every per-provider port (:3100+) — when you hit a pinned port, you can drop the provider/ prefix from the model name.
Providers
Every provider gets its own dedicated port so requests never get misrouted. The router on :3099 picks any active account; the per-provider ports (:3100, :3101, …) pin the request to that provider's pool.
OAuth providers (bring your subscription)
| Provider | Flow | Notes |
|---|---|---|
| Qwen Code | device_code | deprecated — existing accounts still work |
| GitHub Copilot | device_code | uses your Copilot subscription |
| Kimi Coding | device_code | FREE |
| KiloCode | device_code | FREE |
| Kiro (AWS SSO) | device_code | FREE — AWS Builder ID |
| Claude | auth_code + PKCE | Claude.ai subscription |
| Codex (OpenAI) | auth_code + PKCE | fixed port 1455 callback |
| GitLab Duo | auth_code + PKCE | bring your own OAuth app |
| iFlow | auth_code | FREE — returns a long-lived API key |
| Qoder | auth_code | device-token OAuth |
| Cline | auth_code | browser redirect |
| Cursor | import_token | paste token from Cursor IDE |
| OpenCode | free / no-auth | FREE — public shared endpoint |
API-key providers
OpenRouter · Groq · DeepSeek · OpenAI · Anthropic · Google Gemini · NVIDIA NIM — add multiple keys per provider; all of them can round-robin.
Providers marked FREE need no credit card. Free-tier API keys (OpenRouter, NVIDIA, Gemini) are flagged with a badge in the dashboard.
Commands
Setup & connections
drip setup # Interactive onboarding (add → test → serve → openclaude)
drip add # Wizard — arrow-key pick a provider, run the right flow
drip list # Table: ID, email, status, priority, expiration
drip remove <id> # Remove by ID prefix or email
drip enable <id> # Re-enable a disabled connection
drip disable <id> # Skip a connection without deleting it
drip test [id] # Check upstream reachabilityProxy daemon
drip serve on # Start in background
drip serve off # Stop the daemon
drip serve # Show status (router port + per-provider ports)
drip serve restart # Restart (kills stale processes holding the port)
drip serve logs # Tail the log
drip serve fg # Run in foreground (blocks terminal)Models & routing
drip models # All providers, their ports, and model IDs
drip models <provider> # Zoom into one + copy-paste OPENAI_* examples
# e.g. drip models claudeTool integration
drip up openclaude # Wizard: pick provider (↑/↓) → pick model → write settings.json
drip up openclaude --provider kiro --model claude-sonnet-4.5
drip up openclaude --remove # Undo the integrationThe wizard writes the env block to ~/.claude/settings.json and injects export lines into .bashrc / .zshrc / config.fish (or a PowerShell profile on Windows).
Monitoring
drip status # Token totals, estimated cost, active locks
drip unlock [id] # Clear rate-limit locks on one or all accountsConfiguration
drip config # Show current settings
drip config --strategy round-robin # fill-first (default) | round-robin
drip config --port 3099 # Change router port
drip config --sticky-limit 5 # Requests before rotating (round-robin)Per-provider ports
When you add the first connection for a provider, drip allocates a dedicated port starting at :3100. This isolates provider routing cleanly:
$ drip serve
● Proxy running → http://localhost:3099
providers kimi-coding:3100 claude:3101 kiro:3102Point your tool at the specific port if you want to pin a provider:
OPENAI_BASE_URL=http://localhost:3100/v1 # forces Kimi
OPENAI_MODEL=kimi-k2.5Or use the router (:3099) and drip picks from all active accounts using the configured rotation strategy.
Dashboard
Visit http://localhost:3099/dashboard once the proxy is running.
- Add/remove connections per provider with live OAuth flows (device-code, auth-code, token-paste)
- Stack multiple API keys per provider — visual pool
- Proxy pools: route specific connections through HTTP proxies
- Token/cost tracking per account, per model
- FREE badges on free-tier providers
- Multi-language (EN / PT / ZH)
How it works
- OAuth orchestrator — pluggable adapters (
src/auth/providers/*.ts) implement device-code / auth-code + PKCE / auth-code / import flows; one file per provider keeps diffs small. - Ephemeral callback listener — spins up a local HTTP server on a random port (or
:1455for Codex) to catch the OAuth redirect, then shuts it down. - Per-provider listeners — each provider registered in
provider_portsgets its ownBun.serveinstance that forces the provider on every request. - Auto token refresh — each adapter owns its refresh logic; GitHub's short-lived copilot token is cached separately in
provider_data. - Rotation strategies —
fill-first(stay on highest-priority until it rate-limits) orround-robin(cycle with configurable stickiness). - Zero external services — everything runs locally, data lives in
~/.drip/drip.db(SQLite).
Development
Want to hack on drip? Runtime is Bun only.
git clone https://github.com/DripShadow/drip-router.git
cd drip-router
bun install
bun run dev # hot-reload, foreground proxy (bun --hot index.ts serve fg)
bun run start # foreground proxy, no hot-reload
bun run build # embeds logos, bundles to dist/drip
bun run deploy # build + bun link (refresh the globally-linked binary)
bun test # Bun test runnerAlternative one-shot setup (installs deps + bun link in one step):
bash setup.shProject layout:
index.ts # CLI entry — commander wiring
src/
├── commands/ # one file per subcommand (add, serve, list, …)
├── auth/
│ ├── orchestrator.ts
│ └── providers/ # one adapter per provider (device_code / auth_code + PKCE / import)
├── providers/
│ └── registry.ts # single source of truth for provider metadata
├── proxy/ # Bun.serve listeners, upstream builder, translators
├── rotator/ # account selection + strategies
├── token/ # OAuth refresh
├── db/ # SQLite schema + silent migrations
├── web/ # dashboard + wizard (served as text imports)
└── update/ # update banner
scripts/
└── embed-logos.ts # prebuild — emits src/web/logos-embedded.tsSee CLAUDE.md for the full architecture guide — request flow, provider-registry rules, database migration conventions, and Bun-first runtime defaults.
Contributing
PRs are welcome. The project ships with a skill at .claude/skills/contribute/ that walks contributors through the full flow if you use Claude Code; the summary below is the same contract.
1. Branch naming
<type>/<short-kebab-description>Lowercase, kebab-case, under 60 chars. Types:
| Prefix | Use for |
|---|---|
| feat/ | new user-visible capability (new provider, CLI command, dashboard view) |
| fix/ | bug fix |
| hotfix/ | urgent production fix |
| refactor/ | internal restructuring, no behavior change |
| perf/ | performance improvement |
| chore/ | deps, build, tooling |
| docs/ | README, CLAUDE.md, comments |
| test/ | tests only |
| ci/ | .github/workflows, release pipelines |
| release/ | release prep (e.g. release/v4.8.0) |
Examples: feat/add-zai-provider, fix/token-refresh-race, perf/sqlite-wal-mode, chore/bump-commander.
2. Commits — Conventional Commits
<type>(<scope>): <short imperative description>
<optional body — why, not what>
<optional footer — BREAKING CHANGE: …, Refs: …, Closes #123>Rules:
- Subject ≤ 72 chars, imperative mood, lowercase after the colon, no trailing period.
- One logical change per commit — stage explicit files, never
git add -A. - No emojis in subject, body, or footer.
- No
Co-Authored-By: <AI assistant>/ "Generated with …" footers. - Scopes match the directory layout:
auth,auth/<provider>,proxy,proxy/upstream,rotator,token,db,providers,commands,commands/<cmd>,web,web/dashboard,update,cli,build.
Commit types: feat, fix, refactor, perf, chore, docs, style, test, build, ci, revert. Use wip only on private branches that will be squashed before merge.
3. Adding a new provider
- Add an entry to
PROVIDERSinsrc/providers/registry.ts(models, colors, auth type, deprecation flag). - Drop
src/auth/providers/<id>.tsexporting anOAuthAdapter(device_code/auth_code+ optional PKCE /import_token). - Register it in
src/auth/providers/index.ts. - Add any provider-specific upstream quirks to
src/proxy/upstream.ts. - Drop a PNG at
src/public/logos/<id>.png— the prebuild step picks it up on the nextbun run build.
New columns on accounts go in the silent-migration ALTER TABLE block in src/db/index.ts, not in the initial CREATE TABLE — existing users already have their database.
4. Pull request
Push:
git push -u origin <branch>.Open PR:
gh pr create(title mirrors the primary commit).PR body:
## Summary - what changed, in plain terms - why this approach - anything reviewers should look at first ## Test plan - [ ] concrete manual or automated check - [ ] `bun test` passes (or note why it's not relevant) - [ ] `bun run build` succeedsDo not force-push to
main. Do not--no-verifycommit hooks. Do not amend a commit that was already pushed.CI must be green before merge.
Questions first
For non-trivial changes (new provider with odd OAuth flow, schema migration, rotator behavior), open an issue first so we can align on the approach before you invest time in the PR.
Support
- Bugs & feature requests → GitHub Issues
- Security issues → do not open a public issue. Email the maintainer or use GitHub's private vulnerability reporting.
- HTTP API reference →
API.mdcovers/v1/chat/completions,/v1/messages,/v1/models, error envelopes, CORS, and integration recipes. - Architecture questions →
CLAUDE.mdcovers the request flow, DB schema, and provider-registry contract.
Uninstall
bun uninstall -g drip-auth
# Remove stored accounts and data (optional)
rm -rf ~/.dripLicense
MIT © DripShadow
