Skip to main content
Glama
cannavis

imessage-rich-search

by cannavis

imessage-rich-search

macOSのiMessageを全文検索 — Messages.appはインデックス化しているものの、生の chat.db のテキスト列からは決して露出しない リンクプレビューのメタデータ(タイトル、要約、サイト名)を含めて検索します。

License: MIT Python 3.9+ Platform: macOS No deps MCP

このツールが解決する問題

iMessageにURLを貼り付けると、macOSはリッチプレビュー(タイトル、要約、サイト名、ヒーロー画像)を取得し、そのメタデータを message.payload_data 内のNSKeyedArchiverバイナリとして chat.db に保存します。Messages.appの検索バーはこれを読み取りますが、基本的な chat.db の text 列には含まれていません。

そのため、友人が https://x.com/foo/status/123 を送り、プレビューカードに "Obsidian + Claude Code is the most underrated productivity stack" と表示されていた場合、text 列のみを読み取るツールで「obsidian」を検索しても 結果はゼロ になります。Messages.appなら見つかります。このツールでも見つかります。これらは同じ検索範囲を対象としているからです。

Related MCP server: imessage-mcp

特徴

  • メッセージ本文 および デコードされたリンクプレビューのメタデータを一度に検索

  • ハンドル(電話番号/メールアドレス)によるフィルタリング

  • 人間が読みやすい形式またはJSON形式での出力

  • chat.db に対して読み取り専用(SQLite URIモードを使用)

  • CLIの実行時依存関係ゼロ(Python標準ライブラリのみ)

  • Claude Desktop / Claude.aiが直接呼び出せるMCPサーバー機能

  • 新着順の結果表示、ISO 8601タイムスタンプ、送受信方向の矢印、相互参照用のrowid

このツールについて

できること:

  • ローカルの chat.db に対する読み取り専用のフォレンジック/アーカイブ検索

  • 生テキストしか見えないMCP iMessageツールへの追加導入

  • 約200行の標準ライブラリPythonコード

できないこと:

  • Messages.appの代替(UIなし、送信/編集/削除機能なし)

  • 他人のメッセージへのアクセス

  • iCloud / デバイス間同期ツール(このMacにローカル保存されているもののみ検索)

  • フルディスクアクセスの回避(明示的な許可が必要)

  • OCR / 画像 / 音声 / ステッカー / 手書き文字の読み取り(テキストとリンクメタデータのみ)

  • SQLiteに残っていない削除済みメッセージの復元

要件

OS

macOS 11 Big Sur以降(macOS 26までテスト済み)

アーキテクチャ

Apple Silicon (arm64) または Intel (x86_64)

Python

3.9+(システム標準の /usr/bin/python3 が動作し、MCPサーバーには必須です。 インストール を参照)

ディスク

わずか(インストール時約50 KB)

権限

スクリプトを実行するターミナル/アプリに対する フルディスクアクセス

このツールが依存する chat.db のスキーマフィールド(text, payload_data, balloon_bundle_id, handle.id)はmacOS 10.13 High Sierra以降安定しており、公式に謳っているバージョンよりも古い環境でも動作する可能性があります(未テスト)。

インストール

オプションA — pipx(推奨、MCPサーバーにはシステムPythonが必要)

pipx はツールを独自のvenvに分離します。必要に応じて先にpipxをインストールしてください:

brew install pipx
pipx ensurepath

次に、GitHubからこのツールをインストールします。必ず /usr/bin/python3 を明示的に使用してください。これはMCPサーバーにとって重要です。macOSはフルディスクアクセスをClaude.appからApple署名された子プロセスにのみ伝播させるためです。HomebrewのPythonはサードパーティ署名ですが、システム標準の /usr/bin/python3 はApple署名されており、権限を正しく継承します。MCPサーバーが不要(CLIのみ)であれば、Python 3.9+であれば何でも構いません。

pipx install --python /usr/bin/python3 "git+https://github.com/cannavis/imessage-rich-search"

これにより、PATH(~/.local/bin 配下)に3つのコマンドがインストールされます:

  • imessage-rich-search — CLI

  • imrs — CLIの短いエイリアス

  • imessage-rich-search-mcp — MCPサーバー

オプションB — venvへの pip インストール

git clone https://github.com/cannavis/imessage-rich-search
cd imessage-rich-search
/usr/bin/python3 -m venv .venv && source .venv/bin/activate
pip install -e .

オプションC — インストール不要の単一ファイル実行

CLIモジュールは依存関係ゼロです。curlで取得して実行できます:

curl -O https://raw.githubusercontent.com/cannavis/imessage-rich-search/main/src/imessage_rich_search/cli.py
python3 cli.py "obsidian"

フルディスクアクセスの許可(初回のみ必須)

chat.db はmacOSのTCCによって保護されています。フルディスクアクセスがないと unable to open database file というエラーになります。

  1. システム設定 → プライバシーとセキュリティ → フルディスクアクセス を開く

  2. + をクリックし、このスクリプトを実行するアプリを追加する:

    • シェルで直接 imessage-rich-search を実行する場合 → ターミナル(または iTerm, Warp, Ghostty, Alacritty など、実際に使用しているターミナル)を追加

    • MCP経由でClaude Desktopから実行する場合 → Claude.app を追加

    • スクリプトエディタやIDEから実行する場合 → そのアプリを追加

  3. 権限を反映させるため、そのアプリを 完全に終了して再起動 する(⌘Qで終了、ウィンドウを閉じるだけでは不十分)

  4. 確認: python3 -c "import sqlite3; sqlite3.connect('file:'+__import__('os').path.expanduser('~/Library/Messages/chat.db')+'?mode=ro', uri=True).execute('SELECT COUNT(*) FROM message').fetchone()" — エラーにならず数字が表示されれば成功

使用方法

# Basic search across all conversations
imessage-rich-search "obsidian"

# Restrict to one contact
imessage-rich-search "obsidian" --contact "+14073993471"

# JSON for piping into jq, scripts, or another tool
imessage-rich-search "obsidian" --contact "+14073993471" --json | jq '.[].preview[0]'

# Limit results, point at a backup chat.db
imessage-rich-search "claude code" --limit 20 --db /path/to/chat.db

# Short alias
imrs "obsidian"

# Module form (no entry point needed)
python3 -m imessage_rich_search "obsidian"

出力

6 match(es) for 'obsidian':

[2026-04-08T22:56:23+00:00] -> +14073993471  (rowid=234953)
    url:     https://x.com/aiedge_/status/2041908011078447222?s=42
  * preview: Claude Code + Obsidian Ultimate Guide (build an AI second brain)
...

-> = 送信 · <- = 受信 · * = 検索クエリを含むプレビュー行 · rowid = chat.db への相互参照キー。

MCPサーバーとしての使用(Claude Desktop)

会話中にClaude Desktopから直接検索を呼び出せるようになります。

  1. システムPython を使用してパッケージをインストールします(上記のオプションAで --python /usr/bin/python3 を指定)。これは必須です。macOSのフルディスクアクセスは、Claude.appから Apple署名された サブプロセスにのみ伝播するためです。/usr/bin/python3 はApple署名されていますが、Homebrew / pyenv / asdfでインストールされたPythonはそうではなく、tccd によって黙って拒否されます。

  2. エントリポイントの絶対パスを確認します: which imessage-rich-search-mcp

  3. ~/Library/Application Support/Claude/claude_desktop_config.json を編集します:

    {
      "mcpServers": {
        "imessage-rich-search": {
          "command": "/full/path/from/which/imessage-rich-search-mcp"
        }
      }
    }
  4. Claude.appにフルディスクアクセスが付与されていることを確認します(一度許可すればデフォルトで付与されています。システム設定 → プライバシーとセキュリティ → フルディスクアクセスで確認してください)

  5. Claude Desktopを 完全に終了して再起動 します(⌘Q)

これでClaudeはツールとして search_imessages_rich(query, contact?, limit?) を呼び出せるようになります。

TCC継承の確認

MCPサーバーがClaude Desktop内で「unable to open database file」を返す場合、起動の属性チェーンが壊れています。macOSのTCCデーモンのログを確認してください:

log show --predicate 'process == "tccd"' --last 5m | grep -iE "imessage-rich|chat\.db|SystemPolicyAllFiles"

正常なインストールではリクエストが 許可 されていることが表示されます。壊れたインストールでは responsible_path= がApple署名されていないPythonバイナリを指しており、その後に recording denied が続きます。pipx reinstall --python /usr/bin/python3 ... で再インストールして修正してください。

仕組み

chat.db (SQLite, read-only)
  └─ message
       ├─ text                     ← raw text (what basic tools see)
       ├─ payload_data  (BLOB)     ← NSKeyedArchiver bplist of LPLinkMetadata
       │                              (title, summary, site, image refs)
       └─ balloon_bundle_id        ← e.g. com.apple.messages.URLBalloonProvider

For every row:
  1. Read text + payload_data
  2. plistlib.loads(payload_data) → walk $objects → collect strings
  3. Lower-case haystack = text + "\n".join(preview_strings)
  4. Match if query.lower() in haystack

「$objectsから文字列を抽出する」というトリックにより、ccl_bplist や pyobjc、完全なNSKeyedUnarchiverのセマンティクスは不要です。全文検索においてはオブジェクトグラフは重要ではなく、末端の文字列のみが必要だからです。

プライバシーとセキュリティ

  • 読み取り専用。 chat.db をSQLite URIフラグ mode=ro で開きます。

  • ローカルのみ。 ネットワーク通信は一切行いません。(grep -r 'urllib\|requests\|http' src/ は何も返しません。)

  • テレメトリなし。

  • データはMacから外部へ送信されません。 出力を共有することを選択しない限り、データはMac内に留まります。

  • CLIは実行時の依存関係がゼロであり、サプライチェーン攻撃を受ける余地がありません。

  • 脆弱性の報告については SECURITY.md を参照してください。

制限事項

  • 部分一致のみ。 FTS5ランキング、正規表現、論理演算子はありません。必要であれば追加してください(PR歓迎)。

  • ローカルDBのみ。 メッセージがiCloud上にのみ存在し、このMacの chat.db に同期されていない場合、検索結果には表示されません。

  • プレビューメタデータはMessages.appが取得済みである必要があります。 リンクカードが読み込まれなかった場合(オフライン送信、URLの期限切れなど)、検索対象となる payload_data は存在しません。

  • 文字列抽出は設計上、損失を伴います。 bplistからすべての文字列を抽出するため、プレビューリストに画像のMIMEタイプや {0, 0} のような次元タプル、プロフィール画像のURLなどが表示されることがあります。これらは検索結果には影響しませんが、生の出力には含まれます。

  • フルディスクアクセスは必須要件です。 回避策はありません。

トラブルシューティング

症状

修正方法

unable to open database file / cannot open chat.db

実行中のアプリにフルディスクアクセスが付与されていません。アプリを追加し、⌘Qで再起動してください。

0件ヒットするがMessages.appでは見つかる

--contact の形式が間違っています(chat.db 内の handle.id と一致する必要があります。通常は +1XXXXXXXXXX または完全なメールアドレス)。--contact なしで実行して確認してください。

Claude DesktopのMCP呼び出しで unable to open database file となる(CLIは正常)

TCCが起動したPythonを拒否しています。システムPythonで再インストールしてください: pipx reinstall --python /usr/bin/python3 imessage-rich-search。TCC継承の確認セクション を参照。

MCPサーバー起動時に No module named 'imessage_rich_search' となる

pipx install --python /usr/bin/python3 "git+https://github.com/cannavis/imessage-rich-search" で再インストールしてください

Claude Desktopがツールを認識しない

claude_desktop_config.json のJSON構文を確認し、Claudeを完全に終了(⌘Q)して再起動してください。

大規模なデータベースで検索が遅い

現在の実装では行ごとに線形スキャンとbplist解析を行っています。10万件以上のメッセージDBでは数秒かかる場合があります。FTS5仮想テーブルによるインデックス化をロードマップに含めています。

貢献

CONTRIBUTING.md を参照してください。IssueやPRを歓迎します。

変更履歴

CHANGELOG.md を参照してください。

ライセンス

MIT — LICENSE を参照してください。

謝辞

  • 10年間のmacOSリリースを通じて驚くほど安定しているAppleの chat.db スキーマ

  • 長年にわたり payload_data / LPLinkMetadata をリバースエンジニアリングしてきた先人たち

  • MCP仕様を提供している Model Context Protocol

Available Tools

1 tool
search_imessages_richA

Full-text search across macOS iMessages including link preview metadata (title, summary, site name) that Apple stores in payload_data — content the basic chat.db text column does not expose. Returns newest-first matches where the query (case-insensitive substring) appears in either the message body OR the rich link preview.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesSubstring to search for (case-insensitive).
contactNoOptional handle filter, e.g. '+14073993471' or 'name@example.com'.
limitNoMax matches to return (default 50).

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, description carries full burden. Discloses search over message body and rich link preview, case-insensitive substring matching, and newest-first sorting. Could add more on returns (empty results, pagination) but covers key behavioral traits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with purpose, no superfluous words. Each sentence adds value: first defines scope, second details ordering and search targets.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema, so description should cover return structure. It mentions 'newest-first matches' but does not describe fields (e.g., message text, sender, timestamp, preview metadata). Agent may need to infer or handle uncertainly. Lacks completeness for a search tool without output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema descriptions cover 100% of parameters, but description adds operational context: query searches both body and preview, contact is an optional handle filter, and limit default/max. Adds meaning beyond schema fields.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states it performs full-text search across macOS iMessages, including link preview metadata beyond basic chat.db. Specifies scope, search scope (body or preview), and result ordering (newest-first). Distinguishes from potential siblings by highlighting the rich link preview capability.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides context that this tool searches rich link preview metadata not exposed by basic chat.db, implying its niche. However, it does not explicitly state when not to use it or mention alternatives. Still clear enough for an agent to infer appropriate scenarios.

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.

  1. 1 tool updatev0.2.0
    • First observedsearch_imessages_rich

TDQS

A4.3/5.0

Scored across 1 tool

Disambiguation5/5

Only one tool exists, so there is no possibility of confusion or ambiguity between tools.

Naming Consistency5/5

With a single tool, naming consistency is perfect; the name 'search_imessages_rich' is descriptive and follows a clear verb_noun pattern.

Tool Count3/5

A single tool feels thin for a server named 'imessage-rich-search', as it likely covers only a narrow part of iMessage interaction. While the tool is focused, users may expect additional functionality like retrieving messages or managing conversations.

Completeness4/5

The tool thoroughly performs the described search across both message text and rich link previews, but lacks complementary operations such as fetching individual messages or performing more advanced queries, which are minor gaps.

Maintenance

ActivityInactive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    A local MCP server that enables reading iMessage conversations and sending new messages through Claude Desktop. It provides secure, read-only access to your Mac's iMessage database and AppleScript-based message sending capabilities.
    6
    MIT
  • F
    license
    A
    quality
    D
    maintenance
    A read-only MCP server that exposes your iMessage data to Claude Code and Claude Desktop, with automatic contact name resolution.
    3
    -
  • A
    license
    Not graded
    quality
    A
    maintenance
    Read, search, and send iMessages locally from your terminal or through MCP clients like Claude, Cursor, and VS Code.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    macOS-only MCP server that exposes iMessage history to Claude and exports per-chat conversations into an Obsidian vault.
    2
    MIT