wyattjoh/imessage-mcp

wyattjoh/imessage-mcp

๐Ÿ“‡ ๐Ÿ  ๐ŸŽ - A Model Context Protocol server for reading iMessage data from macOS.

CLAUDE.md

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Development Commands

This is a Deno workspace monorepo with two packages:

  • packages/imessage - Core library for iMessage database access
  • packages/imessage-mcp - MCP server implementation

Root Commands (affects all packages)

# Cache dependencies for all packages
deno cache packages/*/mod.ts

# Code quality (runs on all packages)
deno task fmt     # Format all code
deno task lint    # Lint all packages
deno task check   # Type check all TypeScript files

# Run tests
deno task test

# Publish packages to JSR (CI/CD)
deno publish

Package-Specific Commands

# Run the MCP server
cd packages/imessage-mcp
deno run --allow-read --allow-env --allow-sys --allow-ffi mod.ts

# Development with file watching
cd packages/imessage-mcp
deno run --allow-read --allow-env --allow-sys --allow-ffi --watch mod.ts

# Test the core library
cd packages/imessage
deno test --allow-read --allow-env --allow-ffi

Architecture Overview

This monorepo contains a Model Context Protocol (MCP) server and core library that provide read-only access to the macOS iMessage database. The codebase follows functional programming principles with no classes.

Package Structure

  1. @wyattjoh/imessage (packages/imessage/)

    • Core library for iMessage database access
    • Database operations, type definitions, and utilities
    • No MCP dependencies - can be used standalone
  2. @wyattjoh/imessage-mcp (packages/imessage-mcp/)

    • MCP server implementation
    • Imports and uses the core library
    • Provides LLM-accessible tools

Core Components

  1. MCP Server Layer (packages/imessage-mcp/src/index.ts)

    • Creates MCP server instance using @modelcontextprotocol/sdk
    • Defines 6 tools with Zod schemas for validation
    • Uses StdioServerTransport for communication
    • Lazy database initialization pattern
  2. Messages Database Layer (packages/imessage/src/messages.ts)

    • Pure functions for all database operations
    • Direct SQLite access to ~/Library/Messages/chat.db
    • Handles Apple's timestamp format (Core Data epoch: nanoseconds since 2001-01-01)
    • All queries are read-only with parameterized SQL
    • Implements pagination with metadata for all queries
  3. Contacts Integration (packages/imessage/src/contacts.ts)

    • Direct SQLite access to ~/Library/Application Support/AddressBook/Sources/*/AddressBook-v22.abcddb
    • Searches multiple AddressBook databases for comprehensive results
    • Phone number normalization (adds +1 prefix for 10-digit US numbers)
    • Returns both phone numbers and email addresses as potential iMessage handles
  4. Type System (packages/imessage/src/types.ts)

    • Interfaces matching iMessage database schema
    • MessageWithHandle extends Message with denormalized handle data
    • All nullable fields use T | undefined pattern
    • PaginatedResult<T> wrapper for all paginated responses

Key Technical Details

  • Timestamp Conversion: Apple stores timestamps as nanoseconds since 2001-01-01. Conversion formula: date/1000000000 + 978307200
  • Database Paths:
    • Messages: ~/Library/Messages/chat.db
    • Contacts: ~/Library/Application Support/AddressBook/Sources/*/AddressBook-v22.abcddb
  • Functional Patterns: All database functions are pure, taking Database as first parameter
  • Error Handling: Try-catch blocks in MCP tool handlers return error messages as text content
  • Pagination: All tools support limit/offset pagination and return hasMore flag for complete data retrieval

MCP Tools

  1. search_messages - Full-text search with date/contact filters
  2. get_recent_messages - Latest messages across all chats
  3. get_chats - List conversations ordered by last activity
  4. get_handles - All contacts/phone numbers
  5. get_messages_from_chat - Messages from specific chat GUID
  6. search_contacts - Search macOS Contacts by name, returns phone/email handles

Important Pagination Note

All tools return paginated results. When performing analysis or summaries, ALWAYS check the hasMore field in the pagination metadata and continue fetching until hasMore is false to ensure complete data.

iMessage Database Schema Notes

  • message table: Core message data
  • handle table: Contact information (phone/email)
  • chat table: Conversation metadata
  • chat_message_join table: Links messages to chats
  • Boolean fields stored as integers (0/1)
  • GUIDs are unique identifiers for messages and chats

Repository Management

  • Always use deno task fmt, deno task lint, and deno task check after modifying or creating code to ensure that it's correct.
  • When making changes to the available tools, ensure you always update the README.md with the relevant changes.
README.md

iMessage MCP

A Deno monorepo containing packages for iMessage access on macOS:

Features

  • Search messages by text content, contact, or date range
  • Get recent messages
  • List all chats/conversations
  • Get all contacts/handles
  • Retrieve messages from specific chats
  • Search macOS Contacts by name with iMessage handle ID correlation

Requirements

  • macOS (iMessage is only available on macOS)
  • Deno 2.x or later
  • Read access to ~/Library/Messages/chat.db
  • Read access to ~/Library/Application Support/AddressBook/ (for contacts search)

Packages

@wyattjoh/imessage

Core library for accessing iMessage data:

deno add @wyattjoh/imessage
import { openMessagesDatabase, searchMessages } from "@wyattjoh/imessage";

const db = await openMessagesDatabase();
const results = await searchMessages(db, { query: "hello" });
db.close();

See full documentation

@wyattjoh/imessage-mcp

MCP server for LLM integration:

# Run directly from JSR
deno run --allow-read --allow-env --allow-sys --allow-ffi jsr:@wyattjoh/imessage-mcp

# Or install globally
deno install --global --allow-read --allow-env --allow-sys --allow-ffi -n imessage-mcp jsr:@wyattjoh/imessage-mcp

For Claude Desktop app integration, add this to your claude_desktop_config.json:

{
  "mcpServers": {
    "imessage": {
      "command": "deno",
      "args": [
        "run",
        "--allow-read",
        "--allow-env",
        "--allow-sys",
        "--allow-ffi",
        "jsr:@wyattjoh/imessage-mcp"
      ]
    }
  }
}

Option 2: From Source

  1. Clone this repository
  2. Install dependencies:
    deno cache src/index.ts
    
  3. Run the server:
    deno run --allow-read --allow-env --allow-sys --allow-ffi src/index.ts
    # Or use the task:
    deno task start
    

Available Tools

  1. search_messages - Search messages with filters

    • query (optional): Text to search for
    • handle (optional): Phone number or email to filter by
    • startDate (optional): ISO datetime string for start date
    • endDate (optional): ISO datetime string for end date
    • limit (optional): Maximum results (1-200, default: 100)
    • offset (optional): Pagination offset (default: 0)
  2. get_recent_messages - Get the most recent messages

    • limit (optional): Number of messages (1-100, default: 20)
    • offset (optional): Pagination offset (default: 0)
  3. get_chats - List all conversations

    • limit (optional): Number of chats (1-200, default: 50)
    • offset (optional): Pagination offset (default: 0)
  4. get_handles - Get all contacts/handles

    • limit (optional): Number of handles (1-200, default: 100)
    • offset (optional): Pagination offset (default: 0)
  5. get_messages_from_chat - Get messages from a specific chat

    • chatGuid (required): The chat GUID
    • limit (optional): Number of messages (1-200, default: 50)
    • offset (optional): Pagination offset (default: 0)
  6. search_contacts - Search macOS Contacts by name and get phone numbers

    • firstName (required): First name to search for (e.g., 'John')
    • lastName (optional): Last name to search for (e.g., 'Smith'). If omitted, searches across all name fields
    • limit (optional): Maximum results (1-200, default: 50)
    • offset (optional): Pagination offset (default: 0)
    • Returns contact info with phone numbers and email addresses that can be used as handle parameters
    • Searches directly in the macOS AddressBook database for better performance and reliability

Pagination Examples

All tools now support pagination using limit and offset parameters and return pagination metadata:

// Get first 20 recent messages
get_recent_messages({ limit: 20, offset: 0 });

// Get next 20 recent messages (page 2)
get_recent_messages({ limit: 20, offset: 20 });

// Get first 10 chats
get_chats({ limit: 10, offset: 0 });

// Get messages 51-100 from a specific chat
get_messages_from_chat({
  chatGuid: "iMessage;-;+15551234",
  limit: 50,
  offset: 50,
});

// Search with pagination
search_messages({
  query: "meeting",
  limit: 100,
  offset: 200,
});

// Search contacts with pagination
search_contacts({
  firstName: "John",
  lastName: "Smith",
  limit: 50,
  offset: 0,
});

Response Format with Pagination Metadata

All paginated tools now return responses in this format:

{
  "data": [
    // Array of results (messages, chats, handles, etc.)
  ],
  "pagination": {
    "total": 1250, // Total number of results available
    "limit": 100, // Current page size
    "offset": 200, // Current offset
    "hasMore": true, // Whether there are more results to fetch
    "page": 3, // Current page number (1-indexed)
    "totalPages": 13 // Total number of pages
  }
}

This metadata helps you:

  • Know the total number of results without fetching all of them
  • Determine if there are more pages to fetch (hasMore)
  • Calculate which page you're on and how many pages exist
  • Build proper pagination UI components

Security Notes

  • This server runs with read-only access to the iMessage database
  • No messages can be sent or modified
  • The server only accesses local data

Development

This is a Deno workspace monorepo. All commands run from the root affect all packages.

# Clone the repository
git clone https://github.com/wyattjoh/imessage-mcp.git
cd imessage-mcp

# Cache dependencies
deno cache packages/*/mod.ts

# Format all code
deno task fmt

# Lint all packages
deno task lint

# Type check all packages
deno task check

# Run tests
deno task test

# Run MCP server locally
cd packages/imessage-mcp
deno run --allow-read --allow-env --allow-sys --allow-ffi mod.ts

# Publish packages (CI/CD)
deno publish

Working on Individual Packages

# Work on @wyattjoh/imessage
cd packages/imessage
deno test --allow-read --allow-env --allow-ffi

# Work on @wyattjoh/imessage-mcp
cd packages/imessage-mcp
deno run --allow-read --allow-env --allow-sys --allow-ffi mod.ts

License

MIT