claudeers.
// Developer Tools

Lupin

Run Claude Code on any LLM provider without losing your setup, local-first proxy with verified profiles, OAuth device-flow login, failover, content-aware rou…

// Developer Tools[ cli ][ api ][ desktop ][ web ][ mobile ][ claude ]#claude#anthropic#chatgpt#claude-code#cli#deepseek#developer-tools#gemini#devtoolsApache-2.0$open-sourceupdated 13 days ago
Actively maintained
100/100
last commit 10 days ago
last release 13 days ago
releases 7
open issues 0

Install with your AI

Paste into Claude Code, Cursor, or any agent — it reads the repo and wires the tool into your project.

Install and set up Lupin (npm project) into my current project.
Found on https://claudeers.com/lupin
Repo: https://github.com/Fanfulla/Lupin
Homepage/docs: https://www.npmjs.com/package/lupin-code
Detected install method: npm → npm install lupin-code
Category: devtools. Platforms: cli, api, desktop, web, mobile.
Read the repo's README for exact setup and env vars, then install it and wire it into my project.

Claudeers Health Verdict:
active; community-verified: false. Confirm the source before running anything.
// or install directly (npm)
npm install lupin-code
// or clone
git clone https://github.com/Fanfulla/Lupin

// compatibility

Platformscli, api, desktop, web, mobile
Operating systems
AI compatibilityclaude
LicenseApache-2.0
Pricingopen-source
LanguageTypeScript
⠀⠀⠀⠀⠀⠀⠀⠀⣀⣠⣴⣶⣾⣿⣿⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⣀⣤⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⣠⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠿⠗⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⢀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⣰⣿⡿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠐⠛⠁⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠈⠛⢉⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣶⣶⣦⣤⣤⣀⣀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠐⠋⠁⠀⢹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣄⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠛⠛⠛⠉⠉⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷

Lupin

Claude Code, on any model.
The gentleman router: it borrows the Claude Code harness and lends it to other models.




Your whole setup lives in Claude Code, not in the model: MCP servers, skills, CLAUDE.md, hooks, memories, plugins. But Claude Code speaks one protocol, the Anthropic Messages API, so trying another model means changing tool and starting over.

Lupin changes the model. Nothing else moves.

Sixty seconds

npx lupin-code@latest init            # wizard: provider, key, a real connectivity test
npx lupin-code@latest run -- claude   # Claude Code, already routed

If you keep it, install it once and drop the npx. Every example below uses the short command:

npm i -g lupin-code
lupin --version

Switch model with the session open, no restart:

lupin use glm                # you are on GLM-5.2 from the next request
lupin use gpt --bg kimi      # main on GPT, haiku-tier traffic on Kimi
lupin go kimi-sub -- claude  # switch and launch, one gesture

Mix subagents, each agent type on its own model or provider:

lupin agents set subagents --profile ollama-qwen   # every subagent on the local model
lupin agents set explore --profile kimi --wire     # a named agent, frontmatter written for you
lupin agents                                       # the table, plus the id each agent uses

lupin agents prints an id per route (claude-lupin-agent:<name>). Put it in an agent's frontmatter model:, or let Lupin do even that: --wire writes the line into the agent's definition file (the one deliberate exception to "never touch your harness", on an explicit flag, old value printed, ADR-48), and the blanket subagents route travels through CLAUDE_CODE_SUBAGENT_MODEL, which lupin run sets for you. After that one-time aim, the agent is yours, live, from the CLI, the TUI (a) or the control API. There is no other honest way: Claude Code sends no header or metadata that identifies a subagent, so the model id is the one channel a proxy can route on, and the routing stays visible per request in the log (agent:<name> in lupin top).

Use a subscription instead of an API key:

lupin login kimi      # device flow
lupin login openai    # Sign in with ChatGPT
lupin login gemini --i-accept-the-risk
lupin login copilot --i-accept-the-risk

Or without leaving Claude Code at all: open /model and pick a row that reads switch Lupin profile: <name>. Lupin publishes one per profile, and picking one moves the active profile from inside the session, with the conversation intact. That is the answer to running out of quota mid-task, and it is exactly how this was verified: Kimi answered usage limit for this billing cycle, the picker moved the session to ChatGPT, and the next request was served.

One honest limit of the picker

The client re-sends the picked id on every later turn, so Lupin acts on it only when it changes. Consequence: pick switch: B from the picker, then switch to A from the CLI or the TUI, and the picker cannot bring you back to B, because re-picking the row it still shows as selected sends the same id and no gesture is seen. Any other surface works (lupin use B, the TUI, or picking a different row first). The alternative was letting every turn of an old session drag the active profile back, which would mean no other surface could ever hold a switch.

Not one more router: the honest one

Everybody translates formats. Nobody tells you whether the model survives the harness.

That is the hard part. A model can speak the protocol perfectly and still fail every task, because Claude Code demands exact-match edits, a tool loop that closes, and roughly 46,000 tokens of prompt before the first word. So Lupin ships the question as a command:

lupin doctor kimi-sub
lupin doctor scoring the ChatGPT subscription 10/10
A real run against the ChatGPT subscription. Only the waiting is edited: the session took 116 seconds and is held for two.

lupin doctor runs a real headless Claude Code session against a dedicated server on an ephemeral port, and scores it from artefacts on disk (files really edited, scripts that really run), never from what the model claims it did. Six checks, threshold 7, no hidden retries.

Three things it refuses to do, each of them learned the hard way:

  • It will not grade a session that never reached the model. Claude Code reports success when its own loop ends cleanly, even when every request died on a protocol error. Where another tool would print 1/10 and blame the model, the doctor prints notRun and the cause (ADR-23).
  • It will not hide its own help. A 10/10 earned because the proxy repaired a broken tool call is different information from a clean 10/10, and the verdict says which one you got.
  • It will not invent a number. No score is reported for a provider nobody has run.
What the doctor has actually measured (dates included, because a score without one is a rumour)
ProfileScoreWhenNotes
kimi-sub (Kimi Code subscription)10/102026-07-28reproducibility measured separately on 2026-07-19: 10, 10, 10
kimi (Moonshot API key)10/102026-07-1995s, cache_control accepted
openai-sub (ChatGPT subscription)10/102026-08-05116s over 15 requests, 49% of input served from cache (the run in the GIF above)
gemini-sub (Google Code Assist)8/102026-07-29free tier: the run ended on 429 No capacity, which is a tier limit, not a translation defect
lmstudio + gemma-4-12b0/102026-07-19honest: the harness floor and this GPU cannot be satisfied together
copilot-subnot runworks live, but a full doctor run would spend most of a free plan's monthly allowance

Providers

Four lanes, picked by Lupin, never by you. Passthrough first: when a provider already speaks Anthropic, nothing is translated at all.

ProviderLaneCredentialState
Kimi / MoonshotpassthroughAPI key or subscriptionverified live, doctor 10/10
ChatGPT subscriptionresponsesSign in with ChatGPT (PKCE)verified live, doctor 10/10
Gemini Code Assist subscriptioncodeassistSign in with Google (PKCE)verified live, doctor 8/10
GitHub Copilot subscriptiontranslateGitHub device flowverified live 2026-08-05. On the free plan expect about 50 chat requests a month, which one real session can spend
DeepSeek, Z.AI / GLMpassthroughAPI keyimplemented, not scored
OpenRouterpassthrough or translateAPI key344 models, 255 with tool calling
OpenAI, Gemini (pay per token)translateAPI keyimplemented, not scored
Ollama, LM Studio, ds4-serverpassthroughnonelocal, native Anthropic endpoint
llama.cpp servertranslatenonelocal

344 models on OpenRouter, and Claude Code can natively use zero of them, because OpenRouter's Anthropic-compatible endpoint only accepts Anthropic models. Through Lupin the 255 with tool calling become usable. The other 74 connect and stay a chat, which the wizard says out loud instead of letting you find out mid-task.

How the routing works
Claude Code ──ANTHROPIC_BASE_URL──▶ Lupin (127.0.0.1)
                                      │
            ┌───────────────┬─────────┴─────────┬────────────────┐
            ▼               ▼                   ▼                ▼
      [passthrough]    [translate]        [responses]      [codeassist]
      Kimi, DeepSeek   OpenAI, Gemini,    ChatGPT          Gemini Code
      Z.AI, Ollama     llama.cpp,         subscription     Assist
      LM Studio, ds4   OpenRouter,        (WHAM)           subscription
                       Copilot
  • Passthrough rewrites the URL, the auth header and the model name. Nothing else is touched, so the provider's prompt cache keeps hitting: on a local runtime that is the difference between a turn measured in seconds and one measured in minutes.
  • Translate maps requests, responses and SSE streaming, tool calling included, with MCP names longer than 64 characters rewritten through a deterministic hash.
  • responses and codeassist exist because a ChatGPT or Google OAuth token does not spend on those providers' public APIs at all. Each subscription has its own private protocol, so each got its own translator, built from real captured traffic.

Three model slots (opus, sonnet, haiku) map to whatever you point them at, per profile; --bg sends the haiku-tier traffic somewhere cheaper, and the agents table (SPEC-PROVIDERS §4decies) routes each subagent type to its own model or provider.

Where routers really break

A provider can honour the protocol to the letter and still hand you garbage inside the content: reasoning wrapped in <think>, a tool call the server never turned into tool_calls[], special tokens leaking into the text. The model "calls" the tool, nobody runs it, and the agentic loop dies quietly.

In a sample of 382 claude-code-router issues, over 29% land here, re-fixed provider by provider instead of once. Lupin treats it as one problem, with one engine.

The four rules that engine follows
  • One engine for both paths. The same normalizer serves the non-streaming mapper and the SSE translator, and a test feeds it the same input character by character and as a single block, demanding identical results. A normalization that behaves differently while streaming is exactly the bug this makes impossible.
  • Verified markers, never guessed. Eight model families (Qwen3, Qwen3-Coder, GLM, DeepSeek, Kimi K2, Mistral, Llama, GPT-OSS Harmony) checked against the official chat templates and the parsers of vLLM, llama.cpp and SGLang, then put through an adversarial pass that threw out the invented ones. GLM reuses Qwen's <tool_call> with a different payload; DeepSeek uses fullwidth vertical bars where Kimi uses ASCII. A wrong character does not fail loudly, it simply never matches.
  • Reasoning is not lost. reasoning_content becomes a thinking block. On gemma-4-12b the content field arrives empty and the whole answer is in there: drop it and Claude Code receives nothing.
  • Never silently. Every normalization that fires lands in the log and in the doctor verdict.

The terminal, done properly

A bare lupin opens the hub. With the optional Rust sidecar on your PATH it is a live dashboard; without it, a status summary and the next step.

The sidecar is not on npm and never will be: it stays out of the JavaScript runtime by design. Build it from a clone, once, then launch it with the bare command:

cargo build --release --manifest-path tui/Cargo.toml
cp tui/target/release/lupin-tui ~/.cargo/bin/      # anywhere on PATH will do

lupin        # the hub finds the sidecar and opens the dashboard
lupin-tui    # or run it directly

That build is a one-time cost: from then on lupin update rebuilds the sidecar to the matching version on every package update, from the sources the package itself ships (it needs the Rust toolchain; without one it prints the manual command instead).

Keys: 1-9 switch profile, arrows and Enter do the same on the highlighted row, d runs the doctor on the highlighted profile, : opens the command palette, o edits the failover order, a opens agents mode, r refreshes now, q quits.

Agents mode is the subagent mixer on screen: it lists every agent route plus the conventional subagents row (shown even before it exists, so the first gesture is obvious), and on the selected row 1-9 aims it at that profile, x clears it, Enter applies the whole table atomically through the control API, Esc throws the edit away. The daemon writes the config and hot-reloads it, so a live Claude Code session picks the new routing up on its next request. Model-string targets and brand-new route names are one command away in lupin agents set, and the overlay says so rather than hiding the limit.

The doctor takes minutes, so it runs as a child process and its output streams into a panel while the dashboard keeps refreshing underneath. The palette lists init, login and run too, and says plainly that they need a shell: the first reads hidden input, the second waits on a browser, and the third hands the terminal to Claude Code.

Give it 32 rows or more and it draws the portrait full size; below that it keeps every fact and shrinks the art. It needs a real terminal: it takes over the screen, so it will not do anything useful inside another tool's output pane.

⣀⣤⣶⣾⣿⣷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀  L U P I N  v0.2.3   the gentleman router
⠈⢿⣿⣿⣿⣿⣿⣷⣖⠀⠀⠀⠀⠀⠀⠀  daemon up   127.0.0.1:3456
⠀⠴⢿⣿⣿⣿⣿⣿⣿⣀⠀⠀⠀⠀⠀⠀  active: kimi-sub  ->  k3
⠀⠀⠈⠛⢿⠿⣿⣿⣿⣿⣿⣶⣶⣶⣤⣄

Profiles with 1-9 hotkeys, the routing truth per slot, the request tail with every marker (routed, agent, failedOver, tierDowngrade, dialect), and a status line that says in words what just happened. lupin top gives the same truths with no sidecar at all. Details in docs/TUI.md.

There is also a statusline for Claude Code itself, because through a proxy the model introduces itself as the Claude of the system prompt (the UI knows nothing about the mapping, ADR-3), so asking it who it is proves nothing. The truth lives in GET /health, and the statusline shows it as ⇄ profile→model.

Statusline install and every segment it draws

Opt-in, always: Lupin never writes your settings.json (ADR-11). Copy examples/statusline.ps1 (Windows) or examples/statusline.sh (macOS and Linux, needs jq) into ~/.claude/ and register it:

"statusLine": { "type": "command", "command": "powershell -ExecutionPolicy Bypass -File \"C:\\Users\\<you>\\.claude\\statusline.ps1\"" }
SegmentExampleWhat it says
Skill flag[CAVEMAN]active mode or skill (flag file), specific to a personal setup
ModelFable 5⚡the model requested by Claude Code. Through a proxy this is the slot name, not the real model
Lupin routing⇄ kimi-sub→k3active profile and the real model of the opus slot, from /health with a 10s cache. Daemon down shows a red OFFLINE
RepoLupin@main +3/-1folder, git branch, uncommitted lines
Contextctx: 67k/1M (7%)uses total_input_tokens, cache reads included, which is what makes the percentage honest
Efforteffort: xhighreasoning effort, coloured by rising cost
Thinking✦thinkextended thinking active
Cost$4.20suppressed through Lupin: Claude Code prices Anthropic models, so on another provider it would be fiction
PRPR#12✓PR state of the branch
Quota5h: 30% reset 14:00Claude subscription limits, which through Lupin disappear on their own
Update↑v2.1.216a newer Claude Code on npm

Three lines maximum: when space runs out segments drop in order (update, PR, extras, 7d, 5h). The mandatory ones always stay.

Questions people actually ask

Can I use my ChatGPT subscription with Claude Code?

Yes. lupin login openai uses the sanctioned Sign in with ChatGPT flow. The token does not spend on the public OpenAI API, so Lupin talks to the same protocol the official client uses, and lupin doctor openai-sub scores 10/10 on a real session.

Can I run Claude Code on Gemini for free?

Yes, with a caveat worth reading. lupin login gemini reaches Google Code Assist, whose free tier answers on the flash models and returns 429 on the pro ones. Lupin serves you rather than refusing, and logs every substitution as tierDowngrade so you always know which model answered. Two honest warnings: Google collects prompts and code on the free tier with human reviewers able to read them, and Google has suspended accounts for third-party OAuth, which is why the login is gated behind --i-accept-the-risk.

Does my claude-mem / MCP / skills setup keep working?

Everything local does: native tools, local and project MCP servers, plugins, skills, hooks, CLAUDE.md, memory, subagents. Verified with real sessions. What breaks is tied to the claude.ai account, and it breaks with any proxy, not just this one: see the section below.

What does it cost me to run?

Nothing beyond the provider. Lupin is a local process on 127.0.0.1, it has no backend, it uploads nothing, and it never persists prompts or responses. lupin usage aggregates your own log offline, and it sees subagent traffic that the Claude Code transcript does not: 332 requests against 113 visible turns, measured.

Why is Anthropic not in the provider list?

Because Claude Code already runs Claude natively and does it better than a proxy would (ADR-18). Lupin exists to reach the models Claude Code cannot.

What you lose with any proxy

Claude Code ties some features to the claude.ai login and to api.anthropic.com. Point ANTHROPIC_BASE_URL anywhere else (Lupin, claude-code-router, LiteLLM, any gateway) and Claude Code itself disables them. There is no hybrid mode.

  • Remote Control (driving the session from claude.ai or your phone), since v2.1.196.
  • MCP connectors hosted on claude.ai, voice dictation, and the cloud surfaces (web, mobile, Slack, routines, ultrareview).

One cosmetic quirk to expect: resuming a session may print Session model k3 could not be restored. Claude Code persisted the provider's own model name and fails to find it in its catalogue. The routing stays correct, you only lose the persistence of the /model selection across restarts. Lupin does not rewrite the response to hide this, because byte-faithful passthrough is the entire point of passthrough (ADR-7).

Local models, zero keys

Pick ollama, lmstudio, llamacpp or ds4 in the wizard: no key to paste, the models are read from your own server with their real context windows, and you get a warning about the ones that do not declare tool support, since Claude Code cannot take a single step without them.

That distinction is not pedantry. gemma-4-12b declares a 262,144 token window and runs with 8,192: a factor of 32. Lupin always prefers the loaded window over the declared maximum, and marks which one it got.

Everything else

Command reference
CommandDoes
lupinthe hub: TUI when the sidecar is installed, else status and next steps
initwizard: provider, key (never echoed), a real connectivity test
login <provider> / logoutOAuth, with --account <label> for a second account on the same provider
use <profile> [--bg <p>]hot switch, no restart: the open session moves on its next request
go [profile] -- <cmd>switch and run in one step
run -- <cmd>start the daemon if needed and run with the env pointed at Lupin
resume [profile]continue this directory's last session on another provider
doctor [profile]the real headless session, scored on disk artefacts
use <profile> --opus <model>aim a slot by hand, for profiles whose models come from the account
agents set <name> --profile <p> [--wire]per-subagent routes; --wire writes the agent file's model: line for you
updateupdate the npm package and rebuild the TUI sidecar if you have one
list / status / stop / logs -fthe plain truths
toplive console, no sidecar needed
usage [--days N]tokens really served, aggregated from your local log

Every command behaves identically on Windows PowerShell, cmd, and any POSIX shell. lupin run spawns Claude Code with no shell in between, so your arguments arrive byte for byte (ADR-29).

Documentation index
FileContent
docs/NEXT-STEPS.mdStart here: current state, how to verify it, what to do next
DESIGN.mdVision, prior art, positioning, risks
docs/DECISIONS.mdADR log: every decision, the why, the rejected alternatives
docs/SPEC-TRANSLATION.mdTranslation core: mapping, SSE, errors, acceptance fixtures
docs/SPEC-PROVIDERS.mdProvider registry, profiles, slot mapping, quirks
docs/SPEC-CLI.mdCLI, doctor, security, UX
docs/ROADMAP.mdMilestones, verification criteria, next steps
docs/ARCHITECTURE.mdRepo layout, dependency rules (a pure core)
docs/TESTING.mdFixtures from real output, test levels
docs/TUI.mdThe terminal hub: install, keys, panels, troubleshooting
docs/COMPETITIVE.mdCompetitive analysis: white space, steal candidates
docs/DESIGN-OAUTH.mdPluggable credential source, device flow
docs/DESIGN-OAUTH-PKCE-TUI.mdOAuth PKCE, the control API, the Rust sidecar
docs/DESIGN-TRANSLATORS-DEDICATED.mdThe two subscription translators

Principles

  1. Fixture first. The fixture, recorded from real provider output, comes before the code. Real dialects are stranger than you would guess: keep-alive SSE comments, repeated finish_reason, usage arriving after the stream ended, errors delivered as a data frame.
  2. Centralized quirks. Never if (provider === x) scattered around. Flags in one registry, one implementation each.
  3. Privacy. Prompts and responses are never persisted. Keys live in the OS keychain or a 600 file, never in the config and never in the logs. It binds to 127.0.0.1 only.
  4. Zero side effects. Lupin never touches ~/.claude/settings.json. Uninstalling means stopping using it.
  5. No invented numbers. A context window enters the defaults only when the vendor publishes the exact figure. DeepSeek and Gemini write "1M" without saying whether that is 1000 or 1024, so they stay without one: a route that never fires beats a route that fires on the wrong number.
  6. Disciplined scope. Lupin stays a proxy. No Electron app, no web dashboard, no relay bot. The biggest competitor accumulated 853 open issues while adding surface; the answer here is not to add it.

The portrait is Arsene Lupin as Leo Fontan drew him in 1908 for Arsene Lupin contre Herlock Sholmes. Public domain, like the books.

Apache 2.0

// faq

What is Lupin?

Run Claude Code on any LLM provider without losing your setup, local-first proxy with verified profiles, OAuth device-flow login, failover, content-aware routing and an honest per-model compatibility doctor. It is open-source on GitHub.

Is Lupin free to use?

Lupin is open-source under the Apache-2.0 license, so it is free to use.

What category does Lupin belong to?

Lupin is listed under devtools in the Claudeers registry of Claude-compatible tools.

1 views
34 stars
unclaimed
updated 13 days ago

// embed badge

Lupin on Claudeers
[![Claudeers](https://claudeers.com/api/badge/lupin.svg)](https://claudeers.com/lupin)

// retro hit counter

Lupin hit counter
[![Hits](https://claudeers.com/api/counter/lupin.svg)](https://claudeers.com/lupin)

// reviews

// guestbook

0/500

// related in Developer Tools

🔓

The agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Curs…

// devtoolsaffaan-m/JavaScript240,305MIT[ claude ]
🔓

Use Garry Tan's exact Claude Code setup: 23 opinionated tools that serve as CEO, Designer, Eng Manager, Release Manager, Doc Engineer, and QA

// devtoolsgarrytan/TypeScript128,278MIT[ claude ]
🔓

AI coding assistant skill (Claude Code, Codex, OpenCode, Cursor, Gemini CLI, and more). Turn any folder of code, SQL schemas, R scripts, shell scripts, docs,…

// devtoolssafishamsi/Python109,277MIT[ claude ]
🔓

Makes your AI agent think like the laziest senior dev in the room. The best code is the code you never wrote.

// devtoolsDietrichGebert/JavaScript104,762MIT[ claude ]
→ see how Lupin connects across the ecosystem