npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@rikcodes/teamclaude

v1.1.27-rik.1

Published

Multi-account proxy for Claude Code and Codex: pools Claude Max, ChatGPT/Codex, API-key and third-party backend accounts, and rotates on quota

Readme

TeamClaude

Fork notice (rikbrown). This fork adds two features on top of KarpelesLab/teamclaude, currently based on upstream 1.1.26:

  • OpenAI models via a Codex sidecar (sidecars + customModels, opt-in): route gpt-* requests through a supervised local translating proxy to a ChatGPT subscription, under real model names — /model gpt-5.6-sol in the picker and typed, correct 272k context sizing, and dispatchable GPT subagents — while Claude traffic stays on the Claude accounts.
  • Burn-rate projection (projection, on by default): sample each bucket's consumption over a rolling window and tag every account row with whichever window binds first — Ses TTL 38m when it runs out before it resets, Wk 22% unspent when the reset arrives first and that much expires. A readout only: no selection code reads it.

Setup and use of each: Fork features.

Published as @rikcodes/teamclaude; self-update tracks that package, so installs of this fork can never be replaced by an upstream release.

npm install -g @rikcodes/teamclaude

Already have upstream installed globally? Run npm uninstall -g @karpeleslab/teamclaude first — both packages provide the teamclaude and teamrouter commands.

Branch: rik/main. Everything else matches upstream.

CI npm version node License: MIT

Multi-account proxy for Claude Code and Codex: it pools Claude Max, ChatGPT/Codex, API-key and third-party backend accounts, and rotates on quota.

It sits between the coding agent and the provider's API, holds several accounts, and moves to the next one when the current account gets close to its session or weekly limit. The session keeps running instead of stopping on a 429. Claude accounts serve Claude Code, Codex accounts serve the Codex CLI, and both pools share one proxy.

It is built for one person. The "team" is the agents: someone running ten, or fifty, coding-agent sessions at once needs more than one subscription, and switching accounts by hand each time one fills up is what this replaces. Every account in the pool is your own, and the client is the provider's own CLI. It is not a way to share an account between people, and not a bridge for other clients onto subscription credentials — see Scope.

TeamClaude TUI

Quick start

Node.js 20+ required.

npm install -g @rikcodes/teamclaude

teamclaude login     # browser OAuth, run it once per account
teamclaude server    # start the proxy, shows the TUI
teamclaude run       # in another terminal: Claude Code through the proxy

Already logged into Claude Code? teamclaude import takes its credentials instead of a fresh OAuth round. A container image is on GHCR — see Running in a container. API keys, and one email holding accounts in several orgs, are covered in docs/accounts.md.

What it does

  • Rotates to the next account when the 5h session or 7d weekly bucket reaches the threshold (98% by default), preferring the account whose weekly quota resets soonest.
  • Projects each quota window's burn rate against its reset, so a row says Ses TTL 38m · Wk 22% unspent instead of leaving you to read it off a bar (projection, this fork).
  • Tracks the per-model weekly cap separately, so an account out of Fable quota is skipped for Fable requests and still serves Opus and Sonnet.
  • Tells a spent quota bucket apart from a per-minute rate limit and only rotates on the first one. Rotating on a rate limit would just move the burst to the next account and drop the warm cache, so it paces the same account instead.
  • Paces requests onto a freshly switched account, so a herd of agents failing over at the same instant doesn't throttle it and cascade down the fleet.
  • TUI with quota bars, reset countdowns, activity log, and settings you can change while it runs, including adding and removing accounts.
  • Opt-in MCP endpoint that hands the same control plane to Claude Code as tools, so an agent can read the fleet's quota or switch accounts from inside a session.
  • Catches hardcoded api.anthropic.com endpoints (the Claude Design MCP, for one) through a local MITM forward proxy, not only what ANTHROPIC_BASE_URL covers.
  • Holds the request open until quota resets instead of returning 429 when every account is spent, so an unattended run finishes on its own (holdSeconds, off by default).
  • Steers new conversations to one account for a while (teamclaude steer, or t in the TUI) and leaves the running ones where their prompt caches are, so one account's week can be spent first. With --redeem it then spends that account's banked reset, once.
  • Optionally leans on accounts with Anthropic's paid extra usage once every account is out of free quota, instead of returning 429 (allowExtraUsage, off by default — it bills real money). Quota between the switch threshold and 100% is used first, on any account; billing starts only when none is left, and stops as soon as a window resets.
  • Refreshes OAuth tokens before they expire and writes them back to config. Client refreshes pass through untouched.
  • Pools OpenAI Codex subscriptions alongside Claude accounts (experimental): the Codex CLI is routed through the same proxy, by config or transparently through the MITM proxy, and rotates on its own quota.
  • Takes any Anthropic-compatible API (DeepSeek, GLM) as a low-priority fallback for when the Claude accounts are done.
  • Sends one account's traffic through its own HTTP or SOCKS proxy (login --routing "socks5h://user:pass@host:1080"), sign-in and token refresh included, and leaves every other account alone. If that proxy goes down, the request fails over to the next account.
  • Serves OpenAI models next to Claude ones — a supervised local sidecar translates gpt-* requests onto a ChatGPT subscription, with real model names in /model and GPT subagents dispatchable from a Claude parent (sidecars + customModels, this fork).
  • Ships those subagents as a Claude Code plugin: one named agent per model and effort level, which the Agent tool's model parameter cannot express (/plugin install rikclaude-agents@rikclaude, this fork).
  • Shows the fleet's quota inside Claude Code: a readout in the prompt footer and per-seat bars in a pane, as a Claude Code mod (teamclaude-hud, /plugin install teamclaude-hud@rikclaude, this fork).
  • No dependencies. Node built-ins only.

Everyday commands

teamclaude accounts          # accounts with tier and token status
teamclaude status            # live proxy status, needs a running server
teamclaude disable <name>    # pause an account without removing it
teamclaude priority <name> 1 # rotation order, lower = preferred
teamclaude alias --install   # make plain `claude` go through the proxy
teamclaude help              # everything else

Full reference: docs/usage.md.

Configuration

Config is at ~/.config/teamclaude.json ($XDG_CONFIG_HOME honoured) and is meant to be hand-editable. A proxy API key is generated on first use. Observed quota goes to a separate teamclaude.state.json next to it, safe to delete since quota gets re-learned from traffic.

Every field, plus environment variables and network tuning: docs/configuration.md.

How it works

  1. Claude Code talks to the local proxy instead of api.anthropic.com.
  2. The proxy picks an eligible account, injects that account's real token, and rewrites account_uuid in the body to match.
  3. anthropic-ratelimit-unified-* response headers feed the session (5h) and weekly (7d) quota view, which survives a restart.
  4. At the threshold, rotation moves on. On a quota 429 the request is resent on another account, so the client never sees the limit while some account still has headroom.
  5. Expiring tokens, transient network errors and client token refreshes are handled inside the proxy, so none of them interrupt the session.

Step-by-step lifecycle: docs/routing.md.

Fork features

How to set up and use the features in this fork. Everything else in this README is upstream behaviour.

OpenAI models via a Codex sidecar

A Claude Code session can use OpenAI models alongside the Claude accounts. They are billed to a ChatGPT Plus/Pro subscription and use their real model names in the same session. TeamClaude does not translate the wire format itself. A local sidecar does this: raine/claude-code-proxy speaks /v1/messages on the front and the Codex Responses API on the back. TeamClaude starts and supervises this process. It sends every gpt-* request to the sidecar and keeps every other request on the Claude accounts.

1. Install the sidecar and log it into your ChatGPT account (one time):

curl -fsSL https://raw.githubusercontent.com/rikbrown/claude-code-proxy/rik/main/scripts/install.sh | bash
claude-code-proxy codex auth login

This installs rikbrown/claude-code-proxy, a fork of the reference sidecar. Take the fork rather than upstream's Homebrew build: it forwards Codex's quota headers, without which every bar on the account reads unknown, and it lets you raise the 60-second header timeout that otherwise kills a long reasoning turn. See Timeouts.

2. Connect it — add four pieces to ~/.config/teamclaude.json:

{
  "sidecars": [
    { "name": "codex", "command": ["claude-code-proxy", "serve", "--no-monitor", "--port", "18765"] }
  ],
  "accounts": [
    { "name": "codex", "type": "oauth", "accessToken": "unused-local-sidecar",
      "upstream": "http://127.0.0.1:18765", "priority": 100 }
  ],
  "routes": [
    { "name": "codex", "match": ["gpt-*"], "accounts": ["codex"] },
    { "name": "anthropic", "match": ["*"], "accounts": ["your-claude-account", "..."] }
  ],
  "customModels": [
    { "model": "gpt-5.6-sol",   "label": "GPT-5.6 Sol",   "contextTokens": 272000 },
    { "model": "gpt-5.6-terra", "label": "GPT-5.6 Terra", "contextTokens": 272000 },
    { "model": "gpt-5.6-luna",  "label": "GPT-5.6 Luna",  "contextTokens": 272000 }
  ]
}
  • sidecars — the process that TeamClaude owns. It starts with the server, restarts with backoff after a crash, and stops on shutdown. Its pid, restart count and latest stderr lines are in teamclaude status --json under sidecars.
  • accounts — the sidecar as a third-party backend account. The token is a placeholder because the sidecar uses its own Codex login for authentication. priority: 100 is the convention for third-party backends. The routes determine what reaches it.
  • routes — sends gpt-* to the sidecar. Keep the catch-all * route. Without it, the sidecar joins the exhaustion-fallback pool. A spent Claude fleet would then silently send Claude-model requests to the sidecar, which maps claude-* names onto GPT models. With the route, a request can reach a GPT model only when it asks for one by name.
  • customModels — the rows that make the models visible to Claude Code (next section).

3. Restart the server. teamclaude status --json should show the sidecar as running. If it enters a crash loop, stderrTail explains why — the usual cause is that the sidecar is not logged in.

How models get into Claude Code

Claude Code offers only models that it knows, and it does not know gpt-*. customModels closes this gap. Each row contains a model id that the proxy can serve, an optional picker label and description, and the model's context window.

At launch, teamclaude run — and the claude alias, which passes through run — gives these rows to Claude Code:

| Row field | Where it ends up | | --- | --- | | model, label, description | A /model picker row under the real model id (--settings), so /model gpt-5.6-sol works picked or typed | | model | Nothing by default. Set "customModelAgents": true and each row also becomes a plain subagent named after the model (--agents), so "dispatch a gpt-5.6-terra subagent" works from a Claude parent. Off because those agents pin no effort and outrank every agent file on disk — prefer the effort-pinned plugin agents | | contextTokens | CLAUDE_CODE_MAX_CONTEXT_TOKENS, set to the largest value across rows, so Claude Code compacts at the real window instead of assuming 200k |

For tools that spawn claude themselves, teamclaude env can set only environment variables. It carries the window and ANTHROPIC_CUSTOM_MODEL_OPTION for the first row. Agents do not depend on either mode: they are read from disk, whether they come from the rikclaude-agents plugin or from a ~/.claude/agents/<name>.md you write with model: gpt-5.6-terra in its frontmatter.

Each request is routed by the model name in its body, so one session can freely mix models: use claude --model gpt-5.6-sol for a whole session, /model gpt-5.6-sol during a session, or a Claude parent that dispatches a GPT subagent.

To add a model:

  1. Check that your sidecar build lists it: curl -s http://127.0.0.1:18765/v1/models. The sidecar has its own allow-list and rejects any id that it does not know, regardless of the TeamClaude configuration. Upgrade the sidecar if the id is missing.
  2. Add a customModels row. Codex publishes the window for each model as context_window in ~/.codex/models_cache.json; copy it to contextTokens.
  3. Start a new teamclaude run session. The rows are read at launch, so you do not need to restart the server. If you upgraded the sidecar binary, restart the server — or send SIGTERM to the sidecar process and let the supervisor restart it with the new binary. The first SIGTERM only starts a graceful shutdown, which a request in flight holds open; send it a second time to force the exit.

Claude Code prints one [claude-code:unrecognized_model] line to stderr for each custom model. This is expected; suppressing it would lose the correct context window. The quota bars for the sidecar account show unknown unless the sidecar forwards Codex's rate-limit headers, which the fork build in step 1 does and upstream's does not — see Quota. Keep the sidecar on loopback.

The sidecar appears under the account table as a ⚙ line rather than a row because it holds no subscription, is the only account its route can use, and never rotates. The line also shows its supervised process state (up pid 98018, or down (code 1) 3 restarts), followed by what the sidecar reports about itself while it is up (2 active 3 errors, read from its own /monitor endpoint; each is omitted at zero, and both are omitted if that endpoint does not answer).

Several ChatGPT accounts

Read the terms of service before setting this up. OpenAI's Terms of Use prohibit rotating ChatGPT subscriptions past a spent window, and account suspension is a plausible consequence. This is a sharper trade-off than pooling Claude subscriptions because the first-party client lets you switch Claude subscriptions by hand.

One sidecar holds one ChatGPT login, so GPT requests do not rotate and its quota belongs to a login that TeamClaude does not own. Point the sidecar's back leg at TeamClaude so native Codex accounts serve it instead:

Claude Code ──▶ TC /v1/messages (gpt-*) ──▶ sidecar account ──▶ sidecar translates
            ──▶ TC /backend-api/codex/responses ──▶ ChatGPT account pool ──▶ chatgpt.com

Each hop is classified by its path, and the subscription partition keeps the pools apart: on the way in only the sidecar account is eligible, on the way back only the ChatGPT accounts. One route lists both.

1. Add the accounts — run teamclaude login --codex once for each one. A Codex login takes its email as its name. Your Anthropic account probably uses the same name, so the Codex name gets a prefix to keep it unambiguous:

$ teamclaude login --codex
Named "codex:[email protected]" — "[email protected]" is already an account on another provider.

2. Redirect the sidecar and stub its own login, so TeamClaude supplies the credential instead:

{ "name": "codex",
  "command": ["claude-code-proxy", "serve", "--no-monitor", "--port", "18765"],
  "env": {
    "CCP_CODEX_BASE_URL": "http://127.0.0.1:3456/backend-api/codex/responses",
    "CCP_CODEX_TRANSPORT": "http"
  } }
cd ~/.config/claude-code-proxy/codex
cp auth.json auth.json.bak                      # the real login — keep it
echo '{ "access": "delegated-to-teamclaude", "refresh": "", "expires": 4102444800000 }' > auth.json

The sidecar refuses to start with an empty store but never refreshes a far-future token, and TeamClaude replaces both the bearer and the account header on the way out. Leave accountId unset so none of the sidecar's own identity can leak.

3. Put them all on the gpt-* route, sidecar included, and give each account a headersTimeoutMs — the 120s fleet default is shorter than a long reasoning turn:

{ "name": "codex", "match": ["gpt-*"],
  "accounts": ["codex", "codex:[email protected]", "codex:[email protected]"] }

4. Restart the server. A sidecars[].env change is read once at startup, so a reload is not enough.

Three details matter:

  • Leave the sidecar account on the route. It can look removable because it is not a subscription or an account row, but it is the routing target for the way in. Without it, every gpt-* request fails to find an account while teamclaude status shows two healthy ChatGPT accounts on the route.
  • CCP_CODEX_TRANSPORT=http is required. A WebSocket upgrade is relayed with the caller's own headers and draws no account, so the WebSocket transport cannot be pooled.
  • Do not reuse a name across providers. Routes address accounts by name, so a shared name admits both — including the Claude account that cannot serve gpt-*, which outranks the sidecar on priority and wins. TeamClaude warns at startup when it sees one.

One thing differs from the single-account setup: each turn appears twice in the activity list, once per hop. Tokens and quota bars both come from the second hop, where the subscription is, so they are booked against the ChatGPT account that served. The sidecar account holds a stub login and spends nothing of its own, so it reads N req · 0 tok — booking it as well would double every figure.

Full details, including what happens to quota on each hop: Several ChatGPT accounts behind one sidecar.

Burn-rate projection

This feature is on by default. Each account row shows which window binds first: Ses TTL 38m when the session bucket runs out before it resets, or Wk 22% unspent when the weekly reset arrives first and that amount of quota expires. This is a readout only; no selection code reads it. Tune or disable it with projection: { enabled, windowMinutes, wasteFloor }. Details: Quota.

Documentation

| Page | Contents | | --- | --- | | Accounts | OAuth login, import, API keys, multiple orgs, syncing tokens across machines via callback.net, per-account proxy routing, Codex accounts, third-party backends | | Usage | Server and TUI, running Claude Code, shell alias, command reference, browser dashboard, MCP endpoint, CLIProxyAPI-compatible usage API, logging | | VS Code | The Claude Code extension for VS Code through the proxy: settings, a check, updates | | Routing | Rotation, the two kinds of 429, storm control, model routes, session spreading, pinning, prompt cache | | Quota | Quota probe, keep-warm, holding on exhaustion | | OpenAI models | Codex sidecar setup, custom model registration, GPT subagents, limitations | | Subagents | The rikclaude-agents plugin: effort-pinned agents per model, installing it, seeding it for a team | | Configuration | Config format, every field, environment variables, network tuning | | Proxy modes | MITM forward proxy, upstream proxy, per-account routing, sx.org residential egress | | Remote host | Running the fleet on an always-on box: reaching it, moving the accounts, service supervision, pointing clients at it | | Compliance | Who the project is for, and terms of service notes for each provider | | Contributing | What is in scope, and what a pull request needs |

Renaming to TeamRouter

TeamClaude is becoming TeamRouter — it pools Codex and third-party accounts as well as Claude ones, and the name should say so. The rename is spread over several releases so that nothing installed, scripted or configured breaks; the plan and its progress are in issue #72. As of this release the new name is accepted everywhere while the old one stays canonical: teamrouter runs the same CLI as teamclaude, every TEAMCLAUDE_* variable is also read as TEAMROUTER_*, every /teamclaude/… control route also answers at /teamrouter/…, and a ~/.config/teamrouter.json is used when it exists. Nothing on an existing install needs to change, now or when the default flips.

Releasing this fork

Versions are <upstream base>-rik.<n>, e.g. 1.1.19-rik.1. The self-updater orders that tail and installs only that shape (x.y.z or x.y.z-rik.N), so every publish reaches existing installs within a day.

  1. Rebase onto the upstream release you want as the base, if any.
  2. Bump version in package.json and commit.
  3. Push to rik/main — the Publish workflow runs the tests, publishes to npm, and cuts a GitHub release.

The workflow authenticates with npm Trusted Publishing (OIDC), which needs a one-time setup on npmjs.com: @rikcodes/teamclaude → Settings → Trusted Publisher → GitHub Actions, owner rikbrown, repo teamclaude, workflow publish.yml. Until that exists, publish by hand:

pnpm publish --publish-branch rik/main --tag latest --otp=<code>

A prerelease version always needs an explicit --tag, and latest is the tag the self-updater reads.

Security

This repository is a personal fork and is not the canonical project. Upstream's canonical sources are unchanged: the KarpelesLab repository and the @karpeleslab/teamclaude npm package.

This fork is distributed as this repository and the @rikcodes/teamclaude npm package, published by rikbrown. The separate package name means it can never be installed over the canonical one.

Neither is ever distributed as a downloadable binary archive, so be wary of any copy that bundles a .zip and tells you to extract and run it. See SECURITY.md for details and how to report issues.

Scope

TeamClaude is a local proxy holding your own credentials and driving the provider's own CLI, for one person's work. That holds for every provider it supports, not only Anthropic:

  • One person, their own accounts. Not account sharing, not a hosted service, not resale.
  • The provider's own client. Claude Code on Claude accounts, the Codex CLI on Codex accounts. No support for other harnesses on subscription credentials.
  • A third-party backend is an account like any other: a key you were issued, used under that vendor's terms.

How this lines up with the providers' terms, including the multi-subscription question people ask most, is written up in docs/compliance.md. Not legal advice. Changes that step outside this scope are not merged; see CONTRIBUTING.md.

License

MIT — see LICENSE.