dario

askalfMIT活跃维护

把 Claude Code、Cursor、Cline、Aider、Codex CLI 等编码工具的请求统一到一个本地端点,按已付费的订阅席位优先路由,并记录用量账本。

One local endpoint that routes Claude Code, Cursor, Cline, Aider, Codex CLI and the SDKs through the Claude and ChatGPT plans you already pay for: seats first, then the fallback chain you configure, and a ledger of who paid. Zero runtime dependencies.

v6.23.5发布于 2026-11-09 23:32 UTC585star +1 / 7 天77fork同步于 2026-11-10 06:00 UTC

怎么上手

由 README 提炼,执行前请确认
npm install -g @askalf/dario
dario login --no-proxy
dario proxy
硬件要求按 README 说明

README 未说明

下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

把 Claude 和 ChatGPT 订阅变成统一本地端点,让所有 AI 编码工具共用你已付费的额度

把 Claude Code、Cursor、Cline、Aider、Codex CLI 等编码工具的请求统一到一个本地端点,按已付费的订阅席位优先路由,并记录用量账本。

核心能力

  • 在 localhost:3456 提供 Anthropic 与 OpenAI 兼容端点
  • 按剩余额度选座,429 时按配置的 fallback 链切换
  • 按 API 价格记账,拆分各订阅与密钥的消耗
  • 支持每开发者独立密钥,带模型白名单与日预算
  • 零运行时依赖,仅与自配后端通信

容易踩的坑

需先登录 Claude 或 ChatGPT 订阅账号才能路由;OpenAI 兼容工具要用 /v1 结尾的 base URL;未配置 --pool-fallback 时额度耗尽会直接返回 429

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README
这个条目还没有人工点评。如果它对你很有用,欢迎到 提交仓库 页写下你的使用经验。

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    最近发版

    5 个版本v6.23.5
    1. v6.23.5最新正式版2026-11-09 · 2026-11-09 23:32 UTC

      Auto-released from merge of PR #1852 (trigger: push).

      • Fable 5.2, Fable 5.1, Sonnet 5.5 and Haiku 5.5 are priced at their published rates. None of them had a row in the price table, so dario usage, /analytics, the ledger and key budgets costed every request for them at the Sonnet 4.6 rate of $3/$15 per million tokens. Fable 5.2 is $8/$40 and Fable 5.1 is $10/$50, so both read at under half their cost; Sonnet 5.5 is $2/$10 and read 50% high; Haiku 5.5 is $0.10/$0.50 and read thirty times high. A key with a dollar budget was held to the same wrong figure. The ledger stores tokens and prices them when read, so the days already recorded for Fable 5.2, Fable 5.1 and Sonnet 5.5 come out at the right rate. Recorded Haiku 5.5 days come out at its short-prompt rate, which is low for any request in them that was over 100,000 prompt tokens (next entry). Opus 4.5, Sonnet 4.5 and the three Mythos models have rows of their own too.
      • A Haiku 5.5 request over 100,000 prompt tokens is priced at its long-prompt rate. Anthropic charges five times as much on every bucket for such a request, counting input, cache reads and cache writes toward the 100,000. The ledger files those requests under claude-haiku-5-5[long], which dario usage and /analytics/ledger list as a row of its own. Haiku 5.5 rows recorded before this hold both kinds and are priced at the short-prompt rate.
      • fable, sonnet and haiku name Fable 5.2, Sonnet 5.5 and Haiku 5.5 before the live model catalog has answered. The bundled model list gains claude-fable-5-2, claude-fable-5-1, claude-sonnet-5-5 and claude-haiku-5-5, and /v1/models serves them when Anthropic's catalog cannot be reached. With the live catalog nothing changes: the short names already resolved to the newest model it lists.
      • The pricing watcher reports a published model that has no price row. It walked only the rows dario already had, so it reported the table aligned while four models were costed at the fallback rate. It now also reads the two rows the page gives Haiku 5.5 as one model with a long-prompt rate; the second row used to parse as a model id nothing matched.
      • A tool sent to a ChatGPT-plan model keeps its optional parameters optional. Converting a request to the Responses shape dropped the tool's strict field, which left it to the backend's default, and a client's optional parameters came back as required ones: an agent kept filling in an argument it had been told to leave out (#1836). On /v1/chat/completions a tool's own strict is now carried, and a tool without one goes out as strict: false. On /v1/messages a tool goes out as strict: false unless it asked for Anthropic's strict tool use, which is sent without the field as before.
      • dario asks the ChatGPT backend for its model list as Codex CLI 0.167.0. It asked as 0.155.0. The backend answers per client version, so a model newer than the version named is left out of the list, and a request for it is refused as a model no provider lists (#1842). The refusal now names the version the list was asked for as, and DARIO_CODEX_CLIENT_VERSION, which overrides it, is in the configuration reference.
      • gpt-6.1-sol and gpt-6.1-terra are priced at their published rates. dario usage, /analytics and the ledger costed both at gpt-5.6-terra's $2/$12 per million tokens. gpt-6.1-sol is $2/$10 and gpt-6.1-terra is $1/$5, each with cache reads at 0.05x input.

      Built + tested + npm-published inline by cc-drift-auto-release.yml on this run — tokenless via OIDC trusted publishing, provenance-attested. See the workflow log for the publish output.

    2. v6.23.4pre-release2026-11-09 · 2026-11-09 20:38 UTC
      查看更新说明

      Auto-released from merge of PR #1846 (trigger: push).

      Pre-release: a bot cut this version to track a Claude Code version. Everything listed below shipped in it, and npm and GHCR carry it as latest. GitHub's Latest badge stays on the newest release a person cut.

      • The bundled Fable system prompt is the one captured from Claude Code 2.1.321. It is 10135 characters; the bundle held a 9709-character one. Requests for Fable models built from the bundled template carry it.
      • The bundled Opus 5 system prompt is the one captured from Claude Code 2.1.321. It is 9221 characters; the bundle held a 8795-character one. Requests for Opus 5 models built from the bundled template carry it.
      • The bundled Sonnet 5 system prompt is the one captured from Claude Code 2.1.321. It is 14374 characters; the bundle held a 13948-character one. Requests for Sonnet 5 models built from the bundled template carry it.
      • The bundled base system prompt is the one captured from Claude Code 2.1.321. It is 5783 characters; the bundle held a 5357-character one.
      • The bundle's _variantShapeHashes field differs in a way these notes do not break down.

      Built + tested + npm-published inline by cc-drift-auto-release.yml on this run — tokenless via OIDC trusted publishing, provenance-attested. See the workflow log for the publish output.

    3. v6.23.3pre-release2026-11-09 · 2026-11-09 20:18 UTC
      查看更新说明

      Auto-released from merge of PR #1845 (trigger: push).

      Pre-release: a bot cut this version to track a Claude Code version. Everything listed below shipped in it, and npm and GHCR carry it as latest. GitHub's Latest badge stays on the newest release a person cut.

      • Claude Code 2.1.321 is in the supported range. dario doctor and proxy startup no longer warn that it is untested, as they did for anything newer than 2.1.319.
      • The bundled template is labelled Claude Code 2.1.321. It was labelled 2.1.319. Its user-agent value is claude-cli/2.1.321 (external, sdk-cli).

      Changed

      • The key-socket gate logs its refusal the same way: a request on a socket whose bound named key is unknown, revoked or expired now logs one line without -v, with the reason and the source, as the API key check has since 6.23.2. A request on a key Unix socket has no peer address and logs from unknown address; the user-agent and the Access user are reported as for any other request. Never a key value.

      Built + tested + npm-published inline by cc-drift-auto-release.yml on this run — tokenless via OIDC trusted publishing, provenance-attested. See the workflow log for the publish output.

    4. v6.23.22026-11-08 · 2026-11-08 01:28 UTC
      查看更新说明

      Auto-released from merge of PR #1834 (trigger: push).

      Changed

      • A request refused by the API key check (401) now logs one line without -v, with the reason (named key unknown, revoked or expired, or root key mismatch), the peer address, the user-agent and the Access-authenticated user when a Cloudflare Access gate stamped one; never a key value. The request log file already recorded one line per refused request, so the volume is the same; what was missing was anything about who sent it. A request on a key socket whose bound named key is unknown, revoked or expired is refused earlier by the key-socket gate and still logs its rejection only with -v, without the source details.

      Built + tested + npm-published inline by cc-drift-auto-release.yml on this run — tokenless via OIDC trusted publishing, provenance-attested. See the workflow log for the publish output.

    5. v6.23.12026-11-07 · 2026-11-07 16:37 UTC
      查看更新说明

      Auto-released from merge of PR #1832 (trigger: push).

      • Several tool calls in one turn keep their arguments on ChatGPT models. The translators read a call's arguments only from its delta events, so a turn whose calls carried them only on the final events reached the client with every call empty, which Claude Code shows as Error writing file. Both translators now read the final events too. On the Anthropic shape, calls that open before the previous one has finished now wait their turn, so each block runs start to stop in order.
      • Compare records can expire. DARIO_COMPARE_KEEP_DAYS deletes records older than that many days from ~/.dario/compare, on start and hourly. Each record holds a whole prompt and both answers, and nothing cleared them. Off unless set, and only files named as records are touched.

      Built + tested + npm-published inline by cc-drift-auto-release.yml on this run — tokenless via OIDC trusted publishing, provenance-attested. See the workflow log for the publish output.

    README 原文

    未翻译

    dario

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

    npm i -g @askalf/dario or brew install askalf/tap/dario · 0 runtime deps · SLSA-attested every release · nothing phones home · ~45k lines of TypeScript across 88 files · independent, unofficial, third-party (DISCLAIMER.md)

    Start · Why dario · Routing · Risk · Reference · Trust · Coming back after a while?


    You already pay for Claude,1 for ChatGPT, or both. Each plan spends through its own runtime: Claude Code and the Agent SDK on one side, the ChatGPT app and Codex CLI on the other. Cursor, Aider, Cline, Continue, Zed and your own scripts want a base URL and an API key instead, and an API key is a meter: every token billed again, or, on a Max plan since October 2026, a monthly credit balance that stops when it runs out, while the seat's own windows sit idle.

    dario is one local endpoint that puts all of it behind one URL. Point any Anthropic- or OpenAI-compatible tool at http://localhost:3456 and you're done. Each request goes to a seat with headroom. Chain the rest with --pool-fallback and the other plan takes the request when one hits its window, with a metered backend as the last rung if you add one; without a chain, a drained pool returns its honest 429. The ledger prices every request at API rates and shows what each plan absorbed, in the TUI, the dashboard and /metrics.

    Start in 60 seconds

    npm install -g @askalf/dario      # or: brew install askalf/tap/dario
    dario login --no-proxy   # your Claude plan (Pro, Max 5x or Max 20x); add --manual for SSH / headless
    dario proxy              # leave it running, then point any tool at http://localhost:3456 with key `dario`
    

    Anthropic-shaped tools: export ANTHROPIC_BASE_URL=http://localhost:3456 ANTHROPIC_API_KEY=dario. OpenAI-shaped tools use OPENAI_BASE_URL=http://localhost:3456/v1 instead, same key. Every tool that honors those env vars now runs on your subscription.

    Check it answers, from a second terminal:

    curl http://localhost:3456/v1/messages \
      -H "Content-Type: application/json" -H "anthropic-version: 2023-06-01" \
      -d '{"model":"claude-fable-5","max_tokens":64,"messages":[{"role":"user","content":"Hello"}]}'
    

    Add your ChatGPT plan as a second seat with dario add altman.

    What dario does with your login, plainly.

    • It uses the Claude login already on this machine: Claude Code's own store (~/.claude/.credentials.json, or the macOS keychain) or the one dario login saves under ~/.dario/. It refreshes that token when it expires. If this proxy serves only your ChatGPT plan or an API key, start it with --no-claude-auth so it never touches a Claude token that Claude Code here also uses.
    • It sends each Claude request in the shape Claude Code sends, which is what keeps it billing to your plan. --strict-tls and --stealth go further and match Claude Code's TLS handshake and request timing.
    • It talks only to the backends you set up, and reports nothing anywhere. Claude and ChatGPT traffic goes over HTTPS; a backend you add with dario backend add uses whatever its base URL says, so an http:// URL there is sent unencrypted, key included.
    • Whether this use fits each plan's terms is for you and the provider to decide: Anthropic's consumer terms, and the terms of your ChatGPT plan. The longer answer: Will my account get suspended?

    Works with: Claude Code, Cursor, Aider, Cline, Roo Code, Kilo Code, Continue.dev, Zed, OpenHands, OpenClaw, Hermes, Codex CLI, the Claude Agent SDK, the Anthropic and OpenAI SDKs, curl, your own scripts. Per-tool setup →

    Prefer Homebrew? brew install askalf/tap/dario installs the same npm release through a formula that follows the registry (tap); upgrade with brew upgrade dario. Prefer Docker? ghcr.io/askalf/dario:latest, multi-arch (amd64 + arm64), published from the same workflow as every npm release (guide). Something off? dario doctor prints one paste-ready health report.

    Why people pick it

    • Every tool, one URL, either plan. No per-tool keys and no second bill: anything with a base-URL setting runs on the plan you already pay for, your ChatGPT plan behind Claude Code and the Anthropic SDKs, Codex CLI on your Claude plan. Per-tool setup · Two plans
    • Spends the plan before the meter, and finishes the answer. Seats with headroom first, then the --pool-fallback chain you configure: the other plan on a 429, a metered rung last (your Max plan's API credits through a Console key, or an openai-compat backend). No chain means no substitution: a drained pool returns its honest 429. When one model family is parked but the seat still has room, --family-fallback=fable=claude-opus-5-5 serves it as another Claude model instead of a 429 (how). A stream that dies mid-answer is completed on the same model first, chain or not. Nothing is swapped silently: every substituted response says so in a header. Failover
    • Knows who paid, and stops before it costs you. A ledger prices every request at API rates and splits it by plan, by key and by model: what the seats absorbed, what went to extra usage or an API key. In the TUI, the dashboard at /analytics/ui, /analytics, Prometheus /metrics and dario usage (analytics). The overage guard halts the proxy the moment a response bills outside your subscription (guardrails), and shadow compare benchmarks your own traffic against another model, read with dario compare (shadow compare).
    • Many seats, one key per developer. Per-model headroom routing, session-sticky prompt cache, in-flight 429 failover across every seat you hold. New conversations go to the seat with the most headroom by default; --pool-strategy=fill-first fills seats in alias order, expiring-first spends the seat whose weekly window resets soonest, and headroom-by-plan counts each seat's headroom by its plan size, shown in the startup banner, GET /status, dario doctor and dario accounts list (the pool). Named keys carry a preferred seat, a model allowlist and a daily budget; a CI job or a sandboxed agent can be a key with no secret to hold, through --key-socket (key sockets, keys).
    • Tracks Claude Code on its own. Ten unattended watchers run on a schedule: six watch what Claude Code sends, its remote config, how it bills and how it behaves at run time, and four watch the ChatGPT backend, Anthropic's prices, whether the running deploy matches the release, and the watchers themselves. The fix usually ships the same day. Drift

    What it does with a request

    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 + Claude Code template, then api.anthropic.com
    Anthropic Messagesa slug your ChatGPT account listsCodex engineMessages→Responses translation, subscription auth
    Anthropic Messagesgpt-4o, llama-*, any name no plan listsRefused400 + x-dario-upstream-rejection: model_unroutable; reach an API-key backend from this shape with a provider prefix
    OpenAI Chatgpt-* / o1-* / o3-* / o4-*OpenAI-compat backendAuth swap, body forwarded byte-for-byte
    OpenAI Chata slug your ChatGPT account listsCodex enginechat/completions→Responses translation, subscription auth
    OpenAI Chatclaude-*Claude poolOpenAI→Anthropic translation, then the Claude path
    Either<provider>:<model>Forced by prefixExplicit override

    The tool doesn't know. The backend doesn't know. dario is the seam.

    The full Claude lineup, shortcuts, the live model catalog and when a name is refused: routing.md.

    Watch it work

    Every proxy serves a dashboard at http://localhost:3456/analytics/ui: the seats and their headroom, who paid for the last hour, the live request tail, what the ledger says your plans absorbed, 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. Sample data above, rendered from the shipped page; served by a running proxy it goes live with the analytics token or an API key. Analytics

    Will my account get suspended?

    The most common question about dario, and it deserves a straight answer: 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.

    Reference

    Trust & transparency

    SignalStatus
    Source~45k lines of TypeScript across 88 files. One credential path since v5: the pool.
    Dependencies0 runtime. Verify: npm ls --production
    ProvenanceEvery release SLSA-attested via GitHub Actions + Sigstore, published with OIDC trusted publishing: no long-lived npm token exists to leak
    ScanningCodeQL on every push to master, every PR and weekly · ClusterFuzzLite fuzzes the SSE translator, the rejection parsers and the cch stamper weekly · the OpenSSF Scorecard badge above and the Best Practices entry are live
    Tests289 test files run in parallel by npm test on Node 18, 20 and 22; the live e2e / compat / stealth suites have their own entry points. Green on every release
    CredentialsYour own subscription tokens, never logged, redacted from errors, 0600 on disk in 0700 dirs
    NetworkBinds 127.0.0.1 by default; upstream only to configured backends over HTTPS; hardcoded SSRF allow-list; refuses a non-loopback bind without DARIO_API_KEY; refuses cross-origin and DNS-rebound browser requests
    TelemetryNone. No analytics, no tracking, nothing phones home
    OverheadMeasured in the open on every PR: scripts/bench-overhead.mjs runs a real proxy against an instant upstream beside a bare http server serving the same bytes. On loopback dario adds no measurable p50 wall time over that floor; the CPU per request is the number to watch, and the per-request timing split shows it live
    This READMECI fails if the line count above drifts from src/ or a link or anchor here stops resolving (check-readme-line-count.mjs, check-readme-links.mjs); the TUI screenshots are rendered from the real TUI and the diagrams are briefed art, not screenshots (how)
    npm audit signatures
    npm view @askalf/dario dist.integrity
    cd $(npm root -g)/@askalf/dario && npm ls --production
    

    Security reports go to [email protected], not a public issue: SECURITY.md. API stability commitments (@stable / @experimental / @deprecated, deprecation cycles): STABILITY.md.

    Deep dives

    Contributing

    PRs welcome. Small TypeScript codebase, zero runtime deps. Architecture, file-by-file map and the review bar in CONTRIBUTING.md; release mechanics in RELEASING.md.

    git clone https://github.com/askalf/dario && cd dario
    npm install
    npm run dev    # tsx, no build step
    npm test       # 289 files in parallel via test/all.test.mjs
    npm run e2e    # live proxy + OAuth (needs a working Claude backend)
    

    Drift and audit runners, none of them part of npm test:

    npm run drift:wire     # compare a live Claude Code capture against the baked template
    npm run drift:sdk      # Agent SDK / Stainless pin drift
    npm run audit:tui      # drives the real TUI through a fake TTY at 12 geometries
    npm run check:overage  # overage-classifier check against live headers
    npm run stress         # concurrency / queue behaviour under load
    npm run cch:calibrate  # re-derive the billing-tag cch seed for a new Claude Code build
    npm run readme:assets  # regenerate the diagrams and TUI screenshots (README + docs/)
    

    Two easy ways to help beyond code: star the repo, the clearest signal this is useful, and file drift: open an issue when a rate-limit header flips or a tool that worked yesterday breaks today, and it gets documented in public alongside the fix. Follow @ask_alf for drift bulletins as they land.

    Everyone whose issue, pull request or audit shaped dario is credited in CONTRIBUTORS.md.

    Disclaimers

    dario is an independent, unofficial, third-party project. Not affiliated with, endorsed by, or sponsored by Anthropic, OpenAI, or any vendor referenced here. Provided as-is, no warranty. You are solely responsible for compliance with your subscription's terms, the security of your credentials, and the content you send through the proxy. Not for safety-critical, regulated, or production environments without your own review. Full text: DISCLAIMER.md.

    License

    MIT. See LICENSE and DISCLAIMER.md. The embedded README font is Space Mono under the SIL Open Font License.

    Own Your Stack

    dario is the routing layer of Own Your Stack, open tools for owning your AI infrastructure instead of renting it by the token. One subscription. Your box. Your terms.

    Built by Thomas Sprayberry

    dario is part of Own Your Stack, the open toolkit behind Sprayberry Labs, the software studio with one human on staff, run by askalf, the AI operation these tools are part of.

    Built in the open, scars included. Follow the build: @ask_alf

    Sponsors

    dario is funded by its users through GitHub Sponsors: the live-test seats it is checked against before every release are the biggest line item. Sponsors at $25/month and up are listed here.

    This block and the thank-you in each release's notes come from scripts/sponsors.mjs, which reads the public sponsor list; sponsors-readme.yml opens a PR when it changes. Private sponsors are never named.

    Star history

    Footnotes

    1. Pro, Max 5x or Max 20x; the current prices are on claude.com/pricing. ↩