icloud-mcp

Servidor MCP stdio para el Calendario de iCloud con Contactos y Correo opcionales.

Documentación

icloud-mcp

CI Release License: MIT

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.

A stdio MCP client connects to capability gates and four separate iCloud protocol clients.

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.

DominioProtocoloPredeterminado
CalendarioCalDAV HTTPSSiempre activo (lectura + escritura a menos que sea solo lectura global)
ContactosCardDAV HTTPSDesactivado hasta ICLOUD_MCP_ENABLE_CONTACTS
Lectura de correoIMAP TLSDesactivado hasta ICLOUD_MCP_ENABLE_MAIL
Mutación de correoIMAPDesactivado hasta Correo + ICLOUD_MCP_ENABLE_MAIL_WRITE
Envío de correoSMTP STARTTLSDesactivado 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
  1. Crea una contraseña específica de la aplicación. Nunca uses la contraseña principal de la Cuenta Apple.
  2. Guarda la identidad y la contraseña en archivos regulares separados fuera del repositorio.
  3. Asigna a cada archivo el modo 0600 o más estricto y un tamaño máximo de 4 KiB.
  4. 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
  1. Registra la ruta absoluta del binario y el entorno en tu host MCP.
  2. 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.

CantidadCuándo
10Predeterminado: lectura+escritura de Calendario + icloud_capabilities
7Solo lectura global, dominios opcionales desactivados (primera ejecución recomendada)
23Contactos + 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.

GrupoHerramientas
Globalicloud_capabilities
Lectura de Calendariolist_calendars, search_events, get_event, find_free_slots, validate_event, calendar_capabilities
Escritura de Calendariocreate_event, update_event, delete_event
Lectura de Contactoslist_address_books, search_contacts, get_contact
Escritura de Contactoscreate_contact, update_contact, delete_contact
Lectura de Correolist_mailboxes, search_messages, get_message
Mutación de Correoset_message_flags, move_message, trash_message
Envío de Correosend_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:

VariablePredeterminadoContrato
ICLOUD_EMAILningunoIdentidad requerida de Calendario/Contactos. Se admite file:// (archivo regular, <=4 KiB, modo 0600+).
ICLOUD_PASSWORDningunoContraseña específica de la aplicación requerida. Correo la usa como respaldo. file:// como arriba.
ICLOUD_MCP_READ_ONLYfalseInterruptor global de mutación.
ICLOUD_MCP_LOG_LEVELinfoNivel de stderr. Consulta los formatos aceptados a continuación.
ICLOUD_MCP_DEFAULT_TZUTCZona IANA para entradas de Calendario sin desplazamiento y respaldo de escritura recurrente.
ICLOUD_MCP_ENABLE_CONTACTSfalseHerramientas de Contactos. Las escrituras requieren que el modo de solo lectura esté desactivado.
ICLOUD_MCP_ENABLE_MAILfalseLecturas de Correo. Requiere una dirección de Correo y contraseña.
ICLOUD_MAIL_ADDRESSningunoDirección IMAP/SMTP completa cuando Correo está activo. file:// como arriba.
ICLOUD_MAIL_PASSWORDICLOUD_PASSWORDContraseña de Correo dedicada opcional. file:// como arriba.
ICLOUD_MCP_ENABLE_MAIL_WRITEfalseTres herramientas de mutación IMAP.
ICLOUD_MCP_ENABLE_MAIL_SENDfalsesend_message (independiente de la escritura de Correo).
ICLOUD_MCP_SMTP_ALLOWED_RECIPIENTSningunoRequerida 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 start y end aceptan RFC3339 con desplazamiento. También aceptan valores de hora local sin desplazamiento en ICLOUD_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 UTC Z por defecto en el cable. Las creaciones de día completo usan VALUE=DATE.
  • Salida de Calendario usa RFC3339 para eventos temporizados. Siempre incluye un desplazamiento numérico explícito en ICLOUD_MCP_DEFAULT_TZ, nunca Z desnudo. Las fechas de día completo usan YYYY-MM-DD. Consulta calendar_capabilities.outputFormat.
  • Cumpleaños de Contactos: escribe YYYY-MM-DD solamente.
  • Búsqueda de Correo: since inclusivo, before exclusivo (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.com y hosts p[0-9]{1,3}-caldav.icloud.com:443 coincidentes. Contactos usa hosts de Contactos coincidentes. IMAP usa imap.mail.me.com:993. SMTP usa smtp.mail.me.com:587 con 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 usa os/exec ni telemetría. No escribe en disco después del inicio.
  • Auditoría: los registros de mutaciones incluyen domain, resourceType y el HMAC resourceToken local 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 herramienta25s (DAV HTTP 30s)
Resultado Stdio / MCPMarco de 1 MiB. Resultado de 256 KiB. Los errores de protocolo reflejados tienen un límite.
CalendarioRango 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.
Contactos100 libros. 100 resúmenes. 2000 tarjetas escaneadas. Velocidad: 60 lecturas y 20 escrituras por minuto. Concurrencia: 4.
CorreoVelocidad: 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.
EscriturasSin 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í.

DependenciaVersión exactaJustificación
github.com/emersion/go-webdavv0.7.0Primitivas CalDAV. El descubrimiento y las operaciones condicionales permanecen escritas a mano.
github.com/emersion/go-icalv0.0.0-20250609112844-439c63cef608Análisis/codificación de iCalendar
github.com/mark3labs/mcp-gov1.2.0MCP stdio, esquemas, JSON-RPC
github.com/teambition/rrule-gov1.8.2Recurrencia acotada con preservación de zona horaria
golang.org/x/timev0.16.0Limitadores de velocidad por dominio
github.com/emersion/go-vcardv0.1.0Lectura de vCard 3.0/4.0, escritura 3.0
github.com/emersion/go-imap/v2v2.0.0-beta.8IMAP detrás de internal/mail/imapadapter
github.com/emersion/go-messagev0.18.2Límites MIME / texto plano
github.com/emersion/go-smtpv0.25.0SMTP + STARTTLS
github.com/emersion/go-saslv0.0.0-20241020182733-b788ff22d5a6SASL 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

DocumentoPropósito
Integración de hostConfiguración YAML y JSON, procesos multi-cuenta, comportamiento del llamador
Códigos de errorReglas de reintento y recuperación de mutaciones
ArquitecturaInicio, límites de dominio, concurrencia, idempotencia de actualización
Compatibilidad CalDAVDescubrimiento de calendarios, escrituras condicionales, recurrencia, límites
Compatibilidad CardDAVDescubrimiento de contactos, soporte vCard, búsqueda, escrituras condicionales
Compatibilidad de correoSesiones IMAP, identidad de mensajes, mutación, envío SMTP
Política de seguridad e implementaciónModelo de amenazas, informes y controles técnicos
PruebasVerificaciones locales, evidencia de protocolo, CI y puertas de integración en vivo
ContribuciónDesarrollo, escritura, política de pruebas y soporte
Registro de cambiosHistorial 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.