Skip to content

About

Local Streamlit dashboard for auditable Cursor usage, token, cost, session, and activity analysis.

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Cursor Usage & Cost Dashboard

A local, self-hosted dashboard that gives you far more cost insight than Cursor's built-in usage page: daily / weekly cost, week-over-week comparison, per-model and per-token-type breakdowns, cache-savings, request/error rates, activity classification, session inference, distribution/tail analysis, Max-Mode split, a 30-day run-rate projection, and GitHub-style metric calendars.

It reads one accumulating local store (data/usage_events.parquet) that you feed with the CSV you export from Cursor. Re-importing every week just extends your history — nothing is ever lost (events are de-duplicated).

Quickstart (2 minutes)

# 1. clone, then from the project folder:
python3 -m venv .venv
source .venv/bin/activate            # Windows: .venv\Scripts\activate
pip install -r requirements.txt

# 2. run
streamlit run app.py

Then in the app sidebar (📥 Import CSV):

  • Drag-and-drop your exported CSV, or click Import newest from ~/Downloads.

That's it — costs are computed automatically. No code to edit, no config.

Getting your usage CSV

  1. Go to cursor.com/dashboard → Usage.
  2. Export/download the usage events CSV (team-usage-events-*.csv).
  3. Drop it into the dashboard. Do this whenever you want fresh data; the store accumulates history across exports.

You upload the raw export — the app derives every cost column (cache-write / input / cache-read / output → total) from the token counts.

Requirements

  • Python 3.11+ (developed on 3.14).
  • Dependencies pinned in requirements.txt (Streamlit, Plotly, pandas, pyarrow, requests, python-dotenv, truststore). pyproject.toml mirrors runtime deps and adds optional dev tooling.

Development & CI

pip install -r requirements.txt
pip install -e ".[dev]"          # pytest, pytest-cov, ruff

ruff check .
ruff format --check .
pytest
pytest --cov                     # with coverage report

GitHub Actions (.github/workflows/ci.yml) runs Ruff and pytest on Python 3.11 through 3.14 for pull requests and pushes to main.

Optional: automatic pulls via the Cursor Admin API

If you have a Team/Enterprise admin API key, you can skip manual CSVs:

cp .env.example .env          # then set CURSOR_API_KEY=crsr_...
python ingest.py --api        # pulls May 1 -> now into the store

…or use 🔄 Refresh from API in the sidebar. The Admin API also provides chargedCents, which unlocks the "Charged (Cursor)" cost basis for modeled-vs-charged comparison.

Caveats:

  • filtered-usage-events is an admin-only endpoint. A regular Member / User API key (also crsr_-prefixed) returns 401 Invalid Team API Key — in that case just use the CSV flow, which works for everyone.
  • On corporate networks that do TLS inspection (e.g. via a proxy), Python may fail cert verification. This project uses truststore to trust your OS keychain automatically, which resolves it.

What's in each tab

Tab Shows
Overview Cost/token/event selector drives the calendar, daily trend, model share, and cumulative chart
Daily & Weekly Weekly/WoW trends, user-vs-background events, event-size tails, hour×weekday heatmap
By Model Cost and efficiency, model-rank bump chart, token mix, event distributions, rank comparison
Tokens Token distributions/ECDF, daily and weekly volume, composition, calendars, largest events
Cache & savings Cache economics, token-share vs cost-share, efficiency frontier, amplification, cold context
Activity & Errors Exported requests vs rows, activity classes, retry signals, zero-request and no-charge analysis
Distributions & Tails Corrected cost/request distribution, ECDF/Pareto, model violins, percentile trends
Sessions Idle-gap session inference, event timeline, burstiness, trajectories, top sessions
Data Quality Activity review/overrides, retry signatures, pricing coverage, filter impact, integrity checks
Max Mode Cost & request share for Max Mode vs Normal; only appears when Max Mode data exists

The header always shows KPI cards plus an auto-generated insight strip (latest week vs previous, top model, priciest day, run-rate, cache savings, background candidates, review queue, and pricing coverage).

Background-activity policy

The CSV does not directly say whether an event was initiated by the user or by Cursor background maintenance. The sidebar therefore exposes a transparent, adjustable token threshold (250k by default) and four activity views:

  • User-attributed — excludes threshold candidates, zero/no-charge events, and repeated cache-snapshot retry bursts.
  • All activity — raw normalized events.
  • Background only — events classified by the current policy or a manual background label.
  • Needs review — threshold candidates without a manual decision.

The Data Quality tab provides an editable review queue. Manual user/background/unsure labels are persisted locally in data/activity_labels.parquet, keyed by event ID, and always override automatic rules. No machine-learning classifier is used.

Project layout

Path Purpose
app.py Thin Streamlit entrypoint (main() orchestrates sidebar → context → header → tabs)
dashboard/data.py Cached parquet load (mtime bust), API fetch normalization, cache clear helpers
dashboard/sidebar.py CSV import, API refresh, filters, pricing-table expander
dashboard/header.py Title, caption, unpriced warning, insight chips, KPI row
dashboard/context.py FilterState, DashboardContext, frame semantics & aggregates
dashboard/tabs/ One module per dashboard tab
dashboard/charts.py, dashboard/theme.py, dashboard/formatting.py Shared Plotly/CSS/format helpers
transforms.py Aggregation helpers
pricing.py Model rate table + modeled-cost & cache-savings computation
usage_store.py Unified schema, CSV/API normalization, dedup, parquet store
activity.py Background policy, retry-burst detection, and persistent manual labels
cursor_api.py Cursor Admin API client (optional)
ingest.py CLI to seed/refresh the store
data/ Local parquet state (gitignored except data/README.md)
tests/ Synthetic-only pytest suite + Streamlit AppTest smoke tests

See CONTRIBUTING.md for contributor workflow and SECURITY.md for handling API keys and usage exports.

Maintaining pricing

Edit MODEL_PRICING in pricing.py (USD per 1M tokens). Any model missing a rate is flagged as "unpriced" in the app so you know to add it.

About

Local Streamlit dashboard for auditable Cursor usage, token, cost, session, and activity analysis.

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages