imessage-mcp
Provides tools to read macOS Messages history, list chats, read threads with sender names and reactions, search message bodies, see new messages across chats, and optionally send messages through Messages.app.
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., "@imessage-mcpsearch my iMessage history for mentions of 'apartment'"
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.
imessage-mcp
A local MCP (Model Context Protocol) server that lets Claude Code read your macOS Messages history directly, so you stop copy-pasting text threads into chat by hand.
It reads ~/Library/Messages/chat.db and your local Contacts database
directly with Python's stdlib sqlite3. There are no native dependencies and
nothing leaves your Mac: every tool is a local, read-only SQL query plus a
small typedstream decoder for the message bodies that Messages stores as
binary blobs.
What it gives Claude
list_chats(query, limit): recent chats, with names resolved from Contacts.read_thread(chat, since, limit): a thread in order, with sender names, attachment paths, and tapback reactions folded into the message they landed on.search(text, chat, since, limit): full text search over decoded message bodies.whats_new(mark_seen): everything new across every chat since the last call, using a small cursor file at~/.imessage-mcp/cursor.json.send(chat, text): sends a message through Messages.app. Disabled unless you explicitly turn it on, see "Sending" below.
Related MCP server: iMessage MCP Server
Requirements
macOS with Messages.app signed in and syncing.
Full Disk Access granted to whatever process runs this server (your terminal, or Claude Code itself, depending on how you launch it). Without it,
~/Library/Messages/chat.dbwill fail to open even in read-only mode. Grant it under System Settings, Privacy and Security, Full Disk Access.Python 3.12 or newer, managed with
uv.
Install
cd /Users/clint/Projects/imessage-mcp
uv syncRegister with Claude Code
claude mcp add --scope user imessage -- uv run --directory /Users/clint/Projects/imessage-mcp python -m imessage_mcp.serverThat registers the server once, for every project, over stdio.
Sending is off by default
send(chat, text) only works when the server process has the environment
variable IMESSAGE_SEND=1 set. Without it, the tool returns a plain message
saying sending is disabled, and does nothing else.
When enabled, sending goes through osascript and Messages.app:
a one on one chat sends with
send text to buddy handle of (service 1 whose service type is iMessage).a group chat sends with
send text to chat id "<guid>".
The first send will prompt macOS for Automation permission for whatever
process is driving Messages.app. Treat this as a real send: nothing here
double checks with you before the message goes out, so only turn
IMESSAGE_SEND on in a session where you are prepared to review the exact
text before asking the tool to send it.
Privacy
Everything runs locally. The server opens chat.db and your Contacts
database read only (sqlite3 URI mode=ro), decodes text and attachment
paths in process, and returns plain text to Claude. Nothing is uploaded
anywhere, and no network calls happen anywhere in this codebase.
Tests
uv run pytestThe tests read your live chat.db and Contacts database and skip themselves
cleanly if either is unreadable (for example, no Full Disk Access, or run on
a machine with no Messages history).
Layout
imessage_mcp/typedstream.py: decodes theattributedBodyblob that Messages uses instead of plaintextfor most rows.imessage_mcp/db.py: all the read only SQL againstchat.dband Contacts.imessage_mcp/server.py: the FastMCP server and tool definitions.tests/: pytest tests against the live database.
Available Tools
5 toolslist_chatsA
List recent iMessage/SMS chats, optionally filtered by a case insensitive substring match against the chat name, contact names, or chat identifier. Returns one line per chat with ROWID, name, last message time, and message count.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the behavioral disclosure burden. It discloses that the operation is a read-style listing, that matching is case-insensitive, and that output is one line per chat with specific fields (ROWID, name, last message time, message count). It does not mention ordering or pagination, but the core behavior is transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two tightly written sentences. It front-loads the core purpose, then adds filtering behavior and return format without any filler or redundant schema restatement.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has only two optional parameters and an output schema, the description covers the important behavioral choices: listing, optional filtering, case-insensitivity, and returned fields. It is slightly incomplete only in not elaborating on what 'recent' means or how 'limit' affects the result, but these are minor given the schema defaults and output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema itself contains no parameter descriptions (0% coverage), so the description must compensate. It does well for 'query' by explaining case-insensitive substring matching against chat name, contact names, or chat identifier, but it provides no semantics for 'limit' beyond what the parameter name and default already imply.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('List') with a clear resource ('recent iMessage/SMS chats') and details optional filtering by substring against chat name, contact names, or identifier. It also specifies the output shape, making the tool's purpose immediately unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies when to use the tool: when you need a recent chat list, optionally narrowed by a text query. It does not explicitly contrast with sibling tools like search or read_thread, but the listing behavior is stated well enough that an agent would rarely confuse it with those tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_threadA
Read messages from one chat, in date order.
chat accepts a chat ROWID, a chat guid/chat_identifier, or a case
insensitive substring of a contact/display name. If the name is
ambiguous, this returns a list of candidate chats instead of messages.
since is an optional "YYYY-MM-DD" or "YYYY-MM-DD HH:MM" local time
filter. limit caps how many of the most recent matching messages come
back (still returned oldest first).
| Name | Required | Description | Default |
|---|---|---|---|
| chat | Yes | ||
| limit | No | ||
| since | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden and does so well: it discloses chat identifier/name/substring forms, ambiguous-name candidate-list behavior, the date-time format for since, and the limit/ordering nuance. It omits edge cases like no-match handling, but still conveys substantial non-obvious behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and well-structured: purpose first, then each parameter's semantics in turn. Every sentence adds distinct value without repeating schema defaults or titles.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a three-parameter read-only tool with an output schema available, the description covers the main callability concerns: chat resolution, time filtering, and limits/ordering. Minor gaps such as no-match behavior or the default of since do not prevent correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description fully compensates by explaining exactly what chat accepts, what since means and its accepted formats, and how limit affects result selection and ordering. This is the semantic information an agent needs beyond the raw parameter names.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific action ('Read messages from one chat') with a clear resource, scope, and ordering guarantee. The one-chat focus clearly separates it from sibling tools like list_chats, search, and send.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use this tool: reading a single chat's messages in date order. It doesn't explicitly name alternatives or exclusion conditions, so it stops short of full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
searchA
Search decoded message bodies for a substring (case insensitive).
Optionally restrict to one chat (same matching rules as read_thread) and
to messages on or after since ("YYYY-MM-DD" or "YYYY-MM-DD HH:MM").
| Name | Required | Description | Default |
|---|---|---|---|
| chat | No | ||
| text | Yes | ||
| limit | No | ||
| since | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the behavioral burden. It discloses meaningful behavior: search targets decoded bodies, matching is case-insensitive, and the since parameter accepts specific date/time formats. It does not explicitly state read-only status or pagination behavior, but 'search' implies non-mutating and the output schema covers return shape.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded with the core action. The second sentence adds only useful optional-filter details, with no filler or repetition of schema information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 4-parameter tool with an output schema, the description covers the required text parameter and the non-trivial optional filters, including accepted date formats. The one unmentioned parameter, limit, is adequately defined in the schema with its name and default, so an agent has enough information to invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It adds real semantics for text (case-insensitive substring), chat (optional restriction with matching rules aligned to read_thread), and since (on-or-after with two accepted formats). The limit parameter is not mentioned, but its schema title and default value of 50 make it self-explanatory.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Search decoded message bodies for a substring (case insensitive).' It also references read_thread for chat matching rules, which helps differentiate this tool from sibling tools like list_chats and read_thread.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the main use case—locating messages by substring—and explains optional chat and since filters. However, it does not explicitly state when to prefer search over read_thread or list_chats, nor does it provide exclusions. The 'same matching rules as read_thread' note is about parameter behavior, not tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sendA
Send a message through Messages.app.
Disabled by default. Set the environment variable IMESSAGE_SEND=1 on
this server process to enable it. chat accepts the same matching rules
as read_thread. Always show the exact text to the user and get a yes
before calling this.
| Name | Required | Description | Default |
|---|---|---|---|
| chat | Yes | ||
| text | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden. It discloses that sending is disabled by default, requires an environment variable, follows chat matching rules like read_thread, and mandates explicit user confirmation. This gives an agent meaningful safety and prerequisite context beyond the basic action.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and efficient. The core purpose is front-loaded, followed by critical activation and safety instructions. No wasted words or redundant restatement of the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter tool with an output schema, this description covers the essential operational context: activation, chat resolution, and the mandatory consent gate. Nothing critical is missing for an agent to call it safely and correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for both parameters. It adds useful semantics for `chat` by referencing read_thread matching rules, but it does not explicitly define `text` beyond the obvious 'message text' implied by the tool's purpose and the consent warning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Send a message through Messages.app.' This clearly distinguishes sending from the sibling tools (list_chats, read_thread, search, whats_new) without ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides explicit usage conditions: the tool is disabled by default, must be enabled via IMESSAGE_SEND=1, and must only be called after showing the exact text and getting user consent. It does not explicitly contrast with sibling tools, but the purpose is so distinct that exclusion feels implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
whats_newA
Return every message across all chats since the last time this tool advanced its cursor, grouped by chat, oldest first within each chat.
On the very first call (no cursor yet) it returns the last 24 hours.
The cursor lives at ~/.imessage-mcp/cursor.json. When mark_seen is
true (the default), the cursor advances to the newest message ROWID seen
so the next call only returns messages after this one.
| Name | Required | Description | Default |
|---|---|---|---|
| mark_seen | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does so well. It discloses the persistent cursor file location, the default mark_seen side effect that advances the cursor, and the grouping/ordering semantics. This gives an agent a realistic model of stateful behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The main purpose is front-loaded in a single precise sentence, followed by compact cursor mechanics. There is no filler, repetition of schema fields, or unnecessary detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a stateful tool, the description covers the full lifecycle: first call, cursor location, default advancement behavior, grouping, and ordering. Since an output schema exists, omitting return-value details is acceptable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema only provides the parameter name, type, and default; the description explains that mark_seen controls whether the cursor advances and how that affects future calls. The false branch is not explicitly spelled out, but it is easily inferred from the described behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states a precise operation: return every message across all chats since the cursor, grouped by chat with oldest first. This clearly distinguishes it from siblings like read_thread (single chat) and search, while the cursor mechanism separates it from list_chats.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context about first-call behavior and cursor advancement, but it never explicitly says when to prefer whats_new over read_thread, search, or list_chats. The polling use case is implied rather than stated with alternatives or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v0.1.0- First observed
list_chats - First observed
read_thread - First observed
search - First observed
send - First observed
whats_new
TDQS
Scored across 5 tools
Each tool targets a distinct action: listing chats, reading a thread, searching messages, incremental polling, and sending. Even though read_thread and search both return messages, their purposes are clearly separated and easy to tell apart.
list_chats and read_thread follow a verb_noun pattern, while search and send are bare verbs and whats_new is a phrase. All names use lower_snake_case and are readable, but the naming is not fully uniform.
Five tools is a well-scoped set for an iMessage bridge. It covers the main interactions without unnecessary redundancy or surface-area bloat.
The tool set covers the core messaging workflow: enumerate chats, read conversations, search content, poll for new messages, and send replies. There are no obvious dead ends or missing operations for the stated domain.
Maintenance
Related MCP Connectors
Let ChatGPT, Claude & Cursor use your Mac: email, calendar, iMessage, Teams, files. Local, free.
MCP connector for iMessage & Contacts via a local Mac agent + Vercel relay
Search, read, and write your Apple Notes from ChatGPT/Claude via a local Mac agent + MCP relay.
Carbon Voice MCP serves as a bridge that connects AI assistants like ChatGPT, Claude, and Cursor to a user's Carbon Voice account, turning voice messages and conversations into a private, on-demand knowledge base. It provides 28 specialized tools for comprehensive voice messaging management, including creating and sending messages, accessing conversation history with instant transcription, running AI actions (summarization, TLDR generation, meeting notes), and managing workspace collaboration through folders, contacts, and team communications.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables Claude to send and read iMessages on macOS, with smart contact lookup, message history retrieval, and cross-conversation search using natural language commands.5MIT
- AlicenseNot gradedqualityDmaintenanceEnables Claude to read and search through iMessage, SMS, and RCS conversations, including mixed-protocol group chats with Android users. It decodes binary message data from the macOS Messages database to provide a comprehensive view of message history.8MIT
- AlicenseNot gradedqualityAmaintenanceEnables fuzzy search and browsing of Apple Messages (iMessage/SMS) with contact resolution, filtering by sender or date, and context display through CLI, MCP, or Claude Code plugin.4419MIT
- AlicenseAqualityDmaintenanceConnects Claude Desktop to iMessage on macOS, enabling reading conversations, searching messages, sending texts, and managing attachments.77MIT