Turns the LCD keys on an Ajazz/Mirabox/Mars-Gaming AKP03-family stream deck into a live display of Claude Code's usage — 5-hour session %, weekly %, live session count, running subagents, and a burn-rate ETA.
This started as a single-device reverse-engineering project (see
docs/NOTES.md for the full protocol writeup) and has been generalized to
the whole device family below, since they all share one command vocabulary
under different USB IDs.
Windows only. Uses ctypes.windll for foreground-window detection and
.bat launchers; no Mac/Linux port exists (PRs welcome — the HID protocol
layer itself, deck.py/devices.py, isn't Windows-specific).
- Windows 10/11
- Python 3.9+
- The Claude Code CLI installed
and on
PATH(crabdeck shells out toclaude -p /usage) - One of the supported devices below
crabdeck reads Claude Code's local session files (~/.claude/sessions/*.json)
and transcripts (~/.claude/projects/**/*.jsonl) to drive the LIVE/AGENTS
tiles. It only extracts session status and tool-call IDs — never message
content — and only from files already on your own machine. Nothing is sent
anywhere except the one claude -p /usage call itself, which talks to your
already-configured Claude account the same as running /usage in a normal
session would.
git clone https://github.com/tommybobb/crabdeck.git
cd crabdeck
pip install -r requirements.txt
Then run start.bat. First run auto-detects your device and saves it to
config.json; later runs just use that. If more than one supported device is
plugged in, it asks which one. (If you installed into a .venv in this
folder, start.bat uses that automatically; otherwise it falls back to
python on PATH.)
9 buttons (6 with LCD displays) + 3 knobs, 60x60 JPEG tiles:
| VID:PID | Name | Status |
|---|---|---|
0B00:1001 |
Mars Gaming MSD-TWO | verified on hardware |
0300:1001 |
Ajazz AKP03 | untested |
0300:1002 |
Ajazz AKP03E | untested |
0300:1003 |
Ajazz AKP03R | untested |
0300:3002 |
Ajazz AKP03E (rev. 2) | untested |
0300:3003 |
Ajazz AKP03R (rev. 2) | untested |
6602:1002 |
Mirabox N3 | untested |
6603:1002 |
Mirabox N3CN (rev. 3) | untested |
6603:1003 |
Mirabox N3EN | untested |
1500:3001 |
Soomfon Stream Controller SE | untested |
5548:1001 |
TreasLin N3 | untested |
0200:2000 |
Redragon Skyrider SS-551 | untested |
"Untested" means the USB IDs and protocol version came from upstream (see Credits) but nobody has confirmed this code against that exact unit yet. If you own one and it works (or doesn't), please open an issue/PR — there's an issue template for exactly this.
Not supported: the 18-key/0-knob AKP153 family (e.g. Mars Gaming MSD-ONE) — different geometry and packet layout entirely, would need its own device table. PRs welcome.
If your deck isn't listed but shares the CRT/BAT/STP/CLE/LIG command
vocabulary, add one line to DEVICES in devices.py:
(0xVVVV, 0xPPPP): ("Your Device Name", protocol_version, False),protocol_version is 2 for older firmware (1024-byte packets, no rotation) or
3 for newer (1024-byte packets, image rotated 90° CW) — PIDs starting with
0x3 are usually pv3. Run tools/probe_input.py and confirm the printed input
codes match deck.INPUT_CODES before trusting it.
deck.py + devices.py have no dependency on the Claude-usage bits:
import deck
dev = deck.open() # auto-detect/config/prompt, opens interface 0
dev.send_image(1, jpeg_bytes) # jpeg_bytes sized/rotated for dev.profile
dev.clear_key(1)
dev.close()tests/test_devices.py is the only hardware-free test (pytest, or
python tests/test_devices.py directly). claude_state.py and usage.py
also have a built-in self-check under if __name__ == "__main__":.
tools/ holds manual hardware probes (probe_input.py, probe_size.py,
probe_orient.py, probe_clear_key.py, probe_clear_all.py) — these write
to a real connected device and are not run by CI.
Device USB IDs, protocol version table, and wire-protocol details were cross-referenced against:
- 4ndv/opendeck-akp03 (GPL-3.0) — the device support matrix and input code mapping.
- 4ndv/mirajazz (MPL-2.0) — the
CRT/BAT/STP/CLE/LIGtransport protocol and protocol-version semantics.
This repo is an independent implementation (no code copied from either
project) and is MIT licensed — see LICENSE.
"crabdeck" is not affiliated with or endorsed by Anthropic; it just reads Claude Code's local usage data to drive the LCD keys.
docs/NOTES.md has the full reverse-engineering log: USB capture methodology,
firmware quirks, scene-switching behavior of the vendor app, and mistakes made
along the way.
