Skip to main content
Glama

nabaztag-ai 🐰

CI

AI brain for the original Nabaztag rabbit β€” LLM tool-use embodiment, voice pipeline, MCP server. Physical AI, 2006 edition.

What & why

In 2006 the Nabaztag:tag was the first consumer connected device β€” a Wi-Fi rabbit that read the news and wiggled its ears. Twenty years later, this project revives a stock, unopened Nabaztag:tag as the body of a modern AI assistant: wake word β†’ speech-to-text β†’ an LLM with tool use β†’ text-to-speech, played through the rabbit's own speaker, with the LLM deciding ear positions and LED moods itself.

There is also a full-duplex mode: the wake word opens a continuous conversation and you can talk over the rabbit mid-sentence. That needs playback which can be cancelled β€” the 2006 decoder cannot be β€” so it routes audio through the reSpeaker instead, whose on-chip echo cancellation was measured before being relied on. The rabbit keeps the ears and the lights.

The rabbit stays 100% original. It talks to a self-hosted OpenJabNab server; modern audio input comes from an external reSpeaker 4-mic array; the brain runs on a UDOO Bolt (any Linux PC or SBC works) β€” closing a 20-year loop between the first consumer connected device and modern edge AI.

Full spec: docs/ARCHITECTURE.md.

Related MCP server: mcp-connect

Hardware BOM

Item

Role

~Price

Nabaztag:tag (V2), stock

Body: speaker, ears, LEDs, RFID, button

~€70 (second-hand)

reSpeaker Flex XVF3800 Circular-4

Ears-in: 4-mic array, beamforming, DoA

~€50

UDOO Bolt (or any Linux PC/SBC)

Brain: OJN server, rabbit-brain, MCP

you probably have one

(usually nothing) β€” the Bolt's own M.2 Wi-Fi module runs the AP

Dedicated legacy WPA-TKIP AP (Β§4.1)

β€”

Quickstart (no hardware needed)

git clone https://github.com/<you>/nabaztag-ai && cd nabaztag-ai
python -m venv .venv && source .venv/bin/activate
pip install -e "brain[dev]"
pytest                      # runs against the mock-OJN simulator
python -m rabbit_brain.body.demo --mock-ojn   # drive a simulated rabbit

With real hardware, start from Gate S0 (the rabbit's legacy Wi-Fi segment β€” see docs/ARCHITECTURE.md Β§4.1 and ojn/).

On the Bolt, the audio-in pipeline (reSpeaker capture, openWakeWord, silero-vad, DoA) needs the extras and the XVF3800 udev rule:

sudo apt install libportaudio2       # sounddevice's runtime library
brain/scripts/install-audio.sh       # add --stt-local for stt_profile: local
sudo install -m 644 brain/udev/70-respeaker-flex.rules /etc/udev/rules.d/
sudo udevadm control --reload && sudo udevadm trigger
python -m rabbit_brain.audio.demo --config config.yaml --mock-ojn   # mic smoke test

config.yaml is gitignored, so git pull never updates it β€” a config created from an older example can silently keep stale settings (e.g. a missing deepgram.endpointing). Check it against the current shape after pulling:

brain/scripts/config-doctor.py config.yaml         # report drift
brain/scripts/config-doctor.py config.yaml --fix   # rewrite present-but-stale keys in place

(The script exists because openWakeWord's Linux dependency on tflite-runtime has no Python 3.12 wheel; we only use its ONNX backend, so it is installed --no-deps on top of the brain[audio] extra. CI runs the same script on Ubuntu 24.04/3.12.)

Full voice runtime

One persistent process owns the whole conversation loop (one BodyController, one Mp3Server on :8090, one EventListener on :8091):

python -m rabbit_brain.runtime --config config.yaml

Pipeline: reSpeaker β†’ openWakeWord β†’ Deepgram Flux (recognition and end-of-turn detection in one pass, stt_profile: flux) β†’ OpenAI Responses (gpt-5.4-mini) β†’ Piper (self-hosted, it_IT-paola-medium / en_GB-alba-medium, voice routed by the STT-detected language; Deepgram Aura as automatic fallback) β†’ local MP3 β†’ OpenJabNab β†’ Nabaztag speaker. Set conversation.mode: realtime (with audio_out.backend: local) for the full-duplex path instead. stt_profile: cloud switches back to nova-3 + a local silero VAD window, which is what Flux replaces. The runtime loads .env automatically (shell environment wins; --env-file '' disables). Needs OPENAI_API_KEY, DEEPGRAM_API_KEY and the OJN vars in .env (values never logged). Do not run the runtime and the MCP server at the same time β€” both bind :8090/:8091 and each would create its own BodyController. Pick one per session.

Rabbit-facing MP3 delivery goes through Apache, not the built-in server: the MTL decoder ignores aiohttp-served audio (hardware finding). Install the alias once (ojn/apache/brain-audio.conf.example) and set NABAZTAG_MP3_SERVE_HTTP=0 + NABAZTAG_MP3_BASE_URL=http://192.168.66.1/brain-audio in .env. A plain chmod on the audio dir is not enough (403: www-data can't traverse your home directory) β€” the conf example includes the setfacl commands that hardware-confirmed fix it.

Architecture

Nabaztag:tag ◄─Violet proto─► OpenJabNab (self-hosted) ◄─REST─► rabbit-brain
   stock, WPA-TKIP segment         on the Bolt            wake→VAD→STT→LLM(tools)→TTS
                                                                    β”‚
reSpeaker XVF3800 ──USB audio + DoA──────────────────────► BodyController (arbiter)
                                                                    β–²
                                                     nabaztag-mcp β”€β”€β”˜ β†’ Claude Desktop/Code

All body output funnels through the BodyController (single owner of the body, priority queue); bodies are swappable behind the BodyAdapter protocol.

Roadmap

  • v1 β€” Nabaztag:tag via OpenJabNab (this repo, phases S0 β†’ 4)

  • P1 β€” ReachyMiniAdapter: same brain, different body (comparison protocol)

  • P2 β€” VentunoQLocalProfile: fully local STT/TTS/LLM on Arduino VENTUNO Q

License

Apache-2.0 (root, covers brain/, mcp/, demos/, docs, configs) β€” with one exception: ojn/plugin_events/ is an OpenJabNab plugin (webhook egress for button/RFID events) and, as a derivative work of OpenJabNab, is licensed under OpenJabNab's GPL v2 (its LICENSE is OJN's COPYING, copied verbatim). It is cleanly separated: no code is shared with brain/ or mcp/ β€” the brain talks to OJN only over HTTP. The choreography plugin foreseen in the architecture turned out to be unnecessary (Gate G0).

Nabaztag is a trademark of its respective owner; this is an independent community project, not affiliated with Violet/Aldebaran.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    F
    maintenance
    A local MCP server that integrates with Claude Desktop, enabling RAG capabilities to provide Claude with up-to-date private information from custom LlamaCloud indices.
    225
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    A dead simple MCP server for exposing your app functions to AI agents like Claude Desktop.
    7 npm
    6
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    MCP server that enables Claude to control your computer, similar to Anthropic's computer use but easy to set up locally.
    311 npm
    367
    MIT