The Unitree Go2 MCP Server is a server built on the MCP that enables users to control the Unitree Go2 robot using natural language commands interpreted by a LLM.
Server exhibits severe deficiencies in tool definition quality. While tool names follow verb_noun conventions (get_topics, pub_wirelesscontroller, stand_up_from_a_fall, etc.), the vast majority of tools lack proper parameter descriptions and structured schemas. The pub_wirelesscontroller tool has a detailed input schema with parameter descriptions, but 11 of 12 tools have completely empty input schemas ({}), making them impossible for LLMs to understand parameter requirements or constraints. Tool descriptions are present but generic and unhelpfully brief in many cases (e.g., 'Commands the Unitree Go2 robot to stand up from a fallen position' provides no context about prerequisites, side effects, or when to use it versus other movement tools). No output schemas are documented anywhere. Error handling is absent, tools return raw tuples without guidance on failure recovery. The server appears to be a thin wrapper around ROS2 commands with minimal agent-optimization.
Commands the Unitree Go2 robot to perform a dance movement.
Retrieves a list of ROS2 topics and their types. Uses rosbridge if enabled, otherwise uses ROS2 directly.
Commands the Unitree Go2 robot to perform a greeting gesture.
Commands the Unitree Go2 robot to jump forward.
Commands the Unitree Go2 robot to perform a love gesture.
Commands the Unitree Go2 robot to perform a pounce movement.
Publishes WirelessController messages to control the Unitree Go2 robot's movement.
11 of 12 tools have empty input schemas ({}). This violates the fundamental requirement that every tool parameter needs a description and type.
Tool descriptions are uniformly generic and under 50 characters. Examples: 'Commands the Unitree Go2 robot to stand up from a fallen position.' (58 chars) provides no context on when to use stand_up_from_a_fall vs. other movement tools, no dependency hints, no side effects. Descriptions must answer WHAT, WHEN, and what it returns. Current descriptions fail the WHEN requirement entirely.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 42 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 0 | - | v1 |
Commands the Unitree Go2 robot to perform a handshake gesture.
Commands the Unitree Go2 robot to sit down.
Commands the Unitree Go2 robot to stand up from a fallen position.
Commands the Unitree Go2 robot to stop all movements.
Commands the Unitree Go2 robot to perform a stretch movement.
No output schemas documented. Tools return opaque tuples (bool, Any) with no description of what the return value contains or how the LLM should interpret it. An LLM cannot chain tool calls when the return structure is undocumented.
No error handling or recovery guidance. Tools return raw exception strings (e.g., str(e) in execute()). An LLM receives 'Command timed out' and has no guidance on whether to retry, call a different tool, or escalate to the user.
Tool interdependencies undocumented. Many movement tools call stand_up_from_a_fall() internally (stretch, shake_hands, love, pounce, jump_forward, sit_down, greet, dance). An LLM has no visibility into this dependency chain and cannot reason about calling them in sequence.
pub_wirelesscontroller parameter descriptions lack expected ranges and constraints. Parameters are documented as accepting floats but clamped to -3.7..3.7. The description states '(clamped to -3.7 to 3.7)' but does not explain what the values mean semantically (velocity in m/s? percentage? motor command 0-100?).
No distinction between movement commands. Tools like stretch(), shake_hands(), love(), greet() are all gesture movements but have identical names and descriptions that don't distinguish them for LLM decision-making. An LLM has no guidance on which gesture to invoke for a given user intent.