Mac Messages MCP

repository·main·Indexed 43 days ago

https://github.com/carterlasalle/mac_messages_mcp

A Model Context Protocol (MCP) server that enables AI clients like Claude, Cursor, and VS Code to interact with macOS Messages and Contacts. Version 1.1.0 allows for searching, reading, and sending iMessages and SMS/RCS messages, as well as managing attachments and contact lookups via a set of specialized tools.

Tokens
13.1K
Snippets
40
Records
82
Agent score
55%

What's inside Mac Messages MCP

  1. Overview of Mac Messages MCP

    main

    Mac Messages MCP is a Python-based bridge that allows AI assistants (such as Claude Desktop or Cursor) to interact with the native macOS Messages app via the Model Context Protocol (MCP).

    Key capabilities include:

    • Reading Messages: Accessing complete message history with time-based filtering.
    • Sending Messages: Sending iMessages with automatic SMS/RCS fallback for non-Apple devices.
    • Contact Management: Fuzzy searching and resolving contact names to phone numbers.
    • Search: Performing fuzzy searches within message content.
    • Group Chats: Managing both individual and group conversations.
  2. Core Capabilities of Mac Messages MCP

    main

    The Mac Messages MCP server provides AI assistants (like Claude Desktop or Cursor) with direct access to the macOS Messages app. Key capabilities include:

    • Message Reading: Access complete message history with timestamp filtering (hours, days, weeks, months, years), contact filtering, and group chat support.
    • Fuzzy Search: Content-based search using thefuzz integration to find specific terms within message history.
    • Message Sending: Natural language contact resolution (names, phone numbers, emails) and support for sending to existing group chats.
    • Universal Messaging: Automatic fallback to SMS/RCS when iMessage is unavailable, enabling seamless communication with Android users.
    • Contact Intelligence: Fuzzy matching for contacts (e.g., "John" finding "John Smith") and prioritization of direct message handles over group chats.
  3. Performance and Optimization Patterns

    main

    The system is designed for production-grade performance using several key strategies:

    • Database Optimization: Uses indexing for efficient timestamp and handle queries. Message queries are optimized to return complete datasets across all time ranges.
    • Caching Strategy: Implements a 5-minute TTL (Time-To-Live) for contact data and appropriate caching for frequently accessed message data to reduce database load.
    • Memory Management: Employs streaming results to handle large datasets efficiently and performs proper resource cleanup of database connections to prevent leaks.
    • Handle Resolution: Uses an optimized query that prioritizes direct message handles over group chats by analyzing chat counts.
  4. How to work with recipients and group chats

    main

    Recipients

    • Direct Messages: E.164 phone numbers (e.g., +14155551234) are the most reliable. National formats (e.g., (415) 555-1234) work if MAC_MESSAGES_REGION is correctly set.
    • Other Formats: The server also accepts email addresses, contact names, and contact:N selections returned from contact searches.

    Group Chats

    To interact with a group conversation:

    1. Call tool_get_chats to find the chat's identifier.
    2. Use that ID as the chat_id in tool_get_recent_messages to read the conversation.
    3. Use that ID in tool_send_message while setting group_chat=true to send a message.
  5. Architecture Overview of Mac Messages MCP

    main

    The Mac Messages MCP follows a layered architecture to bridge AI assistants (like Claude or Cursor) with macOS messaging capabilities:

    1. MCP Server Layer (server.py): Acts as the protocol interface. It provides a tool-based API, handles request validation, translates errors into user-friendly messages, and orchestrates workflows.
    2. Business Logic Layer (messages.py): Contains the core operations. It manages database querying, contact resolution (using fuzzy matching), message sending via AppleScript (with SMS/RCS fallback), and permission validation.
    3. Data Access Layer: Directly interacts with the system via SQLite (accessing chat.db and AddressBook databases), AppleScript (for native Messages app integration), and the file system (for database detection).

    Component Relationships:

    • AI Assistant $\leftrightarrow$ MCP Client $\leftrightarrow$ MCP Server $\leftrightarrow$ System Resources (Messages, AddressBook, AppleScript).
  6. How fuzzy message search works

    main

    The tool_fuzzy_search_messages tool performs content-based searches using the following flow:

    1. Time Calculation: Converts the requested hour range into an Apple epoch timestamp in nanoseconds.
    2. Database Query: Executes a SQLite query using the calculated timestamps to filter the message history.
    3. Content Extraction: Extracts text from either the text field or the attributedBody field.
    4. Fuzzy Matching: Applies fuzz.WRatio() to match query terms against message content.
    5. Filtering & Ranking: Removes low-confidence matches and sorts the remaining results by relevance score.
  7. How contact resolution works

    main

    The system uses a multi-tiered approach to resolve names to messaging handles:

    1. Primary: Exact match on normalized phone numbers.
    2. Secondary: Fuzzy matching on contact names using difflib.SequenceMatcher.
    3. Tertiary: User disambiguation. If multiple matches are found, the system presents numbered options for the user to select.

    Performance: An in-memory contact cache with TTL (Time-To-Live) is used to optimize repeated lookups.

  8. Understand the messaging fallback strategy

    main
    The server implements a Universal Messaging strategy. When sending a message, it uses AppleScript to detect if iMessage is available for the recipient. If iMessage is unavailable, it automatically falls back to SMS/RCS to ensure the message is delivered across iOS and Android devices, reducing "Not Delivered" errors.
  9. How Handle Resolution works

    main

    Handle resolution is the process of mapping a contact or phone number to a specific messaging handle. In version 0.7.3, the resolution logic was enhanced to prioritize direct message handles over group chat handles. This prevents the "No messages found" error that occurred when a contact parameter was used but the system incorrectly selected a group chat handle instead of a direct one.

    To assist with debugging or manual resolution, the find_handle_by_phone function is available in the public API.

  10. Core Messaging Capabilities

    main

    The MCP server provides several functional capabilities for AI assistants:

    Message Retrieval

    • History Access: Retrieve messages from the chat.db database.
    • Time-Based Filtering: Filter messages by specific time ranges (hours, days, weeks, months, or years).

    Sending Messages

    • Universal Messaging: The send_message function supports iMessage and includes an SMS/RCS fallback, allowing the AI to communicate with Android and other cross-platform users.
    • Contact Resolution: Uses fuzzy matching to resolve contact names to phone numbers.
    • Fuzzy Search: Uses thefuzz integration to allow searching for message content even with slight typos or partial matches.
  11. Technical constraints and limitations

    main

    When building with or using this project, be aware of the following constraints:

    macOS Specifics

    • Database Paths: Relies on fixed paths in ~/Library/Messages/ and ~/Library/Application Support/AddressBook/.
    • AppleScript: Message sending is dependent on the Messages app and AppleScript support.
    • Sandbox: The server cannot function in sandboxed environments.

    Database Access

    • Read-Only: The Messages database is accessed in a read-only mode to prevent data corruption.
    • Schema Dependency: The project relies on Apple's internal SQLite schemas, which are subject to change with macOS updates.

    Performance

    • AppleScript Latency: Message sending has inherent delays due to the nature of AppleScript execution.
    • Contact Matching: Uses difflib for contact matching and thefuzz for message content search.
  12. Implementation: Apple Epoch Timestamp Conversion

    main

    When querying the Messages database, timestamps must be converted to nanoseconds relative to the Apple epoch (January 1, 2001) to ensure correct filtering.

    Correct Logic:

    1. Calculate the target time (e.g., now - X hours).
    2. Calculate the delta between the target time and the Apple epoch.
    3. Convert that delta into total nanoseconds.
    # FIXED timestamp conversion logic:
    current_time = datetime.now(timezone.utc)
    hours_ago = current_time - timedelta(hours=hours)
    apple_epoch = datetime(2001, 1, 1, tzinfo=timezone.utc)
    # CRITICAL FIX: Convert to nanoseconds (Apple's Core Data format)
    nanoseconds_since_apple_epoch = int((hours_ago - apple_epoch).total_seconds() * 1_000_000_000)