PlanLimits CLI (local helper)
A free, zero-dependency Node tool (v0.1.0, Node 18+). It reads your local Claude Code and Codex CLI logs, works out how much of each plan you've used, and tells you which plan to use now. It is the same routing logic as the router. It is not on npm; it runs straight from this site.
Install / run
npx https://planlimits.app/cli/planlimits.tgz status npx https://planlimits.app/cli/planlimits.tgz route --task refactor npx https://planlimits.app/cli/planlimits.tgz route --offline # sends nothing at all npx https://planlimits.app/cli/planlimits.tgz init # writes ~/.planlimits.json
Or download planlimits.tgz and run npm i -g ./planlimits.tgz, then use planlimits status.
What it reads (and what it detects)
| Tool | Where | How the state is decided |
|---|---|---|
| Claude Code | ~/.claude/projects/**/*.jsonl, ~/.config/claude/projects or $CLAUDE_CONFIG_DIR | Auto, partly estimate. Token use in the current 5-hour block (ccusage-style) and the last 7 days. A "usage limit reached" message in your logs means session_hit (or weekly_hit). Anthropic publishes no token limits, so "low" needs your own thresholds in ~/.planlimits.json (labeled estimate). |
| Codex CLI | ~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl (or $CODEX_HOME) | Auto. Uses the 5-hour and weekly used_percent and resets_at that OpenAI's servers report and Codex writes to your log. Windows at 100% mean hit; at 80% or more (configurable) mean low. The plan comes from plan_type. |
| Cursor, Copilot, Windsurf, others | none | Manual. Set each plan's state in ~/.planlimits.json. |
{
"plans": {
"claude-pro": "auto",
"codex-plus": "auto",
"cursor-premium": "fine",
"copilot-pro": "low"
},
"thresholds": {
"claude-code": {
"session_tokens": null,
"weekly_tokens": null,
"low_ratio": 0.8
},
"openai-codex": {
"low_percent": 80
}
}
}
Plan ids are the same as on the router and the API (e.g. claude-max-5x, codex-pro, cursor-super, copilot-pro-plus). States: fine, low, session_hit, exhausted (or weekly_hit).
Privacy
- Your logs, prompts, code and keys never leave your machine. The CLI only reads token counts, timestamps and limit messages.
route(online) sends only plan ids, states and the task type to/api/v1/route. That is the same data the router page logs anonymously: no IP and no email are stored.--offlineorPLANLIMITS_OFFLINE=1sends nothing and uses the plan data bundled in the package (checked 2026-10-19).- The Claude Code hook always runs offline.
Local MCP server
planlimits mcp serves get_my_usage and route_me over stdio, filled in from your local logs.
Claude Code:
claude mcp add planlimits-local -- npx https://planlimits.app/cli/planlimits.tgz mcp
Cursor (~/.cursor/mcp.json):
{
"mcpServers": {
"planlimits-local": {
"command": "npx",
"args": [
"-y",
"https://planlimits.app/cli/planlimits.tgz",
"mcp"
]
}
}
}Add --offline after mcp to keep it fully local. For the hosted data-only server, see MCP docs.
Claude Code hook (warn + hand off)
npx https://planlimits.app/cli/planlimits.tgz hook install claude-code npx https://planlimits.app/cli/planlimits.tgz handoff codex npx https://planlimits.app/cli/planlimits.tgz hook uninstall claude-code
What install does (after asking you to confirm):
- Copies the CLI to
~/.planlimits/cli. - Backs up
~/.claude/settings.json. - Adds one
Stophook. Your other settings and hooks are kept.
After each Claude Code reply the hook checks your local usage. If Claude Code is low or limited, it shows a warning with the route, and saves ~/.planlimits/handoff.md (project folder plus Claude's last message). planlimits handoff codex then starts Codex with that context.
What it can't do: it cannot move, pause or switch a running session. It warns you and prepares the handoff; you decide.
hook uninstall removes only the PlanLimits entry, after another backup. Invalid settings files are never edited.
Known limits
- Claude Code limits aren't published, so Claude states other than "limit message seen" are estimates based on your thresholds.
- Codex numbers are the last snapshot on this machine; usage on other machines or in the cloud only shows up after your next local turn.
- Log formats can change between versions. If detection looks wrong, set a manual state in the config.
Uninstall
npx https://planlimits.app/cli/planlimits.tgz hook uninstall claude-code rm -rf ~/.planlimits ~/.planlimits.json
Nothing else is installed. npx keeps a cache that you can clear with npm cache clean --force.