Open source · ESP32 · 携帯怪獣

Your mascot on every desk.

Tamagooshi is a compact gadget that stays in sync with your product: relaxed when things run smoothly, restless when they don't. Make it fully yours, from the brand on the shell to the games it plays, and pair it with Claude or Cursor to stay on top of your agents' work.

metrics agent BLE / MQTT device mood

Demo

Real screen captures, shown on the device. The firmware draws the same 135 × 240 screen in the desktop simulator and on hardware, so what you see here is exactly what ships.

REAL RECORDING · NO SOUND

    Configuration

    A brand is one config.yaml under brands/<id>/, in three groups: brand (identity), device (what ships in firmware), and hub (metrics and rules). Anything you leave out is simply off. A brand only bakes in the packs, games, and rules it lists, keeping the image small.

    Mascots don't have to come from the built-in packs. Any transparent PNG works as a custom mascot, and the mixer builds one from parts.

    Build & flash

    The config gets onto a device three ways. Flash it in the browser, use the macOS app, or self-host the console with Docker. Same firmware, same result.

    The config builder is one page with the whole flow. Build the config, plug the device in over USB, and flash it in one go. Nothing to install.

    • Live yaml. Every pick updates the config.yaml next to the form.
    • Flash over USB. The gooshi image plus your selections as a config partition, custom theme palettes included. Chrome or Edge on desktop.
    • Or download. Drop the file into brands/<id>/ for the other paths.
    Open the config builder

    The flashed device still needs a hub feeding it metrics. Install it once on the machine that holds your API keys and it pairs over BLE. One pairing carries hub metrics and Claude together.

    pip install -e hub/backend # once, Python 3.10+
    make hub                   # pairs with your device over BLE

    Or skip the bare install. The Docker tab runs the same hub and serves the full console in the browser.

    Development

    For working on the project itself. Nothing here is needed for the three setups above.

    System overview System overview: metric sources, hub, and device

    The desktop simulator draws the same screen as hardware, so most work needs no board at all. It builds and runs locally from the PlatformIO project under firmware/.

    make sim TAMA_BRAND=demo      # build and run the simulator, offline
    make sim-live TAMA_BRAND=demo # run it against the Docker stack's broker

    Apps & games

    Apps and games that can run on the device. Configuration: device.apps and device.games. Some games use IMU/mic for inputs.

    HID mode

    HID (Human Interface Device) apps (controller, media, clicker, jiggler, volume) require a matching HID mode on the device: gamepad, desk (media + keyboard + mouse), or off. Apps whose capability is not in the active mode are locked. Set the mode in the hub. After it saves, reboot the device, forget it on the host, and re-pair so the new HID descriptors apply.

    HID mode: hub on the laptop sets gamepad, desk, or off on the device

    On macOS, if Keyboard Setup Assistant appears for desk mode, dismiss it.

    Apps
    Games

    Gamepad

    Separate from the games that run on-device in firmware. Enable the controller app in the config and the stick pairs as a Bluetooth gamepad.

    games
    • The stick is the gamepad. IMU tilt and buttons map to moves.
    • IMU tester. Wireframe grid to verify the Bluetooth link before shipping a game.
    • Anywhere a gamepad works. Browser games are one example. Anything that reads a BLE gamepad can drive off the stick.
    Open the games

    Mascot Mixer

    In-browser mascot generator. Outputs a six-frame image of expressions for mascot.custom.

    mixer Download 6-frame config.yaml directory Body Brows Hands Color Name
    • Six expressions. One pick per slot, recolored live, previewed in every device mood.
    • Avatar or mascot. Download one frame or all six as one image.
    • Config. Save the image next to config.yaml, list it under mascot.custom.
    Open the mixer