Skip to main content
Glama
cannavis

imessage-rich-search

by cannavis

imessage-rich-search

Полнотекстовый поиск по iMessage в macOS — включая метаданные предварительного просмотра ссылок (заголовки, описания, названия сайтов), которые индексирует приложение «Сообщения», но которые никогда не отображаются в текстовом столбце chat.db.

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

Какую проблему это решает

Когда вы вставляете URL в iMessage, macOS получает расширенный предварительный просмотр — заголовок, описание, название сайта, главное изображение — и сохраняет эти метаданные в chat.db в виде объекта NSKeyedArchiver в столбце message.payload_data. Панель поиска приложения «Сообщения» считывает их. Базовый текстовый столбец text в chat.db их не содержит.

Поэтому, если друг прислал вам https://x.com/foo/status/123, а в карточке предпросмотра было написано "Obsidian + Claude Code is the most underrated productivity stack" — поиск по слову "obsidian" в любом инструменте, который читает только столбец text, вернет ноль результатов. Приложение «Сообщения» находит это. Этот инструмент тоже находит. Они ищут в одной и той же области данных.

Related MCP server: imessage-mcp

Возможности

  • Поиск по телу сообщения и декодированным метаданным предпросмотра ссылок за один проход

  • Фильтрация по идентификатору (телефон / email)

  • Вывод в читаемом человеком формате или JSON

  • Только чтение chat.db (использует режим URI SQLite)

  • Отсутствие зависимостей времени выполнения для CLI (только стандартная библиотека Python)

  • Опциональный MCP-сервер, чтобы Claude Desktop / Claude.ai могли вызывать его напрямую

  • Результаты от новых к старым, временные метки ISO 8601, стрелки направления, rowid для перекрестных ссылок

Что это такое — и чем не является

Является:

  • Инструментом для поиска в режиме только чтения по вашей локальной базе chat.db

  • Дополнением к MCP-инструментам для iMessage, которые видят только «сырой» текст

  • ~200 строками кода на стандартном Python

Не является:

  • Заменой приложения «Сообщения» (нет интерфейса, нельзя отправлять/редактировать/удалять)

  • Способом получить доступ к чужим сообщениям

  • Инструментом для синхронизации iCloud / между устройствами — поиск ведется только по тому, что локально на этом Mac

  • Обходом ограничений «Полного доступа к диску» — вы должны предоставить его явно

  • Средством распознавания OCR / изображений / аудио / стикеров / рукописного ввода (только текст + метаданные ссылок)

  • Способом восстановить удаленные сообщения, если их нет в SQLite

Требования

ОС

macOS 11 Big Sur или новее (протестировано до macOS 26)

Архитектура

Apple Silicon (arm64) или Intel (x86_64)

Python

3.9+ (системный /usr/bin/python3 работает — и обязателен для MCP-сервера, см. Установка)

Диск

Незначительно (~50 КБ после установки)

Разрешения

Полный доступ к диску для терминала/приложения, которое запускает скрипт

Поля схемы chat.db, на которые он опирается (text, payload_data, balloon_bundle_id, handle.id), остаются стабильными со времен macOS 10.13 High Sierra; этот инструмент, вероятно, будет работать и на более старых версиях, хотя это не тестировалось.

Установка

Вариант А — pipx (рекомендуется, для MCP-сервера требуется системный Python)

pipx изолирует инструмент в собственном venv. Сначала установите pipx, если нужно:

brew install pipx
pipx ensurepath

Затем установите этот инструмент из GitHub. Используйте /usr/bin/python3 явно — это важно для MCP-сервера, так как macOS передает «Полный доступ к диску» от Claude.app только дочерним процессам, подписанным Apple. Python из Homebrew подписан сторонним разработчиком; системный /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-сервер

Вариант Б — pip в venv

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 .

Вариант В — один файл, без установки

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 и т.д. — то, что вы используете)

    • Запускаете из Claude Desktop через MCP? → добавьте 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 (Вариант А выше с --python /usr/bin/python3). Это обязательно: «Полный доступ к диску» в macOS передается от Claude.app только подписанным Apple подпроцессам. /usr/bin/python3 подписан Apple; Python из Homebrew / pyenv / asdf не подписан, и доступ будет молча отклонен 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-сервер возвращает "unable to open database file" внутри Claude Desktop, цепочка атрибуции запуска нарушена. Проверьте лог демона TCC в macOS:

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

Трюк с извлечением строк из объектов позволяет избежать необходимости в ccl_bplist, pyobjc или полной семантике NSKeyedUnarchiver — для полнотекстового поиска нас не интересует граф объектов, только конечные строки.

Конфиденциальность и безопасность

  • Только чтение. Открывает chat.db с флагом SQLite URI mode=ro.

  • Только локально. Никаких сетевых вызовов. Никогда. (grep -r 'urllib\|requests\|http' src/ ничего не возвращает.)

  • Нет телеметрии.

  • Данные не покидают ваш Mac, если вы сами не решите поделиться выводом.

  • CLI не имеет зависимостей времени выполнения — нет ничего, что можно было бы атаковать через цепочку поставок.

  • См. SECURITY.md для сообщения об уязвимостях.

Ограничения

  • Только поиск по подстроке. Нет ранжирования FTS5, нет регулярных выражений, нет логических операторов. Добавьте их, если нужно (PR приветствуются).

  • Только локальная БД. Если сообщение живет только в iCloud и не синхронизировано с chat.db на этом Mac, оно не появится.

  • Метаданные предпросмотра зависят от того, загрузило ли их приложение «Сообщения». Если карточка ссылки не загрузилась (отправка офлайн, истекший URL), то payload_data для поиска нет.

  • Извлечение строк является потерей данных по дизайну. Оно извлекает каждую строку из bplist; иногда вы можете увидеть MIME-типы изображений, кортежи размеров вроде {0, 0} или URL-адреса изображений профиля в списке предпросмотра. Они не влияют на результаты поиска, но появляются в «сыром» выводе.

  • Полный доступ к диску — жесткое требование — обходных путей нет.

Устранение неполадок

Симптом

Решение

unable to open database file / cannot open chat.db

Не предоставлен «Полный доступ к диску» приложению. Добавьте приложение, затем ⌘Q + перезапуск.

Возвращает 0 совпадений, но приложение «Сообщения» их находит

Неверный формат --contact (должен совпадать с handle.id в chat.db — обычно +1XXXXXXXXXX или полный email). Запустите без --contact для проверки.

unable to open database file при вызове MCP из Claude Desktop (но CLI работает)

TCC отклонил запущенный Python. Переустановите с системным Python: pipx reinstall --python /usr/bin/python3 imessage-rich-search. См. раздел Проверка работы наследования TCC.

No module named 'imessage_rich_search' при запуске MCP-сервера

Переустановите с помощью pipx install --python /usr/bin/python3 "git+https://github.com/cannavis/imessage-rich-search"

Claude Desktop не видит инструмент

Проверьте синтаксис JSON в claude_desktop_config.json, полностью завершите Claude (⌘Q), перезапустите.

Поиск медленный на огромных базах

Текущая реализация делает линейное сканирование + парсинг bplist для каждой строки. Для БД с 100к+ сообщений ожидайте задержку в несколько секунд. Индекс на основе виртуальной таблицы FTS5 в планах.

Участие в разработке

См. CONTRIBUTING.md. Проблемы и PR приветствуются.

Журнал изменений

См. CHANGELOG.md.

Лицензия

MIT — см. LICENSE.

Благодарности

  • Схема chat.db от Apple, которая остается удивительно стабильной на протяжении десятилетия релизов 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