Ubuntu system tray icon that shows real-time Claude Code usage: active model, % of context consumed, and — if you're subscribed to Claude Pro/Max/Team — the quota consumed over the rolling 5-hour and 7-day windows, with the time remaining before it resets.
Claude Code already shows this information in its own internal status bar (at the bottom of the terminal), but only while the session is open in the foreground. This project reuses that same data and keeps it permanently visible in the Ubuntu system tray, without needing to keep a Claude Code terminal visible.
Claude Code (on every message)
│ sends a session JSON on stdin
▼
statusline/claude-statusline.sh
│ writes the state to ~/.cache/claude-usage/state.json
│ also prints the classic status line back into Claude Code
▼
bin/claude-usage-tray.py (runs in the background, re-reads the file
│ every 3 seconds)
▼
AppIndicator icon in the Ubuntu system tray
statusline/claude-statusline.sh: script invoked by Claude Code (statusLineconfig) on every conversation turn.bin/claude-usage-tray.py: GTK/AppIndicator app that reads the state and displays it in the system tray.autostart/claude-usage-tray.desktop: launches the app automatically at login.
- Ubuntu 24.04 (or any GNOME distro with AppIndicator support)
- Claude Code installed and authenticated
jq,python3-gi, GTK3, AyatanaAppIndicator3
git clone https://github.com/AlexiZ/claude-usage-tray.git
cd claude-usage-tray
chmod +x install.sh
./install.shThe script installs the dependencies, copies the files to the right
places, sets up autostart, and adds (or merges) the statusLine into
~/.claude/settings.json.
# 1. Dependencies
sudo apt update
sudo apt install -y jq python3-gi gir1.2-gtk-3.0 gir1.2-ayatanaappindicator3-0.1
# 2. Statusline script
mkdir -p ~/.claude
cp statusline/claude-statusline.sh ~/.claude/claude-statusline.sh
chmod +x ~/.claude/claude-statusline.sh
# 3. Tray application
mkdir -p ~/.local/bin
cp bin/claude-usage-tray.py ~/.local/bin/claude-usage-tray.py
chmod +x ~/.local/bin/claude-usage-tray.py
# 4. Autostart
mkdir -p ~/.config/autostart
cp autostart/claude-usage-tray.desktop ~/.config/autostart/claude-usage-tray.desktop
# 5. Claude Code config — merge this block into ~/.claude/settings.json
cat settings/settings.example.jsonContent to merge into ~/.claude/settings.json:
{
"statusLine": {
"type": "command",
"command": "~/.claude/claude-statusline.sh"
}
}python3 ~/.local/bin/claude-usage-tray.py &It will then start automatically on every login thanks to the entry
in ~/.config/autostart/.
install.sh asks, during installation, which icon to use:
- System icon (default) — a generic gauge/monitor pictogram
(
utilities-system-monitor). - Your own icon — a
.pngfile (defaults to~/.local/share/icons/claude-icon.png). The Claude logo belongs to Anthropic and is not included in this repo: grab your own file (from claude.ai or Claude Desktop if installed) and place it at the indicated location before relaunching the app.
To change the icon later without rerunning install.sh, edit
ICON_NAME directly in ~/.local/bin/claude-usage-tray.py:
ICON_NAME = os.path.expanduser("~/.local/share/icons/claude-icon.png")Restart the app:
pkill -f claude-usage-tray.py
python3 ~/.local/bin/claude-usage-tray.py &cat ~/.cache/claude-usage/state.jsonThis file should update after every message sent in a Claude Code session. If nothing shows up:
- Check that
~/.claude/settings.jsoncontains thestatusLine. - Test the script by hand:
echo '{"model":{"display_name":"Sonnet"},"session_id":"test123","context_window":{"used_percentage":5},"rate_limits":{"five_hour":{"used_percentage":12,"resets_at":1893456000},"seven_day":{"used_percentage":30,"resets_at":1893999999}}}' | ~/.claude/claude-statusline.sh
- Make sure you've accepted the "workspace trust" dialog for the
folder in Claude Code — otherwise the
statusLinestays inactive.
- The
rate_limitsfields (5h / 7-day quotas) are only present for Claude Pro/Max/Team subscriptions, not for pay-as-you-go API usage. - Data only updates while a Claude Code session is active; between sessions, the icon shows the last known value with an inactive session indicator.
- With multiple parallel Claude Code sessions, they share the same state file (the most recent write overwrites the others).
./uninstall.shAsks for confirmation, then removes everything install.sh set up: the
running process, the tray app, the statusline script, the autostart
entry, the cached usage state, and the statusLine entry in
~/.claude/settings.json (only if it still points to this project's
script). It prints a summary of what was actually removed. System
packages (jq, python3-gi, ...) and any custom icon file you provided
are left in place unless you explicitly opt in when prompted.
MIT — see LICENSE.
