A local-only Go service that monitors Cursor Pro+ usage via internal APIs, stores metrics in SQLite, and sends native macOS notifications when usage exceeds thresholds or switches from Included to On-Demand billing.
This application provides local monitoring and alerting for your Cursor IDE usage. It:
- Monitors Usage in Real-Time: Polls Cursor's internal API every 15 minutes to track your usage
- Stores Historical Data: Saves all usage metrics, events, and costs in a local SQLite database
- Sends Alerts: Notifies you via macOS notifications when:
- Usage exceeds 75%, 90%, or 100% of included credits
- Billing switches from "Included" to "On-Demand"
- Provides Analytics: Shows detailed summaries, cost breakdowns, and usage statistics
- Runs in Background: Can run as a daemon process, detached from your terminal
┌─────────────────┐
│ Cursor IDE │
│ (Local DB) │
└────────┬────────┘
│ JWT Token Extraction
▼
┌─────────────────┐
│ cursor-monitor │
│ (This App) │
└────────┬────────┘
│ API Calls
▼
┌─────────────────┐ ┌──────────────┐
│ Cursor API │◄─────┤ SQLite DB │
│ (Internal) │ │ (Local) │
└─────────────────┘ └──────────────┘
│ │
│ ▼
│ ┌──────────────┐
└──────────────► macOS │
│ Notifications│
└──────────────┘
-
Token Extraction (
internal/auth/auth.go)- Reads JWT session token from Cursor's local SQLite database
- Location:
~/Library/Application Support/Cursor/User/globalStorage/state.vscdb - Extracts
cursor.sessionTokenfrom the key-value store - Uses this token to authenticate API requests
-
API Polling (
internal/monitor/monitor.go)- Every 15 minutes (configurable), makes authenticated requests to:
/api/dashboard/get-usage- Current usage snapshot/api/dashboard/get-monthly-invoice- Invoice items and billing cycle/api/dashboard/get-filtered-usage-events- Detailed usage events
- Handles pagination automatically to fetch all events
- Parses JSON responses into structured Go types
- Every 15 minutes (configurable), makes authenticated requests to:
-
Data Storage (
internal/storage/storage.go)- Stores data in SQLite database (default:
~/.cursor_monitor/metrics.db) - Three main tables:
usage_snapshots- Periodic usage snapshotsinvoice_items- Billing items from invoicesusage_events- Individual API call events with token breakdowns
- Uses UPSERT logic to update existing events with latest cost data
- Stores data in SQLite database (default:
-
Alert Detection (
internal/alerts/alerts.go)- Compares current usage against configured thresholds (75%, 90%, 100%)
- Detects transitions from "Included" to "On-Demand" billing
- Tracks alert history to prevent duplicate notifications
-
Notifications (
internal/alerts/alerts.go)- Uses macOS
osascriptto send native notifications - Shows usage percentage, request counts, and on-demand spending
- Plays system sound (configurable)
- Uses macOS
-
Daemon Mode (
cmd/cursor-monitor/main.go)- Double-fork daemonization for proper background operation
- Creates PID file for process management
- Handles graceful shutdown with signal handling
1. Poll starts
↓
2. Extract JWT token from Cursor's DB
↓
3. Call /api/dashboard/get-usage
Response: {"premiumRequestsUsed": 250, "premiumRequestsLimit": 500, ...}
↓
4. Call /api/dashboard/get-filtered-usage-events (with pagination)
Response: [{"eventDate": "...", "model": "claude-4.5-sonnet", "totalTokens": 50000, ...}, ...]
↓
5. Store snapshot and events in SQLite
↓
6. Calculate usage percentage: 250/500 = 50%
↓
7. Check alert thresholds (50% < 75%, no alert)
↓
8. Wait 15 minutes, repeat
- Real-time Monitoring: Polls Cursor's internal API every 15 minutes
- Usage Alerts: macOS notifications when usage exceeds 75%, 90%, or 100%
- Critical Alerts: Immediate notification when billing switches from Included to On-Demand
- Historical Tracking: Stores all usage metrics in SQLite for analysis
- Cost Analysis: View detailed cost breakdowns and usage statistics
- Single Binary: Zero runtime dependencies - just copy and run
- Background Operation: Run as daemon process, detached from terminal
- Install Go 1.22 or later
- Build the binary:
make build
- Install to PATH (optional):
make install
Copy config.yaml.example to ~/.cursor_monitor/config.yaml and customize:
polling:
interval_minutes: 15
alerts:
thresholds: [75, 90, 100]
on_demand_critical: true
sound: "default"
database:
path: "~/.cursor_monitor/metrics.db"
retention_days: 90
byok:
enabled: false
show_comparison: true
plan:
included_usage_usd: 63.60
plan_name: "Pro+"Important: The config file must be at ~/.cursor_monitor/config.yaml (the default location) or you must pass --config flag to all commands.
# Start the monitoring daemon (foreground)
cursor-monitor start
# Start as background daemon (detaches from terminal, writes PID file)
cursor-monitor start --daemon
# Check current usage status
cursor-monitor status
# View billing cycle summary with invoice items and usage events
cursor-monitor summary
# Show cost analysis (add --byok flag for BYOK comparison)
cursor-monitor costs
cursor-monitor costs --byok
# Manually trigger a poll now (useful for testing)
cursor-monitor refresh
# Import usage events from CSV file
cursor-monitor import usage_events.csv
# Stop background daemon (sends SIGTERM, cleans up PID file)
cursor-monitor stop- start: Begins monitoring with configurable polling interval. Use
--daemonflag to run in background. - status: Shows current usage percentage, request counts, and on-demand spending.
- summary: Displays comprehensive billing cycle information including invoice items and usage event counts with 24-hour time format.
- costs: Shows cost analysis. Use
--byokflag to compare Cursor costs with direct API pricing (seedocs/BYOK_ANALYSIS.mdfor why this is not recommended). - refresh: Immediately triggers a single poll without starting the full daemon.
- import: Imports historical usage events from a CSV file (useful for backfilling data).
- stop: Gracefully stops a running daemon process by reading PID file and sending termination signal.
The application accesses Cursor's internal API endpoints (not publicly documented):
POST /api/dashboard/get-usage- Current usage snapshotPOST /api/dashboard/get-monthly-invoice- Invoice items for billing cyclePOST /api/dashboard/get-filtered-usage-events- Detailed usage events (paginated)
All requests require authentication via JWT session token extracted from Cursor's local database.
usage_snapshots:
- Periodic snapshots of usage metrics
- Includes: request counts, usage percentage, on-demand spending, billing cycle info
invoice_items:
- Aggregated billing items from invoices
- Includes: model name, request count, cost, billing cycle
usage_events:
- Individual API call events
- Includes: timestamp, model, token breakdowns (input, output, cache), cost, event type
By default, data is retained for 90 days. This can be configured in config.yaml:
database:
retention_days: 90- macOS (for native notifications)
- Cursor IDE installed and logged in
- Go 1.22+ (for building)
docs/BYOK_ANALYSIS.md- Comprehensive analysis of BYOK vs Cursor billing (conclusion: don't use BYOK)docs/TESTING.md- Testing guide and test structuredocs/CHANGELOG.md- Complete change logdocs/COMPLETION_SUMMARY.md- Implementation completion summaryplan/IMPLEMENTATION_PLAN.md- Detailed implementation plan and status
MIT