An e-ink dashboard for a TRMNL private plugin: rate limits for Claude Code and Codex, API-equivalent $ per day per agent, and your top projects — pushed from your Mac every 10 minutes.
Data sources (no servers, everything reads local state):
- Claude limits + plan — undocumented
api.anthropic.com/api/oauth/usageendpoint, OAuth token from the macOS Keychain. Unofficial; rate-limited, so don't poll faster than ~10 min. - Codex limits —
codex app-serverJSON-RPC; the CLI handles auth. - $ / day and top projects — ccusage via
pnpm dlx, plus~/.claude/projects/JSONLs for project names and per-day sparklines.
Setup
-
On trmnl.com create a Private Plugin with strategy Webhook; copy its URL.
-
cp config.json.example config.json, paste the URL (config.jsonis gitignored — the UUID lets anyone push to your screen). -
Paste
template.liquidinto the plugin's Markup editor. -
Test:
uv run --no-project push_usage.py --dry-run, then without the flag. -
Install the schedule (edit paths in the plist to match your machine):
cp com.pmigdal.trmnl-usage.plist ~/Library/LaunchAgents/ launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.pmigdal.trmnl-usage.plist
Logs: /tmp/trmnl-usage.log. Fetch failures also render as a warning strip
on the device and exit non-zero.
Config (config.json)
| key | default | |
|---|---|---|
webhook_url |
— | required (or TRMNL_WEBHOOK_URL env var) |
cost_days |
7 | days in the cost chart and sparklines |
top_projects |
6 | project rows |
chart_max_px |
230 | tallest chart bar, px |
Notes
- The template targets TRMNL X's logical viewport (~936×702 @ 2× density); tiles at ≥90% usage invert to black.
- TRMNL webhook caps: 12 pushes/hour, 2 KB payload.
- The screen goes stale while the Mac sleeps — see the "updated" stamp.
MIT © Piotr Migdał
