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— undocumentedapi.anthropic.com/api/oauth/usage
endpoint, OAuth token from the macOS Keychain. Unofficial; rate-limited, so don't poll faster than ~10 min.Codex limits—codex app-server
JSON-RPC; the CLI handles auth.$ / day and top projects—ccusageviapnpm dlx
, plus~/.claude/projects/
JSONLs for project names and per-day sparklines.
On trmnl.com create a
Private Plugin with strategyWebhook; copy its URL. -
cp config.json.example config.json
, paste the URL (config.json
is gitignored — the UUID lets anyone push to your screen). - Paste
template.liquid
into 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.
| 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 |
- 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ł