Herald is a small physical companion for Muse and MCP agents. Two RGB LEDs can show that an agent is working, finished, or needs attention; a speaker can read its reply or announce a result. It runs on an HW678 ESP32-S3 N16R8 with an external I2S amplifier and two ordinary four-leg RGB LEDs.
It began as a bare development board and a speaker test. Speech came next, then two independently controlled LEDs, a narrated light show, remote settings, and an MCP bridge so other agents could use the same hardware. The result is a community extension of the Meta Muse Gadget SDK, with its upstream history and attribution preserved.
Build Herald · Wiring · Commands · MCP and CLI · How it works · Validation and audit
Ask Muse to speak its replies through the desk speaker, or ask Codex or Claude Code to fade the LEDs blue while working and announce completion in green. Use the CLI in a script, set each LED's color directly, or run chase, alternate, fade and sparkle patterns. The narrated showcase combines speech, both LEDs and a synthesized melody, with a countdown for recording it.
Volume and brightness defaults persist across restarts. Remote commands expose Wi-Fi status and scans, device information, diagnostics, cancellation and OTA updates. Agents must actually invoke the tools: installing the MCP server does not automatically add notifications to every task.
Muse uses the SDK's existing Link connection. Other agents and shell scripts use the optional Herald HTTPS endpoint through the shared client, CLI or MCP server. Both paths reach the same firmware command handlers. LAN clients have an ownership lease to coordinate effects; Muse remains outside that lease and can supersede them.
Start with the hardware and firmware guide, then add MCP access if you want other agents to participate. The tested board is HW678 N16R8, not a Seeed XIAO. Follow the wiring guide and use one current-limiting resistor per LED color channel.
Speech is generated by a separate text-to-WAV service you provide; Herald plays the returned audio. There is no microphone, wake word, display or Bluetooth speaker output in this build. Muse pairing requires your own account and SDK token. The optional LAN control path uses separate local credentials.
This is a source-only community prototype, not an official Meta hardware product. Personalized firmware contains credentials and is not distributed. LAN administrative commands require explicit opt-in. See the setup and audit guides for the development-key trust model and verification limits.
The original project overview and license information follow. Herald-specific instructions above take precedence for this board; upstream guides also cover many other devices.
Muse gadgets are open source devices you build yourself. Program an off-the-shelf ESP32 board or set up a Raspberry Pi with our device SDKs, then connect Muse to your displays, buttons, sensors, actuators, and whatever else you've got lying on your workbench.
We open sourced the SDKs and firmware here. It's built by hackers, for hackers, just for fun. Side effects of tinkering may include bricked boards, voided warranties, brownouts, or bankruptcies. Proceed at your own risk!
| ESP32 Device SDK | Connect your ESP32 board to Muse through our open source SDK. Throw in a screen to show images, add audio in and out, or wire up other sensors. |
| Linux Device SDK | Turn that spare Raspberry Pi or Linux box into a Muse gadget. Hack in your own commands to let Muse handle sysadmin chores or your Home Assistant setup. |
| Muse Gadgets Test (iPhone) | Stream your phone's camera, or a clip, to an ESP32 gadget's screen over Wi-Fi: H.264 or VP8 decoded on the board, 30 fps on the round 466 px boards. protocols/VIDEO.md explains how. |
Before you flash or pair a gadget, get an SDK token and review the Gadget SDK Terms. Every gadget needs a token to pair.
ESP32 and Linux gadgets pair with the Muse app on iOS and Android, via
Settings > Devices. Turn on Developer mode there first, then look for devices
prefixed with "MuseGadget".
Each directory has a README.md to get started and an AGENTS.md for coding
agents like Muse Code.
protocols/DEVICE.md says how a gadget describes itself
to Muse.
For battery-input power profiling, see the porting recipe. The opt-in diagnostic core is board-neutral; boards supply its hooks and state matrices, and power_sweep.py drives the USB-free sweep. The isolated diagnostic does not pair or need an SDK token; fixture safety and explicit hardware authorization still come first, as the PPK2 rules describe.
Meet other hackers who are building and customizing Muse gadgets in our community Discord. Get inspired, support each other, and share what you make.
Muse Gadgets is licensed under the Apache License, Version 2.0, found in
LICENSE, except for these third-party files, which keep their
upstream licenses:
| Path | Upstream | License |
|---|---|---|
esp32/components/minimp3/include/minimp3.h |
lieff/minimp3 | CC0-1.0, see LICENSE |
esp32/components/muse/boards/ostb_echoear_display_init.h |
78/xiaozhi-esp32 ESP-VoCat panel sequence | MIT, retained in the file header |
ST7789 tuning table in board_atk_dnesp32s3_box2.c |
78/xiaozhi-esp32 ATK-DNESP32S3-BOX2 board | MIT, see xiaozhi-esp32.txt |
JD9853A initialization sequence in board_seeed_xiao_s3_147.c |
Seeed-Studio/Seeed_GFX2 | MIT, see Seeed_GFX2.txt |
esp32/components/muse/boards/viewe_smartring_display_init.h |
VIEWESMART/smartring_plus panel sequence | Apache-2.0 under VIEWE's copyright, in the file header |
esp32/components/muse/boards/waveshare_s3_185b_init.h |
waveshareteam/ESP32-S3-Touch-LCD-1.85B panel sequences | Apache-2.0, in the file header |
esp32/main/pixel_font.c |
Adafruit GFX glcdfont.c |
BSD-2-Clause, in the file header |
esp32/components/muse/fonts/ |
GNU Unifont 16.0.04, Noto Sans SC, and Montserrat Medium via LVGL, subsets (see its README) | SIL Open Font License 1.1 (Unifont also GPL-2.0+ with the font embedding exception) |
esp32/components/muse/eink/fonts/montserrat.ttf |
Montserrat Medium, via LVGL v9.5.0 | SIL Open Font License 1.1 |
esp32/components/muse/eink/fonts/unscii.ttf |
unscii-8 | Public domain |
esp32/components/muse/eink/fonts/symbols.ttf |
Font Awesome 5 Free, via LVGL v9.5.0 | SIL Open Font License 1.1 (icons CC BY 4.0) |
esp32/main/epd_ssd1677.c |
Seeed-reTerminal-E10xx-Firmware's SSD1677 refresh sequence | MIT, retained in the file header |
esp32/components/tinyh264/src |
the Android Open Source Project's H.264 decoder, via udevbe/tinyh264 | Apache-2.0, AOSP's copyright, see LICENSE |
esp32/components/libvpx_vp8/src |
libvpx v1.16.0's VP8 decoder, trimmed | BSD-3-Clause, the WebM Project authors' copyright, see LICENSE, with Google's patent grant in PATENTS |
Dependencies fetched at build time are under their own licenses: ESP-IDF
components (into esp32/managed_components/), and the simulator's LVGL and
SDL (listed in esp32/simulator/THIRD_PARTY.md).
The Apache License does not cover the Jollybot avatar.
Muse Gadgets Test's sample clips aren't in this repository: the app fetches a few seconds of the Blender Foundation's open movies (CC BY 3.0) when one is played, and shows their credits.
Muse Gadgets Test can use x264 (GPL-2.0) on the phone; this repository carries none
of its code. An APK or iPhone app you build with it is under the GPL
(android/musegadgetstest/README.md,
ios/musegadgetstest/README.md).