A local MCP server for querying and sending iMessages on macOS
This iMessage MCP server has solid naming conventions and basic parameter coverage, but suffers from significant gaps in schema completeness, output documentation, and error handling guidance. Of 13 tools, only 9 have documented input schemas visible in the provided code. Parameter descriptions are present but minimal (10-40 chars). No output schemas are documented. Error handling lacks recovery guidance. The server follows good naming patterns (verb_noun: search_contacts, get_conversation_messages, send_message) and most tools have descriptions between 34-200 chars, placing it slightly above the median (45-55) for community servers, but well below production grade (70+).
Verify database access and diagnose permission issues
Get messages from a specific conversation
Get messages before/after a specific message in the same thread
Get the current progress of a background search index rebuild
Get recent messages across all conversations
A simple hello world tool for testing the server
List all conversations with metadata
Look up a specific contact by phone number or email
Missing output schemas for all tools. Tool definitions document input parameters but no return types, field structures, or example responses are specified. LLMs cannot plan downstream calls or extract required data without knowing what fields to expect.
Three tools lack input schema definitions: check_permissions, search_index_status, and get_rebuild_progress have no visible parameter documentation despite appearing to accept inputs (e.g., get_rebuild_progress needs to know which rebuild to query).
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 43 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 43 | - | v1 |
Rebuild the entire search index from scratch by re-indexing all messages from chat.db
Search for contacts by phone/email
Get the current status of the search index including indexed message count, embeddings count, and database metadata
Search messages by text with optional filters
Send a message to an existing conversation
Error handling lacks recovery guidance. No tools document what errors they can raise, how to classify them (retryable vs user-fixable vs fatal), or what actions the LLM should take next. Example: send_message can fail silently per the server instructions ('messages may silently fail') but provides no detection or guidance.
Parameter descriptions are minimal (10-40 chars average) and lack actionable constraints. Example: 'limit' and 'offset' parameters in list_conversations and get_conversation_messages lack min/max bounds. LLMs can pass unbounded values causing timeouts or oversized responses.
No pagination documentation for list tools. list_conversations and get_conversation_messages return limit/offset parameters but no total_count, has_more, or next_cursor fields are documented. LLMs cannot determine if results are truncated or plan multi-page retrieval.
send_message limitations are buried in the server instructions, not in the tool description. LLMs reading only the tool definition see 'Send a message to an existing conversation' without learning that Messages.app must be running, delivery is unconfirmed, and only existing conversations are supported. Tool descriptions must be self-contained.
rebuild_search_index supports 'background' mode but lacks timeout guidance and completion detection. If background=true, the tool returns immediately but get_rebuild_progress() must be polled. No guidance on polling interval, timeout, or failure mode (e.g., what if the rebuild crashes in background?).
No tool annotations present. The spec supports tool annotations (readOnlyHint, destructiveHint, idempotentHint) to help agents classify operations. send_message and rebuild_search_index should be marked destructiveHint=true; read-only tools should be marked readOnlyHint=true.
Parameter naming inconsistency: 'handle' in lookup_contact vs 'query' in search_contacts, and 'contact' vs 'recipient' in message tools create confusion. Baseline guidance requires consistent naming across tools operating on the same domain (contacts). Should use 'contact_identifier' or similar canonical name.