Claudeq — ESP32-S3 touchscreen control surface for Claude Code (LVGL, OTA, mDNS, WebSerial flashing)
Posted: Tue Jul 14, 2026 12:32 am
Free/open-source (MIT), personal project, no company behind it: **Claudeq**.
Turns a Waveshare ESP32-S3-Touch-LCD-3.49 (172×640 portrait) into a touch UI for controlling Claude Code (Anthropic's terminal coding agent) sessions running on a host machine.
Firmware: ESP-IDF v5.4.1 + LVGL. Talks JSON-over-WebSocket to a host-side Node "bridge" on port 8787. Discovers bridges via mDNS (_claudeq._tcp); optional Tailscale path for bridges off-LAN.
Notable implementation bits:
— OTA: checks a GitHub release for a newer build, pulls the image over HTTPS, shows progress, rolls back automatically on a failed boot. Needed a one-time repartition for anything flashed before OTA support existed (can't change partition tables over the air, obviously) — documented as a one-time USB step.
— Zero-toolchain distribution: release builds are flashed via ESP Web Tools (WebSerial) from a static page, so end users never touch ESP-IDF. `claudeq flash` (auto-detects the serial port) is the CLI fallback.
— Network config lives entirely on-device: first boot (or lost WiFi) opens a captive-portal AP (Claudeq-setup); WiFi/Tailscale creds are entered there, no rebuild.
— Power: standby only kills the backlight/panel, keeps WiFi + WebSocket alive, so it wakes instantly on an incoming event rather than needing a reconnect.
— One physical control (BOOT button) does double duty: short press cycles brightness, long press (~1.5s) locks the screen (touch + wake both disabled — pocket-safe), another long press unlocks.
Host side: a `claudeq` launcher wraps `claude` in a named tmux session (so each project becomes a chip on-screen) and a set of Claude Code hooks forwards session events (questions, status, replies) to the bridge.
Repo has the protocol doc and pinout if useful to anyone working on the same board:
— Protocol: https://github.com/Positronico/claudeq/ ... ROTOCOL.md
— Pinout: https://github.com/Positronico/claudeq/ ... /PINOUT.md
Known limitation: the device↔bridge WebSocket has no auth yet — fine on a trusted LAN/tailnet, not meant for public exposure. On the list.
Project page, full README, and browser flasher below. Happy to go into more depth on any part of the firmware.
Links
— Project page: https://invisible.cat/claudeq
— Repo (source): https://github.com/Positronico/claudeq
— Browser flasher: https://positronico.github.io/claudeq/
— Protocol doc: https://github.com/Positronico/claudeq/ ... ROTOCOL.md
— Pinout doc: https://github.com/Positronico/claudeq/ ... /PINOUT.md
Turns a Waveshare ESP32-S3-Touch-LCD-3.49 (172×640 portrait) into a touch UI for controlling Claude Code (Anthropic's terminal coding agent) sessions running on a host machine.
Firmware: ESP-IDF v5.4.1 + LVGL. Talks JSON-over-WebSocket to a host-side Node "bridge" on port 8787. Discovers bridges via mDNS (_claudeq._tcp); optional Tailscale path for bridges off-LAN.
Notable implementation bits:
— OTA: checks a GitHub release for a newer build, pulls the image over HTTPS, shows progress, rolls back automatically on a failed boot. Needed a one-time repartition for anything flashed before OTA support existed (can't change partition tables over the air, obviously) — documented as a one-time USB step.
— Zero-toolchain distribution: release builds are flashed via ESP Web Tools (WebSerial) from a static page, so end users never touch ESP-IDF. `claudeq flash` (auto-detects the serial port) is the CLI fallback.
— Network config lives entirely on-device: first boot (or lost WiFi) opens a captive-portal AP (Claudeq-setup); WiFi/Tailscale creds are entered there, no rebuild.
— Power: standby only kills the backlight/panel, keeps WiFi + WebSocket alive, so it wakes instantly on an incoming event rather than needing a reconnect.
— One physical control (BOOT button) does double duty: short press cycles brightness, long press (~1.5s) locks the screen (touch + wake both disabled — pocket-safe), another long press unlocks.
Host side: a `claudeq` launcher wraps `claude` in a named tmux session (so each project becomes a chip on-screen) and a set of Claude Code hooks forwards session events (questions, status, replies) to the bridge.
Repo has the protocol doc and pinout if useful to anyone working on the same board:
— Protocol: https://github.com/Positronico/claudeq/ ... ROTOCOL.md
— Pinout: https://github.com/Positronico/claudeq/ ... /PINOUT.md
Known limitation: the device↔bridge WebSocket has no auth yet — fine on a trusted LAN/tailnet, not meant for public exposure. On the list.
Project page, full README, and browser flasher below. Happy to go into more depth on any part of the firmware.
Links
— Project page: https://invisible.cat/claudeq
— Repo (source): https://github.com/Positronico/claudeq
— Browser flasher: https://positronico.github.io/claudeq/
— Protocol doc: https://github.com/Positronico/claudeq/ ... ROTOCOL.md
— Pinout doc: https://github.com/Positronico/claudeq/ ... /PINOUT.md