Skip to content

Repository files navigation

ccstats

Crates.io GitHub Release License: MIT

ccstats token and cost analytics card

ccstats is a fast CLI for token and cost usage analytics for Claude Code, OpenAI Codex, Cursor, Grok, and Kimi Code logs.

Search keywords: claude code usage stats, codex usage stats, cursor usage stats, token usage cli, ai token cost tracker.

Highlights

  • Fast local analysis of usage JSONL logs
  • Claude Code support (~/.claude/projects/)
  • OpenAI Codex support (~/.codex/sessions/)
  • Codex weekly quota pace and reset estimates from provider snapshots
  • Cursor usage API support (CURSOR_API_KEY or CURSOR_SESSION_TOKEN)
  • Grok support (~/.grok/sessions/)
  • Kimi Code support (~/.kimi-code/sessions/)
  • Daily/weekly/monthly/project/session views
  • Top-N leaderboard ranking models or projects by cost share
  • Optional model-level token and cost breakdown
  • Reusable Rust SDK for embedding local usage and cost summaries in other apps

Installation

Homebrew (macOS/Linux)

brew install majiayu000/tap/ccstats

Cargo binstall (prebuilt binary)

cargo binstall ccstats

Cargo install (from source)

cargo install ccstats

Shell script

curl -fsSL https://raw.githubusercontent.com/majiayu000/ccstats/main/install.sh | sh

# Install a specific version
curl -fsSL https://raw.githubusercontent.com/majiayu000/ccstats/main/install.sh | VERSION=v0.2.63 sh

Manual download

Download prebuilt archives and SHA-256 checksums from GitHub Releases.

Quick Start (Codex)

# Install
brew install majiayu000/tap/ccstats

# Today
ccstats codex today

# Daily trend
ccstats codex daily

# Weekly quota pace, remaining percentage, and reset time
ccstats quota

# Same result via unified source flag
ccstats daily --source codex

Quick Start (Cursor)

Cursor usage comes from Cursor's usage API, not from local state.vscdb files. Enterprise teams should set CURSOR_API_KEY. Individual and self-serve plans should set CURSOR_SESSION_TOKEN to the WorkosCursorSessionToken cookie from cursor.com/dashboard/usage.

# Install
brew install majiayu000/tap/ccstats

# Today
ccstats today --source cursor

# Daily trend
ccstats daily --source cursor

# Same source via alias
ccstats daily --source cur

Quick Start (Grok)

Grok support reads each shell.turn.inference_done record from ~/.grok/logs/unified.jsonl. It reports uncached input, cached prompt, completion, and reasoning tokens, then calculates Grok 4.5/4.6 USD cost per inference using xAI's short- or long-context price for the whole request. Observed records are kept in an atomic ccstats ledger because Grok trims the live log in place.

# Install
brew install majiayu000/tap/ccstats

# Today's Grok usage
ccstats grok today

# Daily Grok usage
ccstats grok

# Same source via alias
ccstats daily --source gx

Quick Start (Kimi Code)

Kimi Code support reads per-turn usage.record entries from wire logs under ~/.kimi-code/sessions/, including sub-agent usage, and reports actual input/output/cache token usage per turn.

# Install
brew install majiayu000/tap/ccstats

# Today's usage and cost
ccstats kimi today

# Daily breakdown
ccstats kimi

# Same source via alias
ccstats daily --source km

Crate Documentation

Rust SDK

ccstats can be used as a Rust library when another app needs structured local usage and cost data without spawning the CLI.

use ccstats::{SummaryOptions, UsageRange, UsageSource, summarize_cost_with_cli_config};

let summary = summarize_cost_with_cli_config(SummaryOptions {
    source: UsageSource::Codex,
    range: UsageRange::Today,
    ..SummaryOptions::default()
})?;

println!("today: ${:.2}", summary.cost_usd.unwrap_or(0.0));

The SDK uses the same source registry, parsers, aggregation logic, pricing cache, and fallback pricing as the CLI. Use summarize_cost_with_cli_config when SDK output should follow the same persisted CLI defaults for timezone, offline pricing, strict pricing, and currency. Use summarize_cost when the caller wants fully explicit options. Returned summaries include total tokens, cache read/create tokens, cache hit rate, reasoning tokens, per-model breakdowns, cost_usd, and an optional converted cost when SummaryOptions::currency is set.

Codex weekly quota pace is also available as structured SDK data without spawning the CLI:

use ccstats::load_codex_weekly_quota;

let quota = load_codex_weekly_quota(None)?;
println!("weekly used: {:.1}%", quota.used_pct);
println!("projected at reset: {:.1}%", quota.projected_pct_at_reset);

Pass Some(codex_home) to read an explicit Codex home without modifying process environment variables. The explicit path is authoritative and never falls back to CODEX_HOME or ~/.codex. Missing, stale, malformed, and unreadable snapshots return typed CodexQuotaError values.

Apps that need several windows at once can use the batch API so source logs, pricing, and currency are loaded once for the request:

use ccstats::{MultiSummaryOptions, UsageRange, UsageSource, summarize_cost_ranges};

let overview = summarize_cost_ranges(MultiSummaryOptions {
    source: UsageSource::Claude,
    ranges: vec![
        UsageRange::Today,
        UsageRange::ThisWeek,
        UsageRange::ThisMonth,
    ],
    timezone: None,
    offline: true,
    strict_pricing: false,
    currency: Some("USD".to_string()),
})?;

for summary in overview.summaries {
    println!("{:?}: ${:.2}", summary.range, summary.cost_usd.unwrap_or(0.0));
}

Usage

Claude Code

# Today's usage
ccstats today

# Daily breakdown
ccstats daily

# Weekly summary
ccstats weekly

# Monthly summary
ccstats monthly

# By project
ccstats project

# By session
ccstats session

# 5-hour billing blocks
ccstats blocks

# Top-N leaderboard (ranks by cost, falls back to tokens when costs unknown)
ccstats top                          # top 10 models by cost
ccstats top --dim project --limit 5  # top 5 projects

# With model breakdown
ccstats today -b

# JSON output
ccstats today -j

# Debug mode (timing info)
ccstats today --debug

# Debug model pricing resolution (written to stderr)
# Example: Pricing: glm-5.2 -> glm-5.2 (live)
# Unknown models are reported as: Pricing: <model> -> no match (unknown)
ccstats today --breakdown --strict-pricing --debug

By default, ccstats checks Claude Code logs under ~/.claude/projects/. If Claude Code uses a moved config directory, set CLAUDE_CONFIG_DIR to the Claude config root:

CLAUDE_CONFIG_DIR="/path/to/claude-config" ccstats daily --source claude

OpenAI Codex

# Codex subcommand mode
ccstats codex daily

# Or use unified source flag
ccstats daily --source codex

# Today's Codex usage
ccstats codex today

# Daily Codex breakdown
ccstats codex daily

# Weekly Codex summary
ccstats codex weekly

# Provider weekly quota pace (same as `ccstats quota`)
ccstats codex quota

# By session
ccstats codex session

# With model breakdown
ccstats codex today -b

By default, ccstats checks Codex sessions under ~/.codex/sessions/. You can override the Codex home directory with CODEX_HOME:

CODEX_HOME="/path/to/.codex" ccstats codex daily

Codex weekly quota estimate

ccstats quota reads the newest server-provided 10,080-minute rate-limit snapshot from local Codex session logs. It reports the used and remaining percentages, reset time, projected percentage at reset, and an estimated depletion time when the current pace would exceed 100%. It also prices local usage from the exact active quota window and divides it by the reported used fraction to estimate the full week's API-equivalent USD value and token count.

# Human-readable table
ccstats quota

# Equivalent nested command
ccstats codex quota

# Machine-readable output
ccstats quota --json
ccstats quota --csv

The dollar and token figures are approximations, not official provider allowances. They vary with the current model and cache mix; token totals are only comparable while that mix stays similar. Dollar values use ccstats' current model price resolution; request-level pricing tiers may not be represented. Use --no-cost to omit the value estimate. Quota estimates are reported in USD, so an explicit non-USD --currency is rejected. If no current weekly snapshot exists, the command exits with an error instead of estimating quota from token totals.

Cursor

Cursor uses the unified source flag rather than a dedicated subcommand.

# Today's Cursor usage
ccstats today --source cursor

# Daily Cursor breakdown
ccstats daily --source cursor

# Weekly Cursor summary
ccstats weekly --source cursor

# By session/conversation
ccstats session --source cursor

# Cursor alias
ccstats daily --source cur

Authenticate with one of:

# Enterprise Admin API key from cursor.com/dashboard/api
CURSOR_API_KEY="..." ccstats daily --source cursor

# Dashboard session cookie for individual / self-serve plans
CURSOR_SESSION_TOKEN="..." ccstats daily --source cursor

CURSOR_API_KEY calls POST https://api.cursor.com/teams/filtered-usage-events. CURSOR_SESSION_TOKEN calls the dashboard usage-events endpoint used by cursor.com/dashboard/usage. For tests or offline replay, point CURSOR_USAGE_FILE at a saved JSON payload.

Current limitations:

  • ccstats does not read local Cursor SQLite auth tokens. Set CURSOR_API_KEY or CURSOR_SESSION_TOKEN explicitly.
  • Project aggregation and 5-hour billing blocks are not supported for Cursor.
  • Dashboard session cookies expire; refresh CURSOR_SESSION_TOKEN when requests start failing.
  • Self-serve plans may return token counts with $0 event costs. ccstats records that billed amount instead of estimating Cursor subscription cost from LiteLLM prices.

Grok

# Today's Grok usage
ccstats grok today

# Daily Grok usage
ccstats grok

# Weekly Grok usage
ccstats grok weekly

# By session
ccstats grok session

# By project
ccstats grok project

# Grok alias
ccstats daily --source gx

By default, ccstats uses:

  • ~/.grok/logs/unified.jsonl for per-inference token records
  • ~/.grok/sessions/**/summary.json for model, project, and session metadata
  • the platform cache directory under ccstats/grok/<source-root>/inference-v1.jsonl for the durable, deduplicated ledger

For Grok 4.5 and 4.6, requests below 200k prompt tokens use the short-context rates. Requests at or above 200k use the long-context input, cached-input, and output rates for the entire inference. completion_tokens already includes reasoning, so ccstats separates the displayed fields without charging reasoning twice. Rates follow the xAI pricing reference.

If unified.jsonl is unavailable, ccstats retains the older session turn_completed.usage and context-snapshot fallback for installations that do not emit inference telemetry.

You can override the Grok home directory with GROK_HOME:

GROK_HOME="/path/to/.grok" ccstats grok

Current limitations:

  • The durable ledger starts when ccstats first observes an inference. It cannot recover records Grok trimmed before the first run.
  • Session fallback totals use the fields available in those files and can differ from the Grok Build weekly allowance.
  • Grok models without a published ccstats per-inference tier fall back to the normal pricing resolver.
  • Grok 5-hour billing blocks are not supported.

Kimi Code

# Today's Kimi Code usage and cost
ccstats kimi today

# Daily Kimi Code breakdown
ccstats kimi

# Weekly Kimi Code summary
ccstats kimi weekly

# By session
ccstats kimi session

# By project
ccstats kimi project

# Kimi alias
ccstats daily --source km

By default, ccstats reads Kimi Code wire logs under:

  • ~/.kimi-code/sessions/*/*/agents/*/wire.jsonl (main and sub-agent per-turn usage.record entries)
  • ~/.kimi-code/session_index.jsonl for session-to-project mapping

You can override the Kimi Code home directory with KIMI_CODE_HOME:

KIMI_CODE_HOME="/path/to/.kimi-code" ccstats kimi

Current limitations:

  • Kimi Code subscription models (e.g. kimi-code/k3) have no public per-token pricing; costs use fallback estimates based on Moonshot's official kimi-k2.6 API rates and are marked as fallback in structured output. Use --strict-pricing to show N/A instead.
  • Cache creation tokens are reported but priced at $0 by the Kimi fallback estimate (Moonshot does not publish a separate cache-creation rate).
  • Kimi 5-hour billing blocks and tool-call statistics are not supported.

Common Options

# Bucket by timezone
ccstats daily --timezone UTC

# Locale-aware number formatting
ccstats monthly --locale de

# Filter by date
ccstats daily --since 20260101 --until 20260131

# Monthly budget forecast (uses --until as the as-of date when present)
ccstats monthly --monthly-budget 25 --until 20260415

# Select data source explicitly (supports aliases)
ccstats daily --source codex

# Combine all supported data sources
ccstats monthly --source all

# Cursor source (usage API)
ccstats daily --source cursor

# Cursor alias
ccstats daily --source cur

# Grok source and alias
ccstats daily --source grok
ccstats daily --source gx

# Kimi Code source and alias
ccstats daily --source kimi
ccstats daily --source km

# Offline mode (use cached pricing)
ccstats today -O

# Compact output
ccstats today -c

# Hide cost column
ccstats today --no-cost

Configuration

ccstats reads an optional TOML config file before command execution. CLI flags override config values.

Search order:

  1. ~/.config/ccstats/config.toml
  2. Platform config directory: for example ~/Library/Application Support/ccstats/config.toml on macOS
  3. ~/.ccstats.toml

The first existing config file wins. If that file exists but cannot be read, has invalid TOML, or has a wrong field type, ccstats exits with an error. It does not fall back to defaults or lower-priority config paths. If no config file exists, defaults are used.

Example config.toml:

source = "codex"
timezone = "Asia/Shanghai"
locale = "en"
currency = "USD"
offline = true
strict_pricing = true
compact = true
breakdown = false
order = "desc"
color = "auto"
cost = "show"

Supported keys:

Key Type Values
offline boolean true or false
compact boolean true or false
no_cost boolean true or false
no_color boolean true or false
breakdown boolean true or false
debug boolean true or false
strict_pricing boolean true or false
order string asc, desc
color string auto, always, never
cost string show, hide
timezone string IANA timezone such as UTC or Asia/Shanghai
locale string Locale used for number formatting, such as en or de
currency string Currency code such as USD, CNY, or EUR
source string Source name or alias such as claude, codex, cursor, grok, kimi, or all

Source root env overrides are independent of config keys:

Source Env var Value Default when unset
Claude Code CLAUDE_CONFIG_DIR Claude config root containing projects/ ~/.claude
OpenAI Codex CODEX_HOME Codex root containing sessions/ ~/.codex
Cursor CURSOR_API_KEY or CURSOR_SESSION_TOKEN Admin API key or dashboard session cookie No default; optional CURSOR_USAGE_FILE replay
Grok GROK_HOME Grok root containing sessions/ ~/.grok
Kimi Code KIMI_CODE_HOME Kimi Code root containing sessions/ ~/.kimi-code

Session CSV Columns

ccstats session --csv now includes:

  • reasoning_tokens
  • cache_creation_tokens
  • cache_read_tokens
  • cache_hit_rate

Cache Hit Rate

Statistical table, JSON, CSV, statusline, top, session, project, and block outputs report prompt-cache hit rate as:

cache_read / (input + cache_creation + cache_read) * 100

Table output uses one decimal place and a % suffix. JSON uses the numeric cache_hit_rate field, while CSV uses a two-decimal cache_hit_rate column. Claude, Codex, Cursor, Grok, and Kimi Code expose the required cache-read metric. Mixed --source all output reports the aggregate rate across all selected usage.

Parsing Warnings

When malformed JSONL records are encountered, ccstats reports them in stderr:

Warning: ignored <N> malformed records

Supported Data Sources

Source Directory Override Features
Claude Code ~/.claude/projects/ CLAUDE_CONFIG_DIR Projects, Billing Blocks, Deduplication
OpenAI Codex ~/.codex/sessions/ CODEX_HOME Reasoning Tokens
All Sources Multiple Source-specific env vars Combined daily/weekly/monthly/today/statusline summaries
Cursor Cursor usage API CURSOR_API_KEY / CURSOR_SESSION_TOKEN Per-event tokens, cache tokens, recorded chargedCents
Grok ~/.grok/logs/unified.jsonl GROK_HOME Per-inference usage, Projects, Cache / reasoning tokens, 200k pricing tier, durable ledger
Kimi Code ~/.kimi-code/sessions/ KIMI_CODE_HOME Per-turn usage records, Projects, Cache tokens

Architecture

See docs/ARCHITECTURE.md for:

  • Adding new data sources
  • Data flow and processing pipeline
  • Caching mechanism
  • Architecture and module boundaries

See docs/algorithm/authoritative-token-accounting.md for:

  • Token accounting rules
  • Source-specific normalization
  • Deduplication semantics

License

MIT. See LICENSE.

Releases

Packages

Contributors

Languages