imsg

imsg

Read, search, and send iMessages locally from your terminal or through MCP clients like Claude, Cursor, and VS Code.

Category
Visit Server

README

imsg — fast, local iMessage for your terminal & MCP

Package brand: imsg-mcp · CLI/MCP: imsg / imsg-mcp · PyPI today: pip install mac-imsg (target PyPI: imsg-mcp).

PyPI Python Built with Rust License: MIT macOS only

Read, search, and send iMessage from your terminal — or expose it to Claude, Cursor, VS Code, or any MCP client. Everything runs locally on your Mac: no cloud, no login, no account. Reads open ~/Library/Messages/chat.db read-only; sends go through Messages.app.

Why another one? The hot path — decoding tens of thousands of attributedBody typedstream blobs — is written in Rust (PyO3 + rusqlite), so reads and searches over a large history are several times faster than the pure-Python equivalent that other Messages servers use. Pure Python still ships as a zero-dependency fallback, so it works even where the wheel doesn't.

<!-- BENCH -->

Benchmark

Full-history search over a synthetic 50,000-message database (70% stored as attributedBody blobs), best-of-5, Apple Silicon (16 cores):

operation pure-Python Rust core speedup
full-history search (decodes every message) 120.9 ms 35.7 ms 3.4×
batched blob decode (allocation-bound) 19.1 ms 19.6 ms 1.0×

Two honest caveats, stated up front:

  • Raw blob decoding is ~a wash — it's bound by allocating result strings, not CPU, so native code doesn't help. The win is in search, where Rust decodes and filters across all cores and returns only the matches.
  • It's 3.4×, not 16×, because the SQLite read and result marshalling are serial on both sides; only the decode+match parallelizes. The gap widens on larger histories.

Reproduce: python bench/benchmark.py. Bonus: this search also finds messages whose text lives in an attributedBody blob — which a plain text LIKE query (used by Python-only Messages servers) silently misses. <!-- /BENCH -->

Install

# with uv (recommended) — provisions Python + the prebuilt wheel
# PyPI package name is mac-imsg (imsg was too similar to an existing project);
# the installed CLIs are still `imsg` and `imsg-mcp`.
uv tool install mac-imsg

# or pip
pip install mac-imsg

# or Homebrew
brew install ml-lubich/tap/imsg

Requirements

  • macOS (reads the local Messages database; sends via Messages.app).
  • Full Disk Access for the app that runs imsg — Terminal/iTerm/Ghostty for the CLI, or your MCP client (Claude Desktop, Cursor, VS Code…) for the server. System Settings → Privacy & Security → Full Disk Access → add it, then fully quit and reopen it.
  • Messages.app signed in and able to send a normal message.

Run imsg doctor to check access and see which engine (Rust or Python) is live.

Specs live under docs/ (overview, architecture, design, API, testing).

CLI

imsg -h                           # commands (also: imsg <cmd> -h)
imsg doctor                       # check Full Disk Access + engine
imsg chats                        # recent conversations + their ids
imsg contacts                     # handles (numbers / emails) seen
imsg contacts -q 415              # filter handles by substring
imsg read -c +14155551234         # recent messages with a contact
imsg read --chat 42 --limit 100   # a specific conversation
imsg search "dinner"              # search message text
imsg send +14155551234 "on my way"

Every command accepts -h / --help with options, arguments, and examples (agent-friendly).

MCP server

The imsg-mcp entry point speaks MCP over stdio. Add it to any client:

Claude Code

claude mcp add --transport stdio --scope user imsg -- imsg-mcp

Claude Desktop / Cursor (mcpServers) · VS Code (servers):

{ "mcpServers": { "imsg": { "command": "imsg-mcp" } } }

Tools exposed: check_access, get_recent_messages, search_messages, list_chats, list_contacts, send_message (the only one with a side effect).

How it works

There is no official iMessage API. Every tool in this space does the same two local things; imsg just does the heavy half in Rust:

Operation Mechanism Engine
read / search / list chat.db (SQLite, read-only) + typedstream decode Rust (imsgcore), Python fallback
send AppleScript → Messages.app Python (osascript)

SQLite is the same C library everywhere, so the read speedup comes from doing the per-message attributedBody decode and row marshalling natively instead of in a Python loop. See bench/benchmark.py for the methodology — both engines run identical queries over an identical synthetic database, and the pure-Python column is the same algorithm Python-only servers use.

Privacy & security

  • All database connections are opened read-only (mode=ro).
  • Nothing is uploaded, mirrored, or indexed off-device.
  • Sending is isolated in one function, escapes its AppleScript inputs, and is the only operation that writes anything anywhere.
  • Full Disk Access is broad — grant it only to apps you trust.

Development

git clone https://github.com/ml-lubich/imsg.git && cd imsg
uv venv && source .venv/bin/activate
uv pip install maturin
maturin develop            # builds the Rust core + installs the package
uv pip install -e ".[dev]"
pytest                     # tests run on the pure-Python path (and Rust if built)
python bench/benchmark.py  # regenerate the benchmark

License

MIT © ml-lubich. Not affiliated with Apple. Use responsibly and only with accounts and conversations you own.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured