MCP server for sending WhatsApp messages via ADA BMP API
This MCP server exposes 11 WhatsApp messaging tools with STDIO transport only. Tool naming is generally clear and action-oriented (all start with 'send_'), and all tools have descriptions. However, critical gaps emerge in schema completeness, parameter descriptions, and error handling guidance. Most tools lack explicit input schema visibility in the provided source code, only descriptions are shown, no formal JSON Schema definitions. Parameters like 'to', 'text', 'mediaUrl' have basic type and description annotations in the tool list, but no evidence of structured schema validation or documentation in the actual implementation files. The provided code snippet cuts off at adaClient.ts, preventing full verification of schema definitions. Two tools (send_image and send_image_url) appear to be duplicates with identical schemas, violating the single-responsibility principle. Output schemas are not documented, there is no clear specification of what the API returns or how the LLM should interpret success/failure. Error handling is absent: no recovery guidance, no categorization (retryable vs. fatal), no actionable error messages. All tools are WRITE operations with high-risk implications (sending messages, uploading media), yet no confirmation pattern or dry-run capability exists. The tool descriptions are minimal (1-5 words) and do not explain WHEN to use each variant (why send_image_url vs. send_image_file?) or what to expect from the response. Baseline comparison: average param description in production tools is 72 chars; here most are 10-40 chars. The duplicate tools alone signal a design issue.
Send an audio file
Send a message with 1-3 unique buttons
Send a document file
Send an image from a publicly accessible URL
Send an image from a local file
Send an image from a publicly accessible URL (alias of send_image)
Sequentially send multiple image URLs
Duplicate tool send_image_url is identical to send_image. Both accept to, mediaUrl, text and perform the same operation. This violates single-responsibility and forces LLM to reason about ambiguous tool selection.
No documented output schemas. Tools return AdaResponse (unknown structure) but LLMs are not told what fields to expect (messageId? status? raw API response?). This breaks downstream tool composition and forces LLMs to guess.
Tool descriptions are extremely brief (5-10 words). They do not explain WHEN to use each variant (why send_image vs send_image_url vs send_image_file?) or clarify prerequisites (must mediaUrl be public?). Baseline tool descriptions are 194 chars; most here are <50 chars.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | F | 44 | <=2025-11-25 | v2 |
Send a list message with 1-10 selectable rows
Send a product message from a catalog
Plain text message body
Send a video from a local file
No error handling guidance. No errors indicate what went wrong, why, or what to do next. 'Invalid to number', 'API rate limit exceeded', 'mediaUrl unreachable' all produce identical silent failures. LLMs cannot self-correct.
No confirmation or dry-run pattern for destructive operations. All 11 tools send/upload with WRITE risk but accept no confirmation='true' or dry_run parameter. Agents can accidentally message wrong numbers or spam campaigns.
Parameter 'to' (phone number) requires MSISDN format (628116823073) but description only says 'Recipient phone number'. No validation hint for format, length, or what happens if malformed. LLMs may pass '+62', '62', '811-682-3073', or other variants.
send_list and send_button parameters have constraints (1-3 buttons, 1-10 rows, <=24 char titles) described in text but not enforced as JSON Schema constraints. LLMs may pass 5 buttons or 100-char titles, causing silent truncation or API errors.
Parameter 'mediaUrl' (send_image, send_image_url) described as 'publicly accessible' but no validation that URL is reachable, has valid image mime-type, or will not time out. LLMs may pass malformed URLs or 404s without clear feedback.
send_button parameter 'headerType' is enum ['text', 'image'] but 'header' parameter is described as 'required if headerType is set', dependency is fragile. If 'headerType' is 'text' but header is omitted, error handling is unclear.