Push your Claude.ai usage limits to a GeekMagic SmallTV — a tiny WiFi-connected display the size of a sugar cube — so you can see your 5-hour and weekly quota at a glance without opening the Claude app.
This script targets the GeekMagic SmallTV family — small ESP32-based WiFi clocks with a 1.5" 240×240 IPS display, originally designed to show weather, GIFs and crypto prices. They expose a simple HTTP API for uploading custom images.
Where to buy:
- AliExpress — GeekMagic SmallTV / SmallTV-Ultra
- Official site: geekmagic.com
- Search "GeekMagic SmallTV" on eBay / Amazon for local sellers
Specs:
- 1.5" 240×240 IPS TFT display
- WiFi 2.4 GHz
- USB-C power (5V, 1A)
- ~35 × 39 × 45 mm
This project should work on any SmallTV variant (Lite, Pro, Ultra) and
likely on other GeekMagic models with the same /doUpload endpoint.
Every time it runs (typically once a minute via cron):
- Calls
claude.ai/api/organizations/{org}/usage— the same endpoint the Claude.ai website uses on the Settings → Usage page - Renders a 240×240 PNG with two progress bars:
- Current — 5-hour rolling window
- Weekly — 7-day rolling window
- Uploads the image to your clock over HTTP
Bars are colour-coded:
- 🟢 green under 50%
- 🟡 yellow 50–80%
- 🔴 red above 80%
Both blocks also show time until reset ("Resets in 4h 37m", "Resets in 3d").
The official api.anthropic.com/api/oauth/usage endpoint exists but
has a much stricter rate limit and returns HTTP 429 if you (or any
of your Claude.ai / Claude Code clients) hit it frequently.
The website endpoint is what real apps like ClaudeMeter use, and it tolerates frequent polling.
To bypass Cloudflare's bot challenge (which blocks plain curl/requests
from server IPs) we use curl_cffi,
which impersonates a real Chrome TLS fingerprint.
- Python 3.9+
- A GeekMagic SmallTV (or compatible) on your local network
- A Claude.ai account with an active session
git clone https://github.com/egerkuzma/geekclock-claude.git
cd geekclock-claude
pip install -r requirements.txtFor nicer typography (optional but recommended on Linux):
sudo apt install fonts-interYou need three things:
sessionKey— your Claude.ai session cookie- GeekMagic device IP — find it in your router's DHCP table or in the GeekMagic mobile app
- organization UUID — auto-detected on first run, you can cache it for speed
- Open claude.ai in your browser, log in
- Open DevTools (Cmd+Option+I / F12)
- Application → Cookies →
https://claude.ai - Find the
sessionKeycookie (starts withsk-ant-sid01-...), copy the value
Pick one of the methods:
Method 1 — file (recommended for cron):
echo 'sk-ant-sid01-...' > ~/.claude_session_key
chmod 600 ~/.claude_session_keyMethod 2 — environment variable:
cp .env.example .env
nano .env # fill in CLAUDE_SESSION_KEY and GEEKCLOCK_IPThen source .env before running.
Method 3 — command-line flags:
./geekclock_claude.py \
--session-key "sk-ant-sid01-..." \
--device-ip 192.168.1.100One-off run:
./geekclock_claude.pyRender the image to disk without uploading (handy for testing):
./geekclock_claude.py --output preview.png --dry-runOn the first run the script will auto-detect your organization UUID:
[info] detected org_id=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
(set CLAUDE_ORG_ID to skip this step)
Set CLAUDE_ORG_ID in your environment or pass --org-id to skip
that extra request on every run.
Update every minute:
* * * * * /path/to/geekclock_claude.py >> /tmp/geekclock.log 2>&1The script caches API responses for 5 minutes by default, so even with a minute-by-minute cron only one in five runs actually hits the API. The countdown texts ("Resets in 4h 37m") are recalculated from cached data on every run, so they tick down accurately.
To change cache TTL:
GEEKCLOCK_CACHE_TTL=60 ./geekclock_claude.py # 1 minute
GEEKCLOCK_CACHE_TTL=0 ./geekclock_claude.py # always freshHTTP 401 — sessionKey expired
Cookies on Claude.ai rotate every few days. Open the site in your
browser (any action refreshes the cookie), copy the new sessionKey
into ~/.claude_session_key.
HTTP 403 — Cloudflare challenge
The TLS impersonation isn't matching. Try a different version: edit
the script and change impersonate="chrome" to impersonate="chrome124"
or "safari17_0". If you're on a heavily flagged IP (cloud VPS), this
may keep happening — running on your home network or NAS usually works.
HTTP 429
You (or another client with the same account) are polling too
frequently. Increase --cache-ttl or lower cron frequency.
Image uploads but clock doesn't change Some GeekMagic firmwares require you to pick the image as the active wallpaper in the official app once. After that, overwriting the file at the same path updates the display automatically.
ModuleNotFoundError: No module named 'curl_cffi'
Install dependencies: pip install -r requirements.txt.
geekclock-claude/
├── geekclock_claude.py # the script
├── requirements.txt # Python deps
├── .env.example # config template
├── docs/
│ ├── preview.png # rendered image example
│ └── clock-photo.jpg # photo of the running device
├── README.md
└── LICENSE
- Inspired by ClaudeMeter by Edd Mann — a macOS menu bar version of the same idea
- Uses curl_cffi for Cloudflare bypass
- Targets GeekMagic SmallTV hardware
This is an unofficial tool. It uses Claude.ai's internal web API endpoints which are not publicly documented and may change at any time. Using browser-based authentication may violate Anthropic's Terms of Service. Use at your own risk.
MIT — see LICENSE.
