An MCP server that provides voice conversation capabilities using ElevenLabs API for text-to-speech and speech-to-text conversion, with WhatsApp integration.
Server has 3 tools with basic definitions but significant quality gaps. All tools have descriptions and input schemas are partially visible, but the schemas lack proper type definitions and several parameters are undescribed. Naming follows verb_noun pattern (text_to_speech, speech_to_text, list_elevenlabs_voices) but descriptions are generic and do not answer the critical WHAT/WHEN/WHY questions. Error handling returns status/message dictionaries but provides no recovery guidance. Output schemas are documented informally in docstrings but not formally specified. The voice_id parameter in text_to_speech has a critical flaw: it accepts a parameter but then immediately overwrites it from config (line 'voice_id = ELEVENLABS_VOICE_ID'), violating the principle that parameters should control behavior. Parameters lack validation constraints (e.g., no enum for voice_id, no length limits on text). Security risk: ELEVENLABS_API_KEY is injected via environment but no protection against accidental logging of sensitive audio data.
List all available voices from ElevenLabs Returns: Dictionary containing status and list of voices
Convert speech to text using ElevenLabs API Args: audio_base64: Base64-encoded audio data Returns: Dictionary containing status and transcribed text
Convert text to speech using ElevenLabs API Args: text: The text to convert to speech voice_id: Voice ID to use (defaults to configured voice) Returns: Dictionary containing status, audio data as base64, and format
Parameter voice_id in text_to_speech is misleading: documented as 'Voice ID to use (defaults to configured voice)' but implementation overwrites user input with ELEVENLABS_VOICE_ID from config (line 13: voice_id = ELEVENLABS_VOICE_ID). This violates the principle that tool parameters should control tool behavior. LLM passes a voice_id but it is silently ignored.
No input validation or constraints documented. text_to_speech accepts 'text' parameter with no length limits, encoding constraints, or examples. speech_to_text accepts audio_base64 with no format hints, codec expectations, or size limits. LLM will pass arbitrary values without guidance on valid ranges or formats.
Output schemas are not formally specified. Descriptions mention return values (e.g., 'Dictionary containing status, audio data as base64, and format') but provide no structured schema documentation. LLM cannot reliably plan downstream tool calls or extract fields from responses.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 36 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 33 | - | v1 |
Error handling provides no recovery guidance. All tools return {status: error, message: str(e)} with raw exception strings. Per pattern:recovery-guide, errors must tell LLM what to do next (e.g., 'Voice not found. Call list_elevenlabs_voices() to see available voices'). Generic messages force LLM to guess at recovery.
Tool descriptions are too brief and generic. Average length ~60 chars (baseline 194 chars). Descriptions do not answer WHAT/WHEN/WHY per pattern:tool-description. list_elevenlabs_voices does not mention this is a discovery tool to call before text_to_speech. text_to_speech does not clarify that voice_id defaults to config (even though behavior is wrong). speech_to_text does not specify supported audio formats.
No per-parameter descriptions for audio_base64 encoding constraints or expected formats. LLM does not know if base64 must be padded, what audio codecs are supported, or what max file size exists. Missing constraints per pattern:tool-description baseline: '100% of A+ tool params have descriptions'.
list_elevenlabs_voices output structure not documented. LLM does not know if returned voices include voice_id, name, category, language, or other fields. Without formal schema documentation, LLM cannot reliably extract voice_id to pass to text_to_speech.
No pagination documented for list_elevenlabs_voices despite ElevenLabs API potentially returning many voices. Per pattern:paginated-result, discovery tools returning lists should support limit/offset and return count. Without pagination, large results could blow context window.