io.github.cyberpapiii/imessage-max
平台与服务by cyberpapiii
面向 macOS 上 iMessage 的 AI 优化型 MCP server,可读取、搜索并发送消息。
什么是 io.github.cyberpapiii/imessage-max?
面向 macOS 上 iMessage 的 AI 优化型 MCP server,可读取、搜索并发送消息。
README
iMessage Max
A high-performance MCP (Model Context Protocol) server for iMessage that lets AI agents 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 project now ships a single Swift implementation:
- GitHub releases
- Homebrew
- source builds
- Codex plugin metadata
- Claude Desktop MCPB metadata
The old Python package has been retired and removed from the repository.
Everything current lives under swift/.
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 Contact A and I talk about yesterday?"
→ find_chat(participants=["Contact A"]) + get_messages(since="yesterday")
"Show me the exact details for this thread before I reply"
→ get_chat_details(chat_id="chat123")
"Show me photos from the group chat"
→ list_attachments(chat_id="chat123", type="image")
"Find where we discussed the launch timeline"
→ search(query="launch timeline")
Common Agent Workflows
The tools work best when an agent uses them as short workflows instead of isolated one-off calls.
Agents should treat chat_id values like chat123 as internal handles for tool calls and exact sends. When explaining results to a person, use the returned chat name, group name, or participant-derived label instead of saying "Chat 123."
Find the right conversation, then read it
find_chat(participants=["Contact A"])
get_chat_details(chat_id="chat123")
get_messages(chat_id="chat123", since="yesterday", limit=50)
Use this when the person matters more than the exact thread id.
Search first, then zoom in
search(query="launch timeline", limit=10)
get_context(message_id="msg_456", before=5, after=10)
Use this when you know the topic but not where it was discussed.
Check what needs attention
get_unread()
get_active_conversations(hours=24, min_exchanges=2)
Use this to surface unread threads and active conversations after a broad chat-list sweep.
Work with attachments safely
list_attachments(chat_id="chat123", type="image", since="30d")
get_attachment(attachment_id="att123", variant="vision")
Use list_attachments to discover the message where files were shared first. It still returns exact attachment ids and local-availability state before you fetch a file.
Send with exact targeting when it matters
find_chat(participants=["Contact A", "Contact B"])
send(chat_id="chat456", text="Please use the latest draft")
For sensitive sends, prefer resolving the exact chat first and then using chat_id so the message lands in the intended thread.
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
For local development, advanced setup, and the signed install workflow, see:
Client Icon Metadata
iMessage Max ships icons for the main MCP protocol surface and the client packaging surfaces that use their own metadata:
- MCP
2025-11-25initialize responses include PNGserverInfo.icons. - Each tool advertises a compact PNG tool icon.
- Codex plugin metadata lives in
.codex-plugin/plugin.jsonand usesassets/codex/icon.pngplusassets/codex/logo.png. - Claude Desktop / MCPB metadata lives in
mcpb/manifest.jsonand uses PNG assets undermcpb/assets/.
The committed PNG source set is under assets/icons/ at 16x16, 32x32,
64x64, 128x128, 256x256, and 512x512.
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 Your MCP Client
Add imessage-max to your MCP client's server configuration.
Many MCP clients use a JSON structure like this:
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"
}
}
}
If your client uses a different config format, point it at the same binary path.
4. Reconnect Your MCP Client
After saving the config, reconnect or restart your MCP client. The server should appear in the available tools, and you can verify the connection with diagnose.
Tools
find_chat
Find chats by participants, name, or recent content.
find_chat(participants=["Contact A"]) # Find a direct chat
find_chat(participants=["Contact A", "Contact B"]) # Find a group with both
find_chat(name="Project Group") # Find by chat name
find_chat(contains_recent="latest draft") # Find by recent content
get_chat_details
Inspect a known thread without opening the full conversation.
get_chat_details(chat_id="chat123") # Participants, handles, state, last message
get_chat_details(chat_id="chat123", include_shared_summary=false) # Skip recent shared summary
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="Contact A") # 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="draft") # Search all messages
search(query="budget", from_person="Contact A") # From specific person
search(query="launch", 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
Browse shared items grouped by message. Each row includes exact attachment ids for follow-up fetches.
list_attachments(type="image", since="7d")
list_attachments(chat_id="chat123", type="any")
get_unread
Get unread threads or unread messages. Default is summary by chat.
get_unread() # Summary by chat for last 7 days
get_unread(since="24h") # Summary by chat for last 24 hours
get_unread(format="messages") # Row-level unread messages
send
Send a message or file attachment (requires Automation permission for Messages.app).
send(to="Contact A", text="Checking in")
send(chat_id="chat123", text="Please use the latest draft")
send(chat_id="chat123", file_paths=["/path/save-the-date.jpg"])
send(to="Contact A", file_paths=["/path/reference.png"], text="Sharing the file here")
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
Release Checks
For a lightweight pre-release routine, use:
- docs/validation/2026-04-09-release-checklist.md
- docs/validation/2026-03-13-send-manual-validation.md
Additional send note:
reply_tois currently unsupported- Sends execute immediately when the destination is exact; there is no confirmation gate. Ambiguous destinations are refused with
status: "ambiguous". Theconfirmparameter is deprecated and ignored (kept only for compatibility). Authorization happens in the user's conversation with the agent and in the client's tool-approval UI, not server-side.
Send result semantics (text sends are verified post-send against chat.db):
status: "confirmed"means the message row was found in chat.db with no error;verified_message_guidis the evidencestatus: "uncertain"means transport accepted the send but the row was not found within the polling window; follow up withget_messagesstatus: "mismatch"means the message landed in a different chat than intended; do not treat as successstatus: "sent"means verification was unavailable (DB unreadable); transport accepted onlystatus: "pending_confirmation"means Messages accepted an attachment send, but the file transfer 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 - JSON-shaped tools return MCP
structuredContentas well as legacy text content for older clients
Examples:
{"status":"confirmed","verified_message_guid":"...",...}means delivery was verified in chat.db{"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
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. list_attachments includes nested attachment summaries with available: true/false for each file. To download offloaded attachments, open the conversation in Messages.app.
MCP client not loading the server
- Check config file syntax is valid JSON
- Verify the binary path is correct
- Reconnect or fully restart your MCP client
Architecture
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ MCP Client / │◄───►│ iMessage Max │◄───►│ chat.db │
│ Agent │ │ (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)
Advanced Setup
For HTTP mode, local background service setup, development commands, and contributor-focused workflow details, see:
License
MIT
常见问题
io.github.cyberpapiii/imessage-max 是什么?
面向 macOS 上 iMessage 的 AI 优化型 MCP server,可读取、搜索并发送消息。
相关 Skills
Slack动图
by anthropics
面向Slack的动图制作Skill,内置emoji/消息GIF的尺寸、帧率和色彩约束、校验与优化流程,适合把创意或上传图片快速做成可直接发送的Slack动画。
✎ 帮你快速做出适配 Slack 的动图,内置约束规则和校验工具,少踩上传与播放坑,做表情包和演示都更省心。
MCP构建
by anthropics
聚焦高质量 MCP Server 开发,覆盖协议研究、工具设计、错误处理与传输选型,适合用 FastMCP 或 MCP SDK 对接外部 API、封装服务能力。
✎ 想让 LLM 稳定调用外部 API,就用 MCP构建:从 Python 到 Node 都有成熟指引,帮你更快做出高质量 MCP 服务器。
接口测试套件
by alirezarezvani
扫描 Next.js、Express、FastAPI、Django REST 的 API 路由,自动生成覆盖鉴权、参数校验、错误码、分页、上传与限流场景的 Vitest 或 Pytest 测试套件。
✎ 帮你把API与集成测试自动化跑顺,减少回归漏测;能力全面,尤其适合复杂接口场景的QA团队。
相关 MCP Server
Slack 消息
编辑精选by Anthropic
Slack 是让 AI 助手直接读写你的 Slack 频道和消息的 MCP 服务器。
✎ 这个服务器解决了团队协作中需要 AI 实时获取 Slack 信息的痛点,特别适合开发团队让 Claude 帮忙汇总频道讨论或发送通知。不过,它目前只是参考实现,文档有限,不建议在生产环境直接使用——更适合开发者学习 MCP 如何集成第三方服务。
by netdata
io.github.netdata/mcp-server 是让 AI 助手实时监控服务器指标和日志的 MCP 服务器。
✎ 这个工具解决了运维人员需要手动检查系统状态的痛点,最适合 DevOps 团队让 Claude 自动分析性能数据。不过,它依赖 NetData 的现有部署,如果你没用过这个监控平台,得先花时间配置。
by d4vinci
Scrapling MCP Server 是专为现代网页设计的智能爬虫工具,支持绕过 Cloudflare 等反爬机制。
✎ 这个工具解决了爬取动态网页和反爬网站时的头疼问题,特别适合需要批量采集电商价格或新闻数据的开发者。不过,它依赖外部浏览器引擎,资源消耗较大,不适合轻量级任务。