Sign In

@dexcodesxs/bon

Package Overview
Dependencies
Maintainers
1
Versions
20
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@dexcodesxs/bon

Reverse engineered Bonsai AI CLI — free Claude Opus 4.7 with 1M context, OpenAI-compatible proxy, web dashboard. Cross-platform: termux, linux, macos, windows.

latest
Source
npmnpm
Version
2.5.28
Version published
Weekly downloads
54
157.14%
Maintainers
1
Weekly downloads
 
Created
Source

bonsai.js — free Claude Opus 4.7
preview shown at 2400×1260 (retina) · 4800×2520 4K · SVG source

bonsai.js

Reverse engineered Bonsai AI CLI — enjoy your free AI models.

Open source replacement for @bonsai-ai/cli with OpenAI-compatible API proxy, Statsig exploit, auto key rotation, credential decryption, and premium terminal UI.

install quickstart commands agents models ui changelog findings recon

📜 Latest changes (v2.5.28) — click to expand

v2.5.x — web UI + docs in browser

  • bon ui — launches a full local web dashboard on http://localhost:3000 (express + ejs + htmx + tailwind, zero build, ~5 MB deps). shares session w/ bon CLI via ~/.bonsai-oss/. mobile responsive (hamburger drawer, stacked grids). multi-account dropdown w/ click-to-switch + smart "+ add another account" auto-flow.
  • docs in the UI/docs route auto-renders all 5 markdown files (README, CHANGELOG, MODELS, FINDINGS, TRYBONS_RECON) using marked + tailwind typography. fumadocs-style sidebar + TOC. fetches from github raw w/ 1h cache so works from any install location.
  • bon count "your prompt" — pre-flight token counter using bonsai router's undocumented /v1/messages/count_tokens endpoint. ZERO inference cost. shows user tokens + ~30K cc_system fingerprint = total per-request, plus $/M estimate.
  • OG image — beautiful 1200×630 social preview (SVG-first source, deterministic render). injected as og:image meta into all UI pages.
  • bon ui self-update — checks trybons/VERSION against github on launch, prompts Y/N if newer. auto-installs trybons/ folder if missing (no git clone needed).
  • lucide stroke icons (fixes "models" rendering as "no entry" sign).

v2.4.x — anti-spy + 199 models confirmed

  • --anon mode — per-request random device_id/session_id, neutralized OS headers
  • bon agents — auto-detect cline/cursor/aider/etc + print exact config
  • bon dash — live ANSI dashboard for running api.js
  • bon codex now actually uses OpenAI (was silently mapped to claude)
  • 199 of 213 models tested confirmed working — see MODELS.md

full history → CHANGELOG.md

🕵️ How bonsai spies (RE'd) — click to expand

when u run the official bonsai start, it injects 5 hooks into Claude Code:

  • SessionStart — tarballs ur whole working dir + git bundle of all branches
  • UserPromptSubmit — fires on every prompt, ships diff + transcript + raw prompt
  • Stop / StopFailure / PostToolUseFailure — final exfil

upload runs in a detached background process (survives ctrl+c). 5 minute window. POSTs to api.trybons.ai/snapshots/upload.

bon (this repo) bypasses all of it by just not passing --settings when it launches claude code. hooks never register.

full chain w/ line numbers → FINDINGS.md

What is this?

Bonsai AI (Boolean, Inc.) gives you free access to Claude, GPT, Gemini, and more in exchange for your coding data. Their CLI routes requests through a proxy and collects your prompts, completions, and working directory snapshots.

bonsai.js is a fully reverse-engineered replacement that:

  • Uses the same auth flow (WorkOS device code)
  • Manages the same API keys
  • Launches the same Claude Code / Codex tools
  • Decrypts their encrypted config, blocks snapshot uploads, tracks your limits
  • Auto-rotates keys when you hit the daily token limit
  • Exposes an OpenAI-compatible API — use Bonsai models from curl, Python, any SDK
  • Dumps Statsig feature flags — reveals real rate limits, model names, provider routing

What's new in v2.5.x (latest)

  • bon ui — full web dashboard at http://localhost:3000. express + ejs + htmx + tailwind, zero build step. shares session w/ bon CLI. mobile responsive, multi-account dropdown, /docs browser. see trybons/.
  • bon count "prompt" — free pre-flight token counter (bonsai router has an undocumented /v1/messages/count_tokens endpoint). zero inference cost.
  • OG image for social previews — 1200×630 PNG generated from SVG, injected as og:image on all UI pages.
  • bon ui auto-installs + self-updates — missing trybons/ folder? prompts to download. newer version on github? prompts to update. no git clone needed.
  • 199 of 213 model names accepted by bonsai router (see MODELS.md) — including GPT-5, Gemini 2.5/3.1, Claude Opus 4.5/4.6/4.7, Sonnet 4.5/4.6, Haiku 4.5, GLM-4.6/4.7, Qwen 3.5, DeepSeek V3.2, Mixtral, Kimi K2.5, Cohere Command, MiniMax M2.1, Llama, gpt-oss-120b. For our user, all serve claude-opus-4-7 underneath — see honest update below.

v2.4.x highlights

  • --anon mode — per-request random device_id/session_id/x-claude-code-session-id, neutralized OS headers. bonsai router can't correlate sessions across time. set BONSAI_ANON=1 or pass --anon.
  • bon agents — auto-detects cline/cursor/aider/continue/roo/opencode + prints exact config snippets.
  • bon dash — live ANSI dashboard, req/s sparkline, pool state.
  • bon codex now actually uses OpenAI — was secretly mapping to claude before v2.4.2.
  • smarter rate-limit absorption — api.js loops through whole key pool before returning 429.
  • /stats exposes pool viewpool[], poolFresh, poolLimited, anon, version. bon dash consumes this; you can too.

What was new in v2.3.0

  • Codex flags fully documentedbon --help now has a dedicated CODEX FLAGS section covering all 9 subcommands (exec, resume, fork, apply, review, mcp, plugin, cloud, sandbox) and every option (-c key=val, -s sandbox, --full-auto, --search, -p profile, -i image, etc.). No more guessing.
  • bon cc and bon codex — direct shortcuts that skip the bon start picker. Forward all flags through. bon cc --resume and bon codex exec "fix bug" work exactly like the underlying tool.
  • Smarter 503 / 429 in api.js — used to return a single useless 503 for everything. Now it splits cleanly: 503 only when no key is set (with the actual fix instruction), 429 with Retry-After header + structured body when all keys hit the daily cap. Includes seconds-until-reset so SDKs can back off properly.
  • Transient upstream 5xx auto-retry — api.js now retries once after 500 ms on 502/503/504 from go.trybons.ai. The router blips occasionally; this absorbs them.
  • @bonsai-ai/claude-code bumped to 2.1.112 — npm shipped 20 patch versions since v2.2.0 (was 2.1.92). Router was starting to reject the stale cc_version fingerprint. UA in api.js and bench/fingerprint headers all updated.
  • UI v3 — premium aesthetic — refined cool palette (cooler greens, warmer accents, gold highlights), braille spinner frames (⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏), pill-style status badges with rounded ends, animated banner with tagline, dim-edge frames, divider() and kv() helpers, NO_COLOR / TERM=dumb support so log files stay clean.
  • Steal hint upgradebon steal now walks you through the prereq (npm i -g @bonsai-ai/cli && bonsai login) when nothing's installed instead of failing silently.

What was new in v2.2.0

  • Interactive self-updatebon update now detects your platform (Termux, Linux, macOS, Windows CMD, PowerShell) and prompts Update now? [Y/n] to auto-install the latest version
  • bon bench — benchmark all 6 models side by side: response time, tok/s, token counts, ranked table with winner. Supports --parallel, --verbose, --prompt="..."
  • bon fingerprint — shows everything the router sees about you: device hash, external IP, session info, headers, system prompt hash, local storage contents

What was new in v2.1.0

  • Codex supportbon start option 2 now auto-launches api.js proxy in the background and routes Codex through it. The /responses endpoint translates OpenAI Responses API to Anthropic messages — Codex works out of the box
  • Router bypass fully cracked — reverse-engineered the exact request fingerprint go.trybons.ai validates: Claude Code system prompt (JSON array with billing header), metadata with device_id, ?beta=true query param, and full SDK headers (user-agent, anthropic-beta, x-stainless-*)
  • All models workclaude-opus-4-6 (1M context, default), claude-sonnet-4-6, claude-opus-4-5, claude-sonnet-4-5, claude-sonnet-4-20250514, glm-4.7 — confirmed working through the proxy
  • bon models — new command listing all supported models with routing info and context windows
  • System prompt auto-captureapi.js automatically captures the Claude Code system prompt on first run (spawns a brief CC session, intercepts the prompt, saves to cc_system.json)
  • streamCollect() fix — router returns empty content on non-stream requests; api.js now internally always streams and collects chunks, so both stream and non-stream responses work perfectly
  • fetch() over https.request() — discovered the router rejects HTTP/1.1 (https.request) but accepts HTTP/2 (fetch/undici). All proxy requests now use fetch()
  • Full Claude Code flags passthroughbon start now documents and passes all @anthropic-ai/claude-code flags (40+): --model, --print, --permission-mode, --system-prompt, --effort, --worktree, --mcp-config, --chrome, --remote, and more
  • Update notification — background version check with proper semver comparison (no false alerts)
  • PowerShell installer — native install.ps1 for PowerShell 5.1+ (no && or curl alias issues)
  • api.js — API proxy server with OpenAI + Anthropic format support, streaming, auto key rotation
  • bon statsig — Statsig exploit dumps internal config, rate limits, real model names behind "stealth" display
  • Premium UI overhaul — muted teal/gold/violet palette, gradient banner, unicode-only, no emoji clutter
  • RE updated to @bonsai-ai/cli@0.4.13 — new snapshot hooks (StopFailure, PostToolUseFailure), 8 data collection types

Install

v2.5.8+ ships via npm. one command, every platform:

npm i -g @dexcodesxs/bon
bon --help

That's it. Works the same on Windows / macOS / Linux / Termux because npm handles the bin shim cross-platform. Updates: npm update -g @dexcodesxs/bon (or bon update which auto-runs that for you).

Termux (Android)

pkg install nodejs -y
npm i -g @dexcodesxs/bon

Migrating from the old curl|bash install (≤ v2.5.7)

If you installed via the old script (install.sh / install.ps1 / install.bat), bon will detect this on next run and show a one-time migration notice. To migrate:

npm i -g @dexcodesxs/bon                                          # install via npm
rm -rf ~/.bonsai-oss/bin ~/.bonsai-oss/bonsai.js ~/.bonsai-oss/api.js   # remove old files
bon --version                                                    # verify v2.5.8+

Your auth, keys, profiles in ~/.bonsai-oss/ are untouched — only the binaries get replaced.

Quick Start

bon login              # authenticate with Bonsai
bon start              # launch Claude Code (picker)
bon cc                 # direct claude code (skip picker)
bon codex              # direct codex w/ openai routing
bon ui                 # NEW: web dashboard at localhost:3000
bon api                # OpenAI-compatible proxy on :4000
bon agents             # detect what's installed (cline/cursor/aider/etc)
bon count "your text"  # free pre-flight token counter

API Proxy (new in v2.0.0, major upgrade in v2.1.0)

api.js turns Bonsai into a local API you can hit from anything — curl, Python, OpenAI SDK, Aider, anything that speaks OpenAI or Anthropic format.

v2.1.0 breakthrough: We cracked the full router fingerprint. api.js now injects the Claude Code system prompt, metadata, and SDK headers automatically — every request looks indistinguishable from a real Claude Code session.

bon api                # launch proxy on port 4000
# or
node api.js            # standalone
node api.js -p 8080    # custom port

Supported Models

⚠️ honest update (v2.5.15 — third revision): Round 3 because rounds 1+2 were both partial truths. After a discord user correctly pointed out v2.5.7 cited stale Statsig data, I over-corrected in v2.5.14 to "stealth pool, no fixed model". But the live model self-ID test reveals v2.5.7's headline was actually right.

Empirical truth (7-trial live test on cisez123): Every request serves claude-opus-4-7 with 1M context, reasoning high. Model resists confabulation — when asked "are you Sonnet 4.5?" it replies "No, I am not Sonnet 4.5. I am Claude Opus...". Structured prompt returns: model=claude-opus-4-7, ctx_window=1M, reasoning_effort=99.

Statsig says opus-4.6 but is stale relative to production — they hot-patched routing past the experiment value. Other users in different launchedGroups may bucket to glm-4.6/4.7, sonnet-4.5/4.6, opus-4.5/4.6, or minimax-m2.1. Response always shows display_name: "stealth" (UI hides which model).

Verify yourself: bon api -p 4099 → curl localhost:4099/v1/messages with prompt "what model are you?" — you should see claude-opus-4-7 consistently.

199 of 213 tested model names are accepted by the router (so cline / cursor / codex don't crash on "model not found"). For our user every request actually serves opus-4.7. See MODELS.md for the catalog. Names worth knowing:

FamilyCountExamples
Claude21claude-opus-4-7 (empirical default, 1M ctx), claude-opus-4-6, claude-sonnet-4-6, claude-haiku-4-5
OpenAI75gpt-5, o3, o3-mini, gpt-oss-120b, gpt-realtime-mini
Gemini29gemini-2.5-flash, gemini-3.1-flash-live-preview, gemini-pro-latest
DeepSeek11deepseek-v3-2-251201, deepseek-reasoner
Qwen9Qwen3.5-397B-A17B, Qwen3-Next-80B-A3B-Thinking
GLM (Z-AI)4z-ai/glm-4.7, glm-4-7-251222
Mistral7Mixtral-8x7B-Instruct, codestral-latest
MiniMax5minimax/MiniMax-M2.1, M2.1-lightning
Kimi4kimi-k2-thinking-251104, Kimi-K2.5
Llama / Cohere / Perplexity / others34Llama 3.1 405B, command-r-plus, sonar

1M context modifier: append [1m] to opus models (claude-opus-4-7[1m]).

bon models             # CLI: highlights w/ links
bon ui                 # web: full clickable catalog at /dashboard/models

Endpoints

MethodPathFormat
POST/v1/messagesAnthropic native (passthrough)
POST/v1/messages/count_tokensFree Anthropic token counter (no inference)
POST/v1/chat/completionsOpenAI compatible (auto-translated)
POST/responsesOpenAI Responses API (Codex)
GET/v1/modelsModel list with metadata
GET/healthHealth check
GET/statsSession stats + pool view (used by bon dash)

Usage examples

curl (OpenAI format):

curl http://localhost:4000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model":"claude-opus-4-6","messages":[{"role":"user","content":"hi"}]}'

curl (Anthropic format):

curl http://localhost:4000/v1/messages \
  -H "Content-Type: application/json" \
  -H "anthropic-version: 2023-06-01" \
  -d '{"model":"claude-opus-4-6","max_tokens":1024,"messages":[{"role":"user","content":"hi"}]}'

curl (streaming):

curl http://localhost:4000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model":"claude-opus-4-6","messages":[{"role":"user","content":"hi"}],"stream":true}'

Python (OpenAI SDK):

from openai import OpenAI
client = OpenAI(base_url="http://localhost:4000/v1", api_key="anything")
r = client.chat.completions.create(
    model="claude-opus-4-6",
    messages=[{"role": "user", "content": "hello"}]
)
print(r.choices[0].message.content)

Python (Anthropic SDK):

import anthropic
client = anthropic.Anthropic(base_url="http://localhost:4000", api_key="anything")
r = client.messages.create(
    model="claude-opus-4-6",
    max_tokens=1024,
    messages=[{"role": "user", "content": "hello"}]
)
print(r.content[0].text)

Environment variables (use with any tool):

export OPENAI_BASE_URL=http://localhost:4000/v1
export OPENAI_API_KEY=anything

Features

  • Anthropic <-> OpenAI format translation on the fly
  • SSE streaming support for both formats
  • Auto key rotation when daily limit is hit (multi-account)
  • System prompt auto-injection (Claude Code fingerprint)
  • streamCollect() — internally streams, returns assembled response for non-stream requests
  • Uses fetch() (HTTP/2) — required by router, https.request is rejected
  • Auto-capture of Claude Code system prompt on first run
  • Session stats on shutdown (requests, tokens, estimated savings)
  • Daily limit auto-clear at midnight UTC

Web UI (new in v2.5.0)

bon ui launches a local web dashboard — full multi-page UI with auth, dashboard, key management, activity history, model picker, settings, and docs viewer. Zero build step. Express + EJS + HTMX + Tailwind via CDN. ~5 MB total deps.

bon ui                 # auto-installs trybons/ if missing, boots :3000
bon ui 8080            # custom port
bon ui --update        # force-pull latest UI from github
bon ui --no-update     # skip update check (offline)

Features:

featurewhat
shared sessionreads ~/.bonsai-oss/auth.json so it follows bon login state
WorkOS device codesign in via QR/code in browser, htmx polls for completion
multi-account dropdownclick avatar in sidebar, switch accounts, "+ add another account" auto-flow
/docs browserrenders all 5 markdown files (README, CHANGELOG, MODELS, FINDINGS, RECON) w/ sidebar + TOC + edit-on-github
mobile responsivehamburger drawer on mobile, stacked grids, 44px tap targets
self-updatechecks trybons/VERSION against github on launch, prompts Y/N
OG image1200×630 social preview baked into all pages

Cross-platform: tested on Windows, Linux, macOS, Termux. Pure Node 18+, no native deps.

See trybons/README.md for stack details.

Commands

CommandDescription
bon loginAuthenticate via WorkOS device code flow
bon logoutClear stored credentials
bon startLaunch Claude Code, Codex, or custom tool (picker)
bon ccDirect Claude Code launch, skip picker
bon codexv2.4.2 routes to real OpenAI — direct Codex launch (gpt-5 default)
bon resumeResume last Claude Code session
bon continueContinue last conversation
bon uiNEW v2.5.0 — web dashboard at localhost:3000 (auto-installs trybons/)
bon count "text"NEW v2.4.3 — free pre-flight token counter
bon keysAPI key management (list/create/delete/reveal/import)
bon testTest all API endpoints with status badges
bon infoShow account, config, and consent status
bon whoamiQuick identity check
bon activityView usage activity with token breakdown
bon limitsToday's token usage + time until daily reset
bon statsFull analytics: cost savings, model breakdown, daily chart
bon healthService status check with response times
bon proxy [port]Local proxy server with streaming + token tracking
bon proxy --rotateProxy with auto key rotation on limit hit
bon api [--anon]Launch API proxy (api.js). --anon strips correlation IDs
bon agentsDetect & configure Cline/Cursor/Aider/Continue/Roo/etc.
bon dashLive ANSI dashboard for running api.js (req/s sparkline, pool state)
bon modelsList supported models with routing info
bon benchBenchmark all models (speed, tok/s, ranked table)
bon fingerprintWhat the router sees about you
bon poolView key pool status (fresh vs limited)
bon rotateLaunch Claude Code with auto key rotation
bon multiMulti-account profile management (CLI; UI version in bon ui)
bon stealDecrypt & import official CLI credentials
bon snoopExplain Bonsai's data collection (updated for 0.4.13)
bon statsigExploit Statsig to dump internal configs
bon configView / edit settings
bon troubleshootFix common errors (404, outdated, limits)
bon updateCheck for bonsai.js and package updates
bon dumpFull infrastructure intelligence dump

Flags

Bonsai flags

FlagDescription
--resumeResume last Claude Code session
--continueContinue last conversation
--debugVerbose output
--versionShow version
--helpShow help

Claude Code flags (passed through via bon start)

All @anthropic-ai/claude-code flags work with bon start. Examples:

bon start --model opus                     # use specific model
bon start --print "explain this code"      # non-interactive, print & exit
bon start --effort max                     # max effort (Opus only)
bon start --permission-mode auto           # auto-approve actions
bon start --system-prompt "you are a..."   # custom system prompt
bon start --worktree feature-x             # isolated git worktree
bon start --mcp-config servers.json        # load MCP servers
bon start --chrome                         # enable Chrome integration
bon start --verbose --debug                # full debug output
bon start --max-turns 10 --print "task"    # limit turns in headless mode
FlagDescription
-p, --printNon-interactive mode, print & exit
--model <model>Set model (sonnet, opus, full ID)
--fallback-model <model>Fallback when overloaded
--effort <level>low / medium / high / max
--system-prompt <text>Replace system prompt
--append-system-prompt <text>Append to system prompt
--permission-mode <mode>default / plan / auto / bypassPermissions
--dangerously-skip-permissionsSkip all permission checks
--allowedTools <tools...>Allow tools without prompting
--disallowedTools <tools...>Block tools entirely
--output-format <fmt>text / json / stream-json
--json-schema <schema>Structured JSON output
--verboseFull turn-by-turn output
--name <name>Session display name
--max-turns <n>Limit agentic turns
--max-budget-usd <n>Max spend in dollars
-w, --worktree [name]Isolated git worktree
--add-dir <dirs...>Additional working dirs
--mcp-config <configs...>Load MCP servers
--agent <agent>Use specific agent
--chromeEnable Chrome integration
--remote <task>Create web session on claude.ai
--bareMinimal mode, fastest startup
--settings <file>Load settings JSON

Codex flags (passed through via bon codex or bon start option 2)

All @bonsai-ai/codex (= @openai/codex) flags work. Use bon codex <subcommand> [flags] for a fast path; the api.js proxy handles /responses translation transparently.

bon codex                                  # interactive TUI (defaults to gpt-5)
bon codex exec "refactor api.js"           # one-shot, non-interactive
bon codex --model gpt-5.2-codex            # codex's internal name → maps to gpt-5
bon codex --model claude-opus-4-7          # use claude via codex (override)
bon codex --full-auto                      # sandboxed auto-execution
bon codex -s workspace-write               # sandbox policy
bon codex resume --last                    # resume most recent session
bon codex fork                             # fork a session (picker)
bon codex apply                            # git apply latest agent diff
bon codex --search "best react patterns"   # enable native web_search tool
bon codex -p my-profile -c model="o3"      # use config profile + override
FlagDescription
exec, eRun non-interactively
resume [id]Resume session (--last for most recent)
fork [id]Fork a previous session
apply, aApply latest agent diff to working tree
reviewRun code review on current repo
mcpManage external MCP servers
pluginManage Codex plugins
cloudBrowse Codex Cloud tasks
-c, --config <key=val>Override config (TOML, dotted path)
--enable <feature>Enable feature flag (repeatable)
--disable <feature>Disable feature flag (repeatable)
-p, --profile <name>Profile from ~/.codex/config.toml
--ignore-user-configSkip config.toml (auth still loads)
-m, --model <model>Set model
--ossUse open-source provider
--local-provider <lmstudio|ollama>Local provider (with --oss)
-s, --sandbox <mode>read-only / workspace-write / danger-full-access
--full-autoSandboxed automatic execution
-a, --ask-for-approval <policy>untrusted / on-failure / on-request / never
--dangerously-bypass-approvals-and-sandboxNo prompts, no sandbox
-C, --cd <dir>Working root directory
--add-dir <dir>Additional writable directory
--skip-git-repo-checkAllow running outside a git repo
--ephemeralDon't persist session files
-i, --image <file>...Attach image(s) to initial prompt
--searchEnable native web_search tool
--no-alt-screenInline mode (preserves scrollback)
--remote <ws://...>Connect TUI to remote app server
--output-schema <file>JSON schema for final response

Plugging Other Tools In (new in v2.4.0)

bon agents auto-detects what's installed and prints the exact config snippet. Below is the cheat sheet for the supported tools — they all consume the OpenAI-compatible endpoint at http://localhost:4000/v1.

bon api              # start the proxy first
# or
bon api --anon       # start proxy with anonymized fingerprint to bonsai
bon agents           # see what's installed, get setup instructions
bon dash             # live monitor (in another terminal)
ToolHow to point it at bon
Claude Code (Anthropic)ANTHROPIC_BASE_URL=http://localhost:4000
ANTHROPIC_AUTH_TOKEN=anything
Codex (OpenAI)OPENAI_BASE_URL=http://localhost:4000/v1
OPENAI_API_KEY=anything
Cline (VS Code)Settings → API Provider: OpenAI Compatible
Base URL: http://localhost:4000/v1
Model: claude-opus-4-6
CursorSettings → Models → Add Custom (OpenAI-Compatible)
URL: http://localhost:4000/v1
Model: claude-opus-4-6
Continue (VS Code)~/.continue/config.json:
{"models":[{"title":"bon","provider":"openai","model":"claude-opus-4-6","apiBase":"http://localhost:4000/v1","apiKey":"anything"}]}
Roo Code (VS Code)Settings → API Provider: OpenAI Compatible
URL: http://localhost:4000/v1
AiderOPENAI_API_BASE=http://localhost:4000/v1
OPENAI_API_KEY=anything
aider --model openai/claude-opus-4-6
OpenCodeOPENAI_BASE_URL=http://localhost:4000/v1
OPENAI_API_KEY=anything

All of them respect the 429 + Retry-After response now, and all of them benefit from auto-rotation when you have multiple keys in bon multi.

Statsig Exploit (new in v2.0.0)

Bonsai uses Statsig for feature flags and ships their client SDK key in the CLI bundle. We exploit this to dump their full internal configuration.

bon statsig

What we found

ConfigValue
Daily token limit20,000,000 tokens
Hourly token limit40,000,000 tokens
ProviderOpenRouter (not direct Anthropic)
Models behind "stealth"Claude Opus 4.5/4.6/4.7, Sonnet 4.5/4.6, Haiku 4.5, GPT-5, Gemini, GLM-4.7, Llama, +many more (199 confirmed)
GLM-4.7 routing8 providers (gmicloud, mancer, siliconflow, deepinfra, atlas-cloud, parasail, novita, z-ai)
MiniMax M2.1 routing7 providers (deepinfra, minimax, fireworks, atlas-cloud, novita, gmicloud, minimax-lightning)
Snapshot max size1024 MB (server-tunable per user via Statsig)
cli_snapshot_enabledtrue (default for all users — A/B-testable per account)

The router (go.trybons.ai) proxies to OpenRouter, not directly to Anthropic. Your requests go: bonsai.js -> go.trybons.ai -> OpenRouter -> Anthropic/Google/etc.

Key Rotation (bypass daily limit)

Bonsai has a daily token limit per account. When you hit it, you're locked out until 00:00 UTC.

Solution: auto key rotation. Save multiple Bonsai accounts as profiles, then rotate between them automatically.

# 1. log in with your first account and save it
bon login
bon multi              # choose "Save current", name it "acc1"

# 2. log out, log in with second account, save it
bon logout
bon login              # use different email
bon multi              # save as "acc2"

# 3. repeat for more accounts, then:
bon pool               # see all keys and their status
bon rotate             # launch Claude Code with auto-switch on limit
bon proxy --rotate     # or run a proxy that rotates keys
bon api                # api.js also auto-rotates with pooled keys

When key #1 hits the limit, it automatically switches to key #2 and keeps going.

How It Works

                                                    ┌──────────────┐
┌──────────────┐     ┌──────────────────┐           │  OpenRouter   │
│  bon start   │ --> │  Claude Code      │ -------> │  (real       │
│              │     │  (bonsai fork)    │           │   provider)  │
└──────────────┘     └──────────────────┘           └──────────────┘
                                                           ^
                                                           |
┌──────────────┐     ┌──────────────────┐     ┌──────────────────┐
│  bon api     │ --> │  api.js proxy     │ --> │  go.trybons.ai   │
│  curl/python │     │  :4000            │     │  (router proxy)  │
│  openai sdk  │     │  oai <-> anthro   │     │  validates:      │
│  any tool    │     │  + system prompt  │     │  system prompt   │
└──────────────┘     │  + SDK headers    │     │  headers, meta   │
                     │  + streamCollect  │     │  HTTP/2, ?beta   │
                     └──────────────────┘     └──────────────────┘

Router validation chain: api.js injects the captured Claude Code system prompt (billing header + full prompt as JSON array), metadata with device_id, SDK fingerprint headers (user-agent, anthropic-beta, x-stainless-*), and ?beta=true query param. Uses fetch() for HTTP/2 compliance. Internally streams all requests and collects chunks for non-stream callers.

What We Cracked

ItemDetails
Config encryptionAES-256-CBC with scryptSync("bonsai-cli", "salt", 32) + PBKDF2
Auth flowWorkOS Device Code OAuth (client client_01K2ZG07ZTYR0FQNERK3PS2CB0)
Router fingerprintSystem prompt (JSON array with billing header) + metadata + ?beta=true + full SDK headers
System prompt formatJSON array: [{billing header}, {prompt part 1}, {prompt part 2}] (~27KB)
Required headersuser-agent, anthropic-beta (6 flags), x-stainless-* (7 headers), x-app, x-claude-code-session-id
HTTP/2 requiredRouter rejects https.request() (HTTP/1.1), accepts fetch() (HTTP/2/undici)
Stream-only responsesRouter returns content:[] on non-stream; must use stream:true internally
Router version checkReads cc_version=2.1.112 from x-anthropic-billing-header (bumped in v2.3.0)
Daily limits20M tokens/day, 40M tokens/hour (via Statsig) — resets at 00:00 UTC
Real providerOpenRouter, not direct Anthropic — all models return "model":"stealth"
Snapshot mechanism5 hooks: SessionStart, UserPromptSubmit, Stop, StopFailure, PostToolUseFailure
Data collection8 types: working_directory, git_bundle, diff, prompt, transcript, subagent_transcripts, tarball, snapshot
Statsig configFully exploitable via leaked client SDK key
Supported clients@anthropic-ai/claude-code, @bonsai-ai/claude-code, @bonsai-ai/codex, @mariozechner/pi-coding-agent

Leaked Keys

The bonsai client app embeds public SDK keys in its JavaScript bundle (Statsig, Segment, GTM, Cloudflare web analytics, Datadog RUM). They're write-only telemetry tokens, not secrets — anyone can read them in browser DevTools on app.trybons.ai. We don't republish them here; if you want to inspect, run bon statsig (uses the keys from your local install) or open DevTools on their app and search for statsig-api-key / writeKey / pub strings.

Infrastructure

Full RE'd surface map → TRYBONS_RECON.md. Summary:

ServiceURLStack
Marketingwww.trybons.aiNext.js 19.2-canary + Vercel + CF
Appapp.trybons.aiVite + React + Vercel + CF + GTM + Segment
APIapi.trybons.aiFastAPI + Fly.io + CF
Routergo.trybons.aiFly.io (no CF) → OpenRouter
Authauth.trybons.aiNext.js 14.2.35 + WorkOS hosted-authkit + CF
Docsdocs.trybons.aiMintlify + Vercel
SSOsso.trybons.aiEnvoy + CF (NEW, found in v2.5 recon)
Formsforms.trybons.aiVercel form handler (NEW)
Realtimert.trybons.ailikely WebSocket (NEW)
Stagingapi-staging.trybons.aiDNS unreachable from edge

auth.trybons.ai shipped sourcemaps to production — 4.4 MB of original TypeScript recovered including live Sentry DSN + Datadog tokens. Full chain documented in TRYBONS_RECON.md.

Environment Variables

VariableDescription
BONSAI_OAUTH_CLIENT_IDOverride WorkOS client ID
BONSAI_BASE_URLOverride backend URL (default: api.trybons.ai)
BONSAI_ROUTER_URLOverride router URL (default: go.trybons.ai)
STATSIG_CLIENT_KEYOverride Statsig client key
BONSAI_API_KEYAPI key for api.js proxy

Troubleshooting

"CLI version outdated"

The Bonsai router checks cc_version from Claude Code's billing header. Current version: 2.1.112 (bumped in v2.3.0). We inject this via the system prompt's billing header. Run bon update to check.

"exceeded daily token limit"

Resets at 00:00 UTC. Check bon limits for usage. Use bon rotate for auto key rotation or bon multi to switch accounts manually. api.js also auto-rotates if you have multiple keys.

"Bad Request" from api.js

The router validates a specific fingerprint. Make sure cc_system.json exists in ~/.bonsai-oss/ (auto-captured on first bon api run). If missing, delete and re-run bon api to trigger auto-capture.

"404 Not Found" on Codex

Codex uses the /responses endpoint which the Bonsai router doesn't support. Both bon start option 2 and the new bon codex shortcut auto-launch api.js as a background proxy that translates /responses to /v1/messages. If you still get 404s, make sure api.js is next to bonsai.js (the installer handles this).

"503" or "all keys rate limited" from api.js

v2.3.0 made this much clearer:

  • 503 only fires when no key is set at all → run bon login && bon keys.
  • 429 (with Retry-After header + retryAfter in body) means every key in your pool hit today's daily cap. Add another account with bon multi, or wait for the seconds reported.
  • Transient 502/503/504 from the upstream router auto-retry once now, so this should be much rarer.

"Invalid Bonsai API key"

Create a new key with bon keys or import from official CLI with bon steal.

Typos

bonsai.js auto-corrects common typos: loign -> login, strat -> start, etc.

Privacy

bonsai.js blocks some of Bonsai's data collection:

  • No snapshot hooks — we don't pass --settings with upload commands
  • No Statsig tracking — no feature flag telemetry
  • No Segment analytics — no event tracking
  • --anon mode (v2.4.0) — randomizes device_id, session_id, x-claude-code-session-id per request, and neutralizes OS/arch headers. Bonsai's router can't correlate your requests across time, sessions, or machines.
bon api --anon              # start proxy in anonymized mode
BONSAI_ANON=1 node api.js   # equivalent

Caveat: Bonsai's router still sees your prompt + response content (this is unavoidable — they validate the request body). --anon only blocks the correlation fingerprint, not the content. If your prompts are sensitive, don't send them to a proxy you don't control. Free models still cost something; pay attention to what.

Credits

Reverse engineered from @bonsai-ai/cli@0.4.13, @bonsai-ai/claude-code@2.1.112, and @bonsai-ai/codex@0.105.1. Router fingerprint discovered via traffic capture analysis. All information from publicly available npm packages and client-side network traffic.

Bonsai AI reverse engineered. Enjoy your free models.
Bonsai AI is a product of Boolean, Inc.

Keywords

bonsai

FAQs

Package last updated on 28 Apr 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts