About io.github.cyberpapiii/imessage-max
io.github.cyberpapiii/imessage-max is an MCP server in the Search category: aI-optimized MCP server for iMessage on macOS. Read, search, and send messages.
Install
uvx imessage-maxpip install imessage-maxThis server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.
Ask AI
Ask AI about io.github.cyberpapiii/imessage-max
Powered by Claude · Grounded in docs
Security checks
- ✓README presentThe repository ships documentation.
5 checks have not been run yet.
README
iMessage Max
A high-performance MCP (Model Context Protocol) server for iMessage that lets AI assistants read, search, and send your messages with proper contact resolution.
Built in Swift for native macOS integration - single binary, no runtime dependencies.
Distribution Status
The Swift binary is the primary supported distribution for current releases:
- GitHub releases
- Homebrew tap
- local signed
make installworkflow
The Python package remains in the repository as a legacy/secondary path and should not be assumed to have feature parity with the Swift implementation.
Features
- 12 Intent-Aligned Tools - Work the way you naturally ask questions, not raw database queries
- Contact Resolution - See names instead of phone numbers via macOS Contacts
- Smart Image Handling - Efficient image variants (vision/thumb/full) to avoid token bloat
- Session Grouping - Messages grouped into conversation sessions with gap detection
- Attachment Tracking - Know which images are available locally vs offloaded to iCloud
- Native Performance - Swift with raw SQLite3, Core Image GPU acceleration
- Read-Only Safe - Only reads from chat.db, send requires explicit permission
Why This Exists
Most iMessage tools expose raw database structures, requiring 3-5 tool calls per user intent. This MCP provides intent-aligned tools:
"What did Nick and I talk about yesterday?"
→ find_chat(participants=["Nick"]) + get_messages(since="yesterday")
"Show me photos from the group chat"
→ list_attachments(chat_id="chat123", type="image")
"Find where we discussed the trip"
→ search(query="trip")
Installation
Homebrew (Recommended)
brew tap cyberpapiii/tap
brew install imessage-max
From Source
git clone https://github.com/cyberpapiii/imessage-max.git
cd imessage-max/swift
swift build -c release
# Binary is at .build/release/imessage-max
Stable Dev Install Workflow
For local development, use the built-in make workflow in swift/ instead of
manually rebuilding and re-granting permissions:
cd swift
make setup-signing # one-time: create persistent signing identity
make install # build, sign, restart launchd service, verify health
Why this matters:
- it signs the binary with a persistent local identity so Full Disk Access can persist across rebuilds
- it replaces the release binary in place
- it restarts the launchd-managed
local.imessage-maxservice on port8080 - it verifies the service is healthy after install
Useful commands:
cd swift
make status # show process, signature, version, health
make restart # restart the launchd service
make logs # tail the stderr log
make clean # remove debug artifacts and clear logs
Setup
1. Grant Full Disk Access
Required to read ~/Library/Messages/chat.db:
- Open System Settings → Privacy & Security → Full Disk Access
- Click + to add the binary
For Homebrew installs: The binary is at /opt/homebrew/Cellar/imessage-max/VERSION/bin/imessage-max (not the symlink at /opt/homebrew/bin/). Find it with:
# Open the folder containing the actual binary
open $(dirname $(readlink -f $(which imessage-max)))
For source builds: Add .build/release/imessage-max from your clone directory.
Tip: In the file picker, press ⌘+Shift+G and paste the path to navigate directly.
2. Grant Contacts Access
Required for resolving phone numbers to names. The app will request access on first run, or add manually:
System Settings → Privacy & Security → Contacts → add imessage-max
3. Configure Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
For Homebrew:
{
"mcpServers": {
"imessage": {
"command": "/opt/homebrew/Cellar/imessage-max/VERSION/bin/imessage-max"
}
}
}
For source builds:
{
"mcpServers": {
"imessage": {
"command": "/path/to/imessage-max/swift/.build/release/imessage-max"
}
}
}
4. Restart Claude Desktop
The MCP should now appear in Claude's tools. You can verify with the diagnose tool.
Launchd Service
If you are running iMessage Max as a background HTTP service, the intended development path is the launchd-managed binary at:
~/Library/LaunchAgents/local.imessage-max.plist
That plist should point at:
/Users/YOU/.../imessage-max/swift/.build/release/imessage-max --http --port 8080
The make install workflow updates that binary in place and restarts the
service cleanly.
Tools
find_chat
Find chats by participants, name, or recent content.
find_chat(participants=["Nick"]) # Find DM with Nick
find_chat(participants=["Nick", "Andrew"]) # Find group with both
find_chat(name="Family") # Find by chat name
find_chat(contains_recent="dinner plans") # Find by recent content
get_messages
Retrieve messages with flexible filtering. Returns metadata for media.
get_messages(chat_id="chat123", limit=50) # Recent messages
get_messages(chat_id="chat123", since="24h") # Last 24 hours
get_messages(chat_id="chat123", from_person="Nick") # From specific person
get_attachment
Retrieve image content by attachment ID with resolution variants.
get_attachment(attachment_id="att123") # Default: vision (1568px)
get_attachment(attachment_id="att123", variant="thumb") # Quick preview (400px)
get_attachment(attachment_id="att123", variant="full") # Original resolution
| Variant | Resolution | Use Case | Token Cost |
|---|---|---|---|
vision (default) |
1568px | AI analysis, OCR | ~1,600 tokens |
thumb |
400px | Quick preview | ~200 tokens |
full |
Original | Maximum detail | Varies |
list_chats
Browse recent chats with previews.
list_chats(limit=20) # Recent chats
list_chats(is_group=True) # Only group chats
list_chats(since="7d") # Active in last week
search
Full-text search across messages.
search(query="dinner") # Search all messages
search(query="meeting", from_person="Nick") # From specific person
search(query="party", is_group=True) # Only in group chats
get_context
Get messages surrounding a specific message.
get_context(message_id="msg_123", before=5, after=10)
get_active_conversations
Find chats with recent back-and-forth activity.
get_active_conversations(hours=24)
get_active_conversations(is_group=True, min_exchanges=3)
list_attachments
List attachments with metadata. Includes available field showing if file is on disk.
list_attachments(type="image", since="7d")
list_attachments(chat_id="chat123", type="any")
get_unread
Get unread messages or summary.
get_unread() # Unread from last 7 days
get_unread(since="24h") # Last 24 hours
get_unread(mode="summary") # Summary by chat
send
Send a message or file attachment (requires Automation permission for Messages.app).
send(to="Nick", text="Hey!")
send(chat_id="chat123", text="Running late")
send(chat_id="chat123", file_paths=["/path/save-the-date.jpg"])
send(to="Nick", file_paths=["/path/invite.png"], text="Save the date")
Rules:
- Exactly one of
toorchat_id - At least one of
textorfile_paths - If both are provided, files are sent first and text is sent last
reply_tois currently unsupported
Send result semantics:
status: "sent"means the message or attachment was confirmed successfullystatus: "pending_confirmation"means Messages accepted an attachment send, but it was not confirmed as finished within the polling windowstatus: "failed"means the send failedstatus: "ambiguous"means the target could not be resolved safely
Notes:
pending_confirmationis a normal non-fatal attachment state, not the same as a hard failure- exact chat sends target the existing conversation identified by
chat_id
Examples:
{"status":"sent","success":true,...}means delivery was confirmed within the polling window{"status":"pending_confirmation","success":false,...}means Messages accepted the attachment, but the MCP could not yet confirm final completion
diagnose
Troubleshoot configuration and permission issues.
diagnose() # Returns: database status, contacts count, permissions, capabilities
HTTP Mode
For MCP Router, MCP Inspector, or other HTTP-based integrations:
imessage-max --http --port 8080
Running as a Service (Recommended)
Create a launchd plist at ~/Library/LaunchAgents/local.imessage-max.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>local.imessage-max</string>
<key>ProgramArguments</key>
<array>
<string>/path/to/imessage-max</string>
<string>--http</string>
<string>--port</string>
<string>8080</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/Users/YOU/Library/Logs/imessage-max.stdout.log</string>
<key>StandardErrorPath</key>
<string>/Users/YOU/Library/Logs/imessage-max.stderr.log</string>
</dict>
</plist>
Then load it:
launchctl load ~/Library/LaunchAgents/local.imessage-max.plist
MCP Router Integration
Add to MCP Router as a remote-streamable server:
INSERT INTO servers (id, name, server_type, remote_url, auto_start, disabled, created_at, updated_at)
VALUES ('imessage', 'imessage', 'remote-streamable', 'http://127.0.0.1:8080', 1, 0, strftime('%s','now'), strftime('%s','now'));
Session Management
The HTTP transport supports clean reconnection:
- Each client connection gets its own isolated session
- Sessions auto-expire after 1 hour of inactivity
- If MCP Router disconnects, it can reconnect seamlessly with a fresh session
- No "Server already initialized" errors on reconnection
Troubleshooting
Contacts showing as phone numbers
Run diagnose to check status. If contacts_authorized is false:
- Add the
imessage-maxbinary to System Settings → Privacy & Security → Contacts
"Database not found" error
Add the imessage-max binary to System Settings → Privacy & Security → Full Disk Access
Images show "attachment_offloaded" error
Some attachments are stored in iCloud, not on disk. The list_attachments tool shows available: true/false for each attachment. To download offloaded attachments, open the conversation in Messages.app.
MCP not loading in Claude Desktop
- Check config file syntax is valid JSON
- Verify the binary path is correct
- Restart Claude Desktop completely (Cmd+Q)
Architecture
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Claude/AI │◄───►│ iMessage Max │◄───►│ chat.db │
│ Assistant │ │ (Swift MCP) │ │ (SQLite) │
└─────────────────┘ └────────┬────────┘ └─────────────────┘
│
▼
┌─────────────────┐
│ Contacts.app │
│ (CNContactStore)│
└─────────────────┘
Requirements
- macOS 13+ (Ventura or later)
- Full Disk Access permission
- Contacts permission (for name resolution)
- Automation permission for Messages.app (send only)
Development
cd swift
swift build # Debug build
swift build -c release # Release build
swift test # Run tests
License
MIT
README copy captured when this server was indexed; it may lag the repository. The original is authoritative.