Model or dataset
carterlasalle/mac_messages_mcp avatar
carterlasalle/mac_messages_mcp

Mac Messages MCP: query and send iMessage from an MCP client

An MCP server that securely interfaces with your iMessage database via the Model Context Protocol (MCP), allowing LLMs to query and analyze iMessage conversations. It includes robust phone number validation, attachment processing, contact management, group chat handling, and full support for sending and receiving messages.

326 stars51 forksPythonMIT

At a glance

What is it?
Mac Messages MCP is a local MCP server that opens the macOS Messages and Contacts databases read-only and only touches Messages.app automation when a client calls the send tool. It is macOS-only, needs Full Disk Access, and is best judged on how its permission model fits your machine.
Who is it for?
Adopt Mac Messages MCP if you already run an MCP client on a Mac you control and you want message search, attachment lookup and send reachable from that client, with the send path gated behind an explicit tool call. Do not adopt it for a server, a Linux CI runner, a shared machine, or any setup where you cannot grant Full Disk Access to the launching app, because the README states the server is macOS-only and reading requires that permission.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 13 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The gap Mac Messages MCP fills on a Mac

iMessage history sits in a SQLite database that macOS protects, and Contacts sits in another. A language model has no route into either one. Mac Messages MCP is the adapter: a local Model Context Protocol server that exposes message search, contact lookup, attachment retrieval and sending as tools an MCP client can call. The README frames the audience directly: Claude, Codex, Cursor, VS Code, or any local MCP client.

The design decision worth noticing is the split between reading and writing. The README states the server opens the Messages and Contacts databases read-only, returns only the data a client asks for, and uses Messages.app automation only when the client explicitly calls the send tool. That means a prompt like "find PDFs sent to me this month" never reaches the automation layer. Sending is a separate, deliberate tool call, which is the right shape for anything that can put text on the wire under your name.

It is not a sync service and not a backup tool. There is no remote component in the description, and no account to create. The server runs where the data already lives.

How the server reads messages, contacts and attachments

The mechanism visible in the repository is straightforward. The Python package mac_messages_mcp is launched over stdio by an MCP client, and the tools it registers map onto three local sources: the Messages database, the Contacts database, and Messages.app itself for sending.

Phone numbers are the part that tends to break naive implementations. The README explains that numbers written in national format such as 06 39 98 00 01 or (415) 555-1234 must be expanded to E.164 before they can be matched against the Messages database, and that the expansion needs to know which country the number belongs to. The server reads the Mac's own region setting for this, so on a correctly configured Mac there is nothing to do. The phonenumbers dependency in pyproject.toml is what performs that normalization, and thefuzz plus python-Levenshtein handle approximate name matching in Contacts.

Attachments get their own path. Small images can be returned inline, HEIC images are converted to PNG, and larger or non-image files come back as a local path instead of a payload. The pillow and pillow-heif dependencies exist for exactly that. Group chats are addressed by chat IDs that the server can list, so a read or a send can target a named group rather than a single recipient. Reachability is a separate tool: the client can ask whether a recipient appears reachable through iMessage before sending, which is the difference between a failed send and an informed one.

Installing Mac Messages MCP and running a first query

The README routes installation through uv, which installs the server in an isolated environment so you do not create a virtual environment first. Python 3.10 or newer is required, and uvx can provision a compatible interpreter.

bash
brew install uv
uvx --version

The first command installs the uv toolchain with Homebrew; the second confirms the launcher is available. If uvx --version prints a version, the next step is permissions, not configuration.

Before any client can read anything, the app that launches the server needs Full Disk Access. Open System Settings, Privacy & Security, Full Disk Access, and enable Claude Desktop, Cursor, VS Code, the ChatGPT desktop app, or the terminal you use for Claude Code and Codex CLI. Quit and reopen the app after changing that setting. On the first contact lookup or send, macOS may separately ask for access to Contacts or permission to control Messages.

Then register the server. The command is the same in every client: uvx mac-messages-mcp. For Claude Desktop, the README shows this entry in claude_desktop_config.json, and notes you should preserve any other servers already in the file.

json
{
  "mcpServers": {
    "mac-messages": {
      "command": "uvx",
      "args": ["mac-messages-mcp"]
    }
  }
}

Claude Code takes a CLI form instead, added once at user scope.

bash
claude mcp add --transport stdio --scope user mac-messages -- uvx mac-messages-mcp
claude mcp get mac-messages

Codex clients share MCP configuration on the same Mac, and the README gives both a command and a config.toml form.

toml
[mcp_servers.mac-messages]
command = "uvx"
args = ["mac-messages-mcp"]

VS Code is the odd one out: its mcp.json uses a top-level servers object, while Claude Desktop and Cursor use mcpServers. The README flags that difference explicitly, and it is the most common reason a copied snippet silently does nothing.

Verification is two tool calls before any prompt. Ask the client to call tool_check_db_access, then tool_check_addressbook. Once both succeed, the README's example prompts include "Show me my messages from the last two hours" and "Find messages from Carter about dinner in the last 30 days". The first uvx launch can take longer while it downloads and caches Python dependencies, which is expected rather than a fault.

If a GUI client reports that uvx cannot be found, run which uvx in Terminal and replace the command with the absolute path. Homebrew commonly installs it at /opt/homebrew/bin/uvx on Apple silicon and /usr/local/bin/uvx on Intel Macs.

Where the permission model and platform lock-in bite

The hard boundary is stated in the README itself: this server is macOS-only. There is no Linux or Windows path, and the Dockerfile in the repository builds a container from a Python image but does not change the fact that the underlying databases and Messages.app automation only exist on a Mac. A container is useful for reproducible packaging, not for running the server somewhere else.

Full Disk Access is the second constraint, and it is broader than it sounds. Granting it to a terminal means every process you launch from that terminal inherits the ability to read the Messages database. The README's own instruction to enable the terminal when using Claude Code or Codex CLI is honest about the setup, but it is a real expansion of what that terminal can reach. If that trade is unacceptable on a shared or managed machine, this is the wrong tool regardless of how well the tools work.

National-format phone numbers are the third failure mode. The README states that expansion to E.164 needs a region, that the server reads the Mac's own region setting, and that MAC_MESSAGES_REGION takes an ISO 3166-1 alpha-2 code when your numbers belong to a different region than your Mac is configured for, for example a French SIM on a Mac set to en_US. Without that override, lookups against a mismatched number format can miss contacts that plainly exist.

Sending has its own dependency chain. The README notes that sending requires a Mac signed into Messages plus permission for the launching app to automate Messages, and that Messages.app should be open, signed in, and already able to send a normal message. The server does not establish that state; it assumes it. SMS and RCS fallback is described as applying to eligible phone recipients, so it is not a universal guarantee for every number.

Mac Messages MCP compared with the WhatsApp MCP servers people also search for

The comparison that comes up in search is against WhatsApp MCP servers, including Docker and n8n variants. The difference is not cosmetic.

WhatsApp MCP projects generally sit on top of a network service, which means authentication against an account, a session that can expire or be revoked, and a transport that reaches outside the machine. Mac Messages MCP takes the opposite route: the README describes a server that runs locally, opens local SQLite databases read-only, and uses app automation only for sends. There is no session token to refresh and no remote endpoint in the described design.

The trade is portability and reach. A WhatsApp MCP server can plausibly run in a container or be wired into an automation platform such as n8n because it talks to an API. Mac Messages MCP cannot, because its data source is a file on a Mac and its send path is AppleScript-style automation of a desktop app. If your workflow is a hosted pipeline, this project is not the one to pick. If your workflow is a person at a Mac asking their editor about yesterday's conversation, the local model is the reason it works at all.

Within the iMessage space the relevant alternative is not another MCP server but the manual route: querying the chat database yourself with sqlite3 and scripting sends through osascript. That gives you full control and no dependency, at the cost of reimplementing the E.164 normalization, the fuzzy contact matching, the HEIC conversion and the group chat ID handling that this project already ships.

Maintenance, versioning and what the MIT licence leaves to you

The repository is not archived, and the last push was on 2026-09-03. The most recent release listed is v1.1.0 from 2026-09-01. The project has a CHANGELOG.md, a VERSIONING.md, a SECURITY.md and a CONTRIBUTING.md at the repository root, plus a CI workflow and a fuzz directory, which is more process scaffolding than many MCP servers carry.

Upgrade cost is low by design. Because the recommended launch command is uvx mac-messages-mcp, the client resolves the published package, so an upgrade is a restart of the client or a re-resolution of the package rather than an edit to your config. That also means you are tracking whatever version PyPI serves at launch time unless you pin it. The README does not document rollback, and it does not describe a pinning mechanism, so a team that needs reproducible behaviour across machines has to decide that for itself.

The licence is MIT, declared both in the README badge and in pyproject.toml. MIT is permissive and imposes no copyleft obligation on your own code. It also provides no warranty, and this is software whose whole job is reading your private message history and sending messages as you. The permission surface, not the licence text, is where the real risk sits, and the licence does nothing to constrain it. Nothing here is legal advice; if you are deploying this inside an organisation, the Full Disk Access question belongs with whoever owns device policy.

Editorial conclusion

Adopt Mac Messages MCP if you already run an MCP client on a Mac you control and you want message search, attachment lookup and send reachable from that client, with the send path gated behind an explicit tool call. Do not adopt it for a server, a Linux CI runner, a shared machine, or any setup where you cannot grant Full Disk Access to the launching app, because the README states the server is macOS-only and reading requires that permission. Before wiring it into a client, verify three things on your own machine: that uvx is on PATH and the absolute path works if your GUI client cannot find it, that tool_check_db_access and tool_check_addressbook both succeed after you grant Full Disk Access and restart the app, and that Messages.app is already signed in and able to send a normal message, since the send tool depends on that state rather than creating it.

Frequently asked questions

What is Mac Messages MCP and what does it do?

It is an MCP server that runs locally on a Mac and lets an MCP client such as Claude, Cursor, VS Code or Codex search, read and send messages through the macOS Messages app. The README states it opens the Messages and Contacts databases read-only and uses Messages.app automation only when the send tool is explicitly called.

How do I install Mac Messages MCP?

Install uv with brew install uv, confirm uvx --version works, grant Full Disk Access to the app that will launch the server, then register uvx mac-messages-mcp in your client's MCP configuration. Python 3.10 or newer is required, and uvx provisions it in an isolated environment.

Why does Mac Messages MCP need Full Disk Access?

The README states that reading messages requires Full Disk Access, because the server opens the Messages database directly. You enable it under System Settings, Privacy & Security, Full Disk Access for the app that launches the server, and quit and reopen that app afterwards.

Can Mac Messages MCP send messages without asking me first?

Sending only happens when the client explicitly calls the send tool, and the README's example prompts show drafting with an instruction not to send until confirmation. The server uses Messages.app automation for that call, and requires a Mac signed into Messages with permission for the launching app to automate it.

Does Mac Messages MCP work on Linux or Windows?

No. The README states the server is macOS-only, since it reads the macOS Messages and Contacts databases and automates Messages.app. The repository does include a Dockerfile, but that packages the Python application rather than moving the data sources off a Mac.

Official sources

  1. carterlasalle/mac_messages_mcp on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Community notes

Community notes