Skip to content

Repository files navigation

TokenViewer

English · 简体中文

Know exactly how many tokens you're spending — across every AI coding tool

A native macOS menu-bar app built with SwiftUI + Rust that auto-collects token counts and costs from 25 AI coding tools, aggregates them locally, and surfaces real usage trends in a beautiful dashboard. No cloud account, no Node.js, no browser — just a tiny native app.

ReleasePlatformLicense: CC BY-NC 4.0GitHub stars


TokenViewer Dashboard

If TokenViewer saves you money, please star it on GitHub — it helps other developers find it.


⚡ Quick Start

Requirements: macOS 14 (Sonoma) or later, Apple Silicon or Intel.

  1. Download the latest DMG
  2. Open the DMG and drag TokenViewer.app to /Applications
  3. Launch — the T icon appears in your menu bar
  4. Click the icon for an instant usage summary
  5. Open Dashboard for the full view

What you get immediately:

  • 📊 Today / 7-day / 30-day / Total token counts and cost estimates
  • 📈 Daily trend chart with cache hit rate and cost overlay
  • 🗓️ 53-week activity heatmap
  • 🔒 Live quota bars for 8 providers (ChatGPT, Copilot, Kiro, Cursor, Gemini, Kimi …)
  • 🏠 100% local — all data in ~/.tokenviewer/data.db. No account, no API keys.

"TokenViewer.app can't be opened" — first-launch Gatekeeper warning

The app is ad-hoc signed (not notarized — that requires a paid Apple Developer ID account).

  1. Go to System Settings → Privacy & Security
  2. Scroll to the Security section → click Open Anyway
  3. Confirm Open in the follow-up dialog

You only need to do this once. Alternatively, right-click the app → OpenOpen.


✨ Features

  • 🔌 25 AI tools out of the box — Claude Code, ChatGPT, Kiro, Cursor, GitHub Copilot, Gemini CLI, Opencode, Roocode, Kilo Code, Zed, Goose, Grok, Kimi, Craft, OpenClaw, Hermes, Antigravity, CodeBuddy, WorkBuddy, OhMyPi, Pi, KiloCLI, EveryCode, MiMoCode, ZCode
  • 🏠 100% local — Token data never leaves your machine. No account, no API keys.
  • 🚀 Zero config — Reads existing log files your tools already produce. Nothing installed into those tools.
  • 📊 Beautiful dashboard — Usage trends, model breakdown, cost analysis, provider breakdown, daily detail table
  • 🖥️ Native app — SwiftUI + Rust core. No Electron, no Node.js, no browser. Instant launch.
  • 📈 Smooth trend chart — Catmull-Rom spline with hover tooltip showing input / output / cache / reasoning / cost
  • 🗓️ Activity heatmap — 53-week GitHub-style grid in both the dashboard and the menu-bar panel
  • 📉 Rate limit tracking — Live quota bars with reset countdowns for 8 providers: ChatGPT, GitHub Copilot, Kiro (Free / Pro / Pro+ / Power), Cursor, Gemini, Kimi, Claude, Antigravity
  • 💰 Cost engine — Per-model pricing for all major providers + Kiro, Cursor, Kimi overrides. Multi-currency display (live exchange rates).
  • 🌍 Chinese / English UI — Switch in Settings at any time
  • Incremental sync — File offset cursors + mtime skip + rayon parallel parsing keep repeated syncs under 100 ms when nothing changed
  • 🔒 Privacy-first — Only token counts and timestamps. Never prompts, responses, or file contents.

🖼️ Screenshots

Menu Bar Panel — quick summary, limits, trend

Menu Bar Panel

Dashboard — full usage view

Dashboard

🔌 Supported AI Tools

ToolData SourceMethod
Claude Code~/.claude/projects/*.jsonlPassive reader
ChatGPT~/.codex/sessions/**/rollout-*.jsonlPassive reader
ZCode~/.zcode/cli/db/db.sqliteSQLite reader (model_usage table)
Kiro CLI~/.kiro/sessions/cli/*.json + .jsonlSession file reader + char-based token estimate
Kiro IDE~/Library/.../kiro.kiroagent/dev_data/SQLite + JSONL
GitHub Copilot~/.copilot/otel/*.jsonlOpenTelemetry file reader
CursorcursorDiskModel/usage.jsonPassive reader
Gemini CLI~/.gemini/tmp/*/chats/session-*.jsonPassive reader
Opencode~/.local/share/opencode/opencode.dbSQLite reader
RoocodeVSCode globalStorage tasks/*/ui_messages.jsonPassive reader
Kilo CodeVSCode globalStoragePassive reader
Zed~/Library/.../threads.dbSQLite reader
Goose~/Library/.../sessions.dbSQLite reader
Grok~/.grok/sessions/**/updates.jsonlPassive reader
Kimi~/.kimi/sessions/**/*.jsonlPassive reader
Craft~/.craft-agent/**/*.jsonlPassive reader
OpenClaw~/.openclaw/agents/**/*.jsonlPassive reader
Hermes~/.hermes/state.dbSQLite reader
Antigravity~/.gemini/antigravity*/brain/**/transcript.jsonlPassive reader
CodeBuddy~/.codebuddy/**/*.jsonlPassive reader
WorkBuddy~/.antigravity_cockpit/workbuddy_accounts/*.jsonLocal quota snapshot reader
OhMyPi~/.omp/agent/sessions/**/*.jsonlPassive reader
Pi~/.pi/agent/sessions/**/*.jsonlPassive reader
KiloCLI~/.local/share/kilo/kilo.dbSQLite reader
MiMoCode~/.local/share/mimocode/mimocode.dbSQLite reader (message table)

All integrations are passive readers — TokenViewer only reads files your tools already produce. Nothing is installed into those tools.

Missing your tool? Open an issue — adding a new parser is usually one file.


📊 Rate Limit Tracking

TokenViewer can show live quota usage and reset countdowns for 9 providers:

ProviderPlan LabelsData Source
ClaudeMax / ProAnthropic OAuth API (Keychain)
ChatGPTPlus / Business / ProChatGPT wham API (~/.codex/auth.json)
GitHub CopilotIndividual / BusinessGitHub API (~/.config/github-copilot/)
KiroFree / Pro / Pro+ / Powerkiro-cli /usage
CursorPro / Team / Enterprisecursor.com/api/usage-summary (SQLite session token)
Geminicloudcode-pa.googleapis.com (~/.gemini/oauth_creds.json)
KimiAdagio / Andante / Moderato / Allegretto / Allegroapi.kimi.com/coding/v1/usages
AntigravityUses Gemini quota
WorkBuddyPro / Free / Enterprisecodebuddy.cn billing APIs (workbuddy-desktop.info)

Providers not installed show as greyed-out cards (configured providers sort to the top).


🏗️ How It Works

AI Tool Logs → 25 Rust Parsers → SQLite (~/.tokenviewer/data.db)
↓
FFI (tt_sync / tt_query_*)
↓
SwiftUI Views ← CoreBridge ← UsageViewModel
  • Rust core (core/) — 25 parsers, SQLite storage, pricing engine. Compiled to libtokenviewer_core.a.
  • SwiftUI app (macos/) — Menu-bar status item, popover panel, full dashboard window.
  • Incremental sync — Each parser stores a file offset cursor in SQLite. On the next sync only new bytes are read. Parsers run in parallel (rayon). Files with unchanged mtime are skipped entirely.

🛡️ Privacy

ProtectionDetail
No content capturedOnly token counts, model names, and timestamps. Never prompts, responses, or file contents.
Local-onlyAll data stays in ~/.tokenviewer/data.db. No network calls except optional exchange rate fetch and update check.
No telemetryNo analytics, no crash reporting, no phone-home.
AuditableOpen source. The Rust parsers only extract numeric fields — see core/src/parsers/.

🏗️ Build from Source

Requirements: macOS 14+, Xcode 16+, Rust + aarch64-apple-darwin target, XcodeGen

git clone https://github.com/webkong/TokenViewer.git
cd TokenViewer/TokenViewerNew
# One-shot build + run
./run.sh

Step by step:

# 1. Install Rust target
rustup target add aarch64-apple-darwin
# 2. Build Rust corecd core
cargo build --release --target aarch64-apple-darwin
# 3. Generate Xcode projectcd ../macos
xcodegen generate
# 4. Build and run
xcodebuild -scheme TokenViewer -configuration Release build
open ~/Library/Developer/Xcode/DerivedData/TokenViewer-*/Build/Products/Release/TokenViewer.app

Release build (DMG)

brew install create-dmg gh
./script/release.sh build-dmg # → dist/release/TokenViewer.dmg
./script/release.sh push-release # → GitHub Release (requires gh auth login)
./script/release.sh build-website # → website/dist
./script/release.sh push-website # → gh-pages

🔧 Troubleshooting

No data showing after first launch

Click the sync button (↻) in the menu-bar panel or Dashboard. Data is not synced until you explicitly trigger it or the auto-sync timer fires (default: every 30 min).

Check that your AI tools are on the supported list and have been used at least once.

Kiro token count seems low

Kiro CLI sessions store turns in .json files. Token counts (input_token_count / output_token_count) are 0 by design in kiro-cli — the app estimates tokens from message character counts (÷ 4 chars/token, same as TokenTracker).

Kiro IDE data comes from tokens_generated.jsonl and is stored separately under the kiro-ide source.

Limits page shows "Not configured" for a provider

The rate-limit fetch requires local authentication state:

  • Kiro — must be logged in via kiro-cli (run kiro-cli chat /usage to verify)
  • Cursor — needs state.vscdb from the Cursor app
  • Gemini — needs ~/.gemini/oauth_creds.json (run gemini to authenticate)
  • Kimi — needs ~/.kimi/credentials/kimi-code.json
Today's data shows zero

TokenViewer converts "today" to UTC using your local timezone. If you're in UTC+8 (CST), "today" starts at UTC 16:00 the previous calendar day. Trigger a manual sync — the data should appear.


🤝 Contributing

  • Bugs / feature requests: open an issue
  • New tool parser: add a file in core/src/parsers/, register it in mod.rs and scheduler.rs. See existing parsers for reference.
  • Pull requests: fork → branch → PR. Please describe what you changed and why.

📜 License

CC BY-NC 4.0 — Free for personal and non-commercial use.
Attribution required when redistributing or modifying.
Commercial use is not permitted.


⭐ Star History

Star History Chart

🗺️ Roadmap

  • Windows support — system-tray app with native Win32 UI (planned)
  • Homebrew Cask formula

🙏 Credits

Built by webkong.
Inspired by TokenTracker.


TokenViewer — Know exactly what you're spending on AI.

tokenviewer.webkong.top · GitHub · Releases

About

A native macOS menu-bar app built with SwiftUI + Rust that auto-collects token counts and costs from 24 AI coding tools, aggregates them locally, and surfaces real usage trends in a beautiful dashboard. No cloud account, no Node.js, no browser — just a tiny native app.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages