Skip to main content
Glama
PsychQuant

che-apple-mail-mcp

by PsychQuant

che-apple-mail-mcp

License: MIT macOS Swift MCP

El servidor MCP de Apple Mail más completo: 53 herramientas con búsqueda en milisegundos impulsada por SQLite en más de 250 000 correos.

English | 繁體中文


¿Por qué che-apple-mail-mcp?

Característica

Otros MCP

che-apple-mail-mcp

Herramientas totales

~20

53

Lenguaje

Python

Swift (nativo)

Velocidad de búsqueda

Segundos (AppleScript)

Milisegundos (SQLite)

Campos de búsqueda

Asunto/Remitente

Asunto/Remitente/Destinatario/Fecha

Operaciones por lotes

No

Hasta 50 correos por llamada

Gestión de buzones

Básica

CRUD completo

Colores de correo

No

7 colores de bandera + fondo

Gestión de VIP

No

Gestión de reglas

Parcial

CRUD completo

Firmas

No

Cabeceras/Fuente originales

No


Related MCP server: apple-mail-mcp

Inicio rápido

Instala el plugin. Incluye el binario firmado, la familia de comandos /archive-mail, las reglas de seguridad y el hook de frescura como una sola unidad:

claude plugin marketplace add PsychQuant/che-apple-mail-mcp
claude plugin install che-apple-mail-mcp@che-apple-mail-mcp

Después concede permisos — la ventana de configuración muestra el estado en vivo y enlaza directamente al panel correcto de Configuración del Sistema:

~/bin/CheAppleMailMCP --setup

💡 Acceso completo al disco es lo que hace funcionar la ruta de lectura rápida con SQLite y batch_export_emails_markdown. Sin el, las herramientas siguen ejecutándose pero leen poco o nada, y eso es fácil de confundir con un fallo en vez de con un permiso. macOS no permite que una aplicación solicite ACC programáticamente — hay que activarlo manualmente — y la ventana de configuración existe precisamente para que ese trámite sea rápido.

Plugin frente a solo MCP

Registrar el servidor MCP por sí solo es una vía avanzada con soporte, pero es una instalación estrictamente más reducida. Elígela a sabiendas — nada en tiempo de ejecución te dirá que faltan estas piezas (#353):

Lo que incluye el plugin

Lo que hay con solo MCP

Las 53 herramientas MCP

✅ sí

/archive-mail + -migrate / -rebuild-threads / -repair-synthetic-ids / -view

❌ el procedimiento operativo de archivo no existe

rules/compose-wrapper-free.md — lo que era el bloque de citas y lo que significa una llamada de composición rechazada

⚠️ contexto: desde #304 el wrapper es estructuralmente imposible, así que esta regla ahora explica los seis motivos de rechazo y sus soluciones, en lugar de proteger contra un fallback silencioso

rules/confirmation-triggers.md, rules/false-positivo-detection.md

❌ sin disciplina de confirmación en operaciones destructivas

hooks/session-start.sh — finalización de procesos obsoletos

❌ una sesión puede seguir ejecutando un binario obsoleto después de una actualización

Binario Developer ID firmado y notarizado

❌ un binario auto-compilado lleva firma ad-hoc; en macOS 26 TCC puede mantener FDA/“Automación” de fiar para él, así que los permisos parecen concedidos y después dejan de funcionar (#211)

Sidecar de versión → --self-update + autocontrol de frescura #303

❌ no hay-sidecar junto a un binario compilado a mano, así que esa verificación queda permanentemente callado

git clone https://github.com/PsychQuant/che-apple-mail-mcp.git
cd che-apple-mail-mcp
swift build -c release

# --scope user     : available across all projects (stored in ~/.claude.json)
# --transport stdio: local binary execution via stdin/stdout
# --               : separator between claude options and the command
mkdir -p ~/bin
cp .build/release/CheAppleMailMCP ~/bin/
claude mcp add --scope user --transport stdio che-apple-mail-mcp -- ~/bin/CheAppleMailMCP

Instala el binario en un directorio local como ~/bin/. Evita carpadas de a Nube (Dropbox, iCloud, OneDrive) — la actividad de sincronización provoca tiempos de espera en la conexión MCP.

Para que un binario auto-compilado conserve sus permisos TCC de una reconstrucción a otra, fírmelo con un Developer ID; consulta Firmado y notarización. De lo contrario, espera tener que volver a conceder los permisos tras cada build.


Últimas versiones

Para todos los detalles, consulta CHANGELOG.md.

v2.7.2 (2026-05-10) — clúster attachmentFragment + igualdad de fallback

  • Se ha endurecido la sangría de attachmentFragment en todas las 3 llamadas y se ha eliminado el helper muerto MailController.attachmentScript que evitaba los retardos de mitigación de carrera de la v2.7.0 (#61, #62)

  • Límite de 50 adjuntos y retardos configurables mediante variables de entorno (CHE_MAIL_ATTACHMENT_DELAY_BETWEEN / _TRAILING) (#71, #64)

  • La ruta SQLite de get_email_metadata ahora cae a AppleScript en caso de error — se cierra la última brecha de las herramientas de lectura; las 8 herramientas de lectura con prioridad SQLite tienen ahora un fallback de igualdad (#71)

v2.7.1 (2026-05-09) — corrección de base64 + .partial.emlx + observabilidad

  • Crítico: la división cabecera/cuerpo RFC822 devolvía un índice de matriz relativo en lugar de un índice absoluto de Data, lo que hacía que html_body comenzara con "sion: 1.0\n\n<base64>" en algunos mensajes de Gmail para Android — el base64 crudo se filtraba al contexto LLM y provocaba falsos positivos de AUP posteriores (#72)

  • save_attachment ahora lee desde la caché Attachments/<rowId>/<part_id>/<filename> cuando el cuerpo .partial.emlx está vacío — no más escrituras silenciosas de 0 bytes en mensajes IMAP con binarios eliminados (#66)

  • Los fallos de la ruta rápida SQLite ahora se registran en stderr (SQLite ... fast path failed for rowId=...; falling through to AppleScript) (#69)

v2.7.0 (2026-05-04) — mitigación de carreras en Mail.app

  • AppleScript con varios adjuntos acompasado con pausas de 0.3 s entre adjuntos y 0.5 s finales, para mitigar que Mail.app descarte adjuntos silenciosamente bajo IPC confirmativo (#60)

v2.6.0 (2026-05-03) — refuerzo de seguridad y validación (8 PR, 16 issues)

  • En forward_email el modo “sin formato” ahora incorpora el original citado con > según RFC 3676 (igualdad con el error de reply_email #43) (#44)

  • Fallo duro si los tipos de parámetros no coinciden — bool / [String] ya no se convierten silenciosamente (#35)

  • La validación de emails destinatarios rechaza la inyección de cabeceras (caracteres de control, @ faltante o múltiple) (#41)

  • cc_additional deduplica sin importar mayúsculas/minúsculas (#34)

  • Lista blanca-by-path de adjuntos (~/.ssh, Keychains, base de datos TCC, cookies de navegador) + resolución de symlinks + nueva variable permitida MAIL_PKG_ATTACHMENT_ROOTS por entorno (#38)

  • Las 17 herramientas que reciben id validan el id como Int en el límite del handler — evita la inyección de predicados en AppleScript (#38)

  • Tests de integración con acceso disponible para reply_email en tiempo real (runtime) (#37, #45) + plantillas de matrices de smoke (#46, #47)

v2.5.0 (2026-04-17) — parámetro format para composición

  • Las 4 herramientas de composición (compose_email / create_draft / reply_email / forward_email) ganan el parámetro format: "plain" | "markdown" | "html" (línea de cierre #14, #15)

  • Nueva especificación de capacidad message-composition


Todas las 53 herramientas

Herramienta

Descripción

list_accounts

Lista todas las cuentas de correo

get_account_info

Obtiene detalles de la cuenta

Herramienta

Descripción

list_mailboxes

Lista todos los buzones (carpetas)

create_mailbox

Crea un nuevo buzón

delete_mailbox

Elimina un buzón

get_special_mailboxes

Obtiene los nombres de buzones especiales (bandeja de entrada, borradores, enviados, papelera, no deseado, salida)

Herramienta

Descripción

mark_read

Marcar como leído/no leído

flag_email

Marcar/desmarcar correo

set_flag_color

Establecer el color de la bandera (7 colores)

set_background_color

Establecer el color de fondo del correo electrónico

mark_as_junk

Marcar como spam/no spam

move_email

Mover a otra bandeja de correo

copy_email

Copiar a otra bandeja de correo

delete_email

Eliminar correo (mover a la papelera)

Herramienta

Descripción

compose_email

Enviar un correo electrónico (admite cc/bcc/adjuntos; format: solo plain desde #304; from_address opcional para selección del remitente en cuentas múltiples — ver #131, tipo de registro —? ruta limpia admitida mediante la ventana emergente From verificada, #219). El cuerpo siempre proviene del editor de Mail — ver check_accessibility; una llamada que no pueda ejecutarse limpiamente FALLA con un motivo concreto y no crea nada (#304)

reply_email

Responder a un correo electrónico. Opcionales: cc_additional, attachments, save_as_draft, format (desde v2.4.0). El modo de texto plano incrusta el original citado > del RFC 3676 (desde v2.5.0 / #43). El nuevo cuerpo se pega en la respuesta nativa de Mail (#218); un format que no sea plain o la falta de permiso de Accesibilidad FALLA en lugar de recurrir a un mecanismo alternativo (#304)

forward_email

Reenviar correo. Opcional: body + format. El modo de texto plano incrusta el original citado > del RFC 3676 (desde v2.5.0+ / #44). Un reenvío sin cuerpo no asigna nada y no requiere permiso de Accesibilidad; con cuerpo se aplican las mismas reglas que reply_email (ver #218 y #304)

redirect_email

Redirigir el correo electrónico (conserva el remitente original)

open_mailto

Abrir una URL mailto

Ejemplo de respuesta como borrador (v2.4.0+)

Responder a un hilo, añadir CC adicional, adjuntar archivos y guardarlo como borrador para que una persona lo revise antes de enviarlo:

reply_email(
    id="<message id from search_emails>",
    mailbox="INBOX",
    account_name="iCloud",
    body="Reply text",
    cc_additional=["x@y.com"],
    attachments=["/path/to/file.pdf"],
    save_as_draft=true
)

Herramienta

Descripción

list_drafts

Listar los borradores de correo: cada entrada incluye un subject y un id numérico (#276, de tipo aditivo; alimenta update_draft.draft_id / delete_email.id)

create_draft

Crear un borrador (admite adjuntos; from_address opcional para selección del remitente en varios mapas cuentas — ver #131, ruta limpia admitida mediante la ventana emergente From verificada, #219). El cuerpo siempre proviene del editor de Mail: ver check_accessibility; una llamada que no pueda ejecutarse limpiamente FALLA con un motivo concreto y no crea nada (#304)

update_draft

Reemplazar un borrador existente (upsert, #276): buscar por draft_id o por subject_match exacto → crear un reemplazo (hereda la elegibilidad y el aviso de create_draft) → eliminar el anterior. Se crea primero y se elimina después deliberadamente, con un justificante posterior a la creación (un fallo siempre se inclina por conservar los borradores: en el peor caso ambas pueden existir, nunca ninguna). 0 coincidencias o más de 1 siempre se rechazan (se indican los candidatos). El reemplazo no recibe una NUEVA id.

Herramienta

Descripción

list_attachments

Listar adjuntos de correo

save_attachment

Guardar un adjunto en el disco

Herramienta

Descripción

list_vip_senders

Listar remitentes VIP

Herramienta

Descripción

list_rules

Listar reglas de correo

get_rule_details

Obtener detalles de una regla

create_rule

Crear una regla nueva

delete_rule

Eliminar una regla

enable_rule

Activar/desactivar una regla

Herramienta

Descripción

list_signatures

Listar firmas de correo electrónico

get_signature

Obtener el contenido de la firma

Herramienta

Descripción

list_smtp_servers

Listar servidores SMTP

Herramienta

Descripción

check_for_new_mail

Comprobar si hay correo nuevo

synchronize_account

Sincronizar la cuenta IMAP

Tool

Descripción

get_emails_batch

Obtiene hasta 50 correos en una sola llamada (errores por elemento)

list_attachments_batch

Lista los adjuntos de hasta 50 correos

batch_export_emails_markdown

Exportación masiva en el servidor a markdown literal y adjuntos (manifiesto de frontmatter congelado; concurrencia serializada por output_dir — #193 / #236)

export_emails_markdown

EN DESUSO — renombrado a batch_export_emails_markdown (#233); el alias se eliminará no antes de v3.0

Herramienta

Descripción

extract_name_from_address

Extrae el nombre de la dirección de correo

extract_address

Extrae el correo de una dirección completa

get_mail_app_info

Obtiene información de Mail.app

import_mailbox

Importa un buzón desde un archivo

Herramienta

Descripción

check_fda

Comprueba el estado de Acceso al disco completo (disponibilidad de la vía rápida de SQLite)

check_accessibility

Comprueba el permiso de Accesibilidad (rutas GUI de redactar/responder; sin él, esas herramientas se niegan a funcionar)

check_automation

Comprueba el permiso de Automatización (Apple Events a Mail) — sonda sin avisos, cuatro estados con corrección (#293); el binario tiene su PROPIA concesión, que osascript funcione no significa binario autorizado (#288)

Forma de la respuesta: search_emails / list_emails

Ambas herramientas devuelven un objeto contenedor { results, returned, limit, truncated }no un array simple (cambiado en v2.14.0, #204). Lee las coincidencias desde .results:

Campo

Significado

results

Array de objetos de resultado (los campos por objeto no cambian con respecto a la forma previa al contenedor). Los objetos de search_emails incluyen id, subject, sender, date_received, account_name, mailbox, to, y además account_id cuando el UUID de la cuenta es resoluble. Los objetos de list_emails incluyen id, subject, sender.

returned

Número de objetos que hay en results

limit

limit efectivo aplicado a la consulta

truncated

true cuando hay más resultados disponibles que los devueltos — aumenta limit o acota la consulta para recuperar el resto (definitivo en la vía rápida de SQLite; heurística de mejor esfuerzo en el respaldo de AppleScript — ver más abajo)

truncated es concluyente en la vía rápida de SQLite (obtiene internamente limit + 1); en el respaldo de AppleScript es una heurística de «mejor de esfuerzo» returned == limit. Cualquier consumidor de «enumerar → procesar en lote» debe comprobar truncated antes de asumir que tiene el conjunto completo.


Instalación

Empieza por Inicio rápido — instalar el plugin es la vía admitida y te da los comandos, las reglas de seguridad, el hook de desactualización y un binario firmado. Todo lo siguiente es la ruta avanzada / de desarrollo: registra únicamente el servidor MCP, una instalación estrictamente menor (consulta Plugin frente a solo MCP para saber qué falta; nada en tiempo de ejecución te lo advertirá).

Requisitos

  • macOS 13.0+

  • Xcode Command Line Tools (para la ruta de compilación propia que se indica abajo)

  • Apple Mail con al menos una cuenta configurada

Paso 1: Compilar

git clone https://github.com/PsychQuant/che-apple-mail-mcp.git
cd che-apple-mail-mcp
swift build -c release

Paso 2: Configurar

Para Claude Desktop

Edita ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "che-apple-mail-mcp": {
      "command": "/full/path/to/che-apple-mail-mcp/.build/release/CheAppleMailMCP"
    }
  }
}

Para Claude Code (CLI)

# Copy to ~/bin and register (user scope = available in all projects)
mkdir -p ~/bin
cp .build/release/CheAppleMailMCP ~/bin/
claude mcp add --scope user --transport stdio che-apple-mail-mcp -- ~/bin/CheAppleMailMCP

Paso 3: Conceder permisos

La vía más rápida es la ventana de configuración, que muestra el estado en vivo de Acceso al disco completo / Automatización / Accesibilidad, vuelve a comprobarlo mientras los concedes y abre por ti el panel correcto de Ajustes del Sistema:

~/bin/CheAppleMailMCP --setup

Para hacerlo a mano en su lugar:

Automatización (control de Mail.app):

open "x-apple.systempreferences:com.apple.preference.security?Privacy_Automation"
  1. Busca CheAppleMailMCP y habilita el permiso para Mail.app

  2. Si usas Claude Code, añade también Terminal o iTerm

Acceso al disco completo (la vía rápida de SQLite y export_emails_markdown leen ~/Library/Mail):

open "x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles"

macOS concede el Acceso al disco completo al proceso responsable — la app que inicia este servidor —, no al binario en sí. Para un servidor MCP ejecutado por Claude Code dentro de una terminal, el proceso responsable es la terminal (Ghostty / Terminal / iTerm), así que añade tu app de terminal aquí y actívalo. Una concesión en la terminal cubre todos los servidores MCP que lance. (Si en cambio ejecutas el binario directamente, o usas el paquete de Claude Desktop, añade terk — ~/bin/CheAppleMailMCP — pueşte así será su propio proceso responsable.) El mensaje de error de denegación de FDA te nombre a esos candidatos — no identifica automáticamente la app exacta, porque macOS no expone una API fiable dentro del proceso para eso (#214). Sin Acceso al disco completo, las herramientas de lectura caen silenciosamente a la vía más lenta de AppleScript y las funciones solo de SQLite (projection, export_emails_markdown) fallan. Para la ruta de ejecución directa, una compilación firmada con Developer ID hace que la concesión sobrevive a los cambios de versión — consulta Firma y notarización.

Configuración guiada (#213) — en lugar de los pasos manuales anteriores, el binario incluye asistentes de configuración:

  • CheAppleMailMCP --setup abre una pequeña ventana con el estado en vivo del Acceso al disco completo (lo re-comprueba con un temporizador y cambia a "Listo ✅" en el momento en que lo concedes), además de una comprobación de Automatización a petición y los botones "Abrir los ajustes de Acceso al disco completo" / "Copiar la ruta del binario".

  • CheAppleMailMCP --check-fda imprime el estado sin interfaz (y abre el panel cuando el acceso está denegado), indicado para ejecutarlo desde una terminal o un script.

  • La herramienta MCP check_fda informa del mismo estado a Claude a petición (llámala cuando falle alguna función solo SQLite).

Ninguna de estas opciones puede eliminar el único selector manual (Apple pone la FDA en el grupo de solo manual junto con Accesibilidad / Grabación de pantalla), pero hacen obvio el juego con «¿qué hago?» y dan retroalimentación en tiempo real en cuanto lo activas.

Accesibilidad (composición, #175/#304) — un permiso separado y opcional del Acceso total al disco. Mail.app envuelve cualquier cuerpo de mensaje saliente inyectado por AppleScript en <blockquote style="cite">, lo que algunos clientes móviles institucionalizan y muestran como una cita de tu propio texto — y que el emisor no puede ver localmente, porque el estilo en ningura del envoltorio no tiene borde. Desde #304 el código que lo producía ya no existe: cada herramienta de composición toma su cuerpo del propio editor de Apple Mail — un traspaso mailto: para compose_email / create_draft, el verbo nativo de responder / reenviar más pegar para reply_email / forward_email — y controla guardar / enviar / adjuntar con atajos de teclado, lo que requiere Accesibilidad (Ajustes del Sistema → Privacidad y seguridad → Accesibilidad), concedida al mismo proceso responsable de la FDA (tu terminal / Claude Desktop). La herramienta MCP check_accessibility y la fila Accesibilidad de la ventana --setup informan del estado. Sin ella, estas herramientas ahora FALLAN en lugar de degradarse — no hay un segundo camino al que recurrir, así que una llamada que no pueda ejecutarse limpiamente devuelve un error con nombre y no crea nada. El error apunta a open_mailto, que no requiere ninguna concesión TCC (no puede llevar adjuntos; guardas o envías tú la ventana). Hay exactamente seis condiciones que rechazan una llamada: un format que no sea plain; un asunto vacío; que no se haya concedido Accesibilidad; un from_address que no sea una dirección addr-spec simple; una ruta de adjunto con caracteres no ASCII (#220); y un destinatario con un nombre para mostrar que esta ruta no puede rellenar (siempre en cc/bcc; to en un envío — el nombre para mostrar de to de un borrador se rellena mediante la GUI, #277). Para un cuerpo correcto desde una cuenta no predeterminada, pasa from_address: la GUI lo selecciona en el menú emergente From de Apple Mail y relee la selección, abortando antes de arriesgarse a un remitente equivocado (#219). Eliminado con la ruta heredada: format: "markdown" / "html" — ninguna ruta disponible hoy ofrece texto enriquecido sin la asignación de cuerpo que se eliminó. Eso es lo que existe, no una prueba de imposibilidad (#310): la ruta de pegado (#218) es una segunda vía sin envoltorio y NSPasteboard puede transportar contenido enriquecido, pero el MIME que produce no está verificado — #306 lo zanja; #308 / #309 son alternativas: los parámetros require_wrapper_free y sanitize_links, y las vías de escape MAIL_DISABLE_MAILTO_COMPOSE / CHE_MAIL_DISABLE_PASTE_REPLY. Dos capacidades acompañan a todo esto, dicho sin rodeos: componer sin ventana visible (el propósito original de las vías de escape) ya no es posible, y compose_email ya no puede enviar a Name <addr> — usa create_draft y envía tú el borrador.

Autontización TCC (-1743) y la vía de escape sin TCC

Si las herramientas basadas en AppleScript fallan con AppleScript error (-1743): Not authorized to send Apple events to Mail, falta el permiso de Automatización de este binario. El binario MCP firmado tiene su propia concesión de Automatización — su identidad TCC está vinculada a la identidad de firma del binario (la lección #211 en el eje FDA), separada de la de tu terminal. Verificado empíricamente: que osascript controle Apple Mail desde tu shell no significa que el binario esté autorizado. Concede en Ajustes del Sistema → Privacidad y seguridad → Automatización — busca la entrada del binario / su proceso anfitrión (extensión de Claude Desktop: dentro de Claude.app) y activa Apple Mail. Si no existe ningún elemento, se está recordando una denegación anterior y macOS no volverá a preguntar: ejecuta tccutil reset Keydown, y a continuación reintenta con una herramienta de Mail para volver a provocar el aviso. Las concesiones son por instanciado, y una descripción del binario puede invalidar la entrada (#211).

Hasta que exista la concesión, open_mailto sigue funcionando: pasa por LaunchServices (TCC cero, #287) y abre una ventana de redacción sin bloque de cita en el cliente de correo predeterminado del sistema. mailto no puede llevar adjuntos (conforme a RFC 6068) — arrastra los archivos manualmente.

Paso 4: Reinicia Claude

# For Claude Desktop
osascript -e 'quit app "Claude"' && sleep 2 && open -a "Claude"

# For Claude Code - start a new session
claude

Casos de uso

Lenguaje natural (Claude Desktop)

"List all my mail accounts"
"Show unread emails in Gmail inbox"
"Search for emails about 'quarterly report'"
"Send an email to john@example.com about the meeting"
"Flag important emails in red"
"Create a rule to move newsletters to a folder"

Llamadas directas a herramientas (Claude Code)

"Use list_accounts to show my accounts"
"Use search_emails to find emails containing 'invoice'"
"Use set_flag_color to mark email ID 12345 as blue"
"Use check_for_new_mail to refresh"

Colores de marcador y de fondo

Colores de marcador (set_flag_color)

Índice

Color

0

Rojo

1

Naranja

2

Amarillo

3

Verde

4

Azul

5

Púrpura

6

Gris

-1

Sin

Colores de fondo (set_background_color)

blue, gray, green, none, orange, purple, red, yellow


Rendimiento y almacenamiento

Ruta rápida SQLite + .emlx

La mayoría de las herramientas de lectura prefieren el índice local Envelope Index de Apple Mail (SQLite) y los archivos de mensajes .emlx del disco a la interfaz de aplicación de AppleScript, con una fallback transparente a AppleScript cuando la ruta SQLite no puede completar una solicitud:

Herramienta

Ruta SQLite/.emlx

Fallback a AppleScript

get_email

  • ante cualquier error | | get_emails_batch | ✓ (por elemento de la lista) | ✓ (por elemento de la lista) | | get_email_headers | ✓ | ✓ ante cualquier error | | get_email_source | ✓ | ✓ ante cualquier error | | search_emails | ✓ | ✓ cuando el lector no está disponible | | list_attachments | ✓ | ✓ ante cualquier error | | save_attachment | ✓ | ✓ ante cualquier error | | get_email_metadata | ✓ | ✓ ante cualquier error (desde #71) |

Para la ruta de lectura de save_attachment, la ruta rápida es 10–100× más rápida que AppleScript (según mediciones de #12). La proporción de mejora de las demás herramientas depende de la forma de la solicitud; en general, las grandes lecturas multimentales reciben la mayor mejora.

La ruta rápida requiere:

  • El proceso anfitrión debe tener concedido Acceso total al disco (Ajustes del Sistema → Privacidad y seguridad → Acceso al disco).

  • El almacenamiento local de Apple Mail en ~/Library/Mail/V10/....

  • El mensaje se ha sincronizado a un archivo .emlx local.

Las cuentas EWS / Exchange omiten deliberadamente la ruta rápida

Las cuentas Exchange (EWS) en Apple Mail no generan archivos .emlx — los cuerpos de los mensajes están en un servidor y se obtienen de forma dinámica. Para estas cuentas, las 8 herramientas de lectura (incluida get_email_metadata desde #71) degradan de forma transparente a IPC a AppleScript (lo cual es correcto, pero más lento). Síntomas:

  • Una descarga de 500 mensajes EWS será mucho más lenta que la descarga de 500 mensajes IMAP/Gmail.

  • No es un bug, sino una restricción de la arquitectura de almacenamiento de Apple Mail (ver #9).

Diagnosticar el salto de la ruta rápida

Cuando la ruta rápida falla para una cuenta que no es EWS, el fallo se registra en stderr (desde #69). Ejecuta el binario en una terminal y observa stderr para distinguir:

  • EnvelopeIndexReader init failed: ... — base de datos inaccesible (normalmente: falta permiso de Acceso total al disco)

  • SQLite get_email fast path falló para rowId=N: ... — fallo por mensaje (por ejemplo, solo .partial.emlx, MIME malformado, archivo aún no sincronizado)

En ambos casos se degrada de forma transparente a AppleScript con ... falling through to AppleScript en la línea de registro, de modo que el comportamiento se conserva mientras se restaura la observabilidad.


Solución de problemas

Problema

Solución

Servidor desconectado

Reconstruye con swift build -c release

No se permite enviar eventos de Apple

Añade permisos en Ajustes del Sistema > Automatización

Mail.app no responde

Asegúrate de que Mail.app esté en ejecución con cuentas configuradas

Los comandos superan el tiempo de espera

Las bandejas de entrada grandes tardan más; prueba búsquedas específicas

La recuperación masiva es más lenta de lo esperado

Vigila en stderr las líneas ... falling through to AppleScript. Las cuentas EWS/Exchange siempre usan el método de respaldo (ver Rendimiento y almacenamiento); otras cuentas que registran el método de respaldo indican un problema .emlx reparable

save_attachment falla con -1728 "Can't get account" o -1719 "Invalid mailbox index"

Desde la edición #173 ambos errores regresan con una pista útil que nombra la referencia fallida (cuenta / buzón / mensaje). Las causas habituales: dos cuentas de Mail.app comparten el mismo display_name, o por correo electrónico con account_name cubre varios por las cuentas — ver Desambiguación de cuentas a continuación.


Desambiguación de cuenta

El selector account "<display_name>" de AppleScript de Mail.app no es único cuando dos cuentas comparten el mismo display_name: un patrón común cuando un alias global de iCloud reenvía a una dirección de Gmail en sí misma, o cuando se superponen Google Workspace y Gmail personal. Cualquier método de ruta es AppleScript (save_attachment fallback, get_email, march_read, etc.) elegirá entonces de forma no determinista la cuenta equivocada → errores -1728 / -1719.

La solución: produce cuenta_id (UUID de Mail.app, único a nivel mundial) junto a cuenta_nombre. Cuando se proporciona, save_attachment usa en cambio el selector account id "<UUID>" de Mail.app, evitando así la ambigüedad:

// Tool call: save_attachment with account_id
{
    "id": "273214",
    "mailbox": "[Gmail]/全部郵件",
    "account_name": "alice@example.com",
    "account_id": "C38E0583-47F8-4468-BE70-43155C15549D",  // ← disambiguates
    "attachment_name": "report.pdf",
    "save_path": "/tmp/report.pdf"
}

Descubriendo account_id:

  • Desde resultados search_emails: cada objeto de la matriz results (un SearchResultjemplo) tiene un campo account_id junto con account_name (rellenos al decodificar el UUID de la cuenta de la autoridad mailboxes.url de SQLite mediante MailboxURL.decode: Mail.app estándar de almacenamiento codifica el UUID en la autoridad de URL del buzón; no existe SELECT directo mailboxes.account_id). Recommended: pásalo directamente.

  • Manualmente: lee en ~/Library/Mail/V10/MailData/Claves de aplicación/AccountsMap.plist. Claves de nivel superior son los UUID; el valor AccountURL contiene la dirección de correo equivalente codificada en porcentaje y en la autoridad de URLAuthority.

  • En AppleScript: tell application "Mail" to get id of every account devuelve tan UUID.

Backward compatibility: account_id es opcional. Cuando se omite (o está vacío), las herramientas recurran a la ruta heredada de account "<display_nombre>" — comportamiento idéntico al de #101 — excepto una excepción de save_attachment (#1733): cuando account_name contiene @ (forma de correo, la forma que produce herramientas de rutas SQLite como search_emails), save_attachment well, it first looks it reverse in AccountsMap and slackly upgrades to selector account id "<UUID>" (the upgrade is logged to stderr). Exactamente una coincidencia → ese UUID; varias cuentas behind a single address (ej., catch-all de iCloud + Gmail) → error accionable que lista todas las candidatas en lugar de un -1728; si no hay coincidencia → the original path of display_name, unchanged. Edge: a mail account whose description legitimately contains @ and equals another account's email now grows in the email scope: pay account_id explicitly to force the selector. Rest tools maintain strict pre-#101 fallback (el barrido en todas las herramientas es #176).

Scope: account_id is accepted in all AppleScript-routed tools that refer to mail by account. Todo comenzó con save_attachment (#101); la revisión de #104 tras eso, añadió las 13 herramientas de un solo mensaje / movimiento / retransmisión / buzón que vienen a continuación::

  • save_attachment (#101) — el predecesor

  • PR-A — 5 herramientas de mutación de un único mensaje: mark_read, flag_email, set_flag_color, set_background_color, mark_as_junk

  • PR-B — 3 herramientas de movimiento / eliminación: move_email, copy_email, delete_email

  • PR-C — 3 herramientas de retransmisión de mensajes: reply_email, forward_email, redirect_email

  • PR-D — 2 herramientas CRUD de buzones: create_mailbox, delete_mailbox

La superficie se ha ampliado desde el conjunto #104:

  • #176 — generalizó el paso por resolveAccountIdForTool para el corre→UUID a todos los 14 (manipuladores de escritura por AppleScript, para que un account_name con forma de correo se resuelva al selectorUUID, no solo a un account_id aceptado).

  • #180 — introdujo account_id en los fallbacks de AppleScript de las herramientas de lectura con el ( getMailboxsearch_emailsget_emailget / headers / source / metadata / attachments / get_unread_count) mediante resolveMailboxRef / resolveMsgRef (el PR-E que se había pospuesto ahora está hecho).

  • #179get_special_mailboxes admite account_id / account_name para los nombres reales de buzones especiales por cuenta.

  • #191 — las herramientas de acción de nivel de cuenta check_new_mail y synchronize_account ganaron la interfaz de escapar account_id (synchronize_account acepta solo account_id).

Todavía no cubiertos por con account_id (en seguimiento): get_account_info / list_mailboxes (#202).

compose_email / create_draft no presentan define la defecto de colisión de display_name: en su demonstrate it hacen make new outgoing message en lugar de referenciar a un correo existente por cuenta, por lo que nunca emiten un selector account "<display_name>". A selección del remitente multi-cuenta ya está disponible con uso de from_address opcional (#131): pasa cualquiera de las direcciones de correo configuradas en Mail.app ("alice@example.com" o formulario RFC 5322 "Alice <alice@example.com>") para fijar el sender del mensaje saliente; si no, usa la cuenta predeterminada. Usa list_accounts para descubrir las direcciones configuradas en el Mac actual.

No se admite mover o copiar entre cuentas mediante account_id (#129 — from #127 verify). move_email y copy acepta un único account_id, que atraviesa tanto el msgRef de origen como el mailboxRef de destino. The architectural choice is correct (movement remains within a single account, because Mail.app’s AppleScript move message to <mailboxRef> requires the destination mailbox to be expressed relative to a unique account context). Mail.app’s UI allows cross-account moves by drag and drop, but the AppleScript-routed tools move_email / copy_email cannot replicate it — when move_email with account_id of a one account is expected, and the destination to_mailbox is dealt with against another account, it silently chooses the mailbox of the wrong account with that name (if both account have it) or throws -1719 "Invalid mailbox index". Si necesitas una copia del mismo contenido en una cuenta de procedencia distinta, puedes reconstruct manually with save_attachment + compose_email — note that it is not a real move/copy: the original metadata (Message-ID, date-received, flags, labels) and no message identity are preserved.


Technical details

  • Framework: MCP Swift SDK v0.10.0

  • Ruta de lectura: SQLite (Envelope Index) + analizador de archivos .emlx, con fallback de AppleScript para EWS / .emlx no analizables

  • Ruta de escritura / estado: AppleScript través de NSAppleScript

  • Transport: stdio

  • Plataforma: macOS 13.0+ (Ventura y posterior)


Firma y notarización

El binario distribuido está firmado Developer ID y notarizado, y esto no es cosmético. La ruta de lectura rápida necesita Acceso Full Disk Access (FDA) y macOS TCC vincula una concesión de FDA al requisito designado del binario. Para un binario ad-hoc ese requote es el cdhash, así que cada cambio de versión invalidaba con la concesión y existen que re-add en binaria a la lista de Full Disk Access después de cada release. Una firma estable de Developer ID vincula la concesión a la identidad de firma en su lugar, de modo que sobrevive carries bumps de versión (#211) — esa firma, not not jazione, es lo que provide persistence.

La notarización es importante y para los lanzamientos en cuarentena: una descarga de navegador o de install .pmb (Claude Desktop), donde Gatekeeper evalúa el binario en el primer desplieque. El path del plugin wrapper (a curl + exec no establece ningún atributo de cuarentena, por eso Gatekeeper nunca se ejecuta allí. Nota pero, notamos para que «published release asset» esté seguro de ejecutarEl en la ruta any.

La primera concesión aún es manual. El FDA accessibility (PCServiceSystemPolicyAllFiles) no tiene petición programática con mediante una Api — una app únicamente te lleva mediante un deep enlace en el panel de ajustes. La firma hace que esa primera concesión sea permanente, no automática.

Configuración de una sola vez (para mantenedores)

# 1. Developer ID Application cert in your login keychain (needs an Apple Developer account)
security find-identity -p codesigning -v        # find your identity

# 2. notarytool keychain profile (prompts for an app-specific password — never pass it on the CLI)
xcrun notarytool store-credentials <profile-name> \
  --apple-id <your-apple-id> --team-id <your-team-id>

# 3. Export both for the signed targets
export DEVELOPER_ID='Developer ID Application: Your Name (TEAMID)'
export NOTARY_PROFILE='<profile-name>'

Instalación de desarrollo en tu propia máquina — no (rápida — sin notarización)

make install-signed     # build + Developer ID sign + copy to ~/bin

Utiliza esto para obtener una concesión de FDA estable en tu propio Mac sin esperar la notarización de Apple: tu propio certificado se ejecuta correctamente en local y la concesión sobrevive a futuras reconstrucciones. Concede el Acceso completo al disco una vez a ~/bin/CheAppleMailMCP y habrás terminado.

Lanzamiento de distribución (firmado + notarizado + publicado)

make release-signed VERSION=vX.Y.Z      # wraps scripts/release.sh with REQUIRE_CODESIGN=1

Esto crea un binario universal (arm64 + x86_64), lo firma, lo notariza (de 1 a 15 min de notarización de Apple) y lo sube al lanzamiento de GitHub. Aquellos forks sin treetografías aún pueden crear un lanzamiento de desarrollo sin firmar con SKIP_CODESIGN=1 ./scripts/release.sh v1.Y.Z.


Contribuciones

¡Las contribuciones son bienvenidas! No dudes en abrir un Pull Request.


Lit LikHappy

MIT License - consulta LICENSE para conocer los detalles.


Autor

Creado por Ch Cien (@kiki830621)

Si te resulta útil, considera darle una estrella.

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

Maintenance

Maintainers
1dResponse time
4dRelease cycle
44Releases (12mo)
Commit activity
Issues opened vs closed

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
    A
    quality
    A
    maintenance
    Enables AI assistants to interact with Apple Mail through natural language, providing comprehensive email management including reading, searching, composing, organizing, and analyzing emails across all configured accounts. Includes an expert skill system that teaches intelligent email workflows and productivity strategies.
    26
    193
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables unified email management across Gmail, Outlook, iCloud, and IMAP providers with tools for search, send, organize, and batch operations via natural language.
    58
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables using Apple Mail accounts to search, read, manage, draft, and send messages from Codex or Claude Code locally.
    MIT

View all related MCP servers

Related MCP Connectors

  • Manage Gmail end-to-end: search, read, send, draft, label, and organize threads. Automate workflow…

  • Read, search, send, organize, draft and schedule email across your inboxes from any MCP client.

  • Let ChatGPT, Claude & Cursor use your Mac: email, calendar, iMessage, Teams, files. Local, free.

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/PsychQuant/che-apple-mail-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server