jons-mcp-imessage
Enables AI assistants to read iMessage history and send messages on macOS. Supports conversation listing, message search with keyword and semantic modes, contact lookup, and sending messages to existing conversations.
README
jons-mcp-imessage
A local MCP server for querying and sending iMessages on macOS.
This FastMCP server exposes tools through the Model Context Protocol (MCP), enabling AI assistants to read your iMessage history and send messages.
Requirements
- macOS (tested on Tahoe 26.x, should work on recent versions)
- Python 3.10+
- Messages.app (for sending messages)
Permissions Required
This server requires specific macOS permissions to function. Permission issues are the most common cause of problems.
Full Disk Access (Required for Reading Messages)
The application running this server needs Full Disk Access to read ~/Library/Messages/chat.db.
To grant Full Disk Access:
- Open System Settings (or System Preferences on older macOS)
- Navigate to Privacy & Security → Full Disk Access
- Click the lock icon and authenticate if needed
- Click the + button
- Add the appropriate application:
- If using Claude Desktop: Add
Claude.app(usually in /Applications) - If running from terminal: Add your terminal app (e.g.,
Terminal.app,iTerm.app,Zed.app) - If running via another app: Add that specific application
- If using Claude Desktop: Add
- Restart the application after granting access
How to verify: Run check_permissions tool - it will report whether database access is working.
Automation Permission (Required for Sending Messages)
To send messages via AppleScript, the application needs permission to control Messages.app.
This permission is prompted automatically the first time you try to send a message. Click "OK" to allow.
To manually grant or verify:
- Open System Settings → Privacy & Security → Automation
- Find your application (Terminal, Claude Desktop, etc.)
- Ensure Messages is checked
Contacts Permission (Optional - For Contact Name Enrichment)
The server can enrich message responses with contact names from your Contacts app. This is optional - all features work without it, but you'll see phone numbers/emails instead of names.
To enable contact name enrichment:
- Open System Settings (or System Preferences on older macOS)
- Navigate to Privacy & Security → Contacts
- Click the lock icon and authenticate if needed
- Click the + button
- Add the appropriate application:
- If using Claude Desktop: Add
Claude.app(usually in /Applications) - If running from terminal: Add your terminal app (e.g.,
Terminal.app,iTerm.app)
- If using Claude Desktop: Add
- Restart the application after granting access
What you get with Contacts permission:
- Message responses include
contact_namefield (e.g., "John Smith" instead of just "+15551234567") - Conversation responses include
participant_namesfield lookup_contacttool becomes available for explicit contact lookups
Without Contacts permission:
- Contact name fields will be
null lookup_contactreturns an error message- All other functionality works normally (graceful degradation)
Installation
# Clone the repository
git clone <your-repo-url>
cd jons-mcp-imessage
# Install with uv
uv pip install -e .
Running the Server
uv run jons-mcp-imessage
Adding to Claude Code
# Register the MCP server with Claude Code
claude mcp add jons-mcp-imessage -- uv run --directory /path/to/jons-mcp-imessage jons-mcp-imessage
Adding to Claude Desktop
Add the following to your Claude Desktop configuration file:
Location: ~/Library/Application Support/Claude/claude_desktop_config.json
{
"mcpServers": {
"jons-mcp-imessage": {
"command": "uv",
"args": [
"run",
"--directory",
"/path/to/jons-mcp-imessage",
"jons-mcp-imessage"
],
"env": {
"OPENAI_API_KEY": "sk-your-openai-api-key"
}
}
}
}
Notes:
- Replace
/path/to/jons-mcp-imessagewith the actual path to this repository - Replace
sk-your-openai-api-keywith your OpenAI API key (required for semantic search) - If you don't have an OpenAI key, omit the
envsection entirely - keyword search will still work - Restart Claude Desktop after modifying the config
Search Features
The search system combines two powerful search methods:
Keyword Search (FTS5)
Full-text search using SQLite FTS5 with BM25 ranking. Supports:
- Phrase search:
"exact phrase" - Prefix matching:
word* - Proximity:
word1 NEAR word2 - Boolean:
word1 AND word2,word1 OR word2,NOT word
Semantic Search
AI-powered search using OpenAI embeddings to find conceptually similar messages, even when exact keywords don't match.
Setup
- Basic Setup (keyword search only): Works out of the box
- Full Setup (hybrid search): Set your OpenAI API key:
export OPENAI_API_KEY=your-api-key
Search Modes
hybrid(default): Combines keyword + semantic results using RRFkeyword: FTS5 only (no API key needed)semantic: Embedding similarity only (requires API key)
Index Management
The search index is stored separately from iMessage's chat.db at:
~/.local/share/jons-mcp-imessage/search_index.db
Tools available:
search_index_status- Check index health and sync statusrebuild_search_index- Full reindex (use if issues occur)
Troubleshooting
| Issue | Solution |
|---|---|
| "No results found" | Check if index is synced with search_index_status |
| Semantic search not working | Verify OPENAI_API_KEY is set |
| Slow first search | Index is building in background, try again shortly |
| Stale results | chat.db may be locked by Messages app |
Available Tools
Reading Messages
| Tool | Description |
|---|---|
check_permissions |
Verify database access and diagnose permission issues |
list_conversations |
List all conversations with metadata (participants, last message, etc.) |
get_conversation_messages |
Get messages from a specific conversation by contact or chat_id |
get_recent_messages |
Get recent messages across all conversations |
get_message_context |
Get messages before/after a specific message in the same thread |
search_messages |
Search messages by text content with optional filters |
search_contacts |
Search for contacts/handles by phone number or email in iMessage database |
lookup_contact |
Look up contact name from Contacts app by phone/email (requires Contacts permission) |
Sending Messages
| Tool | Description |
|---|---|
send_message |
Send a message to an existing conversation |
send_message Limitations
Important: The send_message tool has significant limitations:
-
Existing conversations only: Can only send to contacts you have previously messaged. New contacts require starting a conversation manually in Messages.app first.
-
No delivery confirmation: The tool reports success when the message is handed to Messages.app, but cannot confirm actual delivery. Messages may silently fail if:
- The recipient has blocked you
- The phone number/email is invalid
- Network issues occur
-
Messages.app must be running: If Messages.app is not running, the tool will fail with a "Messages not running" error.
-
Service detection: By default, attempts iMessage first. Use
service="SMS"to force SMS for non-iMessage contacts.
Example Usage
# Check if permissions are configured correctly
check_permissions()
# List your 10 most recent conversations
list_conversations(limit=10)
# Get messages from a specific contact
get_conversation_messages(contact="+15551234567", limit=20)
# Search for messages containing specific text
search_messages(query="dinner plans", sender="+15551234567")
# Get context around a specific message (5 messages before and after)
get_message_context(rowid=12345, before=5, after=5)
# Send a message (to existing conversation only)
send_message(recipient="+15551234567", message="Hello!")
Troubleshooting
"Permission denied" or "Unable to read database"
Cause: Full Disk Access not granted.
Fix: Follow the Full Disk Access instructions above. Make sure to:
- Grant access to the correct application (the one actually running the server)
- Restart the application after granting access
"Messages not running (-600)"
Cause: Messages.app is not running.
Fix: Open Messages.app before sending messages.
"Not allowed to send Apple events (-1743)"
Cause: Automation permission not granted.
Fix:
- Go to System Settings → Privacy & Security → Automation
- Find your application and enable Messages access
- If not listed, try sending a message again to trigger the permission prompt
"Can't get buddy id" or "existing conversations only"
Cause: Trying to message a contact you haven't messaged before.
Fix: Start a conversation with this contact manually in Messages.app first, then try again.
Messages appear empty or "(non-text message)"
Cause: The message contains only attachments (images, videos) or is a system message (like "renamed the group").
Note: This is expected behavior. The server extracts text content only.
Privacy Considerations
This server accesses your local iMessage database and optionally your Contacts database. Be aware that:
- All message history is accessible: The server can read all messages stored locally
- Contact information is exposed: Phone numbers and email addresses are visible
- Attachments are referenced: File paths to attachments (photos, videos) are included
- No cloud access: Only locally-stored messages are accessible (not messages only on iCloud)
Contact Name Privacy
If you grant Contacts permission:
- Contact names come from YOUR Contacts app: The server reads your personal contact list to enrich message responses
- Names are NOT stored: Contact names are resolved at query time and are NOT stored in any database or search index
- Names are cached in-memory only: The server loads all contacts into memory on first use, cache is cleared on restart
- All Contacts databases are read: Includes main Contacts DB plus any per-source databases (iCloud, CardDAV, etc.)
Use appropriate caution when granting AI assistants access to this server.
Development
Setup
# Install with dev dependencies
uv pip install -e ".[dev]"
Running Tests
# Run all tests
uv run pytest
# Run with coverage
uv run pytest --cov=src
# Run a specific test file
uv run pytest tests/test_parser.py
Code Quality
# Type check
uv run mypy src/jons_mcp_imessage
# Format code
uv run black src tests
# Lint code
uv run ruff check src tests
Project Structure
jons-mcp-imessage/
├── src/
│ └── jons_mcp_imessage/
│ ├── __init__.py # Package exports
│ ├── constants.py # Configuration constants
│ ├── exceptions.py # Custom exceptions
│ ├── utils.py # Utility functions
│ ├── server.py # FastMCP server setup
│ ├── db/
│ │ ├── __init__.py # Database module exports
│ │ ├── connection.py # SQLite connection management
│ │ ├── models.py # Pydantic data models
│ │ ├── parser.py # attributedBody binary parser
│ │ └── queries.py # Query helpers and utilities
│ └── tools/
│ ├── __init__.py # Tool exports
│ ├── health.py # Permission checking
│ ├── contacts.py # Contact search
│ ├── conversations.py # Conversation tools
│ ├── messages.py # Message tools
│ └── send.py # Message sending
├── tests/
│ ├── test_parser.py # attributedBody parser tests
│ ├── test_db.py # Database utility tests
│ └── test_send.py # Send tool tests
├── docs/
│ └── IMESSAGE_DATABASE_FORMAT.md # Database format documentation
├── pyproject.toml # Project configuration
├── CLAUDE.md # AI assistant guidance
└── README.md # This file
License
MIT
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。