icloud-mcp
Servidor MCP stdio para el Calendario de iCloud con Contactos y Correo opcionales.
Documentación
icloud-mcp
Accede a Calendario, Contactos y Correo de iCloud a través de Model Context Protocol. Un único binario Go sirve JSON-RPC sobre stdio y se conecta mediante CalDAV, CardDAV, IMAP y SMTP.
El servidor funciona sin interfaz gráfica con contraseñas específicas de la aplicación. Utiliza protocolos remotos, sin frameworks de macOS, automatización de navegador ni APIs privadas de Apple. Los archivos de distribución admiten Linux amd64/arm64 y macOS arm64. CI también compila para Windows amd64.
Cualquier host MCP con stdio puede iniciar el binario con su entorno de proceso.
El binario no carga .env ni archivos de configuración específicos del host.
| Dominio | Protocolo | Predeterminado |
|---|---|---|
| Calendario | CalDAV HTTPS | Siempre activo (lectura + escritura a menos que sea solo lectura global) |
| Contactos | CardDAV HTTPS | Desactivado hasta ICLOUD_MCP_ENABLE_CONTACTS |
| Lectura de correo | IMAP TLS | Desactivado hasta ICLOUD_MCP_ENABLE_MAIL |
| Mutación de correo | IMAP | Desactivado hasta Correo + ICLOUD_MCP_ENABLE_MAIL_WRITE |
| Envío de correo | SMTP STARTTLS | Desactivado hasta Correo + ICLOUD_MCP_ENABLE_MAIL_SEND + política de destinatarios |
Recordatorios, Notas, Fotos, Drive, Buscar, Llavero, Mensajes y Casa están fuera del alcance admitido. Los Recordatorios modernos no utilizan el conector CalDAV de este servidor.
Inicio rápido
Usa Go 1.26.0 o posterior:
go install github.com/ThomasCrouzet/icloud-mcp/cmd/icloud-mcp@latest
- Crea una contraseña específica de la aplicación. Nunca uses la contraseña principal de la Cuenta Apple.
- Guarda la identidad y la contraseña en archivos regulares separados fuera del repositorio.
- Asigna a cada archivo el modo
0600o más estricto y un tamaño máximo de 4 KiB. - Configura el entorno para acceso de solo lectura al Calendario:
export ICLOUD_EMAIL='file:///private/path/icloud-email'
export ICLOUD_PASSWORD='file:///private/path/icloud-password'
export ICLOUD_MCP_READ_ONLY=true
export ICLOUD_MCP_DEFAULT_TZ=Europe/Paris # owner IANA zone; default UTC
- Registra la ruta absoluta del binario y el entorno en tu host MCP.
- Reinicia el proceso MCP después de los cambios de configuración.
Stdio transporta JSON-RPC. Stderr transporta registros y eventos de auditoría de mutaciones. El servidor lee los archivos de credenciales solo al inicio. El descubrimiento del Calendario requiere acceso a la red antes de que stdio comience.
Esta configuración expone 7 herramientas: lecturas de Calendario, ayudantes locales y
icloud_capabilities. El proceso no construye un cliente de Contactos o Correo.
Dominios opcionales (aún en formato export independiente del host):
# Contacts reads (writes also need ICLOUD_MCP_READ_ONLY=false)
export ICLOUD_MCP_ENABLE_CONTACTS=true
# Mail reads: IMAP identity may differ from ICLOUD_EMAIL (e.g. name@icloud.com)
export ICLOUD_MCP_ENABLE_MAIL=true
export ICLOUD_MAIL_ADDRESS='file:///private/path/icloud-mail-address'
# Optional separate password; otherwise Mail uses ICLOUD_PASSWORD.
# export ICLOUD_MAIL_PASSWORD='file:///private/path/icloud-mail-password'
# Mail mutation (flags / move / trash); independent of send
export ICLOUD_MCP_ENABLE_MAIL_WRITE=true
export ICLOUD_MCP_READ_ONLY=false
# Mail send: requires exact recipient allowlist even under global read-only
export ICLOUD_MCP_ENABLE_MAIL_SEND=true
export ICLOUD_MCP_SMTP_ALLOWED_RECIPIENTS='alice@example.com,bob@example.net'
Consulta .env.example para el contrato completo de 12 variables.
Herramientas MCP
El servidor expone un máximo de 23 herramientas. Las herramientas desactivadas están ausentes de
tools/list. El proceso no construye clientes para dominios desactivados.
| Cantidad | Cuándo |
|---|---|
| 10 | Predeterminado: lectura+escritura de Calendario + icloud_capabilities |
| 7 | Solo lectura global, dominios opcionales desactivados (primera ejecución recomendada) |
| 23 | Contactos + lectura de Correo + mutación + envío, solo lectura desactivado |
ICLOUD_MCP_READ_ONLY=true elimina cada escritura de Calendario/Contactos, cada mutación de
Correo y el envío de Correo. No habilita un dominio de lectura desactivado.
| Grupo | Herramientas |
|---|---|
| Global | icloud_capabilities |
| Lectura de Calendario | list_calendars, search_events, get_event, find_free_slots, validate_event, calendar_capabilities |
| Escritura de Calendario | create_event, update_event, delete_event |
| Lectura de Contactos | list_address_books, search_contacts, get_contact |
| Escritura de Contactos | create_contact, update_contact, delete_contact |
| Lectura de Correo | list_mailboxes, search_messages, get_message |
| Mutación de Correo | set_message_flags, move_message, trash_message |
| Envío de Correo | send_message |
Las operaciones de actualización y eliminación de Calendario admiten ocurrencias y usan
If-Match sólido. Contactos usa identificadores de libro opacos y escribe vCard 3.0.
Correo usa identidades (mailbox, UIDVALIDITY, UID), lecturas PEEK y una política de destinatarios
exacta para SMTP. set_message_flags falla de forma segura con
protocol_error cuando se anuncia CONDSTORE. Esto ocurre porque go-imap
beta.8 no puede observar MODIFIED etiquetado. Consulta las notas de comportamiento completas:
docs/caldav-compatibility.md,
docs/carddav-compatibility.md,
docs/mail-compatibility.md.
Crear UIDs e idempotencia de actualización
create_event y create_contact usan client_uid o su alias idempotency_key
como UID del recurso. Una creación devuelve conflict si ese UID existe.
Nunca sobrescribe silenciosamente el objeto.
Solo update_event y update_contact almacenan resultados en caché mediante idempotency_key.
La caché local del proceso contiene 1.024 entradas, con un máximo de 256 KiB por carga útil.
La misma clave y parámetros devuelven el resultado guardado. Parámetros diferentes devuelven
conflict. Los éxitos y errores definitivos permanecen durante 15 minutos. Los resultados
desconocidos permanecen hasta la salida del proceso. Las reclamaciones pendientes no caducan.
Una caché completa rechaza nuevas reclamaciones antes de una escritura. Mantén la clave y espera capacidad.
Después de una respuesta ambigua, usa get_event o get_contact antes de una nueva actualización.
Una nueva clave o reinicio del proceso no demuestra que la escritura anterior falló.
Usa un etag nuevo y sólido para una actualización nueva necesaria.
Consulta el contrato de caché y el procedimiento de recuperación.
Configuración
Exactamente 12 variables de entorno del producto:
| Variable | Predeterminado | Contrato |
|---|---|---|
ICLOUD_EMAIL | ninguno | Identidad requerida de Calendario/Contactos. Se admite file:// (archivo regular, <=4 KiB, modo 0600+). |
ICLOUD_PASSWORD | ninguno | Contraseña específica de la aplicación requerida. Correo la usa como respaldo. file:// como arriba. |
ICLOUD_MCP_READ_ONLY | false | Interruptor global de mutación. |
ICLOUD_MCP_LOG_LEVEL | info | Nivel de stderr. Consulta los formatos aceptados a continuación. |
ICLOUD_MCP_DEFAULT_TZ | UTC | Zona IANA para entradas de Calendario sin desplazamiento y respaldo de escritura recurrente. |
ICLOUD_MCP_ENABLE_CONTACTS | false | Herramientas de Contactos. Las escrituras requieren que el modo de solo lectura esté desactivado. |
ICLOUD_MCP_ENABLE_MAIL | false | Lecturas de Correo. Requiere una dirección de Correo y contraseña. |
ICLOUD_MAIL_ADDRESS | ninguno | Dirección IMAP/SMTP completa cuando Correo está activo. file:// como arriba. |
ICLOUD_MAIL_PASSWORD | ICLOUD_PASSWORD | Contraseña de Correo dedicada opcional. file:// como arriba. |
ICLOUD_MCP_ENABLE_MAIL_WRITE | false | Tres herramientas de mutación IMAP. |
ICLOUD_MCP_ENABLE_MAIL_SEND | false | send_message (independiente de la escritura de Correo). |
ICLOUD_MCP_SMTP_ALLOWED_RECIPIENTS | ninguno | Requerida si el envío está activo. Usa direcciones exactas o * literal. El * literal causa una advertencia de inicio. Usa direcciones exactas cuando sea posible. |
Los booleanos aceptan solo no establecido, 0, false, 1 o true. Los valores inválidos causan un
fallo de inicio. El servidor valida la configuración antes del acceso a la red.
La escritura o el envío de Correo sin Correo causa un error de inicio. Correo sin dirección o
contraseña también causa un error de inicio. El envío sin política de destinatarios causa un
error de inicio, incluso en modo de solo lectura.
El modo de solo lectura global puede coexistir con los indicadores de escritura y envío, pero evita su registro.
El servidor recorta los niveles de registro e ignora mayúsculas y minúsculas. Acepta debug o -4,
info, warn, warning o 2, y error o 4. Los valores no establecidos o no reconocidos
usan info.
Usa -version para imprimir la versión. El indicador opcional
-health 127.0.0.1:port sirve /healthz y /status en loopback. Ambos
puntos finales devuelven JSON con dominios y límites de velocidad. El indicador opcional
-audit-format=json|text selecciona el formato de auditoría de mutaciones en stderr.
El formato predeterminado es json.
Fechas
- Entrada de Calendario
startyendaceptan RFC3339 con desplazamiento. También aceptan valores de hora local sin desplazamiento enICLOUD_MCP_DEFAULT_TZ. Usa valores sin desplazamiento para la hora local del usuario. Las creaciones recurrentes y las creaciones con una zona horaria explícita escriben TZID y VTIMEZONE. Las creaciones temporizadas no recurrentes usan UTCZpor defecto en el cable. Las creaciones de día completo usanVALUE=DATE. - Salida de Calendario usa RFC3339 para eventos temporizados. Siempre incluye un
desplazamiento numérico explícito en
ICLOUD_MCP_DEFAULT_TZ, nuncaZdesnudo. Las fechas de día completo usanYYYY-MM-DD. Consultacalendar_capabilities.outputFormat. - Cumpleaños de Contactos: escribe
YYYY-MM-DDsolamente. - Búsqueda de Correo:
sinceinclusivo,beforeexclusivo (YYYY-MM-DD).
Seguridad (resumen)
El texto remoto no confiable puede influir en un LLM en el host. Las etiquetas no forman una frontera de seguridad. Un modelo comprometido puede llamar a cada herramienta registrada. Este riesgo se aplica a cada host y proveedor.
- Egreso fijo: Calendario usa
caldav.icloud.comy hostsp[0-9]{1,3}-caldav.icloud.com:443coincidentes. Contactos usa hosts de Contactos coincidentes. IMAP usaimap.mail.me.com:993. SMTP usasmtp.mail.me.com:587con STARTTLS obligatorio. Los destinos no son configurables. El servidor ignora las variables de entorno de proxy DAV y verifica TLS 1.2 o posterior. - Aislamiento: cada dominio tiene credenciales, transportes, dialers, limitadores, semáforos y pilas de protocolo separados. Ningún cliente HTTP autenticado se conecta a múltiples dominios.
- Secretos: el servidor elimina secretos, incluidas las formas Basic y SASL PLAIN.
Las lecturas de
file://solo de inicio requieren modo 0600 o más estricto. El servidor no usaos/execni telemetría. No escribe en disco después del inicio. - Auditoría: los registros de mutaciones incluyen
domain,resourceTypey el HMACresourceTokenlocal del proceso. Nunca contienen rutas sin procesar, UIDs, buzones o destinatarios. - Riesgo residual: un proceso tiene credenciales para todos los dominios habilitados. Los indicadores de características no eliminan el código compilado. Para un aislamiento más fuerte, usa el modo de solo lectura y habilita menos dominios. También puedes usar una contraseña de Correo dedicada o procesos separados.
Política completa: SECURITY.md, docs/security.md. Arquitectura: docs/architecture.md.
Límites (resumen)
| Plazo de herramienta | 25s (DAV HTTP 30s) |
| Resultado Stdio / MCP | Marco de 1 MiB. Resultado de 256 KiB. Los errores de protocolo reflejados tienen un límite. |
| Calendario | Rango de búsqueda: 366 días. Resultados: 400 en total, 2.500 por calendario y 10.000 materializados entre calendarios. Recurrencia: 2.000 expansiones, 100k pasos por serie y 250k pasos por búsqueda. Velocidad: 60 lecturas y 20 escrituras por minuto. Concurrencia: 4 lecturas y 2 escrituras. |
| Contactos | 100 libros. 100 resúmenes. 2000 tarjetas escaneadas. Velocidad: 60 lecturas y 20 escrituras por minuto. Concurrencia: 4. |
| Correo | Velocidad: 60 lecturas, 20 mutaciones y 20 envíos por minuto. Semáforos: 2 lecturas, 1 mutación y 1 envío. Sin reintento de mutación o envío. |
| Escrituras | Sin reproducción automática de PUT/DELETE de Calendario, escrituras de Contactos, mutaciones IMAP o SMTP. Los resultados ambiguos usan outcome_unknown. |
El servidor descubre Calendario al inicio y Contactos cuando se usa por primera vez. Cada llamada usa una sesión IMAP o SMTP nueva. Consulta estos documentos para velocidades, presupuestos de analizador y reglas de reintento: docs/testing.md, docs/architecture.md.
Múltiples cuentas
Un proceso tiene una identidad de iCloud. Inicia un proceso separado para cada identidad. Asigna a cada proceso un entorno separado y un puerto de salud opcional. Consulta integración de host.
Dependencias
Usa Go 1.26.0 o más reciente. El proyecto tiene un módulo y exactamente 10 dependencias directas. Si agregas una dependencia directa, agrega su justificación aquí.
| Dependencia | Versión exacta | Justificación |
|---|---|---|
github.com/emersion/go-webdav | v0.7.0 | Primitivas CalDAV. El descubrimiento y las operaciones condicionales permanecen escritas a mano. |
github.com/emersion/go-ical | v0.0.0-20250609112844-439c63cef608 | Análisis/codificación de iCalendar |
github.com/mark3labs/mcp-go | v1.2.0 | MCP stdio, esquemas, JSON-RPC |
github.com/teambition/rrule-go | v1.8.2 | Recurrencia acotada con preservación de zona horaria |
golang.org/x/time | v0.16.0 | Limitadores de velocidad por dominio |
github.com/emersion/go-vcard | v0.1.0 | Lectura de vCard 3.0/4.0, escritura 3.0 |
github.com/emersion/go-imap/v2 | v2.0.0-beta.8 | IMAP detrás de internal/mail/imapadapter |
github.com/emersion/go-message | v0.18.2 | Límites MIME / texto plano |
github.com/emersion/go-smtp | v0.25.0 | SMTP + STARTTLS |
github.com/emersion/go-sasl | v0.0.0-20241020182733-b788ff22d5a6 | SASL PLAIN después de STARTTLS |
Compilación y pruebas
make build # local host binary, VERSION defaults to dev
make test # go test ./... -race -cover
make lint # go vet + pinned golangci-lint
make release VERSION=v0.4.0 # packaged linux/arm64, digest-pinned Go 1.26.9 image
make release-all VERSION=v0.4.0 # packaged linux/amd64, linux/arm64, darwin/arm64 (host Go)
make install # host-compatible build to INSTALL_DIR (default ~/.local/bin)
Los objetivos de lanzamiento requieren un árbol de trabajo limpio y una versión que no sea dev. Los archivos contienen
el binario, LICENSE y THIRD_PARTY_NOTICES.md. El directorio dist/ también
contiene un archivo de suma de verificación SHA-256. Los lanzamientos de etiquetas de GitHub ejecutan make release-all
solo después de que CI y gitleaks tengan éxito para esa etiqueta. Usan Go 1.26.9 con
check-latest deshabilitado.
El make release local usa la ruta de contenedor con digest fijado para linux/arm64.
Los blobs de lanzamiento incluyen firmas sin clave de cosign. -version primero usa el
valor de ldflags de lanzamiento. Si este valor está ausente, usa la información de compilación del módulo Go.
Por lo tanto, go install ...@version informa la versión del módulo.
CI verifica formato, pruebas de carrera, fuzzing, vulnerabilidades, secretos, texto público
y compilaciones multiarquitectura. Aplica mínimos de cobertura y un límite de binario de 20 MiB.
Las pruebas en vivo requieren la etiqueta de compilación integration y puertas explícitas de dominio/escritura.
CI nunca las ejecuta. Consulta Pruebas.
Para evidencia de protocolo solo con fixtures, usa una ruta de salida absoluta fuera del repositorio:
make protocol-evidence EVIDENCE_DIR=/external/path
El ejecutor compila un ejecutable a partir de pruebas cmd/icloud-mcp con registro MCP
compartido y código de inicio stdio. También ejecuta escenarios de idempotencia y
recurrencia en proceso. Guarda transcripciones, metadatos de ejecución, revisión de fuente,
diff de trabajo, valores SHA-256 de fixtures y resultados fuera del repositorio.
CI conserva el artefacto protocol-evidence durante 14 días. Estas verificaciones usan fixtures
sintéticos y no establecen compatibilidad en vivo con iCloud.
Documentación
| Documento | Propósito |
|---|---|
| Integración de host | Configuración YAML y JSON, procesos multi-cuenta, comportamiento del llamador |
| Códigos de error | Reglas de reintento y recuperación de mutaciones |
| Arquitectura | Inicio, límites de dominio, concurrencia, idempotencia de actualización |
| Compatibilidad CalDAV | Descubrimiento de calendarios, escrituras condicionales, recurrencia, límites |
| Compatibilidad CardDAV | Descubrimiento de contactos, soporte vCard, búsqueda, escrituras condicionales |
| Compatibilidad de correo | Sesiones IMAP, identidad de mensajes, mutación, envío SMTP |
| Política de seguridad e implementación | Modelo de amenazas, informes y controles técnicos |
| Pruebas | Verificaciones locales, evidencia de protocolo, CI y puertas de integración en vivo |
| Contribución | Desarrollo, escritura, política de pruebas y soporte |
| Registro de cambios | Historial de lanzamientos |
Atribución
La forma de las herramientas de calendario y varios patrones fueron inspirados por
github.com/roygabriel/mcp-icloud-calendar
(MIT, copyright 2026 Gabe). El código fue reescrito, no copiado. Este servidor añade
egreso duro por dominio, redacción, analizadores acotados, mutación condicional,
Contactos, Correo y sin telemetría.
Contribución
Consulta CONTRIBUTING.md. Ejecuta gofmt, make test y make lint
antes de abrir una solicitud de extracción.
Licencia
MIT. Consulta LICENCIA y avisos de terceros.