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

解决的问题

当您将 URL 粘贴到 iMessage 中时,macOS 会获取富预览(标题、摘要、站点名称、主图),并将该元数据作为 NSKeyedArchiver 二进制数据存储在 chat.db 的 message.payload_data 中。Messages.app 的搜索栏会读取它,但基础的 chat.db text 列并不包含这些内容。

因此,如果朋友给您发送了 https://x.com/foo/status/123,而预览卡片显示为 “Obsidian + Claude Code 是最被低估的生产力组合” —— 在任何仅读取 text 的工具中搜索“obsidian”将返回零结果。Messages.app 可以找到它,而此工具也可以找到它。它们搜索的是相同的覆盖范围。

Related MCP server: imessage-mcp

功能

  • 一次性搜索消息正文和解码后的链接预览元数据

  • 按联系人(电话/电子邮件)过滤

  • 人类可读或 JSON 输出

  • 对 chat.db 只读(使用 SQLite URI 模式)

  • CLI 无运行时依赖(仅使用 Python 标准库)

  • 可选的 MCP 服务器,以便 Claude Desktop / Claude.ai 可以直接调用它

  • 结果按最新排序,包含 ISO 8601 时间戳、方向箭头、用于交叉引用的 rowid

它是什么 — 以及不是什么

是:

  • 对本地 chat.db 进行只读的取证/归档搜索

  • 仅能看到原始文本的 MCP iMessage 工具的补充工具

  • ~200 行标准库 Python 代码

不是:

  • Messages.app 的替代品(无 UI,无法发送/编辑/删除)

  • 访问他人消息的途径

  • iCloud / 跨设备同步工具 — 仅搜索此 Mac 本地的内容

  • 绕过“完全磁盘访问权限”的工具 — 您必须明确授予权限

  • OCR / 图像 / 音频 / 贴纸 / 手写识别器(仅限文本 + 链接元数据)

  • 恢复 SQLite 中已删除消息之外的内容的工具

要求

操作系统

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 将工具隔离在自己的虚拟环境中。如果需要,请先安装 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 下)安装三个命令:

  • imessage-rich-search — CLI 工具

  • imrs — CLI 的简短别名

  • imessage-rich-search-mcp — MCP 服务器

选项 B — 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. 点击 + 并添加您将运行此工具的应用程序:

    • 直接在 shell 中运行 imessage-rich-search?→ 添加 Terminal(或 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"

安装正常时会显示请求被 allowed。安装损坏时会显示 responsible_path= 指向非 Apple 签名的 Python 二进制文件,随后是 recording denied。使用 pipx install --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 语义的需求 — 对于全文搜索,我们不关心对象图,只关心叶子字符串。

隐私与安全

  • 只读。 使用 SQLite URI 标志 mode=ro 打开 chat.db。

  • 仅限本地。 无网络调用。永远不会。(grep -r 'urllib\|requests\|http' src/ 返回空。)

  • 无遥测。

  • 除非您选择共享输出,否则没有任何数据会离开您的 Mac。

  • CLI 没有运行时依赖项 — 没有什么可以通过供应链攻击。

  • 请参阅 SECURITY.md 进行漏洞报告。

限制

  • 仅限子字符串匹配。 没有 FTS5 排名,没有正则表达式,没有布尔运算符。如果您需要,请添加它(欢迎提交 PR)。

  • 仅限本地数据库。 如果消息仅存在于 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 万条以上的消息数据库,预计需要几秒钟。基于 FTS5 虚拟表的索引已在路线图中。

贡献

请参阅 CONTRIBUTING.md。欢迎提交问题和 PR。

更新日志

请参阅 CHANGELOG.md。

许可证

MIT — 请参阅 LICENSE。

致谢

  • Apple 的 chat.db 模式,在十年的 macOS 版本中一直非常稳定

  • 多年来对 payload_data / LPLinkMetadata 进行逆向工程的人们

  • Model Context Protocol 的 MCP 规范

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