multimodal-imessage-mcp
This MCP server lets an agent read, search, and send iMessages/SMS/RCS on a Mac, including viewing attachments and confirmation-gated sending.
Read recent messages across conversations, optionally including group chats.
Search messages by contact name, phone number, or message content.
Fetch full conversations by contact/phone or chat ID, optionally time-limited.
List recent chats or structured chat metadata: handles, last sender, preview, group status, counts.
Find SMS outreach follow-ups with status, risk labels, and evidence snippets.
Look up contact phone numbers/emails from macOS Contacts.
List delivery failures and SMS/RCS recovery status.
Get message attachments, returning images as viewable content and converting HEIC to JPEG.
Recommend iMessage, SMS/RCS, or auto before sending based on local history.
Send messages or tapbacks only with explicit confirmation; batches require preview and approval token.
Optional release flags add database deletion tools and experimental Messages UI edit/undo/cleanup actions.
Allows reading, searching, and sending iMessages, viewing attachments (including HEIC to JPEG conversion), managing contacts, and reacting to messages on macOS.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@multimodal-imessage-mcp Show me my latest messages"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
You: What did Mom text me today?
Agent: (calls get_conversation with contact "Mom", last 24 hours)
Mom, 9:14 AM: Are you still coming Sunday?
Mom, 9:15 AM: [attachment: IMG_2041.HEIC]
You: Show me the photo.
Agent: (calls get_attachment, converts HEIC to JPEG, looks at the image)
It is a photo of a garden with a new fence.This server reads the Messages database on your Mac (~/Library/Messages/chat.db) and exposes it to MCP clients such as Claude Code, Codex and Claude Desktop. It is for people who want an agent to help with their texts: catch up on a thread, search for a flight confirmation, review which prospects replied, or draft and send a reply after you approve it.
It exists because other iMessage tools only read the text column of chat.db. On macOS 14 and later most messages live in the attributedBody column instead, so those tools return empty or partial threads. This server decodes attributedBody and returns the full message text.
Features
Complete message text. Decodes Apple's
NSAttributedStringblob so modern messages are not dropped. See How it works.Photos the agent can see.
get_attachmentreturns images as image content. HEIC photos are converted to JPEG with macOSsips.Name lookup. Contact names resolve through the local AddressBook databases. The Contacts app does not need to be running.
Send behind a confirmation.
send_message,send_message_batchandreact_to_messagedo nothing unlessconfirmistrue. Batches also need an approval token from a preview call.iMessage and SMS/RCS. Choose a service, or let
autopick one. An opt-in flag retries by SMS/RCS when a blue bubble fails.Outreach helpers. Structured chat lists, follow-up detection and delivery-failure reports.
Dangerous tools stay off by default. Deleting and UI-driven editing are behind release flags.
Related MCP server: jons-mcp-imessage
Install
Requirements:
A Mac with the Messages app signed in.
Node.js 18 or newer and older than 26 (
enginesinpackage.json). Node 24 LTS is recommended: the locked native SQLite dependency (better-sqlite3) does not build on Node 26.A terminal or app with the macOS permissions below.
The package is not on npm. Install from source:
git clone https://github.com/tszaks/imessage-mcp.git
cd imessage-mcp
npm install
node index.js # prints "iMessage MCP server v... running on stdio", then waits for an MCP clientPress Ctrl-C to stop it. Normally your MCP client starts it for you.
Client configuration
Replace /path/to/imessage-mcp with the folder you cloned, and use the full path to a supported Node (find it with which node; Homebrew on Apple silicon is usually /opt/homebrew/bin/node). Desktop apps do not inherit your shell PATH, and a bare node can pick an older system Node that crashes the native module.
Claude Code
claude mcp add imessage -- /opt/homebrew/bin/node /path/to/imessage-mcp/index.jsOr add this to a project .mcp.json:
{
"mcpServers": {
"imessage": {
"command": "node",
"args": ["/path/to/imessage-mcp/index.js"]
}
}
}Codex
Add to ~/.codex/config.toml:
[mcp_servers.imessage]
command = "/opt/homebrew/bin/node"
args = ["/path/to/imessage-mcp/index.js"]Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"imessage": {
"command": "/opt/homebrew/bin/node",
"args": ["/path/to/imessage-mcp/index.js"]
}
}
}Restart the client after editing. Grant permissions to the app that launches the server (the client or its terminal), not to Node itself.
Tools
The server registers these tools (from index.js). Tools marked with a flag appear only when that release flag is set in IMESSAGE_MCP_RELEASES.
Tool | What it does |
| Read the latest messages across all conversations |
| Search by contact name, phone number or message text |
| Get a thread with a contact or number, optionally limited to the last N hours |
| List recent chats as JSON: chat ID, handles, last sender, preview, group status, counts |
| Get a thread as structured JSON by chat ID |
| Find SMS outreach threads that need review or follow-up, with risk labels |
| Return the image or file attached to a message (images are viewable, HEIC converted) |
| Send an iMessage or SMS/RCS. Requires |
| Recommend iMessage, SMS/RCS or auto for a recipient from local history (best effort) |
| Preview a batch, then send it with |
| List failed or pending outgoing messages and SMS/RCS recoveries |
| List recent conversations by activity |
| Find a phone number or email by contact name |
| Send a tapback (love, like, dislike, laugh, emphasize, question). Requires |
| Delete exact message rows from the local database, with a backup first. Flag: |
| Preview and delete whole local threads with an approval token. Flag: |
| Experimental: edit a recent outgoing iMessage through the Messages UI. Flag: |
| Experimental: undo send through the Messages UI. Flag: |
The read_receipts flag adds read-receipt fields to existing results instead of adding a tool.
Usage
Example prompts:
"Show me my recent messages."
"Search my messages for 'flight confirmation'."
"Find outreach prospects from the last 7 days who replied and need follow-up."
"Preview this batch of 10 follow-up texts." (returns exact recipients, messages, warnings and an approval token before anything sends)
"Show recent delivery failures."
"Show me the photo from message 538516."
"Send 'Running 10 min late' to +1234567890." (the agent must show you the message first, then pass
confirm: true)
Release flags
Release flags are opt-in through the MCP server environment:
{
"mcpServers": {
"imessage": {
"command": "node",
"args": ["/path/to/imessage-mcp/index.js"],
"env": {
"IMESSAGE_MCP_RELEASES": "auto_sms_fallback,cleanup_failed_imessage_after_sms_fallback,message_mutation_tools,experimental_message_ui_actions,read_receipts"
}
}
}
}Flag | Behavior |
|
|
| After |
| Exposes |
| Exposes |
| Adds read receipt fields to structured conversation results and read status hints to |
Mutation tools
delete_messages accepts exact message ROWIDs:
{ "message_ids": ["538516", "538517"] }It does not require confirmation. It reports deleted IDs, missing IDs, backup location, and any remaining rows found during verification.
delete_threads is a two-step exact-batch flow:
{ "chat_ids": [101, 102] }The preview returns one approval_token for that ordered list and the thread metadata shown in the preview. To delete, send the same ordered chat_ids, confirm: true, and that token:
{ "chat_ids": [101, 102], "confirm": true, "approval_token": "..." }Changing the order, list, or token fails the request.
edit_message and undo_send_message are experimental because Messages does not expose first-class AppleScript commands for those actions. They open the conversation, find the visible outgoing bubble by text snippet, use the contextual menu, then verify the result. They are intended to affect actual Messages behavior, not fake local-only DB edits.
Optional tuning:
IMESSAGE_MCP_SEND_VERIFY_DELAY_MS=2500This controls how long the MCP waits before checking the local Messages database for the new outgoing row.
Permissions and privacy
This server can read your whole message history and contacts, and send messages as you. Run it only with agents and clients you trust.
What it reads (locally)
~/Library/Messages/chat.db: all messages, handles, chats and attachment metadata. The database is opened read-only except for the two mutation tools.~/Library/Messages/Attachments/: files you ask for withget_attachment.~/Library/Application Support/AddressBook/Sources/*/AddressBook-v22.abcddb: contact names, numbers and emails, read-only, cached in memory.
What it can change
Send messages and tapbacks through AppleScript, only with
confirm: true.With
message_mutation_tools: delete rows inchat.db. A timestamped backup ofchat.db,chat.db-walandchat.db-shmgoes to~/Library/Messages/mcp-backups/first.With
experimental_message_ui_actionsorcleanup_failed_imessage_after_sms_fallback: it opens Messages and clicks through its menus.HEIC conversion writes a temporary JPEG to
/tmp.
What it sends
The server makes no network requests of its own and has no analytics. Message text and images you ask for are returned to your MCP client, and from there to whatever model that client uses. Check your client's and model provider's privacy terms. Messages you send go out through the Messages app like any other message.
macOS permissions you must grant
Permission | Where | Needed for |
Full Disk Access | System Settings > Privacy & Security > Full Disk Access | Reading |
Automation | Prompted on first use (System Settings > Privacy & Security > Automation) |
|
Accessibility | System Settings > Privacy & Security > Accessibility | Only for |
Reading needs only Full Disk Access. Sending needs Automation as well.
How it works
The attributedBody Fix
Apple's iMessage database (~/Library/Messages/chat.db) has two columns for message content:
text: the legacy plain text column (used by older macOS versions)attributedBody: a serializedNSAttributedStringblob (used by macOS 14+)
On modern macOS, Apple gradually migrated message storage to attributedBody to support rich text, mentions, and formatting. The text column is increasingly just a legacy fallback that's often NULL.
This server detects messages with NULL text and extracts the content from attributedBody by parsing the binary NSTypedStream format:
Finds the
NSStringmarker in the binary blobReads past the type header bytes (
01 94 84 01 2b)Decodes the length prefix (single-byte for short messages, multi-byte for longer ones)
Extracts the UTF-8 text payload
Attachment Handling
iMessage attachments are stored in ~/Library/Messages/Attachments/ with paths tracked in the attachment table. The get_attachment tool:
Queries the attachment metadata for a given message ID
Resolves the
~/Library/Messages/...path to an absolute pathFor JPEG/PNG/GIF/WebP: reads the file and returns base64 image content
For HEIC (iPhone default): converts to JPEG using macOS
sipsbefore returningFor other files: returns metadata and the file path
FAQ
Can an agent send a message without asking me?
Not through the confirmation tools. send_message, send_message_batch and react_to_message refuse unless confirm is true, and batches also need the approval token from a preview. The agent still decides when to call them, so keep tool approval on in your client. delete_messages needs no confirmation when its flag is enabled.
Does my data leave my Mac? The server itself sends nothing anywhere. Anything a tool returns goes to your MCP client and its model provider.
Troubleshooting
"Failed to open iMessage database" Grant Full Disk Access to the terminal or app that launches the server: System Settings > Privacy & Security > Full Disk Access.
Contact lookup returns no results Contact resolution reads the macOS AddressBook SQLite databases directly (no Contacts app needed). Make sure Full Disk Access is granted. If a contact was just added, restart the MCP server to refresh the cache.
Native module crash / "NODE_MODULE_VERSION mismatch"
Rebuild native dependencies: npm rebuild. This happens when your Node.js version changes. Also make sure your Claude Desktop config uses the full path to node (see Client configuration).
Missing messages from a conversation
This is exactly the bug this server fixes. Make sure you're running the latest version which includes the attributedBody extraction.
Contributing
See CONTRIBUTING.md. Security reports go through SECURITY.md. This project follows the Code of Conduct. Changes are listed in CHANGELOG.md, and coding agents should read AGENTS.md.
License
Available Tools
14 toolsdetect_message_serviceA
Inspect local Messages history for a recipient and recommend iMessage, SMS/RCS, or auto before sending. This is best-effort because Apple does not expose a direct preflight availability API.
Inputs: to (required), limit.
find_outreach_followupsA
Find SMS outreach conversations that need agent review or follow-up. Returns structured candidates with status, risk labels, and evidence snippets.
Inputs: limit, hours_ago, max_results, outreach_terms.
get_attachmentA
Get an attachment (image, file) from a message. Returns images directly so Claude can view and analyze them. Use message IDs from get_conversation results.
Inputs: message_id (required).
get_conversationA
Get full conversation thread with a specific contact or phone number, optionally filtered by time. Shows text content and indicates attachments.
Inputs: limit, contact, hours_ago, phone_number.
get_conversation_by_chat_idA
Get a conversation by iMessage chat_id as structured JSON. Use chat_id from list_chats_structured or find_outreach_followups.
Inputs: chat_id (required), limit, hours_ago.
list_chats_structuredB
List recent chats as structured JSON with chat IDs, handles, last sender, last message preview, group status, and message counts.
Inputs: limit, hours_ago.
list_delivery_failuresA
List recent outgoing messages that Messages marked failed, pending, or potentially recovered by SMS/RCS fallback. Use this to find red Not Delivered bubbles.
Inputs: limit, hours_ago, include_pending.
list_recent_chatsB
List recent active conversations, sorted by most recent activity
Inputs: limit, hours_ago.
lookup_contactA
Look up a contact name in macOS Contacts to find their phone number or email
Inputs: name (required).
react_to_messageA
React to a message with an emoji (❤️, 👍, 👎, 😂, ‼️, ❓). IMPORTANT: Always show the user which message and reaction before sending, and get explicit confirmation.
Inputs: confirm (required), reaction (required), message_id (required).
read_recent_messagesB
Read recent iMessages from your Messages app
Inputs: limit, include_group_chats.
search_messagesA
Search for messages by contact name, phone number, or message content
Inputs: query (required), limit.
send_messageA
Send an iMessage or SMS/RCS to a contact (uses AppleScript). Supports iMessage (blue bubble), SMS/RCS (green bubble), or auto-detection with verified fallback when the auto_sms_fallback release flag is enabled. IMPORTANT: Always show the user the message content and recipient before sending, and get explicit confirmation.
Inputs: to (required), confirm (required), message (required), service.
send_message_batchA
Preview or send a reviewed SMS/iMessage batch. Preview returns an approval token. Sending requires the same exact batch, confirm=true, and the token.
Inputs: items (required), confirm, service, approval_token.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 14 tools
Several tools overlap significantly: read_recent_messages, list_chats_structured, and list_recent_chats all list conversations with varying formats. get_conversation and get_conversation_by_chat_id retrieve threads but differ only in ID type, which could confuse agents. send_message and send_message_batch have overlapping purposes (sending messages) with subtle differences in batching.
Most tools follow a verb_noun pattern (read_recent_messages, search_messages, send_message, list_delivery_failures), but there are inconsistencies: get_conversation vs get_conversation_by_chat_id (one is specific, one generic), and list_chats_structured vs list_recent_chats (both list chats but with different modifiers). The style is consistent snake_case, but the verbs (read, search, get, list, send, detect, find, lookup, react) vary without a clear hierarchy.
14 tools is within the well-scoped range for a messaging server. The count is slightly high but justified by the need to handle message reading, searching, sending, attachments, and delivery status. Each tool serves a distinct function (though some overlap), so the count is reasonable.
The server covers core iMessage workflows: listing, searching, reading conversations, sending (including batch), reactions, attachments, and delivery failures. However, it lacks obvious lifecycle operations like deleting messages, marking as read/unread, or editing sent messages. There's also no tool to create a new conversation with a new contact, only sending to existing/known contacts. These gaps are not fatal as most agents would work around them, but they are notable for a comprehensive messaging tool.
Maintenance
Related MCP Connectors
Send and read iMessages from your own Mac and Apple ID — drafts, history and contacts.
Send and receive iMessage, SMS, RCS, and WhatsApp, and manage contacts, chats, and numbers.
MCP connector for iMessage & Contacts via a local Mac agent + Vercel relay
Explore your Messages SQLite database to browse tables and inspect schemas with ease. Run flexible…
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables reading, searching, and sending iMessages directly from MCP-compatible clients by accessing the local macOS iMessage database, supporting conversations, attachments, and both individual and group chats.674 npm10MIT
- AlicenseAqualityDmaintenanceEnables 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.1311MIT
- FlicenseAqualityDmaintenanceEnables reading, searching, and sending iMessages on macOS by accessing the local messages database and utilizing AppleScript. Users can list conversations, search message history, and send messages to individuals or group chats directly through the Model Context Protocol.6-
- AlicenseNot gradedqualityDmaintenanceEnables reading, sending, and managing iMessage conversations on macOS through MCP.1MIT