One local endpoint · every AI tool you own · who paid for what

Your Claude and ChatGPT subscriptions each live inside their own apps. dario makes them work everywhere, and keeps the receipt.

Point Claude Code, Cursor, Aider, Cline, Codex CLI, the SDKs and anything with a base-URL setting at localhost:3456. Each request goes to a seat with headroom; with a fallback chain the other plan takes it when one hits its window; and the ledger prices every request at API rates so you can see what each plan absorbed.

0 runtime dependencies SLSA-attested every release Nothing phones home MIT, independent, unofficial
terminal
$ npm install -g @askalf/dario
  # or: brew install askalf/tap/dario
$ dario login        # your Claude plan: Pro, Max 5x or Max 20x
  Login successful.
$ dario proxy        # leave it running
  dario · http://localhost:3456
  Your Claude subscription is now an API.
  Pool: 1 account · OAuth healthy · Model passthrough
Every AI tool you own, the subscriptions you already pay for. Claude Code, Cursor, Cline, Aider, Codex CLI and the Agent SDK send requests to dario at localhost:3456, which forwards each one to your Claude plan or your ChatGPT plan and, with a fallback chain configured, fails over between them on a 429.
Start in 60 seconds

Two base URLs, one key, every tool

You already pay for Claude, for ChatGPT, or both, and each plan spends through its own runtime: Claude Code and the Agent SDK, the ChatGPT app and Codex CLI. The tools that want a base URL and an API key get a meter instead: per token, or a monthly credit balance that stops when it runs out, while the seat's own windows sit idle. dario is the seam: install it, log in once, point everything at it, and the seat is spent first.

Anthropic-shaped tools
export ANTHROPIC_BASE_URL=http://localhost:3456
export ANTHROPIC_API_KEY=dario
# claude, aider --model sonnet, the Anthropic SDKs
OpenAI-shaped tools
export OPENAI_BASE_URL=http://localhost:3456/v1
export OPENAI_API_KEY=dario
# Codex CLI, the OpenAI SDKs, chat/completions and Responses

Works with every tool that honors those variables or has a Base URL field. Per-tool setup, with the gotchas each one has:

Who paid for what

A dashboard at /analytics/ui

The ledger prices every request at API rates and says which plan absorbed it. Every proxy serves the page: the seats and their headroom, who paid for the last hour, the live request tail, the keys and their budgets, and the overage halt with a Resume button. Nothing loads from outside the proxy, light and dark follow your system, every chart has a table view, and it reads on a phone or a wall display.

The dario dashboard on sample data: a hero figure of what today's requests would have cost at API list prices and the share the seats absorbed, a KPI row, four seats with 5h and 7d meters and reset timers, a routing bar of who paid for the last hour, the live request tail and the request timing split.

Sample data, rendered from the shipped page opened from disk. Served by a running proxy it goes live, with the analytics token or an API key.

  • Knows what it saved youA ledger prices every request at API list rates and keeps the number across restarts: today, 7 days, 30 days, all time; per model and per consumer, covered by a seat vs metered.
  • The same numbers everywhereThe TUI, /analytics, Prometheus /metrics, the per-request timing split and dario usage --card read the same ledger and the same window.
  • Yours to readOne file served by the proxy, no library, no font, no analytics. What each route carries
Why people pick it

Routing, failover, a pool, a ledger, a guard

A tool sends a request to dario, the Claude plan answers 429, dario re-serves the request on the ChatGPT plan which answers 200, and the tool sees the x-dario-pool-fallback header.

Failover that finishes the answer

With a --pool-fallback chain, a 429 on one plan is re-served by the other. A stream that dies mid-answer is completed on the same model first, chain or not.

Two plans and failover
dario in front of a Claude plan with three seats, work, personal and side, each with a utilisation bar; the new conversation goes to the seat with the most headroom.

Many seats, one endpoint

Per-model headroom routing, a session-sticky prompt cache and in-flight 429 failover across every seat you hold. New conversations go to the seat with the most headroom; fill-first, expiring-first and headroom-by-plan are a flag away.

The pool
dario halted: the lines from Claude Code, Cursor, Cline, Aider and the Agent SDK are cut at a red barrier after the Claude plan returned a response tagged overage.

Stops before it costs you

The overage guard halts the proxy the moment a response bills outside your subscription, and tells you why. Resume from the dashboard, the API or the CLI.

Guardrails
The claude binary sends its request shape through dario; a timeline of releases ends in a red dot labelled drift, under a radar sweep.

Tracks Claude Code on its own

Ten unattended watchers catch wire-shape drift and ship the fix, usually the same day. Every change is published as a feed you can subscribe to.

How dario tracks Claude Code · the wire-drift feed

Every tool, one URL

No per-tool keys and no second bill: anything with a base-URL setting runs on the plan you already pay for.

Per-tool setup

Either plan, either wire shape

Your ChatGPT plan behind Claude Code and the Anthropic SDKs; Codex CLI on your Claude plan. Messages, chat/completions and Responses, translated once at the front door.

Two plans

One key per developer

Named keys with a preferred seat, a model allowlist and a daily budget in dollars or tokens. A key can also be a unix socket, so a CI job holds no secret. The ledger and the dashboard split spend by key.

Keys and budgets

Knows what it saved you

A ledger prices every request at API rates; the TUI, the dashboard, /analytics and Prometheus /metrics all read it.

API-equivalent spend

Your traffic as the benchmark

Shadow-compare any request against another model and read the results with dario compare.

Shadow compare

Runs where you run

A laptop, a server, Docker, Kubernetes, a Pi in a closet. Binds loopback by default and refuses a public bind without a key. Replicas share seats through one lock service, with --pool-shared-state their rate-limit readings and sticky bindings too, and with --pool-shared-accounts one account list, so a new replica starts with its peers' accounts.

Docker · Multiple instances
What it does with a request

The tool doesn't know. The backend doesn't know.

You point every tool at one URL. dario reads each request, decides which plan or backend owns it, and forwards it in that backend's native protocol.

Client speaksModelRoutes toWhat happens
Anthropic Messagesclaude-* / opus / sonnet / haikuClaude poolOAuth swap and the Claude Code template, then api.anthropic.com
Anthropic Messagesa slug your ChatGPT account listsCodex engineMessages to Responses translation, subscription auth
Anthropic Messagesgpt-4o, llama-*, any name no plan listsRefused400 with x-dario-upstream-rejection: model_unroutable; reach an API-key backend from this shape with a provider prefix
OpenAI Chatgpt-* / o1-* / o3-* / o4-*OpenAI-compatible backendAuth swap, body forwarded byte-for-byte
OpenAI Chata slug your ChatGPT account listsCodex enginechat/completions to Responses translation, subscription auth
OpenAI Chatclaude-*Claude poolOpenAI to Anthropic translation, then the Claude path
Either<provider>:<model>Forced by prefixExplicit override

dario is the seam. The full lineup, shortcuts, the live model catalog and when a name is refused

The most common question

Will my account get suspended?

I can't promise you won't be actioned, and I'd be skeptical of anyone who does. Only Anthropic decides how it enforces its terms. What I can do is lay out exactly how dario works, so you can weigh the risk yourself instead of taking anyone's word for it.

dario runs entirely on your machine, authenticates as you with your own Claude login, sends requests in the shape the official client sends, and reports nothing anywhere. What it adds is letting tools other than Claude Code use that subscription, and whether that falls within your plan's terms is Anthropic's call. The full answer, including the billing-split contingency dario is built for.

Trust and transparency

Small enough to read, checked in the open

0runtime dependencies. Verify with npm ls --production.
~45klines of TypeScript across 88 files. CI fails if the line count drifts.
SLSAattested every release through GitHub Actions and Sigstore, published with OIDC: no long-lived npm token exists to leak.
3 × Node289 test files run in parallel on Node 18, 20 and 22; CodeQL on every push, ClusterFuzzLite weekly, an OpenSSF Scorecard.
127.0.0.1by default; upstream only to configured backends over HTTPS; a non-loopback bind is refused without DARIO_API_KEY.
Nonetelemetry. No analytics, no tracking, nothing phones home. Your tokens are never logged and sit 0600 on disk.
verify it yourself
npm audit signatures
npm view @askalf/dario dist.integrity
cd $(npm root -g)/@askalf/dario && npm ls --production
Everything inside the box labelled your machine: the tools and dario. Only two lines leave it, to the Claude plan and the ChatGPT plan, through a padlock. Pills read 0 deps, no telemetry, MIT.

Security reports go to security@askalf.org, not a public issue: SECURITY.md. API stability commitments: STABILITY.md. The measured overhead of the proxy on every PR: bench-overhead.mjs.

Reference

The docs