skills/ccusage/SKILL.md
Check Claude Code API usage, token consumption, and quota remaining. Use when asked about usage, tokens, costs, quota, or how much Claude Code capacity is left.
npx skillsauth add svenflow/dispatch ccusageInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Two data sources: local (ccusage npm package, reads JSONL logs) and server-side (daemon-cached quota from Anthropic API).
# Combined view: local block stats + server-side quota (default)
~/.claude/skills/ccusage/scripts/usage
# Local only
~/.claude/skills/ccusage/scripts/usage daily
~/.claude/skills/ccusage/scripts/usage weekly
~/.claude/skills/ccusage/scripts/usage monthly
# Server-side (reads from daemon cache by default — instant, no API call)
~/.claude/skills/ccusage/scripts/usage server # Human-readable
~/.claude/skills/ccusage/scripts/usage server --json # Raw JSON
~/.claude/skills/ccusage/scripts/usage server --check 80 # Exit 0 if < 80%
~/.claude/skills/ccusage/scripts/usage server --reset-time # ISO 8601 reset time
~/.claude/skills/ccusage/scripts/usage server --hours-until-reset # Hours as float
~/.claude/skills/ccusage/scripts/usage server --force # Bypass cache, hit API directly
The daemon's health check loop fetches quota from Anthropic every ~15 min (adaptive backoff: 15min base → 2h cap on failures). Results are:
~/dispatch/state/quota_cache.json (atomic write)quota.fetched event on system topic (with utilization + backoff state)dispatch-api reads quota_cache.json and serves it at /api/dashboard/ccuThe server-usage CLI reads from the cache file — it never hits the Anthropic API unless you pass --force. This prevents quota hammering and makes it instant.
~/dispatch/state/quota_cache.json
api.anthropic.com/api/oauth/usageAuthorization: Bearer <oauth-token>anthropic-beta: oauth-2025-04-20claudeAiOauth.accessToken~/.claude/.credentials.json → claudeAiOauth.accessTokenclaude.ai/api/organizations/{org_id}/usagelastActiveOrg cookieThe bus stores every quota.fetched event with utilization snapshots. Use SQL to find big jumps and correlate with heavy sessions.
-- Show quota changes over time, flagging big jumps
WITH quota_seq AS (
SELECT
offset,
datetime(timestamp/1000, 'unixepoch', 'localtime') AS ts,
timestamp,
json_extract(payload, '$.five_hour.utilization') AS fh,
json_extract(payload, '$.seven_day.utilization') AS sd,
LAG(json_extract(payload, '$.five_hour.utilization')) OVER (ORDER BY offset) AS prev_fh,
LAG(json_extract(payload, '$.seven_day.utilization')) OVER (ORDER BY offset) AS prev_sd,
LAG(timestamp) OVER (ORDER BY offset) AS prev_ts
FROM records
WHERE topic = 'system' AND type = 'quota.fetched'
)
SELECT ts,
fh || '%' AS five_hour,
sd || '%' AS seven_day,
CASE WHEN prev_fh IS NOT NULL THEN '+' || (fh - prev_fh) || '%' END AS fh_delta,
CASE WHEN prev_sd IS NOT NULL THEN '+' || (sd - prev_sd) || '%' END AS sd_delta,
CASE WHEN prev_ts IS NOT NULL THEN (timestamp - prev_ts) / 60000 || 'm' END AS gap
FROM quota_seq
WHERE prev_fh IS NULL OR (fh - prev_fh) > 5 OR (sd - prev_sd) > 2
ORDER BY offset DESC
LIMIT 20;
-- Given a time window (between two quota.fetched events), find which sessions were active
-- Replace the timestamps with values from the quota jump query above
SELECT
session_name,
COUNT(*) AS events,
SUM(duration_ms) / 1000.0 AS total_sec,
COUNT(DISTINCT tool_name) AS unique_tools,
GROUP_CONCAT(DISTINCT tool_name) AS tools_used
FROM sdk_events
WHERE timestamp BETWEEN 1743187827000 AND 1743188792000 -- replace with actual ms timestamps
AND event_type = 'tool_result'
GROUP BY session_name
ORDER BY total_sec DESC;
sqlite3 ~/dispatch/state/bus.db "
SELECT datetime(timestamp/1000, 'unixepoch', 'localtime') AS ts,
json_extract(payload, '$.five_hour.utilization') || '%' AS fh,
json_extract(payload, '$.seven_day.utilization') || '%' AS sd
FROM records
WHERE topic='system' AND type='quota.fetched'
ORDER BY offset DESC LIMIT 20
"
sqlite3 ~/dispatch/state/bus.db "
SELECT datetime(timestamp/1000, 'unixepoch', 'localtime') AS ts,
json_extract(payload, '$.backoff_seconds') AS backoff,
json_extract(payload, '$.consecutive_failures') AS failures,
json_extract(payload, '$.error') AS error
FROM records
WHERE topic='system' AND type='quota.fetch_failed'
ORDER BY offset DESC LIMIT 10
"
Claude Code uses 5-hour billing blocks. The blocks command shows:
The --hours-until-reset flag enables quota-aware scheduling:
# In task scheduler: only run if reset is within 5 hours
HOURS=$(~/.claude/skills/ccusage/scripts/server-usage --hours-until-reset 2>/dev/null)
if [ "$(echo "$HOURS <= 5" | bc)" -eq 1 ]; then
# Run heavy tasks — tokens would be wasted anyway
fi
Use the quota-check CLI — it checks both usage percentage AND time-to-reset in one call. Agents that copy-paste the inline snippet often miss cases or skip the check entirely, causing retry-loop token explosions.
# Standard quota gate (skip if >80% used AND reset >5h away)
~/.claude/skills/ccusage/scripts/quota-check --verbose
if [ $? -eq 1 ]; then
echo "Skipping — quota too high and reset not soon"
exit 0
fi
# Proceed with expensive task...
~/.claude/skills/ccusage/scripts/quota-check # Default: 80% threshold, 5h window
~/.claude/skills/ccusage/scripts/quota-check --threshold 90 # Gate at 90% instead
~/.claude/skills/ccusage/scripts/quota-check --hours 3.0 # Tighter window (3h)
~/.claude/skills/ccusage/scripts/quota-check --verbose # Print decision reason to stderr
Exit codes:
0 = proceed (usage is below threshold OR reset is within the window)1 = skip (usage high AND reset is far away)2 = error reading cache (fail open — treat as proceed)Decision logic: proceed if usage < threshold (quota available) OR if reset is within the window (burn tokens that would reset anyway). Skip only when both conditions are unfavorable.
In agent task prompts, use the direct form:
FIRST: Run ~/.claude/skills/ccusage/scripts/quota-check --verbose
If exit code is 1, log "Skipping — quota gate" and EXIT immediately.
This pattern is used by nightly bugfinder and latency finder tasks in ~/dispatch/scripts/setup-nightly-tasks.py.
# Only use this if quota-check CLI is unavailable for some reason
HOURS=$(~/.claude/skills/ccusage/scripts/server-usage --hours-until-reset 2>/dev/null)
if [ $? -ne 0 ] || [ -z "$HOURS" ]; then
echo "Could not check quota — skipping"
exit 0
fi
if [ "$(echo "$HOURS > 5.0" | bc)" -eq 1 ]; then
echo "Skipping — reset not within 5h window (${HOURS}h remaining)"
exit 0
fi
When reporting to user via SMS, include both local and server numbers:
Server-side: X% weekly (resets Day Time)
5-hour block: X% used, Xh Xm remaining
Local estimate: XM tokens ($X) this block
development
Use when building React/Next.js components, dashboards, admin panels, apps, or any web interface. Trigger words - react, frontend, ui, dashboard, component, interface, web app, polish, audit, design review.
tools
Track flight status and get FlightAware links. Use when asked about flights, flight status, arrival times, or flight tracking. Trigger words - flight, flying, UA, AA, DL, landing, arriving, departure.
development
Query real-time locations of people sharing via Find My. Look up where someone is, reverse geocode GPS coordinates, set up geofence alerts. Trigger words - findmy, find my, location, where is, geofence, track location.
tools
Access Figma designs via MCP or Chrome. Use when asked about Figma files, design mockups, wireframes, or UI designs. Trigger words - figma, design, mockup, wireframe, UI design, FigJam.