Local MCP approval server that sends WhatsApp messages via Twilio for requesting approval before executing tools
This server has a single tool 'permissions__approve' with significant quality gaps. The tool has a description (positive), but the naming convention is non-standard (uses double underscore instead of verb-first), parameter descriptions are minimal, and critical context is missing. The tool's core function, blocking execution pending human approval, is a meta-level capability rather than a domain tool, which limits its applicability. Output schema is not explicitly documented. Error handling returns plain error strings rather than actionable recovery guidance. The implementation uses database polling (inefficient, blocking), and the tool lacks idempotency hints or confirmation patterns despite managing critical approval workflows.
Request approval via WhatsApp before executing a tool.
Tool naming violates verb_noun convention. 'permissions__approve' uses double underscore and is ambiguous, does it request approval, grant approval, or check approval status? Should follow pattern like 'request_approval' or 'request_tool_execution_approval'.
Parameter descriptions are extremely sparse. 'tool_name' has no type hint in description (though type is in schema). 'input' is described only as 'The input parameters for the tool', does not explain format, encoding, size limits, or how LLM should construct it. 'reason' description is minimal.
Output schema is not documented. Tool returns dict with keys like 'approved', 'denied', 'error', but LLM has no visibility into expected structure, field types, or what to do with each response variant. LLMs need to know what fields to expect.'
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 47 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 48 | - | v1 |
Error responses are not actionable. Examples: {'error': 'Twilio not configured'}, {'error': 'Request timed out'}. Per pattern:recovery-guide, errors must tell LLM what to do next. Current errors are silent, no retry guidance, no alternative suggestions. LLM cannot self-correct.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). This tool DOES have side effects (sends WhatsApp message, modifies database state) but provides no hints to LLM about idempotency, destructiveness, or retry safety. Critical for agent safety.
No confirmation/dry-run pattern. Tool sends real WhatsApp messages as side effect but has no way for agent to preview, confirm, or test without committing. Per pattern:confirmation-request, irreversible operations should support confirmation step.
Blocking wait via database polling is inefficient and unsafe. Tool uses asyncio.sleep(2) in a 300-second loop, blocking the entire agent. No support for webhooks, callbacks, or event-driven notifications. This pattern does not scale and creates timeouts.
Tool conflates approval request with tool execution. 'permissions__approve' accepts tool_name and input but does not actually execute the tool, it only requests approval. This creates confusion: does the LLM receive approval status and then call the original tool separately? Or does this tool execute it? Unclear composition breaks agent planning.
Parameter 'input' accepts arbitrary dict/object with no schema validation. LLM can pass any structure. No constraints on size, depth, or content. Risk of malformed payloads, oversized requests, or injection attacks. Per pattern:constrained-input, parameters must validate early.
Tool description (20 chars) is below rubric minimum of 10 - 1024 and lacks key context. Does not explain WHEN to use this vs other approval tools, HOW the human responds, or WHAT happens on approval/denial.