Use Anthropic ratelimit headers as primary Claude scrape (Clawdmeter method)#39
Merged
Merged
Conversation
…method)
The cookie-based scrapes work but depend on Claude Desktop or Firefox
staying signed in to claude.ai. Hermann Bjorgvin's Clawdmeter (which
Codexmeter forked from) ships a cleaner approach: hit the documented
/v1/messages endpoint with the OAuth bearer Claude Code already keeps
in the macOS Keychain, ignore the response body, and parse the
anthropic-ratelimit-unified-{5h,7d}-{utilization,reset} headers
Anthropic returns on every request. No browser, no Cloudflare wall,
no page-layout fragility.
- New scripts/claude-plan-usage-oauth-headers.py reads the OAuth token
from `Claude Code-credentials` Keychain entry (or ~/.claude/.credentials.json
on Linux), POSTs a 1-token Haiku probe to api.anthropic.com, and
normalizes the rate-limit headers into the same plan-usage cache
shape the daemon already consumes. Falls through to the desktop
cookie script on any failure.
- LaunchAgent + install.sh switched to the headers script as primary.
The cookie scrapers remain as fallbacks.
- local_claude_activity_snapshot reorders to prefer the fresh
plan-usage cache over the statusline hook — the hook only updates
when Claude Code itself makes an inference call, which can be
minutes stale even when its file mtime is fresh.
- Tests now also stub CLAUDE_LIMITS_FILE so they don't read the real
hook file from ~/.claude.
- CLAUDE.md runbook updated to describe the new priority order and
credit Clawdmeter.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 32e7c1d1b5
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
try_fallback() was invoking claude-plan-usage-desktop.py with no args, which made the desktop script default to 'scrape' and overwrite ~/.config/codexmeter/claude-plan-usage.json whenever the OAuth path failed — even when the user ran the oauth-headers script as 'print' for troubleshooting. Forward the command verbatim so 'print' remains non-mutating end-to-end. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Ported the cleaner scrape approach from the Clawdmeter repo that CodexMeter forked from. Instead of decrypting browser cookies and hitting
claude.ai/api/.../usage, the new primary script POSTs a 1-token Haiku probe to the documentedapi.anthropic.com/v1/messagesendpoint with the OAuth bearer Claude Code already keeps in the macOS Keychain, then reads the rate-limit headers Anthropic returns on every response:anthropic-ratelimit-unified-5h-utilization(0.0–1.0 float)anthropic-ratelimit-unified-5h-reset(epoch seconds)anthropic-ratelimit-unified-7d-utilizationanthropic-ratelimit-unified-7d-resetWhy this is better
claude.ai/api/.../usage/v1/messagesChanges
scripts/claude-plan-usage-oauth-headers.py(the new primary). Falls through to the existingclaude-plan-usage-desktop.pyon any failure, which itself falls through to the Firefox script. Three-layer scrape chain.install.shpoint at the headers script as primary.local_claude_activity_snapshotreorders to prefer the fresh plan-usage cache over the statusline hook. The hook lags reality because it only refreshes when Claude Code itself makes an API call — so a fresh-mtime hook file can still describe utilization from minutes ago.CLAUDE_LIMITS_FILEso they don't leak the developer's real~/.claude/plan-limits.jsonstate.CLAUDE.mdrunbook updated with the new priority order and credit to Clawdmeter.Test plan
pytest -q(11 passed)ruff check daemon/ scripts/ tests/clean/health.scrape.source = "oauth_headers",/usagereports5h 38% used · 7d 13% usedmatching what claude.ai shows--no-fallbackis omitted, failures spawnclaude-plan-usage-desktop.pyautomatically🤖 Generated with Claude Code