Reachy Mini Daemon Interaction
Relevant source files
The following files were used as context for generating this wiki page:
This document outlines how the Reachy Mini MCP server interacts with the underlying reachy_mini daemon, which controls the physical robot or its simulator. The MCP server acts as a high-level abstraction layer, translating tool calls from an AI system into commands for the robot. This interaction is primarily managed through the reachy-mini Python SDK, but also involves direct HTTP requests to the daemon for specific features like playing recorded moves.
The core purpose of this system is to provide a simple, token-efficient interface for AI systems to control a Reachy Mini robot, enabling "embodied consciousness expression."
Sources: src/server.py:4-8, src/init.py:1, README.md:3-5
Architecture Overview
The system employs a layered architecture to separate concerns. An AI system (like Claude, GPT, or Grok) communicates with the MCP Server by invoking tools. The MCP Server then uses the reachy-mini SDK to send commands to the Reachy Mini Daemon. The daemon is the low-level process that directly interfaces with the robot hardware or the MuJoCo simulator.
Sources: README.md:46-48, src/server.py:5-6
This diagram illustrates the command flow from the AI to the robot.
Sources: README.md:46-48, src/server.py
Connection Management
Connection to the Reachy Mini daemon is handled lazily. An instance of the reachy_mini.ReachyMini class is not created when the server starts, but rather on the first tool call that requires robot interaction.
Sources: src/server.py:182-185
Lazy Initialization
The get_robot() function manages a global _robot_instance. If the instance is None, it imports ReachyMini, initializes it, and stores it for subsequent calls. This prevents connection attempts if no robot-related tools are ever used.
The connection process involves an __enter__() call on the robot instance, which is part of the SDK's context management for handling connections.
Sources: src/server.py:180-201
Connection Cleanup
To ensure a clean shutdown, the cleanup_robot() function is registered to run at exit using atexit. This function calls __exit__() on the robot instance if it exists, properly closing the connection to the daemon.
Sources: src/server.py:204-213, 1002-1003
Modes of Interaction
The MCP server interacts with the daemon in two distinct ways:
- SDK-Mediated Communication: For most core functions like head movement, camera access, and audio playback.
- Direct HTTP Communication: For discovering and playing pre-recorded moves from HuggingFace libraries.
SDK-Mediated Communication
Tools such as look(), show(emotion=...), rest(), speak(), listen(), and snap() use the reachy-mini SDK, which is listed as a dependency in pyproject.toml. The SDK object, obtained via get_robot(), provides high-level methods that abstract the underlying API calls to the daemon.
For example, the look() tool calls robot.goto_target() to position the head.
Sources: pyproject.toml:11, src/server.py:399-404
The following sequence diagram shows the flow for a look() command.
Sources: src/server.py:382-405
Direct HTTP Communication
For managing recorded moves from Pollen Robotics' libraries, the server communicates directly with the daemon's HTTP API. This is necessary for features not exposed through the current version of the SDK used by the project.
The base URL for the daemon is configured via the REACHY_DAEMON_URL environment variable, defaulting to http://localhost:8321/api.
Sources: src/server.py:943, README.md:78-79
Daemon API Endpoints
The server uses the following daemon endpoints for recorded moves:
| Method | Endpoint | Function(s) | Purpose |
|---|---|---|---|
GET | /move/recorded-move-datasets/list/{dataset} | discover() | List available moves in a library. |
POST | /move/play/recorded-move-dataset/{dataset}/{move_name} | _do_play_move() | Trigger a recorded move by name. |
GET | /move/running | _wait_for_moves_complete() | Check if any moves are currently running. |
Sources: src/server.py:976-980, 994-997, 953-955
Sequence for Playing a Recorded Move
The show(move="...") tool call triggers a direct HTTP POST request to the daemon to play the specified move.
Sources: src/server.py:348-350, 989-1000
Move Completion Polling
The speak() tool, when using choreographed moves, needs to know when a move has finished before starting the next action. The _wait_for_moves_complete() function handles this by repeatedly polling the daemon's /move/running endpoint until it returns an empty list, indicating all moves are complete.
Sources: src/server.py:756-757, 946-962
Summary
The reachy-mini-mcp server's interaction with the Reachy Mini daemon is a hybrid model. It primarily relies on the reachy-mini SDK to abstract away the complexity of robot control for core functionalities like direct motor control and media streams. However, for advanced features like playing choreographed moves from online libraries, it bypasses the SDK to make direct HTTP requests to the daemon's API. This dual approach allows the server to leverage the stability of the SDK while retaining the flexibility to access newer or more specialized daemon features directly.