Your Claude usage limits, in the macOS menu bar, in your timezone.
ClaudeBar shows your Claude plan's usage limits in the menu bar — the same numbers you'd find on Claude's usage page, nothing more. The bar shows the highest percentage across your limits; the dropdown lists each one: session (5h window), weekly across all models, and any model-scoped limits like Fable or Sonnet, each with a progress bar and its reset time in your local timezone.
That's the whole app. No cost tracking, no charts, no extras. The menu renders instantly from cached data and refreshes in the background.
Looking for the same simple menu bar experience for Codex? See CodexBar.
brew install --cask gordonbeeming/tap/claude-barNeeds macOS 15+ on Apple Silicon, plus Claude Code installed and logged in — ClaudeBar reads its OAuth token from the Keychain (read-only; click Always Allow when macOS asks). It never writes or refreshes the token; that's Claude Code's job. If the token expires, ClaudeBar keeps showing the last known numbers with a hint to open Claude Code. macOS re-asks for that Keychain permission every so often — Keychain access explains why, and how self-contained sign-in stops it.
make install
open ~/Applications/ClaudeBar.appmake install signs with your Apple Development identity when one exists, falling back to ad-hoc. Ad-hoc mints a fresh signing identity every build, so the Keychain prompt comes back after each rebuild; a real identity keeps the grant forever.
Open Settings… from the dropdown:
- Usage colours — by default the icon turns orange/red when Claude's API says a limit is at warning/critical. Untick Use Claude's severity levels and you get a blue → orange → red bar: drag the two splitters to pick your own warning and critical percentages.
- Launch at login — on by default, toggle it here.
ClaudeBar polls GET https://api.anthropic.com/api/oauth/usage (once a minute, plus on menu open when stale) with the Claude Code OAuth token, and renders the limits array it gets back — one row per limit with percent used, a progress bar, and "Resets 5:00 pm · in 4h 55m" converted from UTC to your system timezone. The app is an accessory (no Dock icon, no app switcher entry); it just lives in the menu bar.
By default ClaudeBar reads one Keychain item — Claude Code's Claude Code-credentials — to get the OAuth token the usage endpoint needs. In this mode it only reads: it never writes the item, refreshes the token, or touches the refresh token.
macOS gates that read behind a consent prompt. Click Always Allow and macOS trusts ClaudeBar for that item — until Claude Code next rotates its token. Claude Code refreshes its OAuth token a couple of times a day, and every refresh rewrites the Keychain item, which clears the item's list of trusted apps. So the prompt comes back and you grant it again. It isn't a bug in ClaudeBar or a setting that didn't save; macOS treats a rewritten item as new and re-checks who's allowed to read it.
Settings → Usage data source → Self-contained sign-in does its own OAuth login and stores the token in a Keychain item ClaudeBar created. Because ClaudeBar owns that item, macOS never runs the cross-app consent prompt, and Claude Code's rotations don't touch it — so the prompt stops.
It works because ClaudeBar now holds its own token pair: refreshing rotates its refresh token, never Claude Code's, so the CLI stays logged in. That's the trap the obvious "just refresh the token ourselves" idea falls into — Anthropic's refresh tokens are single-use, so refreshing Claude Code's copy logs the CLI out (an unrelated menu bar app hit exactly that: CodexBar #1161). Doing our own login avoids it. If the self-contained token ever fails, ClaudeBar falls back to Claude Code's token, so the worst case is the prompt you already know.
One caveat: sign-in reuses Claude Code's own OAuth client, since there's no public third-party OAuth for this endpoint. It's the same "act as Claude Code" posture as the claude-code User-Agent ClaudeBar already sends, and it could break if Anthropic changes the flow — the fallback keeps the app working if it does.
The default stays read-only and prompt-bearing; self-contained is opt-in.
make run # swift run, straight from source
make test # swift test — core logic is fully unit-testedThe core library (ClaudeBarCore) holds everything testable: ISO8601 parsing, timezone formatting, severity thresholds, JSON decoding that survives unknown limit kinds. The app target is a thin SwiftUI MenuBarExtra on top.
Tag vX.Y, publish a GitHub release for it, and CI does the rest: signs with Developer ID, notarizes, staples, uploads the DMG, and pushes the updated cask to the tap so brew upgrade --cask gordonbeeming/tap/claude-bar picks it up.