Loading...
Loading...
Local token cost analytics dashboard for Claude Code sessions — reads JSONL transcripts and provides per-prompt cost breakdowns, heatmaps, and usage insights.
npx skill4agent add aradotso/trending-skills token-dashboard-claude-analyticsSkill by ara.so — Daily 2026 Skills collection.
~/.claude/projects/git clone https://github.com/nateherkai/token-dashboard.git
cd token-dashboard
python3 cli.py dashboardpip installgit clone https://github.com/nateherkai/token-dashboard.git
cd token-dashboard
py -3 cli.py dashboard# Start the full dashboard UI at http://127.0.0.1:8080
python3 cli.py dashboard
# Populate/refresh the SQLite cache, then exit
python3 cli.py scan
# Print today's totals in the terminal
python3 cli.py today
# Print all-time totals in the terminal
python3 cli.py stats
# Show active optimization tips in terminal
python3 cli.py tips
# Dashboard with options
python3 cli.py dashboard --no-open # don't auto-open browser
python3 cli.py dashboard --no-scan # skip initial scan, use cached DB only
python3 cli.py dashboard --projects-dir /path/to/projects --db /path/to/cache.db# Change port (default: 8080)
PORT=9000 python3 cli.py dashboard
# Change bind address (WARNING: keep 127.0.0.1 — 0.0.0.0 exposes data on network)
HOST=127.0.0.1 python3 cli.py dashboard
# Custom projects directory
CLAUDE_PROJECTS_DIR=/custom/path python3 cli.py dashboard
# Custom SQLite cache location
TOKEN_DASHBOARD_DB=/custom/path/cache.db python3 cli.py dashboardpricing.json{
"models": {
"claude-opus-4-5": {
"input": 15.00,
"output": 75.00,
"cache_write": 18.75,
"cache_read": 1.50
}
},
"plans": {
"api": { "label": "API", "multiplier": 1.0 },
"pro": { "label": "Pro ($20/mo)", "multiplier": 0.0 },
"max": { "label": "Max ($100/mo)", "multiplier": 0.0 }
}
}| OS | Path |
|---|---|
| macOS / Linux | |
| Windows | |
~/.claude/token-dashboard.db| Tab | What it shows |
|---|---|
| Overview | All-time totals, daily charts, cost by plan, top tools, recent sessions |
| Prompts | Most expensive user prompts ranked by tokens; click to see tool calls and result sizes |
| Sessions | Turn-by-turn view with per-turn tokens and tool calls |
| Projects | Per-project comparison: tokens, sessions, files touched |
| Skills | Most-invoked skills and their token costs |
| Tips | Rule-based suggestions (repeated file reads, oversized tool results, low cache-hit rate) |
| Settings | Switch between API / Pro / Max pricing plans |
http://127.0.0.1:8080/api/# Overview stats
curl http://127.0.0.1:8080/api/overview
# Most expensive prompts
curl http://127.0.0.1:8080/api/prompts
# Session list
curl http://127.0.0.1:8080/api/sessions
# Single session detail
curl http://127.0.0.1:8080/api/sessions/<session-id>
# Project comparison
curl http://127.0.0.1:8080/api/projects
# Optimization tips
curl http://127.0.0.1:8080/api/tipspython3 cli.py scanimport sqlite3
import os
db_path = os.path.expanduser("~/.claude/token-dashboard.db")
conn = sqlite3.connect(db_path)
# Get top 10 most expensive prompts
cursor = conn.execute("""
SELECT
project_slug,
session_id,
input_tokens,
output_tokens,
cache_read_tokens,
cost_usd,
substr(user_text, 1, 80) as prompt_preview
FROM turns
ORDER BY cost_usd DESC
LIMIT 10
""")
for row in cursor.fetchall():
print(f"${row[5]:.4f} | {row[0]} | {row[6]}")
conn.close()import sqlite3
import os
db_path = os.path.expanduser("~/.claude/token-dashboard.db")
conn = sqlite3.connect(db_path)
cursor = conn.execute("""
SELECT
date(created_at) as day,
SUM(input_tokens) as total_input,
SUM(output_tokens) as total_output,
SUM(cache_read_tokens) as total_cache_read,
SUM(cost_usd) as total_cost
FROM turns
GROUP BY date(created_at)
ORDER BY day DESC
LIMIT 30
""")
for row in cursor.fetchall():
print(f"{row[0]}: ${row[4]:.4f} ({row[1]} in, {row[2]} out, {row[3]} cached)")
conn.close()import sys
import os
# Add the project root to path
sys.path.insert(0, '/path/to/token-dashboard')
from token_dashboard.scanner import Scanner
projects_dir = os.path.expanduser("~/.claude/projects")
db_path = os.path.expanduser("~/.claude/token-dashboard.db")
scanner = Scanner(projects_dir=projects_dir, db_path=db_path)
scanner.scan()
print("Scan complete")import urllib.request
import json
# Requires dashboard to be running: python3 cli.py dashboard --no-open
with urllib.request.urlopen("http://127.0.0.1:8080/api/overview") as resp:
data = json.loads(resp.read())
print(f"Total sessions: {data['total_sessions']}")
print(f"Total cost (API): ${data['total_cost_usd']:.2f}")
print(f"Cache hit rate: {data['cache_hit_rate']:.1%}")rm ~/.claude/token-dashboard.db
python3 cli.py scanPORT=9090 python3 cli.py dashboardpython3 cli.py tips > optimization-tips.txt# Add to crontab: 0 9 * * * /path/to/daily-stats.sh
cd /path/to/token-dashboard && python3 cli.py today >> ~/claude-usage-log.txt# If Claude Code projects are in a non-standard location
python3 cli.py dashboard --projects-dir ~/work/.claude/projects| Problem | Solution |
|---|---|
| "No data" / empty charts | Run |
| Port 8080 in use | |
| Numbers stuck/wrong | Delete |
| Two instances running | Stop all instances first — they fight over the SQLite DB |
| Use |
| No sessions found | Ensure Claude Code has been used and files exist in |
cli.py
└─► token_dashboard/scanner.py # reads JSONL, dedupes by message.id, writes SQLite
└─► token_dashboard/server.py # serves /api/* JSON routes + web/ static files
└─► web/ # vanilla JS + vendored ECharts, no build step
pricing.json # editable model/plan pricing
~/.claude/token-dashboard.db # SQLite cache (auto-created)message.id