Apple Messages MCP
Apple Messages MCP
Читайте и ищите свои переписки iMessage, SMS и RCS из Claude на macOS.
Дополнение к claude-connector-apple-mail и claude-connector-apple-reminders.
Статус: чтение и поиск работают надёжно. Отправка работает, но не проверена на
реальной отправке — вызов скрипта реализован, его синтаксис проверен, но
Apple уже ломала send раньше, так что первую реальную отправку считайте тестом.
См. Отправка сообщений.
Инструменты
Инструмент | Описание |
| Итоги, количество непрочитанных, разбивка по службам (iMessage/SMS/RCS), диапазон дат |
| Переписки, сначала самые недавние, с участниками и превью |
| Сообщения в одной переписке, сначала старые, с постраничной разбивкой |
| Поиск подстроки по всей истории, с фильтром по переписке, отправителю и диапазону дат |
| Одно сообщение полностью, с вложениями и временными метками доставки |
| Вложение в байтах, в кодировке base64 |
| Прогрев или пересоздание локального поискового индекса |
| Открыть Messages с предзаполненным текстом — вы нажимаете «Отправить» |
| Отправить в существующую переписку; доставляется немедленно |
Related MCP server: jons-mcp-imessage
Требования
macOS 13 Ventura или новее. RCS требует macOS 26 или новее.
Полный доступ к диску для приложения Claude — требуется для чтения.
Разрешение автоматизации для Messages — требуется для отправки и для имён контактов. macOS запрашивает его автоматически.
Предоставление полного доступа к диску
Системные настройки → Конфиденциальность и безопасность → Полный доступ к диску
Включите Claude (добавьте
/Applications/Claude.appчерез +, если его нет в списке)Завершите работу Claude и откройте его снова. macOS кэширует это разрешение при запуске процесса, поэтому перезапуск обязателен — без него расширение будет продолжать давать сбои.
Почему здесь нужен полный доступ к диску, а для Apple Mail — нет
Расширение Apple Mail общается с Mail.app полностью через скрипты, поэтому ему не нужны особые разрешения. Messages так работать не может.
Словарь AppleScript для Messages предоставляет ровно четыре класса — account,
chat, participant, file transfer — и никакого класса сообщений. Проверено
на macOS 26.5.2:
$ osascript -e 'tell application "Messages" to get every text message of first chat'
syntax error: Expected "from", etc. but found identifier. (-2741)Переписки и участники перечисляются нормально; тексты сообщений просто не
доступны. Поэтому единственный путь чтения — SQLite через ~/Library/Messages/chat.db, который
защищён TCC. В отличие от автоматизации, полный доступ к диску нельзя запросить
программно — пользователь должен предоставить его вручную.
Поэтому расширение использует оба разрешения для разных задач:
Задача | Механизм | Разрешение |
Сообщения, переписки, поиск, вложения | SQLite на | Полный доступ к диску |
Имена контактов для «сырых» идентификаторов | Скрипты Messages | Автоматизация |
Отправка | Скрипты Messages ( | Автоматизация |
Окно создания, предзаполнение | Схема URL | нет |
Имена контактов берутся из класса participant в Messages (свойство full name), который
читает карточку контакта пользователя. Это обходит отдельно защищённую базу
AddressBook — если автоматизация запрещена, идентификаторы просто отображаются как «сырые» номера.
Заметки по реализации
attributedBody. Начиная с Ventura, message.text часто равен NULL, а
текст сообщения хранится в message.attributedBody в формате Apple typedstream — это
устаревший формат NSArchiver, который plistlib не умеет читать. typedstream.py декодирует его на
чистом Python, так что пакету не нужна зависимость PyObjC. Он опирается на
имя класса NSString/NSMutableString и читает полезную нагрузку UTF-8 с префиксом длины
после маркера типа +. Декодирование полное: не поддающееся декодированию тело даёт
None, а не приводит к сбою запроса.
Временные метки. message.date — это эпоха Apple (2001-01-01), в секундах до
macOS 13 и в наносекундах начиная с неё. Оба варианта распознаются и обрабатываются.
Поиск. В chat.db нет текстового индекса, и большинство текстов живут только в
attributedBody, где SQL их не видит. Такое сочетание сложнее, чем кажется.
Первая реализация расширяла свой предикат до
m.text LIKE ? OR m.attributedBody IS NOT NULL и повторно фильтровала декодированный
текст в Python. Поскольку второе условие истинно почти для каждой современной
строки, LIMIT запроса усекал сканирование до нескольких сотен самых новых сообщений
до того, как фильтр Python вообще запускался — поэтому любое более старое совпадение молча исчезало. Поиск
реального сообщения возвращал ноль результатов, а не был медленным. На истории
объёмом 916 МБ это означало, что поиск фактически покрывал только последние несколько дней.
Исправление — декодировать один раз, а не при каждом запросе. index.py зеркалирует декодированные
тексты, приведённые к нижнему регистру, в ~/Library/Caches/apple-messages-mcp/search-index.db,
к которому затем подключается поиск — так что совпадение, фильтры, сортировка и
LIMIT применяются ко всей истории в SQL. Зеркало:
Инкрементальное. Новые сообщения находятся по водяному знаку
message.ROWID. Правки и отмены отправки повторно используют существующий ROWID, поэтому каждое обновление также просматривает последние 2000 строк — но только те, у которыхdate_editedустановлен или оба столбца тела теперь NULL, поскольку повторное декодирование 2000 блоков при каждом поиске — это реальная работа, которая почти всегда ничего не находит. Правка, которую Messages каким-то образом не пометил, или правка старше этого окна, требуетrefresh_search_index(rebuild=True). Улучшение декодераattributedBodyтакже оправдывает пересоздание; увеличениеSCHEMA_VERSIONпринудительно его выполняет.Приведено к нижнему регистру, и только это. Отображаемый текст по-прежнему берётся из chat.db, так что зеркало — чисто оракул для сопоставления. Хранение
str.casefold()уменьшает его размер вдвое и делает сопоставление без учёта регистра корректным для не-ASCII — SQLiteLIKEсворачивает регистр только для ASCII.Одноразовое. Оно живёт в
~/Library/Cachesи пересоздаётся при удалении. Ничто здесь не пишет в chat.db.
Не FTS5, несмотря на более ранний план: FTS5 сопоставляет целые токены, поэтому
MATCH 'dentist' никогда не найдёт «mydentist», что уже, чем семантика подстроки,
которую документирует search_messages. Сканирование подстрок по компактному тексту
в нижнем регистре уже быстрое, так что FTS5 удвоил бы индекс ради семантики, которую мы
не можем использовать. Добавить его позже — изолированное изменение, если какой-то запрос
вдруг станет тормозить.
Только чтение и без блокировок. Соединения открываются с mode=ro, и ни один оператор
не изменяет базу данных. Если SQLite не может открыть живой WAL в режиме только для чтения, он
переключается на частную копию-снимок, так что работающий Messages.app никогда не нарушается.
Tapbacks, правки, ответы. Реакции декодируются из
associated_message_type (2000–2007, а диапазон 3000 — их удаления),
ответы в ветках — из thread_originator_guid, а правки — из date_edited.
Отправка сообщений
В Messages нет объекта черновика, поэтому нет точного аналога подхода Mail-расширения «сначала черновик». Поэтому путь записи реализован на двух уровнях, и они намеренно не эквивалентны.
compose_message — безопасный вариант по умолчанию. Открывает Messages с получателем и
текстом, предзаполненными через схему URL imessage: / sms:, и останавливается. Человек
читает и нажимает «Отправить», так что ничего не покидает машину по указанию Claude.
Это также единственный способ начать новую переписку. Не требует никаких разрешений.
send_message — доставляет немедленно. Использует send из интерфейса скриптов
и не может быть отменено. Он принимает chat_id, а не номер телефона,
что не ограничение, а суть: словарь принимает либо participant, либо chat, и адресация
существующей переписки по GUID позволяет Messages выбирать транспорт (iMessage / SMS / RCS)
вместо того, чтобы вызывающий угадывал и молча отправлял SMS тому, кто на iMessage. Также требуется
confirm=True — чисто как защита от случайного срабатывания.
Что проверено, а что нет
Подтверждено на macOS 26.5.2 — словарь предоставляет
send : direct-parameter (file | text), to: (participant | chat)перечисление service type — это SMS, iMessage, RCS, у chat есть
свойство GUID id для адресации, и сгенерированный AppleScript компилируется.
Не подтверждено: что реальная отправка действительно доставляет. Apple уже ломала
AppleScript send раньше, и его наличие в словаре никогда не было
доказательством работоспособности. Ничто в тестовом наборе не доставляет сообщение, так что первая
реальная отправка — это эксперимент. Если она не сработает, shortcuts run с действием
«Отправить сообщение» — следующий вариант, который стоит попробовать.
Текст сообщения передаётся в AppleScript как аргумент osascript (on run argv),
а не вставляется в исходный код скрипта, поэтому тело, содержащее
двойную кавычку, инертно, а не вызывает синтаксическую ошибку или инъекцию.
Отправка вложений не подключена, хотя прямой параметр file означает,
что она в пределах досягаемости.
Разработка
python3 tests/test_db.py # SQL, decoder, and search-index tests
python3 tests/test_send.py # compose URLs, send guards, argv safety
python3 tools/probe_schema.py # verify the real chat.db (needs Full Disk Access)
./build.sh # test, validate manifest, pack the .mcpbtests/test_db.py создаёт одноразовые базы данных с реальной схемой, поэтому SQL
можно проверять без полного доступа к диску или реальной истории сообщений. Один из тестов
прячет совпадение под 3000 более новых сообщений — это регрессионный тест для
описанной выше ошибки усечённого поиска.
tests/test_send.py никогда ничего не отправляет и не открывает окно: он покрывает построитель
URL, защитные условия и точный argv osascript — так что он безопасен
где угодно и, соответственно, не может сказать вам, работает ли send от Apple.
Ни один из наборов не касается реального поискового индекса; оба внедряют временный.
Лицензия
MIT
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables Claude to send and read iMessages on macOS, with smart contact lookup, message history retrieval, and cross-conversation search using natural language commands.5MIT
- AlicenseAqualityDmaintenanceEnables AI assistants to read iMessage history and send messages on macOS. Supports conversation listing, message search with keyword and semantic modes, contact lookup, and sending messages to existing conversations.1311MIT
- AlicenseNot gradedqualityDmaintenanceEnables Claude to read and search through iMessage, SMS, and RCS conversations, including mixed-protocol group chats with Android users. It decodes binary message data from the macOS Messages database to provide a comprehensive view of message history.19MIT
- AlicenseNot gradedqualityBmaintenanceEnables Claude to send and read iMessages on macOS, with human approval required for sending and no auto-replies.51Apache 2.0
Related MCP Connectors
Let ChatGPT, Claude & Cursor use your Mac: email, calendar, iMessage, Teams, files. Local, free.
MCP connector for iMessage & Contacts via a local Mac agent + Vercel relay
Search, read, and write your Apple Notes from ChatGPT/Claude via a local Mac agent + MCP relay.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/falconbradley/claude-connector-apple-messages'
If you have feedback or need assistance with the MCP directory API, please join our Discord server