Skip to content

πŸ“Š Claudometer - Don't let "Usage limit reached" catch you off guard. Real-time Claude usage monitoring for macOS & Linux with near-limit alerts.

License

Notifications You must be signed in to change notification settings

leonardocouy/claudometer

Repository files navigation

Claudometer

A tray-first desktop application for macOS and Linux that shows your Claude and Codex usage limits in near real-time.

Claudometer Tray Menu Claudometer Settings

Features

  • Real-time usage tracking - Monitor your 5-hour session and weekly limits (Claude + Codex)
  • Provider + auth options:
    • Claude: Claude Code (OAuth) or Claude Web (sessionKey cookie)
    • Codex: Codex OAuth (local login) or Codex CLI
  • System tray integration - Always visible in your menu bar, stays out of your way
  • Near-limit alerts - Get notified when approaching usage limits (β‰₯90%)
  • Secure credential storage - Claude session keys stored in OS Keychain (macOS) or Secret Service (Linux)
  • Auto-updates - Stay up to date with signed automatic updates
  • Multi-organization support - Switch between Claude organizations seamlessly (Claude Web only)

Installation

macOS

Download the latest .dmg from GitHub Releases, open it, and drag Claudometer to your Applications folder.

Linux

Download from GitHub Releases:

Format Best for
.AppImage Universal (recommended) - just download and run
.deb Ubuntu, Debian, Pop!_OS
.rpm Fedora, RHEL, openSUSE

Tip: For AppImage, make it executable with chmod +x Claudometer*.AppImage and run it.

Build from Source

If you prefer to build from source, see the Development section below.

Quick Start

  1. Launch Claudometer - The app starts minimized in your system tray
  2. Open Settings - Click the tray icon β†’ "Open Settings..."
  3. Choose what to track:
    • Claude (optional):
      • Claude Code (recommended): run claude login once and Claudometer will use those credentials
      • Claude Web: paste your sessionKey cookie from claude.ai
    • Codex (optional):
      • Codex OAuth (recommended): log in with codex and Claudometer will read your local credentials
      • Codex CLI: uses the local codex binary
  4. Save - Your usage stats will appear in the tray menu

Project Structure

claudometer/
β”œβ”€β”€ src-tauri/                     # Tauri (Rust) backend + bundling config
β”‚   β”œβ”€β”€ tauri.conf.json            # App + bundle + updater config
β”‚   β”œβ”€β”€ capabilities/              # Permission scopes
β”‚   └── src/                       # Rust modules (tray, polling, commands, settings)
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ renderer/settings/         # Vite settings UI (Tauri invoke + events)
β”‚   └── common/                    # Shared types for the settings UI
β”‚       └── generated/             # Generated IPC types (from Rust)
β”œβ”€β”€ assets/                        # Tray icons
β”œβ”€β”€ package.json
β”œβ”€β”€ tsconfig.json
└── CLAUDE.md                      # AI assistant instructions

How It Works

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ User Actions                                                β”‚
β”‚ β€’ Launch app                                                β”‚
β”‚ β€’ Open settings                                             β”‚
β”‚ β€’ Select usage source                                       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             β”‚
             β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Tauri backend (src-tauri/src)                               β”‚
β”‚ β€’ Initializes tray icon                                     β”‚
β”‚ β€’ Starts polling loop (configurable interval)               β”‚
β”‚ β€’ Coordinates data flow                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             β”‚
             β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Polling Loop                                                β”‚
β”‚ 1. Read settings (enabled providers + sources)              β”‚
β”‚ 2. Fetch provider snapshots (Claude + Codex)                β”‚
β”‚ 3. Normalize/parse responses                                β”‚
β”‚ 4. Update tray menu + emit snapshot event                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             β”‚
             β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Usage Provider                                              β”‚
β”‚ β€’ Claude Web: claude.ai/api (Cookie sessionKey=...)         β”‚
β”‚ β€’ Claude OAuth: api.anthropic.com/api/oauth/usage           β”‚
β”‚ β€’ Codex OAuth: chatgpt.com/* (Bearer token)                 β”‚
β”‚ β€’ Codex CLI: local codex binary                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Data Flow

  1. App starts β†’ Loads settings (including usage source)
  2. Every N seconds β†’ Polls usage data for the selected source
  3. On response β†’ Parses JSON and updates tray menu text
  4. On error β†’ Updates tray to show error state; polling only pauses when all enabled providers are blocked (missing key / unauthorized)

Debug (simulate notifications)

Enable debug tray actions:

CLAUDOMETER_DEBUG=1 bun run dev

Then use the tray menu items under β€œDebug:” to simulate near-limit and reset notifications.

Development

Prerequisites

  • Bun runtime
  • macOS or Linux (Windows not currently supported)

macOS:

xcode-select --install

Linux (Ubuntu/Debian):

sudo apt update && sudo apt install -y \
  libwebkit2gtk-4.1-dev libappindicator3-dev pkg-config build-essential

Linux (Fedora):

sudo dnf install webkit2gtk4.1-devel libappindicator-gtk3-devel pkg-config gcc-c++

Linux (Arch):

sudo pacman -S webkit2gtk-4.1 libappindicator-gtk3 pkg-config base-devel

Build from Source

# Install Bun (if not installed)
curl -fsSL https://bun.sh/install | bash

# Clone and build
git clone https://github.com/leonardocouy/claudometer.git
cd claudometer
bun install
bun run build

# Output in ./src-tauri/target/release/bundle/

Available Scripts

Command Description
bun run dev Run Tauri app in development mode
bun run dev:ui Run settings UI only (Vite)
bun run build Build Tauri bundles (uses tauri.conf.json)
bun run build:ui Build settings UI only
bun run sync-versions Keep versions in sync across config files
bun run typecheck TypeScript type checking
bun run check Run Biome linter and formatter checks
bun run lint Auto-fix linting issues
bun run format Auto-format code
bun run generate:ipc-types Generate src/common/generated/ipc-types.ts from Rust
bun run check:ipc-types Fail CI if IPC types drift

Tech Stack

Layer Technology
App Framework Tauri v2
Build Tool Tauri CLI + Vite
Language TypeScript 5.9
Runtime Bun
Settings Storage tauri-plugin-store (non-sensitive data)
Secret Storage OS Keychain / Secret Service (keyring crate)
Linting/Formatting Biome
Testing Rust unit tests (cargo test --manifest-path src-tauri/Cargo.toml)

Manual Test Matrix

Run these checks on:

  • macOS (Apple Silicon + Intel)
  • Linux (GNOME + KDE)

Checklist:

  1. Tray starts with no windows; menu shows snapshot lines.
  2. β€œOpen Settings…” creates/focuses the settings window.
  3. Web mode: saving a valid session key refreshes snapshot and updates tray.
  4. CLI mode: after you’ve logged into Claude Code, refresh shows snapshot and updates tray.
  5. β€œRemember session key” (web only) persists across restart (Keychain / Secret Service).
  6. Disabling β€œRemember” keeps the key memory-only (does not persist across restart).
  7. Notifications: near-limit alerts (>= 90%) and reset notifications (when enabled).
  8. Autostart toggle reflects system state after restart/login.
  9. β€œCheck for Updates…” shows a result (up-to-date / update available / error).
  10. Codex OAuth: after logging in with codex, refresh shows Codex usage in tray.
  11. Codex CLI: with codex installed, refresh shows Codex usage in tray.

Security & Privacy

Authentication Handling

Claude Web session key (sessionKey):

  • Stored only in OS credential storage when β€œRemember” is enabled (Keychain / Secret Service)
  • Memory-only when β€œRemember” is disabled (no persistence)
  • Never logged: Session key is never included in logs, error messages, or telemetry
  • Validation before storage: Session key is validated against Claude API before being saved

CLI Mode:

  • Managed by Claude Code: Uses your Claude Code OAuth session
  • Auto-refresh: Tokens are refreshed automatically by the CLI
  • Claudometer reads only: App only reads credentials, never modifies them
  • No persistence: Claudometer doesn't store or cache OAuth tokens
  • Platform-specific credential location:
    • macOS: Reads from system Keychain (Service: Claude Code-credentials)
    • Linux: Reads from ~/.claude/.credentials.json

What Gets Sent

Web Mode:

  • HTTPS requests to claude.ai/api/* endpoints:
    • GET /api/organizations - Fetch available organizations
    • GET /api/organizations/:id/usage - Fetch usage stats
  • Session key sent as Cookie header (same as browser)

CLI Mode:

  • HTTPS requests to api.anthropic.com/api/oauth/* endpoints:
    • GET /api/oauth/usage - Fetch usage stats
  • OAuth token sent as Bearer header

Codex:

  • HTTPS requests to chatgpt.com usage endpoints (OAuth mode)
  • Authorization sent as Bearer header (and optional chatgpt-account-id header)

Claudometer does not persist Codex tokens; it reads local credentials when needed.

Local Storage

The app stores these settings locally (non-sensitive) via tauri-plugin-store:

  • Refresh interval (seconds)
  • Selected organization ID
  • "Remember session key" preference
  • Provider toggles + sources (Claude/Codex)
  • Autostart preference
  • Updater preferences

Troubleshooting

Tray shows "unauthorized"

Web Mode: Your session key is invalid or expired:

  1. Open Settings
  2. Get a fresh session key from claude.ai (see Quick Start)
  3. Paste and save

CLI Mode: Your OAuth token expired:

  1. Re-authenticate with Claude Code:
    claude
    # Follow OAuth flow again
  2. App will automatically use new credentials

Tray shows "rate limited"

Claude API is rate-limiting your requests:

  • The app automatically backs off for 5 minutes
  • Consider increasing your refresh interval in Settings

Session key doesn't persist across restarts (Linux)

If β€œRemember session key” is disabled in Settings, your session key will not persist across restarts.

No organizations found

Your Claude account doesn't have any organizations:

  • Free Claude accounts still have a "personal" organization
  • If you see this error, try logging out and back in to claude.ai
  • Get a fresh session key

Polling stopped

Check the tray menu:

  • Unauthorized: Session key/token expired (see above)
  • Rate limited: Auto-recovers in 5 minutes
  • Error: Check the error message in the tray menu

If you have both providers enabled, polling only pauses when all enabled providers are blocked (missing key / unauthorized).

Codex not working

If Codex shows "unauthorized":

  • Codex OAuth: log in again via codex, then click β€œRefresh now”.
  • Codex CLI: ensure codex is installed and available on your PATH.

CLI mode not working

If you selected "Claude Code" but see "Claude CLI credentials not found":

macOS: Claudometer reads credentials from the system Keychain. Ensure you're logged in:

claude login

The credentials are stored automatically in Keychain by Claude Code.

Linux: Claudometer reads from ~/.claude/.credentials.json. Ensure the file exists:

ls -la ~/.claude/.credentials.json

If missing, authenticate with Claude Code:

claude login

Tip: If CLI mode doesn't work, you can use Web mode as an alternative - just paste your sessionKey cookie from claude.ai.

Roadmap

  • Windows support
  • Desktop notifications when approaching usage limits
  • Historical usage graphs
  • Menu bar percentage display
  • Auto-update mechanism

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes following the existing code style
  4. Run bun run check to ensure code quality
  5. Submit a pull request

License

MIT

Related Projects

  • Claude API - Official API (different from web usage tracking)
  • Tauri - Lightweight desktop apps with Rust backend + system WebView

About

πŸ“Š Claudometer - Don't let "Usage limit reached" catch you off guard. Real-time Claude usage monitoring for macOS & Linux with near-limit alerts.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •