ESP32-based AI voice assistant with MCP server implementation for device control, music playback, camera, and settings management
This ESP32 device control server has 10 tools with moderate definition quality. Most tools have descriptions (8/10), but many lack proper parameter validation and structured output schemas. Tool names follow verb_noun convention reasonably well (get_device_status, set_volume, take_photo). However, parameter descriptions are often vague or missing constraints. For example, self.set_press_to_talk accepts 'mode' as a free-form string with only informal guidance ('press_to_talk' or 'click_to_talk') rather than an enum constraint. Output schemas are not documented anywhere in the source. Error handling is minimal, no recovery guidance, no categorization of error types. The server lacks tool annotations (readOnlyHint, destructiveHint) despite having clear READ_ONLY and WRITE operations. No pagination support for list operations. Parameter descriptions average ~40 chars, below the 72-char baseline for A+ tools.
Set the volume of the audio speaker. If the current volume is unknown, you must call `self.get_device_status` tool first and then call this tool.
Take a photo and explain it. Use this tool after the user asks you to see something. Args: `question`: The question that you want to ask about the photo. Return: A JSON object that provides the photo information.
Bind this ESP32 device to a user account using a 6-digit binding code. Users need to: 1. Login to the web console (http://47.118.17.234:2233) 2. Generate a binding code (valid for 5 minutes) 3. Tell the device: '绑定设备,绑定码123456' Parameters: `binding_code`: 6-digit binding code from web console `device_name`: Optional custom device name (default: ESP32音乐播放器) Returns: Success message with bound username, or error message.
Get the current device binding status and information. Returns: Device binding status, MAC address, bound username, etc.
Unbind this device from the current user account. This will remove the device binding and require re-binding to use personalized features. Returns: Success or error message.
No output schemas documented. Tools like get_device_status, take_photo, and device.status return data but provide no schema definition. LLMs cannot plan downstream calls or extract fields reliably.
Enum constraints missing. self.set_press_to_talk and self.screen.set_theme accept free-form strings instead of declared enums. LLMs may hallucinate invalid values like 'press_to_talk_mode' or 'light_mode'.
No tool annotations. Tools marked WRITE (set_volume, set_brightness, bind, unbind, play_song) lack destructiveHint. Tools marked READ_ONLY lack readOnlyHint. Agents cannot distinguish safe from risky operations.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | F | 48 | <=2025-11-25 | v2 |
Provides the real-time information of the device, including the current status of the audio speaker, screen, battery, network, etc. Use this tool for: 1. Answering questions about current condition (e.g. what is the current volume of the audio speaker?) 2. As the first step to control the device (e.g. turn up / down the volume of the audio speaker, etc.)
Play the specified song. When users request to play music, this tool will automatically retrieve song details and start streaming. parameters: `song_name`: The name of the song to be played. `artist`: (Optional) The artist name. Highly recommended when playing from playlists to ensure correct song match. return: Play status information without confirmation, immediately play the song.
Set the brightness of the screen.
Set the theme of the screen. The theme can be `light` or `dark`.
Switch between press to talk mode (长按说话) and click to talk mode (单击说话). The mode can be `press_to_talk` or `click_to_talk`.
Minimal error handling. No recovery guidance, error categorization, or actionable error messages. If bind fails, the LLM has no guidance on what to try next.
Parameter descriptions lack constraints. self.audio_speaker.set_volume documents range (0-100) in schema but not in description text. LLMs may not parse JSON Schema constraints reliably.