Desktop widget and CLI that shows real-time Claude Code usage limits and cost.
Project description
Claude Usage Widget
A desktop widget that displays your Claude Code usage limits in real time. Shows session and weekly utilization percentages fetched from the Anthropic API, with an always-on-top OSD overlay and a system tray / menu bar icon.
Features
- Real API data -- fetches rate-limit utilization from
anthropic-ratelimit-unified-*response headers - OSD overlay -- transparent, borderless widget in the corner of your screen showing session and weekly usage bars with reset countdowns
- System tray / menu bar -- quick-glance usage info and a detailed popup window
- Cross-platform -- native GTK3 on Linux, native AppKit/rumps on macOS
- Auto-refresh -- updates every 30 seconds (configurable)
- Resizable -- scroll wheel to scale the OSD up or down (0.6x--2.0x)
- Opacity control -- adjustable OSD transparency via the tray / menu bar
- Draggable -- left-click and drag to reposition the OSD
- Minimizable -- right-click the OSD to collapse it to a thin progress bar
- Active sessions -- shows running Claude Code sessions with project paths and durations
- Cost estimation -- widget shows estimated $ spent today and cache savings using model pricing
- Usage forecasting -- burn rate calculation shows "at this rate you'll hit the limit in Xh Ym"
- Per-project breakdown -- top 5 projects by token usage today
- Themes -- 5 built-in themes (default, catppuccin-mocha, dracula, nord, gruvbox-dark), set via
"theme": "dracula"inconfig.json
Requirements
- Python 3.10+
- Claude Code CLI installed and authenticated (OAuth)
Linux
- GTK3, python3-gi, python3-gi-cairo, python3-cairo
gir1.2-ayatanaappindicator3-0.1(system tray)
macOS
rumpsandpyobjc-framework-Cocoa(installed automatically viarequirements-macos.txt)
Installation
Linux
# 1. Install system dependencies (Ubuntu/Debian)
sudo apt install python3-gi python3-gi-cairo python3-cairo gir1.2-ayatanaappindicator3-0.1
# Fedora
sudo dnf install python3-gobject python3-gobject-cairo python3-cairo gtk3
# Arch
sudo pacman -S python-gobject python-cairo gtk3 libappindicator-gtk3
# 2. Clone and run
git clone https://github.com/bozdemir/claude-usage-widget.git
cd claude-usage-widget
python3 main.py &
# 3. Autostart on login (optional)
./install.sh
macOS
# 1. Clone
git clone https://github.com/bozdemir/claude-usage-widget.git
cd claude-usage-widget
# 2. Install Python dependencies
pip3 install -r requirements-macos.txt
# 3. Run
python3 main.py
# 4. Autostart on login (optional) -- installs a Launch Agent
./install-macos.sh
Usage
OSD Overlay Controls
| Action | Effect |
|---|---|
| Scroll up / down | Resize (0.6x--2.0x) |
| Left-click drag | Move the OSD |
| Right-click | Minimize / restore |
System Tray / Menu Bar
- Session / Weekly -- current usage percentages
- Details... -- opens a detailed popup with usage bars and active sessions
- Refresh -- force an immediate data refresh
- OSD Overlay -- toggle the OSD on or off
- OSD Opacity -- set OSD transparency (100% / 75% / 50% / 25%)
- Quit -- exit the widget
Configuration
All settings are optional. Copy config.json.example to config.json and edit the values you want to change:
cp config.json.example config.json
{
"daily_message_limit": 200,
"weekly_message_limit": 1000,
"daily_token_limit": 5000000,
"weekly_token_limit": 25000000,
"refresh_seconds": 30,
"osd_opacity": 0.75,
"osd_scale": 1.0
}
| Setting | Default | Description |
|---|---|---|
refresh_seconds |
30 |
How often to fetch new data from the API (seconds) |
osd_opacity |
0.75 |
OSD background opacity (0.15--1.0) |
osd_scale |
1.0 |
OSD scale factor (0.6--2.0) |
daily_message_limit |
200 |
Daily message limit for local tracking in the popup |
weekly_message_limit |
1000 |
Weekly message limit for local tracking in the popup |
daily_token_limit |
5000000 |
Daily token limit for local tracking |
weekly_token_limit |
25000000 |
Weekly token limit for local tracking |
claude_dir |
~/.claude |
Path to the Claude Code data directory |
theme |
default |
Color theme for the OSD and popup. One of default, catppuccin-mocha, dracula, nord, gruvbox-dark |
Keys omitted from config.json fall back to built-in defaults. claude_dir is not included in the example file because the default is correct for most setups.
Themes
The widget ships with 5 built-in color themes. Select one by adding "theme": "<name>" to your config.json:
{
"theme": "dracula"
}
Available themes:
- default -- the original widget palette (screenshots welcome)
- catppuccin-mocha -- soft pastel dark theme (screenshots welcome)
- dracula -- classic purple-and-pink dark theme (screenshots welcome)
- nord -- cool arctic blue palette (screenshots welcome)
- gruvbox-dark -- warm retro-style dark theme (screenshots welcome)
How It Works
The widget reads your Claude Code OAuth credentials from ~/.claude/.credentials.json (Linux) or the macOS Keychain and makes a minimal API call (max_tokens=1 to claude-haiku-4-5-20251001) to read the rate-limit response headers:
anthropic-ratelimit-unified-5h-utilization: 0.58
anthropic-ratelimit-unified-5h-reset: 1776186000
anthropic-ratelimit-unified-7d-utilization: 0.10
anthropic-ratelimit-unified-7d-reset: 1776690000
These are the same values shown on the claude.ai usage page. The widget also reads local data from ~/.claude/ for message counts, token usage per model, and active session tracking.
How the OSD Works
The OSD is a transparent, borderless window rendered entirely via 2D drawing primitives:
- Linux -- a
Gtk.Windowwith theNOTIFICATIONtype hint uses Cairo to draw rounded rectangles, progress bars, and text onto an RGBA surface. The compositor handles transparency;set_accept_focus(False)prevents the overlay from stealing keyboard focus. - macOS -- an
NSWindowatNSFloatingWindowLevelwithNSWindowStyleMaskBorderlessand a transparentNSViewsubclass does the equivalent drawing via AppKit (NSBezierPath,NSColor,NSAttributedString).
Scale and opacity -- Both platforms store a float scale (0.6--2.0, default 1.0) and opacity (0.15--1.0, default 0.75) that are applied at draw time. Scale multiplies every pixel dimension (padding, font size, bar height, window size) before drawing, so the entire widget resizes proportionally without re-layout. Opacity is used as the alpha channel of the background fill; bar and text elements are drawn at full alpha on top so they remain legible at low opacity.
Refresh cycle -- A background thread wakes every refresh_seconds (default 30), makes an API call, and posts the result back to the main thread via GLib.idle_add (Linux) or a rumps.Timer-drained queue (macOS). The main thread then invalidates the OSD window, triggering a synchronous redraw. User interactions (scroll to resize, drag to move, right-click to minimize) update scale and position in place and queue an immediate redraw without waiting for the next refresh tick.
Troubleshooting
Linux: OSD not visible
- Ensure XWayland is available. The widget forces
GDK_BACKEND=x11for reliable borderless windows. - Check if the process is running:
ps aux | grep main.py
Linux: no system tray icon
- Install
gir1.2-ayatanaappindicator3-0.1. - On GNOME, you may need the AppIndicator extension.
Linux: Cairo errors (Couldn't find foreign struct converter)
- Install
python3-gi-cairo:sudo apt install python3-gi-cairo
Linux: ImportError: cannot import name '_gi' from partially initialized module 'gi'
This usually means a broken user-level PyGObject install is shadowing the system package. Fix:
pip uninstall -y PyGObject pycairo
sudo apt install --reinstall python3-gi python3-gi-cairo gir1.2-ayatanaappindicator3-0.1
macOS: no menu bar icon
- Make sure
rumpsis installed:pip3 install rumps - If using a virtualenv, ensure
pyobjc-framework-Cocoais also installed.
API authentication fails
- Make sure the Claude Code CLI is installed and you are logged in (the
claudecommand should work). - Linux: the OAuth token is read from
~/.claude/.credentials.json. - macOS: the OAuth token is read from the Keychain, with a fallback to
~/.claude/.credentials.json.
Contributing
Contributions are welcome. A few guidelines:
- Bug reports -- open an issue with your OS, Python version, and the full error output. If the OSD is invisible, include
xrandrorsystem_profiler SPDisplaysDataTypeoutput. - Pull requests -- keep changes focused. One fix or feature per PR. Run the widget manually on the target platform before submitting.
- Platform parity -- features that affect the OSD or tray should work on both Linux and macOS, or be clearly gated behind a platform check.
- No new dependencies -- avoid adding Python packages beyond those already in
requirements-macos.txtand the listed GTK stack. If a dependency is truly necessary, discuss it in an issue first. - Code style -- follow the existing conventions. No formatter is enforced; just match the surrounding code.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file claude_usage_widget-0.2.2.tar.gz.
File metadata
- Download URL: claude_usage_widget-0.2.2.tar.gz
- Upload date:
- Size: 96.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5d36a6a9dbe85f78f5823db1ce327a2db52d5e42dd928eeafc723b2d0d123ed5
|
|
| MD5 |
96fbe7b315ace28ad454924e4507c280
|
|
| BLAKE2b-256 |
a29dd0a4b6e54df89190eae988b5d099ba23e6fccb33c963a24aacb9e90960fb
|
Provenance
The following attestation bundles were made for claude_usage_widget-0.2.2.tar.gz:
Publisher:
publish.yml on bozdemir/claude-usage-widget
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
claude_usage_widget-0.2.2.tar.gz -
Subject digest:
5d36a6a9dbe85f78f5823db1ce327a2db52d5e42dd928eeafc723b2d0d123ed5 - Sigstore transparency entry: 1349906052
- Sigstore integration time:
-
Permalink:
bozdemir/claude-usage-widget@8643d4413a8668873c115fc069cec7d2587e49ef -
Branch / Tag:
refs/tags/v0.2.2 - Owner: https://github.com/bozdemir
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8643d4413a8668873c115fc069cec7d2587e49ef -
Trigger Event:
push
-
Statement type:
File details
Details for the file claude_usage_widget-0.2.2-py3-none-any.whl.
File metadata
- Download URL: claude_usage_widget-0.2.2-py3-none-any.whl
- Upload date:
- Size: 80.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ce92b9190215547a4b25faa74d6ed71cb3bdb15ea9d07eab61b669ed478753a4
|
|
| MD5 |
aa3e73c555c44f0dad2f81213abcb914
|
|
| BLAKE2b-256 |
b55bb36248aec2c38cc1ba656358d122b257ad1f8243c5c769e666875b1e7897
|
Provenance
The following attestation bundles were made for claude_usage_widget-0.2.2-py3-none-any.whl:
Publisher:
publish.yml on bozdemir/claude-usage-widget
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
claude_usage_widget-0.2.2-py3-none-any.whl -
Subject digest:
ce92b9190215547a4b25faa74d6ed71cb3bdb15ea9d07eab61b669ed478753a4 - Sigstore transparency entry: 1349906122
- Sigstore integration time:
-
Permalink:
bozdemir/claude-usage-widget@8643d4413a8668873c115fc069cec7d2587e49ef -
Branch / Tag:
refs/tags/v0.2.2 - Owner: https://github.com/bozdemir
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8643d4413a8668873c115fc069cec7d2587e49ef -
Trigger Event:
push
-
Statement type: