Self-contained MCP server using Baileys (linked-device protocol) for WhatsApp integration with full access control, pairing, allowlists, and group support with mention-triggering
This STDIO-only MCP server for WhatsApp has 9 tools with mixed definition quality. Tools are named using domain-specific conventions (whatsapp-channel:*, reply, get_*, list_*, catch_up, set_*, group_config) but lack consistent verb-first patterns found in 90% of production tools. Descriptions vary from adequate (reply, get_chats) to sparse (list_contacts, get_tasks). Critical gap: NO input schemas are visible in the provided source code. The schema definitions listed in the server summary appear to be inferred rather than extracted from explicit TypeScript/JSON schema registration. Per the HARD SCORING RULE, if schemas are not visible in source, schema score MUST be 0. This severely depresses overall quality scores.
Get recent messages from a specific chat, including both sent and received messages, with full context and media paths for attachments.
List active WhatsApp chats with message counts, unread status, and last activity. Includes waiting messages count for each chat.
Retrieve task list stored in tasks.md file for the WhatsApp channel.
View or update group configuration including cron jobs and mention requirements. Configuration is stored in group's config.md file.
List all saved WhatsApp contacts with their phone numbers and display names.
Send a reply message to a WhatsApp chat. Supports text, mentions (@-prefixed contact names or numbers), and optional media attachments. Messages over chunk size are split and mentions only attach to relevant chunks.
Update the task list in tasks.md file for the WhatsApp channel.
NO input schemas are visible in source code. Tool definitions show parameter names and informal descriptions (e.g., 'phone': {'type': 'string', 'description': '...'}) but these appear inferred, not extracted from explicit JSON Schema or TypeScript schema registration in server.ts. Per HARD SCORING RULE: if schemas are not visible in source, schema score MUST be 0.
Descriptions lack clarity on when to call each tool vs. alternatives. Example: both 'catch_up' and 'get_chats' retrieve messages, but the distinction is not clearly documented. 'catch_up' requires a chat identifier; 'get_chats' does not, but descriptions do not guide the LLM to choose correctly. Pattern: tool-description.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 42 | <=2025-11-25 | v2 |
Manage WhatsApp channel access control. Supports commands: review (open access screen to allowlist contacts), policy (set pairing/allowlist policy), pair (add contact via pairing code), set owner (set permission request delivery target)
Configure WhatsApp phone number for the channel. User provides country code + number without '+' prefix (e.g. 886912345678)
Parameter descriptions are informal and lack precision. Example: 'reply' tool's 'mentions' parameter is described as 'Array of contact names, numbers, or \'all\' for group mentions' but does not clarify format constraints, validation rules, or error handling if a mention does not exist. 'configure' tool's 'phone' description includes an example '886912345678', LLMs may latch onto this literal value in real calls. Pattern: constrained-input.
'whatsapp-channel:access' tool accepts a command parameter with enum values ('review', 'policy', 'pair', 'set', 'status') but the description does not explicitly declare the enum. The 'args' parameter is underspecified: what format do arguments take for each command? LLM must guess.
'get_tasks' and 'set_tasks' descriptions are minimal (35-50 chars). 'get_tasks' just says 'Retrieve task list', does not explain where tasks are stored, format, or use case. 'set_tasks' says 'Update the task list', does not mention side effects or validation. Pattern: tool-description baseline expects 10-1024 chars with WHAT/WHEN context.
'list_contacts' description (40 chars) is under the 20-char hard minimum for passing description checks. Per HARD SCORING RULE, description score CANNOT exceed 40.
Output schemas are not documented. get_chats, catch_up, list_contacts, and get_tasks return structured data, but the response format is not specified in descriptions or visible in source. LLMs cannot plan downstream calls without knowing what fields are present (e.g., does get_chats return 'chat_id' or 'jid'?). Pattern: tool output documentation.
No error handling documentation. Tools do not describe what happens if a chat is not found, a contact name is invalid, or a WhatsApp connection fails. No recovery guidance (e.g., 'If chat not found, call get_chats to list available chats'). Pattern: recovery-guide, error-classification.
Destructive tools (reply, set_tasks, group_config with 'set' action, whatsapp-channel:configure, whatsapp-channel:access) lack confirmation or dry-run patterns. Sending a message is irreversible, LLMs should be warned and offered a confirmation step. Pattern: confirmation-request.
Tool naming mixes conventions: some use verb_noun (get_chats, list_contacts, catch_up, get_tasks, set_tasks), others use domain:verb (whatsapp-channel:configure, whatsapp-channel:access), and one is just a noun (reply). Inconsistency makes it harder for LLMs to disambiguate. Best practice: consistent verb_noun across all tools. Pattern: tool naming.