Shows your Claude.ai weekly usage percentage in the GNOME or KDE Plasma panel and dock.
Top panel (right side, next to Wi-Fi/battery):
The icon is the static Anthropic star logo. The percentage label is color-coded: green below the warning threshold · amber at or above it · red at or above the critical threshold (defaults: 70 / 90, applied to current pacing — see Color semantics under Configuration). On the broken tier the icon itself swaps to a red-tinted variant.
Scroll on the panel label to cycle the displayed metric through every eligible meter — Current session, All models, Sonnet only, Claude Design, the daily routine-run counter, Extra usage if active. The popup's ✴ marker tracks which one is currently in the panel. (Sonnet at 0 % is skipped so the panel doesn't show "0 %" for a meter the popup also hides.)
Click the panel label to open the popup:
The ✴ marks the metric shown in the panel label.
With extra usage enabled on your account, a second section appears:
Dock icon (once pinned — see Installation below):
- Outer ring — All models weekly usage (green → amber → red)
- Inner ring — Sonnet only weekly usage (blue by default); hidden entirely when Sonnet usage is 0%
Hover the dock icon to see a one-line summary tooltip:
Reset times show a countdown (⏱h:mm) when less than 12 h away, or a day + time otherwise. Sonnet is omitted from the tooltip when its usage is 0%.
The icon regenerates automatically on each data fetch.
The panel and dock icons change color when the data is suspect or Claude is having problems. Three tiers:
| State | Trigger | Panel icon | Dock icon | Popup status |
|---|---|---|---|---|
| Normal | Fresh data, no errors | Anthropic orange + percentage colors | Orange tile · colored rings | normal meter list |
| Stale | No fresh data in 15 min (~2 missed fetches) | Ghosted, 40% opacity | Greyscale tile · grey rings | 🕐 No update in N min |
| Broken | One of: · No fresh data in 20 min (~3 missed) · 2+ consecutive scrape failures (claude.ai returned an error, login expired, page changed) · Anthropic's status page ( status.claude.com) reports an incident on the claude.ai component |
Red-tinted | Orange tile · solid red rings | ⚠ <reason> — names the cause |
The Chrome extension polls Anthropic's public status page on every cycle and surfaces the incident text (e.g. "Anthropic reports: Minor Service Outage") in the popup so you don't need to alt-tab to find out whether it's your laptop or theirs.
Recovery is automatic: the next successful scrape resets the state and the icons return to their normal colors.
On macOS? The Debian/distro instructions here don't apply — jump to the macOS section below.
Requirements: GNOME Shell 45–50 or KDE Plasma 6 + systemd-user + Google Chrome or Mozilla Firefox (logged in to Claude.ai). The browser extension and local server are identical on both desktops and both browsers; only the panel frontend differs (GNOME Shell extension vs KDE plasmoid — see KDE Plasma below). Chromium-family browsers (Brave, Edge, Vivaldi) load the Chrome extension unchanged.
Minimum distro versions that ship GNOME Shell 45 or newer (KDE users need Plasma 6.0+):
| Distro | Minimum | Ships with |
|---|---|---|
| Fedora | 39 (Nov 2023) | GNOME 45 |
| Ubuntu | 23.10 — or 24.04 LTS | GNOME 45 / 46 |
| Debian | 13 (Trixie, Aug 2025) | GNOME 48 |
| RHEL | 10 (2025) | GNOME 47 |
| Arch · openSUSE Tumbleweed | rolling | latest |
Older releases (Debian 12 Bookworm = GNOME 43, RHEL 9 = GNOME 40, Ubuntu 22.04 LTS = GNOME 42) ship too-old GNOME Shells for the extension to load. The Python server, systemd unit, and Chrome extension still install on those, but the panel indicator won't appear until the desktop is upgraded.
The three install paths below cover different distro reaches — pick whichever matches your system:
Add the apt.indri.studio repository, then install via apt:
# 1. Trust the signing key
curl -fsSL https://apt.indri.studio/key.gpg \
| sudo gpg --dearmor -o /etc/apt/keyrings/indri.gpg
# 2. Add the source
echo "deb [signed-by=/etc/apt/keyrings/indri.gpg] https://apt.indri.studio stable main" \
| sudo tee /etc/apt/sources.list.d/indri.list
# 3. Install
sudo apt update && sudo apt install claude-usage
claude-usage-setup # run as yourself, not rootclaude-usage-setup creates your config file, enables the systemd service, enables the GNOME extension, and installs the dock entry — all in one step. (On KDE Plasma the package installs the plasmoid; add it to a panel yourself — see KDE Plasma below.)
Download the pinned source tarball from the apt.indri.studio mirror and run the install script in-tree:
# Pointer lists the current version + sha256
curl -fsSL https://apt.indri.studio/sources/claude-usage-latest.json
# Then download + extract + run the upstream install.sh
TARBALL=$(curl -fsSL https://apt.indri.studio/sources/claude-usage-latest.json | python3 -c 'import json,sys; print(json.load(sys.stdin)["tarball"])')
curl -fsSL "$TARBALL" | tar -xz
cd claude-usage-*
./install.shNothing is compiled — install.sh is a wire-up script that copies JS + Python files into your XDG directories, compiles the gschema XML, and registers the systemd user service + dock launcher. Python deps (python3-cairo, python3-pil) install via apt/dnf/pacman automatically if missing.
curl -fsSL https://apt.indri.studio/install-claude-usage.sh | bashSame wire-up as Option B, with no clone step. The bootstrap fetches the latest release tarball into a temp dir, then execs the upstream install.sh. Pass --uninstall through with bash -s --:
curl -fsSL https://apt.indri.studio/install-claude-usage.sh | bash -s -- --uninstallPick one install method. Running the
.deband source/curl installs simultaneously creates a systemd unit conflict:install.shregisters a user-levelclaude-usage-fetch.servicethat takes precedence over the system-level unit from the.deb, so one service silently never runs. If switching methods, uninstall the old one first (see Uninstall).
Load the Chrome extension:
- Open
chrome://extensions - Enable Developer mode (top-right toggle)
- Click Load unpacked → select:
- Clone install (Option B):
chrome-extension/inside the repo - One-liner install (Option C):
~/.local/share/claude-usage/chrome-extension/ - .deb install (Option A):
/usr/share/claude-usage/chrome-extension/
- Clone install (Option B):
Chromium-family browsers (Brave, Edge, Vivaldi) use the same steps.
Load the Firefox extension (alternative to Chrome):
Firefox needs a signed add-on for a permanent install. Two ways:
-
Permanent (recommended): install the signed
.xpifrom the project's releases (built withtask build-firefox-zipthenweb-ext sign --channel=unlisted). It installs on stock Firefox/ESR like any add-on and survives restarts. -
Developer / try-it: run
task build-firefox-zip, unzip the result, then in Firefox openabout:debugging#/runtime/this-firefox→ Load Temporary Add-on → select itsmanifest.json. Temporary add-ons are removed every time Firefox restarts — fine for a quick try, not for daily use.
Firefox auto-grants the host permissions on load — no manual step (you can review them
under about:addons → Claude Usage Tracker → Permissions and data). One Firefox-specific
detail, handled for you by the bundled server: unlike Chrome, Firefox enforces CORS on the
extension's 127.0.0.1 fetch even with host_permissions, so the local server sends the
required Access-Control-Allow-Origin for moz-extension:// origins. Tested on Firefox 151
(Max plan, live meters scraped and shown in the panel).
Firefox ships the same extension as Chrome (shared source); only the manifest differs, so behaviour is identical.
Log out and back in — activates the GNOME Shell extension. (KDE: instead add the widget to a panel — see KDE Plasma below.)
Pin the dock icon (one-time):
- Press Super → search "Claude Usage"
- Right-click → Add to Favorites
Nothing to do. Everything starts automatically:
| Component | How it starts |
|---|---|
| Local data server | systemd user service (claude-usage-fetch.service) |
| Chrome extension | Persists in Chrome across restarts |
| GNOME panel indicator | Loaded by GNOME Shell from enabled-extensions list |
| KDE panel indicator | Loaded by Plasma once the widget is added to a panel |
Data updates every 7 minutes — the Chrome extension scrapes claude.ai/settings/usage and writes ~/.cache/claude-usage/usage.json. If you already have that page open in a tab, it reads from there; otherwise it opens a temporary background tab. The panel indicator updates immediately when the file changes.
When a meter hits 100%, the panel label switches from the static percentage to a live countdown: ⏱H:MM (hours:minutes to reset), ticking down every minute. If multiple meters are maxed, the soonest-resetting one drives the label. The extension also shifts to an aggressive ~1-min re-scrape cadence starting ~1 min before the predicted reset, polling every minute until it confirms the window rolled over, then returns to the normal 7-min cadence. Because reset times have only minute resolution, the panel typically reflects the new lower percentage within 1–2 minutes of the actual reset.
Force an immediate refresh — two ways:
- Click the Claude Usage Tracker icon in the Chrome toolbar. Opens a fresh background tab, scrapes, closes the tab. Background to the user.
- Open
claude.ai/settings/usagein any normal tab (via the popup's "Open Usage Page" item, a bookmark, the address bar, anything). The extension auto-scrapes the page once it finishes loading and stays out of your way — the tab isn't touched, it's just read. Debounced to one auto-scrape per 30 s so a page reload or a second tab doesn't double-fire.
Check the raw data:
cat ~/.cache/claude-usage/usage.json
cat ~/.cache/claude-usage/port # which local port the server bound (7331-7340)Run the diagnostics tool:
claude-usage-statusReports service health, cache freshness, meter breakdown, and extension state in one command.
On KDE Plasma 6 the indicator is a plasmoid (the .deb installs it to /usr/share/plasma/plasmoids/org.indri.claude-usage/; the Chrome extension and local server work exactly as on GNOME). To add it:
- Right-click a panel → Add Widgets…, search Claude Usage, and click it. In a panel it shows the compact indicator — the bundled icon plus the selected meter's
%in its pacing colour — and click it to expand the full breakdown (every meter with a bar + reset countdown, the data-age line, a panel-metric selector, and an "Open Usage Page" link). Scroll the panel indicator to cycle which meter the%tracks. - Configure: right-click the widget → Configure Claude Usage… — colours, warning/critical thresholds, popup font, and sizes. These persist in KConfig; colour/threshold/font choices are also mirrored to
~/.config/claude-usage/config.jsonso the dock-launcher icon (generate-icon.py) picks them up.
Add it to a panel, not the desktop. A panel gives the compact icon that expands on click; dropped on the desktop a plasmoid renders its full breakdown directly (Plasma shows the full representation for desktop widgets) — fine as a desktop widget, but not the compact indicator. Adding it to both at once (as the live test harness does, to exercise both representations) is why you'd see two breakdowns.
On macOS the indicator is a menu-bar app (claude-usage.app) — the analog of the GNOME panel. The browser extension and the local data server work exactly as on Linux; only the frontend differs. It's a menu-bar-only app (no Dock icon).
Requirements: macOS 13 Ventura or newer (Apple Silicon or Intel) + Google Chrome or Mozilla Firefox logged in to Claude.ai.
brew install --cask wbniv/tap/claude-usageThis installs claude-usage.app to /Applications, clears its quarantine flag, and loads a LaunchAgent (studio.indri.claude-usage) that starts the app at login and restarts it if it crashes. The app bundles the local data server and runs it in-process, so there's no separate service to manage — one agent covers what systemd + the GNOME extension do on Linux.
Then load the browser extension exactly as on Linux (see Both paths — complete setup above): chrome://extensions → enable Developer mode → Load unpacked → the bundled chrome-extension/ folder (inside the app at claude-usage.app/Contents/Resources/, or from a clone). Chrome/Brave/Edge/Vivaldi and Firefox behave identically to Linux.
The Anthropic star plus the selected meter's % in the menu bar, colour-coded by pacing (green/amber/red — see Color semantics under Configuration). The star tints red when Anthropic reports an outage and ghosts grey when data goes stale — the same three tiers as Linux. Click the menu-bar item for the full breakdown (every meter with a coloured pacing bar + reset countdown, the data-age/status line, Open Usage Page, and Quit). Scroll over the item to cycle which meter the % tracks; click a meter row in the dropdown to pin it as the panel metric. When a meter hits 100% the label switches to a live ⏱H:MM countdown.
Open Preferences… from the menu-bar dropdown (⌘,) for colour wells (the % label colours + popup colours) and steppers (warning/critical thresholds, popup bar width, popup font size). Changes apply within a couple of seconds.
Under the hood macOS has no GSettings — settings live in ~/.config/claude-usage/config.json (the same keys and defaults as the Linux gschema; see All settings and defaults below), which the Preferences window round-trips. You can also edit it by hand:
mkdir -p ~/.config/claude-usage
cat > ~/.config/claude-usage/config.json <<'JSON'
{ "threshold_warning": 60, "popup_color_normal": "#2a9a2a" }
JSONThe dropdown's status line already reports staleness and Anthropic outages. For a deeper look:
launchctl print gui/$(id -u)/studio.indri.claude-usage # is the agent loaded?
launchctl kickstart -k gui/$(id -u)/studio.indri.claude-usage # restart it
tail -f /tmp/claude-usage.err.log # app + server stderrIf the menu-bar icon is missing after install, reload the agent:
launchctl bootout gui/$(id -u)/studio.indri.claude-usage
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/studio.indri.claude-usage.plistbrew uninstall --cask claude-usage # also boots out the LaunchAgent
brew uninstall --zap --cask claude-usage # …and wipes ~/.cache + ~/.config state tooOn GNOME, all settings are stored in GSettings (dconf). Open the preferences UI:
gnome-extensions prefs claude-usage@indri.studioChanges to colors, thresholds, bar width, and font sizes apply instantly — no restart needed. (On KDE, configure via the widget's right-click Configure Claude Usage… dialog — see KDE Plasma above.)
You can also set any value from the command line:
gsettings set org.indri.claude-usage popup-color-normal '#0000ff'
gsettings set org.indri.claude-usage threshold-warning 60
gsettings reset org.indri.claude-usage popup-color-normal # restore defaultColor semantics: colors reflect your current pacing, not raw % used. The driver is pct ÷ fraction-of-period-elapsed — so 50% used halfway through a week is "on pace for 100%" and shows red, while 80% used near the end of a week is "on pace for ~90%" and shows amber. Per-meter period lengths are inferred over time from observed reset distances; until enough history accumulates, colors fall back to raw % used.
All settings and defaults:
| Setting | Default | Description |
|---|---|---|
weekly-color-green |
#8cff8c
|
Dock outer ring · below warning threshold |
weekly-color-amber |
#ffe033
|
Dock outer ring · ≥ warning threshold |
weekly-color-red |
#ff5933
|
Dock outer ring · ≥ critical threshold |
sonnet-color |
#4dbfff
|
Dock inner ring (hidden when Sonnet usage is 0%) |
popup-color-normal |
#2a9a2a
|
Popup text · below warning threshold |
popup-color-warning |
#d07000
|
Popup text · ≥ warning threshold |
popup-color-critical |
#e03030
|
Popup text · ≥ critical threshold |
panel-color-normal |
#ffffff
|
Panel label · below warning threshold |
panel-color-warning |
#d07000
|
Panel label · ≥ warning threshold |
panel-color-critical |
#e03030
|
Panel label · ≥ critical threshold |
threshold-warning |
70 |
Pacing % at which color flips to warning (see Color semantics below) |
threshold-critical |
90 |
Pacing % at which color flips to critical |
bar-width |
10 |
█░ bar character count in popup |
panel-font-size |
11 |
Panel label font size (px) |
panel-label-spacing |
6 |
Pixels between panel icon and label |
popup-font-size |
10 |
Popup meter row font size (px) |
popup-font-family |
monospace |
Popup meter row font family |
panel-icon-size |
16 |
Panel icon pixel size |
The four dock-ring colors (
weekly-color-*,sonnet-color) also accept an 8-digit#RRGGBBAAvalue to make the ring translucent. The popup and panel-label colors are text and require the 6-digit#RRGGBBform.
The cache file doesn't exist yet. Click the Chrome extension toolbar icon to trigger a fetch.
The Chrome extension may not be running. Open Chrome → chrome://extensions → confirm Claude Usage Tracker is enabled. Click its toolbar icon to force a fetch.
Reset times are displayed in your system timezone. Claude.ai returns times in the browser's timezone, which your desktop controls. They will agree unless you have manually overridden the browser timezone.
systemctl --user status claude-usage-fetch.service
systemctl --user restart claude-usage-fetch.servicechrome://extensions → Claude Usage Tracker → Errors. Clear them, then click the toolbar icon to retry.
GNOME:
gnome-extensions list --enabled | grep claude-usage
# If not listed:
gnome-extensions enable claude-usage@indri.studioKDE: right-click a panel → Add Widgets… → search Claude Usage. If it's not listed, confirm the plasmoid is installed (ls ~/.local/share/plasma/plasmoids/org.indri.claude-usage or /usr/share/plasma/plasmoids/org.indri.claude-usage) and restart Plasma (kquitapp6 plasmashell && kstart6 plasmashell).
Force a data fetch (Chrome toolbar icon) or re-run the icon generator directly:
# Source install:
python3 ~/.local/share/claude-usage/generate-icon.py
# .deb install:
python3 /usr/share/claude-usage/generate-icon.pygsettings get org.indri.claude-usage popup-color-normal
gsettings reset org.indri.claude-usage popup-color-normal
gsettings reset-recursively org.indri.claude-usage # restore all defaultsThe extension currently requires loading unpacked. To publish to the Chrome Web Store:
- Register at chrome.google.com/webstore/devconsole ($5 one-time developer fee)
- Build the submission zip:
task build-chrome-zip→ producesdist/claude-usage-chrome-{VERSION}.zip - Upload the zip in the developer console
claude-usage/
chrome-extension/ Chrome extension (load via chrome://extensions → Load unpacked)
desktop/gnome/ GNOME Shell 45–50 panel + dock indicator (extension)
desktop/kde/ KDE Plasma 6 panel + popup indicator (plasmoid)
desktop/macos/ macOS menu-bar indicator (NSStatusItem, Python + PyObjC)
desktop/launcher/ Dock launcher entry template (.desktop)
server/ Local HTTP server, shared pacing/colour/tier core
(usage_core.py) + dock icon generator
systemd/ Linux user service (macOS uses a launchd LaunchAgent)
packaging/ .deb, Chrome Web Store, and macOS .app/cask build scripts
scripts/ Build + maintenance utilities. Includes one
render-*.py per docs/*.png so screenshots are
regenerable from source, not hand-captured.
install.sh Source install; run once per machine
PRIVACY.md Chrome Web Store privacy policy
MANUAL.md This file
To regenerate any documentation image, run its dedicated script — e.g.
python3 scripts/render-popup-screenshot.py for docs/popup-screenshot.png.
Each script builds a synthetic state and pipes through headless Chrome (or
Cairo, for the dock icon) so the image matches what the live code produces
at those values. When extension.js or generate-icon.py changes rendering,
re-run every render-*.py and commit the refreshed PNGs.
Source install:
./install.sh --uninstall.deb install:
sudo apt remove claude-usagepostrm runs as root, so it only cleans system files under /usr/share/. Per-user state from claude-usage-setup is left behind — remove it manually for a full wipe:
rm -f ~/.local/share/applications/claude-usage.desktop
rm -f ~/.local/share/icons/hicolor/*/apps/claude-usage.png
rm -f ~/.local/share/icons/hicolor/icon-theme.cache
rm -rf ~/.cache/claude-usage(The icon is emitted at five hicolor sizes — 48, 64, 96, 128, 256 — so XDG icon-theme lookup always finds a live ring-painted version. The glob clears all of them.)
(The org.gnome.shell.enabled-extensions dconf entry is harmless once the extension files are gone — GNOME Shell silently ignores unknown UUIDs.)
Both: open chrome://extensions, remove Claude Usage Tracker, and log out.




