Skip to main content
Glama

imessage-mcp

A local MCP server that exposes your Mac's iMessage data to Claude Desktop / Claude Code. Two surfaces:

  1. SEND via AppleScript → Messages.app

  2. READ via direct, read-only SQLite access to ~/Library/Messages/chat.db

Everything is local. No API keys, no network calls.

Install

# 1. Clone / copy into ~/mcp-servers/imessage-mcp
cd ~/mcp-servers/imessage-mcp

# 2. Create a Python 3.11+ venv and install deps
python3.12 -m venv .venv
.venv/bin/pip install -e .

Permissions (required)

Full Disk Access — so we can read chat.db

System Settings → Privacy & Security → Full Disk Access → toggle ON for:

  • your terminal app (e.g. Terminal, iTerm2, Ghostty), AND

  • Claude.app (if using Claude Desktop)

Automation — so we can control Messages.app

System Settings → Privacy & Security → Automation → expand your terminal / Claude.app and toggle Messages to ON.

Messages.app must be running and signed into iMessage.

If a permission step is missing, the server errors with the exact settings path to open.

Claude Desktop config

Merge into ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "imessage": {
      "command": "/Users/YOUR_USERNAME/mcp-servers/imessage-mcp/.venv/bin/python",
      "args": ["-m", "imessage_mcp.server"]
    }
  }
}

(The absolute path to the venv's python is the safest — it avoids PATH ambiguity. Replace YOUR_USERNAME.)

Tools

Tool

Purpose

send_imessage(recipient, body, service?)

Send via Messages.app. recipient is a phone, Apple ID email, or existing buddy name.

list_recent_chats(limit=20)

Newest-first chats with last-message preview and unread count.

get_chat_messages(chat_id?, handle?, limit=50, since?)

Messages for a chat; provide chat_id or handle.

search_imessages(query, since?, until?, from_contact?, limit=25)

Case-insensitive LIKE across message bodies.

get_my_info()

Self-handles + DB metadata.

Dates are ISO8601 in and out. Internally, Apple stores message.date as nanoseconds since 2001-01-01 UTC; the server converts both ways.

Safety invariants

  • chat.db is opened with sqlite3.connect("file:...chat.db?mode=ro", uri=True). Any write attempt raises sqlite3.OperationalError: attempt to write a readonly database.

  • send_imessage passes recipient / body / service as separate osascript argv entries — no shell interpolation, no injection.

  • Attachments return metadata only (filename, mime_type, total_bytes). Blobs are never read.

Limitations

  • Scheduled / delayed sends are not supported.

  • Rich / reply-threaded messages may have their text stored in attributedBody (NSKeyedArchive). We best-effort extract the embedded NSString; messages with more exotic payloads (images, taps, Apple Pay) will show empty body but correct metadata.

  • Delivery confirmation: send_imessage reports success from osascript's exit code. To verify the message actually went through, call search_imessages or get_chat_messages a few seconds later.

  • This is macOS-only and will not work on sandboxed App Store apps.

Local development

.venv/bin/pytest -q
Install Server
A
license - permissive license
A
quality
C
maintenance

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/camfortin/imessage-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server