Skip to main content
Glama
falconbradley

Apple Messages MCP

Apple Messages MCP

Lee y busca tus conversaciones de iMessage, SMS y RCS desde Claude, en macOS.

Complemento de claude-connector-apple-mail y claude-connector-apple-reminders.

Estado: la lectura y la búsqueda son sólidas. El envío funciona, pero no está probado en un envío real — la llamada de scripting está implementada y su sintaxis verificada, pero Apple ha roto send antes, así que trata el primer envío real como una prueba. Ver Envío de mensajes.

Herramientas

Tool

Description

get_stats

Totales, recuento de no leídos, desglose por servicio (iMessage/SMS/RCS), rango de fechas

list_chats

Conversaciones, las más recientes primero, con participantes y una vista previa

get_chat_messages

Mensajes de una conversación, de más antiguo a más reciente, paginados

search_messages

Búsqueda de subcadenas en todo el historial, filtrada por chat, remitente y rango de fechas

get_message

Un mensaje completo, con adjuntos y marcas de tiempo de entrega

get_attachment

Bytes del adjunto, codificados en base64

refresh_search_index

Calienta o reconstruye el índice de búsqueda local

compose_message

Abre Messages con el texto prellenado — pulsas enviar

send_message

Envía a una conversación existente; entrega inmediatamente

Related MCP server: jons-mcp-imessage

Requisitos

  • macOS 13 Ventura o posterior. RCS requiere macOS 26 o posterior.

  • Acceso total al disco para la app de Claude — necesario para la lectura.

  • Permiso de Automatización para Messages — necesario para el envío y para los nombres de contacto. macOS solicita este permiso automáticamente.

Cómo otorgar Acceso total al disco

  1. Ajustes del Sistema → Privacidad y Seguridad → Acceso total al disco

  2. Activa Claude (añade /Applications/Claude.app con + si no aparece en la lista)

  3. Sal y vuelve a abrir Claude. macOS guarda en caché este permiso al iniciar el proceso, por lo que el reinicio es obligatorio: la extensión seguirá fallando sin él.

Por qué esto necesita Acceso total al disco cuando Apple Mail no

La extensión de Apple Mail se comunica con Mail.app enteramente mediante scripting, por lo que no necesita permisos especiales. Messages no puede funcionar de esa manera.

El diccionario de AppleScript de Messages expone exactamente cuatro clases — account, chat, participant, file transfer — y ninguna clase de mensaje. Verificado en 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)

Los chats y los participantes se enumeran sin problema; los cuerpos de los mensajes simplemente no están expuestos. Así que la única vía de lectura es SQLite sobre ~/Library/Messages/chat.db, que está protegido por TCC. A diferencia de la Automatización, el Acceso total al disco no puede solicitarse mediante programación: el usuario debe concederlo manualmente.

Por lo tanto, la extensión utiliza ambos permisos para distintas tareas:

Ámbito

Mecanismo

Permiso

Messages, chats, búsqueda, adjuntos

SQLite sobre chat.db

Acceso total al disco

Nombres de contacto para identificadores sin procesar

Scripting de Messages

Automatización

Envío

Scripting de Messages (send)

Automatización

Ventana de redacción, prellenada

Esquema de URL imessage: / sms:

ninguno

Los nombres de contacto provienen de la clase participant de Messages (full name), que lee la tarjeta de Contactos del usuario. Esto evita la base de datos de AddressBook, protegida por separado: si se deniega la Automatización, los identificadores se muestran simplemente como números sin procesar.

Notas de implementación

attributedBody. Desde Ventura, message.text es frecuentemente NULL y el cuerpo vive en message.attributedBody como un typedstream de Apple — el formato heredado de NSArchiver, que plistlib no puede leer. typedstream.py lo decodifica en Python puro, por lo que el paquete no necesita dependencia de PyObjC. Se ancla en el nombre de clase NSString/NSMutableString y lee la carga útil UTF-8 con prefijo de longitud después del marcador de tipo +. La decodificación es total: un cuerpo no decodificable produce None en lugar de hacer fallar la consulta.

Marcas de tiempo. message.date es la época de Apple (2001-01-01), en segundos antes de macOS 13 y en nanosegundos desde entonces. Ambos casos se detectan y se manejan.

Búsqueda. chat.db no incluye ningún índice de texto, y la mayoría de los cuerpos viven solo en attributedBody, donde SQL no puede verlos. Esa combinación es más problemática de lo que parece.

La primera implementación ampliaba su predicado a m.text LIKE ? OR m.attributedBody IS NOT NULL y volvía a filtrar el texto decodificado en Python. Como esa segunda cláusula es verdadera para casi todas las filas modernas, el LIMIT de la consulta truncaba el escaneo a los últimos cientos de mensajes antes de que el filtro de Python llegara a ejecutarse, por lo que cualquier coincidencia más antigua desaparecía silenciosamente. Una búsqueda de un mensaje real devolvía cero resultados en lugar de ser lenta. En un historial de 916 MB, eso significaba que la búsqueda cubría efectivamente solo los últimos días.

La solución es decodificar una sola vez en lugar de hacerlo por consulta. index.py replica los cuerpos decodificados y convertidos a minúsculas (casefold) en ~/Library/Caches/apple-messages-mcp/search-index.db, contra el que las búsquedas hacen join — de modo que la coincidencia, los filtros, el orden y el LIMIT se aplican al historial completo en SQL. El espejo es:

  • Incremental. Los mensajes nuevos se encuentran mediante una marca de agua message.ROWID. Las ediciones y las cancelaciones de envío reutilizan un ROWID existente, por lo que cada actualización también examina las 2000 filas más recientes — pero solo aquellas con date_edited establecido o con ambas columnas de cuerpo ahora NULL, ya que volver a decodificar 2000 blobs en cada búsqueda es un trabajo real que casi nunca encuentra nada. Una edición que Messages no haya marcado de algún modo, o una más antigua que esa ventana, necesita refresh_search_index(rebuild=True). Mejorar el decodificador de attributedBody también justifica una reconstrucción; aumentar SCHEMA_VERSION fuerza una.

  • Solo con casefold, y nada más. El texto mostrado sigue viniendo de chat.db, por lo que el espejo es puramente un oráculo de coincidencias. Almacenar str.casefold() reduce su tamaño a la mitad y hace que la coincidencia sin distinción de mayúsculas sea correcta para texto no ASCII — el LIKE de SQLite solo pliega mayúsculas para ASCII.

  • Desechable. Vive en ~/Library/Caches y se reconstruye si se elimina. Nada de esto escribe en chat.db.

No es FTS5, a pesar del plan anterior: FTS5 coincide con tokens completos, por lo que MATCH 'dentist' nunca encuentra "mydentist", lo cual es más restrictivo que la semántica de subcadena que documenta search_messages. Un escaneo de subcadenas sobre texto compacto con casefold ya es rápido, así que FTS5 habría duplicado el índice para una semántica que no podemos usar. Añadirlo más adelante es un cambio contenido si alguna consulta llegara a ir lenta.

Solo lectura y sin bloqueos. Las conexiones se abren con mode=ro y ninguna sentencia muta la base de datos. Si SQLite no puede abrir el WAL en vivo en modo solo lectura, recurre a una copia instantánea privada para que una instancia en ejecución de Messages.app nunca se vea afectada.

Tapbacks, ediciones, respuestas. Las reacciones se decodifican desde associated_message_type (2000–2007, con el rango 3000 como sus eliminaciones), las respuestas en hilo desde thread_originator_guid, y las ediciones desde date_edited.

Envío de mensajes

Messages no tiene objeto de borrador, por lo que no existe un análogo exacto del diseño de borrador primero de la extensión de Mail. Por lo tanto, la vía de escritura se presenta en dos niveles, y deliberadamente no son equivalentes.

compose_message — el valor seguro por defecto. Abre Messages con el destinatario y el cuerpo prellenados mediante el esquema de URL imessage: / sms:, y se detiene. Una persona lo lee y pulsa enviar, así que nada sale de la máquina por orden de Claude. Esta es también la única forma de iniciar una conversación nueva. No necesita ningún permiso.

send_message — entrega inmediatamente. Utiliza el send de la interfaz de scripting, y no se puede deshacer. Toma un chat_id en lugar de un número de teléfono, lo cual no es una limitación sino el objetivo: el diccionario acepta tanto un participant como un chat, y dirigirse a un chat existente por GUID permite que Messages elija el transporte (iMessage / SMS / RCS) en lugar de que quien llama adivine y envíe silenciosamente un SMS a alguien que está en iMessage. También requiere confirm=True, puramente como protección contra una activación casual.

Qué está verificado y qué no

Confirmado en macOS 26.5.2 — el diccionario expone

send : direct-parameter (file | text), to: (participant | chat)

la enumeración service type es SMS, iMessage, RCS, chat tiene una propiedad id GUID para dirigirse a él, y el AppleScript generado compila.

No confirmado: que un envío real realmente entregue. Apple ha roto el send de AppleScript antes, y su presencia en el diccionario nunca ha sido prueba de que funcione. Nada en el conjunto de pruebas entrega un mensaje, así que el primer envío real es el experimento. Si falla, shortcuts run con una acción "Enviar mensaje" es la alternativa que vale la pena probar a continuación.

El texto del mensaje llega a AppleScript como un argumento de osascript (on run argv) en lugar de ser interpolado en el código fuente del script, por lo que un cuerpo que contenga una comilla doble es inerte en lugar de un error de sintaxis o una inyección.

El envío de adjuntos no está conectado, aunque el parámetro directo file significa que está al alcance.

Desarrollo

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 .mcpb

tests/test_db.py crea bases de datos desechables con el esquema real, por lo que el SQL puede validarse sin Acceso total al disco ni un historial de mensajes real. Una de ellas entierra una coincidencia bajo 3000 mensajes más recientes, que es la prueba de regresión para el error de búsqueda truncada descrito anteriormente.

tests/test_send.py nunca envía nada ni abre una ventana: cubre el constructor de URL, las cláusulas de protección y el argv exacto de osascript — por lo que es seguro en cualquier lugar y, en consecuencia, no puede decirte si el send de Apple funciona.

Ninguna de las dos suites toca el índice de búsqueda real; ambas inyectan uno temporal.

Licencia

MIT

A
license - permissive license
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables Claude to send and read iMessages on macOS, with smart contact lookup, message history retrieval, and cross-conversation search using natural language commands.
    5
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Enables 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.
    13
    11
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables 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.
    19
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables Claude to send and read iMessages on macOS, with human approval required for sending and no auto-replies.
    5
    1
    Apache 2.0

View all related MCP servers

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.

View all MCP Connectors

Latest Blog Posts

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