Learning MCP - A robot control server using FastMCP to expose robot movement and sensor data as MCP tools
This server has significant definition quality gaps. All three tools have descriptions, but they are extremely brief (8-27 characters) and fail to meet the 10-1024 character baseline or provide context for LLM selection. Parameter descriptions are missing or minimal. The `move_robot` tool accepts free-form direction strings without enum constraints, inviting hallucinated values. Output schemas are only partially documented, `get_battery_level` returns a string, while `get_camera_frame` returns a dataclass without field-level documentation. Error handling is absent: no guidance on what happens if the robot is unreachable, battery is critically low, or camera stream has no frames. The server lacks idempotency guarantees, permission checks, and recovery guidance. Tool composition is reasonable (three focused tools), but parameter naming and validation are weak.
Get the current battery level of the robot in Volts
Get the latest camera frame from the robot
Move the robot in a specified direction for a given duration
Tool descriptions are far too brief (8-27 chars, baseline 10-1024). `get_camera_frame` is just 'Get the latest camera frame from the robot' (27 chars), lacks WHEN to use it, prereqs, or what fields the response contains.
`move_robot` direction parameter accepts free-form strings ('forward', 'backward', 'left', 'right', 'stop'), no enum constraint. LLMs will hallucinate values like 'forwards', 'northeast', 'up'. Should declare as enum: ['forward', 'backward', 'left', 'right', 'stop'].
Parameter descriptions are missing or trivial. `direction` param in `move_robot` is described as 'Direction to move: forward, backward/back/backwards, left, right, or stop' (81 chars), borderline acceptable but mixes examples with constraint doc. `duration` lacks constraints (range, units). `get_battery_level` and `get_camera_frame` have empty input schemas but no explanation of prereqs (e.g. 'Camera stream must be initialized').
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 50 | 2026-07-28+ | v2 |
| 2026-03-09 | D | 59 | - | v1 |
Output schemas are undocumented or incomplete. `get_battery_level` returns a string with no schema. `get_camera_frame` returns a dataclass `ImageFrame` with fields (width, height, encoding, timestamp, received_at, image_base64), structure is visible in code but not declared in tool schema. LLM cannot plan what fields to expect.
No error handling or recovery guidance. Code silently falls back ('if reply is None: return "No camera frames received yet"'), LLM does not know if this is a timeout, permission issue, or initialization problem, and has no path to retry. `move_robot` has no error responses if direction is invalid or robot is unreachable.
Tool composition is sound (three focused tools), but parameter naming could be tighter. `duration` param in `move_robot` lacks numeric bounds, baseline guidance is to specify min/max (e.g. 0.1 - 60.0 seconds). Unbounded durations invite LLM to pass absurd values.
No idempotency declaration. Calling `move_robot` twice with the same direction and duration will move the robot twice, not idempotent. If an agent retries on a network error, the robot moves again. Should document this behavior or implement idempotent semantics (e.g. with a unique request ID).