A physical Claude Code companion running on M5Paper V1.1
A Claude Code sidekick running on an M5Paper V1.1 (4.7" e-ink, 540ร960, GT911 touch, ESP32). Sits on your desk and mirrors every Claude Code session you have open: project, branch, model, context usage, recent activity, Claude's latest reply. When Claude wants to run a tool, the full content shows up as a full-screen approval card with hardware buttons and touch options.
| ๐ Multi-session dashboard | Left column lists every active Claude Code window; tap a row to focus. Right column shows model + context-window progress bar. |
| ๐ Hardware approval | PreToolUse shows a full-screen card with the complete command / diff / preview. PUSH approves, DOWN denies. DND mode (long-press UP) auto-approves for batch tasks. |
| ๐ฌ Touch-answer questions | Claude's AskUserQuestion options render as up to 4 big tap targets; tapping sends the chosen label back as the answer. |
| ๐ FIFO queue | Multiple windows asking for approval get queued; resolving the current one automatically pops the next. |
| ๐ Bilingual UI | 3.4 MB CJK TTF shipped on LittleFS; toggle English โ ไธญๆ in the Settings page. All prompts, replies, activity lines render Chinese correctly. |
| ๐ Two transports | USB serial (default, zero-setup) or BLE (Nordic UART, macOS passkey pairing), auto-selected. |
| โ๏ธ Settings page | Tap SETTINGS (top-right) for transport / battery / sessions / DND / budget / uptime / last message / language toggle. |
| ๐ฑ Cat buddy | A small ASCII cat in the footer reacts to state โ idle / busy / attention / celebrate / DND / sleep. |
| ๐ Claude Code plugin | One /buddy-install handles PlatformIO + Python deps + mklittlefs arch patch on Apple Silicon + hooks merge + firmware + filesystem flashing + daemon launch. |
- M5Paper V1.1 (4.7" e-ink, 540ร960, GT911 capacitive touch, ESP32, 16MB flash)
- USB-C cable (required for initial flash; BLE works afterwards)
Prereqs: PlatformIO Core,
Homebrew (Apple Silicon only, for native mklittlefs), and an M5Paper V1.1.
# Clone
git clone https://github.com/op7418/m5-paper-buddy.git
cd m5-paper-buddy
# Recommended: install as a Claude Code plugin.
# Register the plugin/ directory with Claude Code, then:
/buddy-install/buddy-install automatically:
- Verifies PlatformIO is installed
- Installs Python deps (
pyserial,bleakfor BLE mode) - On Apple Silicon, patches PlatformIO's x86_64
mklittlefs(brew install mklittlefs+ symlink) souploadfscan run - Merges the hook block into
~/.claude/settings.json(backs up first) - If a Paper is plugged in, flashes firmware + filesystem (font)
- Launches the daemon in the background
Manual install (no plugin):
pio run -e m5paper -t uploadfs # flash the font to LittleFS (~90s)
pio run -e m5paper -t upload # flash firmware (~30s)
python3 tools/claude_code_bridge.py --budget 200000
# Then manually copy plugin/settings/hooks.json's hooks block into
# ~/.claude/settings.jsonOnce installed, these slash commands are available in Claude Code:
| Command | Purpose |
|---|---|
/buddy-install |
First-time setup / re-verify environment |
/buddy-start |
Start the daemon (idempotent) |
/buddy-stop |
Stop the daemon |
/buddy-status |
Daemon pid, serial device, hooks state, tail of log |
/buddy-flash |
Rebuild + reflash firmware AND filesystem (stop โ flash โ start) |
State directory: ~/.claude-buddy/ (pid, log).
| Button / zone | Dashboard | Approval card |
|---|---|---|
| PUSH (middle) | nudge a redraw | approve |
| DOWN (bottom) | toggle demo | deny |
| UP (top) | short: force GC16 refresh (clears ghosting) ยท long โฅ1.5s: toggle DND | โ |
| Tap session row | focus that session on the dashboard | โ |
Tap SETTINGS |
open settings page | โ |
| Tap option card | โ | answer AskUserQuestion |
Default is BUDDY_TRANSPORT=auto โ USB serial if plugged in, else BLE.
BUDDY_TRANSPORT=ble /buddy-start
BUDDY_TRANSPORT=serial /buddy-startFirst BLE connect triggers macOS's system pairing dialog; the Paper displays a 6-digit passkey, you type it on the Mac. Subsequent reconnects are automatic.
The progress bar shows the currently-focused session's
context-window usage divided by a limit, computed from the last
assistant message's usage.input_tokens + output_tokens in the
session's transcript JSONL.
Default limit is 200K (Claude 4.6 standard context). For the 1M-context 4.7 beta:
BUDDY_BUDGET=1000000 /buddy-startSet 0 to hide the bar.
Default: English. Tap SETTINGS โ language / ่ฏญ่จ to switch to ไธญๆ. Choice persists in NVS across reboots.
src/
ble_bridge.cpp/h # Nordic UART Service, line-buffered TX/RX
stats.h # NVS-backed state (approvals/denials/level/DND/language)
paper/
main.cpp # UI, state machine, touch, settings, i18n
data_paper.h # TamaState + JSON parsing (UTF-8 safe)
xfer_paper.h # status responses, name/owner/unpair cmds
buddy_frames.h # ASCII cat frames (6 states)
data/cjk.ttf # CJK font flashed via `pio run -t uploadfs`
partitions-m5paper.csv # 3 MB app + 13 MB LittleFS (font needs room)
platformio.ini
plugin/ # Claude Code plugin
plugin.json # manifest
commands/ # /buddy-* slash commands
scripts/ # install / start / stop / status / flash / common
settings/hooks.json # hooks to merge into ~/.claude/settings.json
README.md # plugin's own README
tools/claude_code_bridge.py # daemon: HTTP โ serial/BLE bridge
- docs/ARCHITECTURE.md โ technical architecture, wire protocol, daemon + firmware internals, debugging war stories
- docs/PRODUCT.md โ product thinking, design tradeoffs, future vision, notes for forkers
(Both docs are in Chinese; feel free to open a PR translating to English.)
Firmware iteration:
pio run -e m5paper # build only
pio run -e m5paper -t upload # flash firmware
pio run -e m5paper -t uploadfs # refresh LittleFS (only when font changes)Daemon iteration:
/buddy-stop && /buddy-start
# or:
plugin/scripts/stop.sh && plugin/scripts/start.shTail the log: tail -f ~/.claude-buddy/daemon.log
This project was inspired by Anthropic's
claude-desktop-buddy โ
the Nordic UART Service + heartbeat-JSON wire protocol shape is the
same, so in principle a Paper running this firmware can also be driven
by that project's desktop bridge.
Bundled font: GenSenRounded Regular, from the M5Stack M5EPD library's
examples.
This project is licensed under GPL-3.0 with an explicit attribution clause:
Any fork, modification, or redistribution MUST:
- Preserve the
Copyright ยฉ 2026 op7418notice- Visibly credit
op7418 / m5-paper-buddyin the derivative work's README or About page- Release the derivative itself under GPL-3.0 or later with full source code publicly available
In short: you're free to fork / modify / use commercially, but any modified version must be open-source and must credit this project. Closed-source derivatives are not permitted.
See the "Attribution & derivative obligations" section at the top of LICENSE for the full terms.
Third-party components
data/cjk.ttf: GenSenRounded Regular, from the M5EPD library's examples. The font's own license terms apply to that file.- Nordic UART Service UUIDs and heartbeat JSON schema reference anthropics/claude-desktop-buddy (MIT).
