Home
Relevant source files
The following files were used as context for generating this wiki page:reachy-mini-mcp is a Model-Context-Protocol (MCP) server designed to give AI systems control over a Pollen Robotics' Reachy Mini robot. It provides a simple, token-efficient set of tools that allow an AI (such as Claude, GPT, or Grok) to interact with the physical world through the robot's capabilities: speaking, listening, seeing, and expressing emotions via physical movement.
The project's goal is to provide a high-level interface for "embodied consciousness expression," abstracting away the complexities of robotics. The server is built using Python, leveraging the fastmcp library for the MCP implementation and the reachy-mini SDK for robot communication. The software is distributed under the MIT License.
Sources: README.md:3-7, src/init.py:1, LICENSE, pyproject.toml:2-6
Architecture
The system follows a layered architecture where tool calls from an AI are progressively translated into physical robot actions. The MCP server acts as the central bridge between the AI's intent and the robot's hardware.
This diagram illustrates the data flow from the AI to the robot.
The server exposes seven primary tools, a number chosen to align with Miller's Law for cognitive simplicity.
Sources: README.md:41-44, src/server.py:5-7
Core Components
- MCP Server (
server.py): The main application, built withFastMCP. It defines the tools available to the AI, parses incoming requests, and executes the corresponding robot actions. - Robot Connection (
get_robot): A lazy-initialized singleton pattern is used to manage the connection to the robot. The connection is only established on the first tool call, improving startup time. It connects to the Reachy Daemon, which must be running separately. - Reachy Daemon: A background service provided by the Reachy Mini SDK that exposes a REST API for controlling the robot. The MCP server communicates with this daemon, by default at
http://localhost:8321/api.
Sources: src/server.py:29-38, 175-194, README.md:92-93
Tools API
The server provides 7 tools for robot control.
| Tool | Args | Purpose |
|---|---|---|
speak | text, listen_after=0 | Voice + gesture, optionally listen after |
listen | duration=3 | STT via Deepgram Nova-2 |
snap | - | Camera capture (base64 JPEG) |
show | emotion, move="" | Express emotion or play recorded move |
look | roll, pitch, yaw, z, duration | Head positioning (degrees) |
rest | mode="neutral" | neutral / sleep / wake |
discover | library="emotions" | Find available recorded moves |
Sources: README.md:13-23
show(emotion, move)
This tool controls the robot's physical expression. It has two modes of operation:
- Built-in
emotion: Triggers one of 12 pre-defined, local choreographies for common emotions. These are fast and defined directly insrc/server.py. - Recorded
move: Plays a more complex, professionally choreographed move from Pollen Robotics' libraries. These are fetched and played via the Reachy Daemon. Themoveargument overridesemotionif both are provided.
The following diagram shows the logic flow for the show tool.
Built-in Emotions:
The EXPRESSIONS dictionary maps 12 emotion strings to specific head and antenna motor positions, movement duration, and an interpolation method.
neutralcuriousuncertainrecognitionjoythinkinglisteningagreeingdisagreeingsleepysurprisedfocused
Sources: src/server.py:61-163, 298-326
speak(text, listen_after, voice)
This tool vocalizes text through the robot's speaker and can perform choreographed movements embedded within the text.
Choreographed Speech:
Moves can be embedded in the text using the syntax [move:move_name]. The server parses this text, triggering the specified move just before speaking the subsequent text chunk.
Example: speak("[move:curious1] What's this? [move:surprised1] Oh wow!")
The following sequence diagram illustrates this process.
Sources: src/server.py:603-611, 680-724
Text-to-Speech (TTS) Providers:
The speak tool uses one of two TTS providers, with Grok Voice being the preferred option if configured.
- Grok Voice: Used if the
XAI_API_KEYenvironment variable is set. Supports several voices likeEve,Ara,Leo,Rex, andSal. - Deepgram Aura 2: Used as a fallback if
XAI_API_KEYis not set. Requires theDEEPGRAM_API_KEY.
This diagram shows the TTS provider selection logic.
Sources: README.md:49-56, 90-91, src/server.py:433-440
listen(duration)
Captures audio from the robot's microphones for a specified duration and transcribes it to text using Deepgram's Nova-2 Speech-to-Text (STT) service. This requires the DEEPGRAM_API_KEY to be set. The function captures raw audio, converts it to WAV format in memory, and sends it to the Deepgram API.
Sources: src/server.py:794-814, 560-591
snap()
Captures a single frame from the robot's camera, encodes it as a JPEG image, and returns it as a base64-encoded string. This allows the AI to "see" its environment.
Sources: src/server.py:817-838
look(...)
Provides direct, fine-grained control over the robot's head orientation (roll, pitch, yaw) and height (z). This is a lower-level alternative to the show tool, intended for precise positioning. Input values are clamped to safe ranges to prevent hardware strain.
Sources: src/server.py:329-370
rest(mode)
Manages the robot's power state.
neutral: Returns the robot to a default, upright pose.sleep: Moves the robot to a resting position and reduces power to the motors.wake: Wakes the robot from sleep mode.
Sources: src/server.py:841-861
discover(library)
Lists the available recorded moves from Pollen Robotics' HuggingFace libraries. This allows an AI to dynamically discover what move names can be used with the show tool. It queries the Reachy Daemon API to get the list of moves.
emotions: Lists 81 expressions.dances: Lists available dance choreographies.
Sources: src/server.py:900-925
Configuration
Configuration is managed primarily through environment variables and, for Claude users, a JSON configuration file.
Environment Variables
| Variable | Required | Default | Purpose |
|---|---|---|---|
XAI_API_KEY | No | - | API key for Grok Voice TTS (preferred). |
GROK_VOICE | No | Eve | Specifies the Grok voice to use. |
DEEPGRAM_API_KEY | Yes* | - | API key for Deepgram TTS (fallback) and STT. |
REACHY_DAEMON_URL | No | http://localhost:8321/api | The API endpoint for the Reachy Daemon. |
REACHY_MEDIA_BACKEND | No | default_no_video | Configures the SDK's media backend. |
*Required if XAI_API_KEY is not set.
Sources: README.md:90-93, src/server.py:186, 434, 444, 564, 870
Claude Integration
The server can be integrated with Anthropic's Claude by adding an entry to the MCP servers configuration file. This allows Claude to discover and use the Reachy Mini tools directly.
Claude Desktop Config (claude_desktop_config.json):
{
"mcpServers": {
"reachy-mini": {
"command": "poetry",
"args": ["-C", "/path/to/reachy-mini-mcp", "run", "python", "src/server.py"],
"env": {
"DEEPGRAM_API_KEY": "your_key_here"
}
}
}
}
Sources: README.md:59-71
Setup and Execution
The project is managed with Poetry.
Installation and Execution:
- Install dependencies:
poetry install - Set API keys:
export DEEPGRAM_API_KEY=your_key_here - Start the simulator daemon:
mjpython -m reachy_mini.daemon.app.main --sim --scene minimal - Run the MCP server:
poetry run python src/server.py
The server can also be run via the reachy-mini-mcp script defined in pyproject.toml. The main entry point in src/server.py registers a cleanup function cleanup_robot using atexit to ensure the robot connection is properly closed on shutdown.
Sources: README.md:30-38, pyproject.toml:15-16, src/server.py:950-957