Skip to content
jiggsfooPublic

About

A Claude-powered desk robot: M5Stack Stackchan that watches, remembers the day, and talks back. Local STT/TTS, Anthropic-only cloud.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Stackchan Companion

A desk robot that keeps me company while I work. It looks at me every few minutes, remembers the day, and occasionally says something. Usually dry. Sometimes kind. Mostly silent.

"It's 11. Breakfast is a morning thing. Just saying."

Tap its head and it becomes a voice interface to my Claude Code sessions and calendar.

Built on the M5Stack Stackchan (K151 kit, ESP32-S3) and Claude.

Cartoon of the Stackchan desk robot next to a laptop and a coffee mug

What it does

  • Notices things. Every few minutes it grabs a low-res camera frame. Claude Haiku decides, with the day's log, whether anything is worth saying. Most looks end in silence on purpose.
  • Remembers the day. A small local log lets it say "you haven't eaten yet" instead of judging one frame.
  • Talks back. Tap the head, or answer within a few seconds of a remark. Speech is transcribed locally, Claude Sonnet answers, and the robot speaks with a local neural voice. The face and head move while it talks.
  • Runs my sessions by voice. "What's running?", "does anything need me?", "start a session on Acme to check the deal ranking." Anything that acts is read back first and only runs on a clear "yes".
  • Knows when to shut up. Silent during calendar meetings, during calls (any app using the mic), outside working hours, and when I'm away from the desk.

Privacy by design

  • The only cloud is the Anthropic API on my own key. No M5Stack or third-party robot cloud.
  • Speech-to-text (whisper.cpp), voice activity detection (Silero) and text-to-speech (Kokoro) all run on the Mac.
  • Camera frames and audio are never written to disk.
  • It never comments on anyone else in frame, and never sends messages to other people.

How it fits together

 Stackchan (ESP32-S3)                       Mac
 ┌─────────────────────┐   WebSocket   ┌──────────────────────────────────────┐
 │ camera, mic, touch  │──────────────▶│ companion (Python)                   │
 │ face, servos, speaker│◀──────────────│  observe → Claude Haiku → remark     │
 │ Moddable JS mod     │   speech WAV  │  listen  → Silero VAD → whisper.cpp   │
 └─────────────────────┘               │  answer  → Claude Sonnet + tools      │
                                       │  speak   → Kokoro TTS                 │
                                       │  gates   → calendar (EventKit), mic,  │
                                       │            idle time, work hours      │
                                       └──────────────────────────────────────┘
Path What lives there
companion/ Mac-side service: observation loop, voice turns, gates, tools, socket server
firmware/mods/companion/ Moddable mod that runs on the robot: camera, mic streaming, face, head moves, offline screen
tools/calnow/ Tiny Swift CLI that reads calendar events through EventKit (recurring events included)
launchd/, scripts/ Run as a LaunchAgent; build and flash helpers
vendor/stack-chan Upstream stack-chan firmware, pinned to v1.1.0

Running it

You need the K151 kit, a Mac, an Anthropic API key, and the local models (whisper.cpp small.en, Silero VAD v5, Kokoro).

git clone --recurse-submodules https://github.com/jiggsfoo/stackchan.git
cd stackchan
python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
cp config.example.toml config.toml        # calendars, hours, voice, model paths
cp .env.example .env                      # ANTHROPIC_API_KEY, COMPANION_TOKEN
cp firmware/mods/companion/secrets.example.js firmware/mods/companion/secrets.js

scripts/fw.sh deploy                                                    # host firmware (Moddable SDK 9.5 via xs-dev)
scripts/fw.sh mod -- $PWD/firmware/mods/companion/manifest.json         # the companion mod
scripts/install-launchd.sh                                              # start the Mac service

Set the Mac's mDNS name in firmware/mods/companion/manifest.json before flashing. docs/spike-notes.md has the hardware gotchas.

The session tools expect my personal Claude Code session manager. Without it, voice still works for chat and calendar questions.

Tests

.venv/bin/python -m pytest                       # Mac side
node firmware/mods/companion/commands.test.mjs   # firmware command logic

Status

A personal project that runs on my desk every day. Not a product. Issues and ideas are welcome, but I'm not promising support.

About

A Claude-powered desk robot: M5Stack Stackchan that watches, remembers the day, and talks back. Local STT/TTS, Anthropic-only cloud.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages