Local MCP server for reading and sending Messages on macOS
This server has solid fundamentals with clear, action-oriented tool names and documented input schemas. All 5 tools follow verb_noun naming (list_*, get_*, search_*, send_*). However, there are significant gaps: tool descriptions are present but generic (averaging ~60 chars, below the 194-char production baseline), parameter descriptions are minimal, output schemas are not documented, and error handling lacks recovery guidance. The send_message tool accepts opaque chatId but no human-readable identifier (e.g., phone number or contact name), forcing users to first call list_chats. Most parameters lack constraints (min/max, enum values, format specifications). Error messages are not visible in the source, so recovery guidance cannot be assessed. The codebase shows good input validation (normalizeLimit, normalizeIdentifier) but these are internal, not reflected in parameter schemas or descriptions.
Get messages from a specific chat
List conversations with optional search and filtering
Search for contacts by name, phone number, or email
Search for messages across all chats
Send a message to a chat via iMessage
send_message requires opaque chatId; no human-readable identifier (phone, email, contact name). Forces mandatory lookup call. Pattern: natural identifiers.
Output schemas not documented. LLM cannot predict field structure or plan downstream calls. All tools lack documented return types.
Tool descriptions are generic and short (avg 57 chars vs 194-char baseline). Missing WHEN to use, dependencies, and return type hints. Example: 'Search for messages across all chats' doesn't explain if it searches by date range, sender, or content only.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 48 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 0 | - | v1 |
Parameter constraints not declared in schemas. limit accepts 1 - 100 but no enum/minimum/maximum in visible schema. No pattern validation for query strings (SQL injection risk). Validation is implicit in code, invisible to LLM.
Error handling not visible. No recovery guidance ('User not found. Try list_chats first.'). send_message will fail silently on invalid chatId with no actionable error for LLM.
send_message is destructive (WRITE risk) but no dry-run, confirmation step, or confirmation request pattern. Agent could accidentally send malformed messages or to wrong contacts without guard rails.
get_chat_messages and search_messages lack pagination info in visible schema. No total_count, has_more, or next_cursor. If results exceed 20, LLM cannot request more without explicit offset knowledge.
Parameter descriptions are minimal (avg 35 chars). Query parameters don't specify search scope (name? identifier? participant handles? all three?). Offset meaning unclear, is it message count or page number?