Skip to main content
Glama
IceyWu

icloud-calendar-mcp

by IceyWu

icloud-calendar-mcp

Servidor MCP de Apple iCloud Calendar fiable y ligero. TypeScript/Node.js nativo, se conecta directamente a iCloud a través de CalDAV; no depende de Java, Python, Go, AppleScript, macOS ni Calendar.app.

Resumen en inglés: Un servidor MCP TypeScript multiplataforma orientado a producción para Apple iCloud Calendar. Proporciona CRUD CalDAV protegido, identificadores opacos persistentes, escrituras idempotentes, control de concurrencia ETag, expansión de recurrencias, stdio y transporte Streamable HTTP seguro.

Instalación

Requiere Node.js 20 o superior. Debe usar una "contraseña específica para la aplicación" de Apple, no la contraseña principal de la cuenta Apple.

npx icloud-calendar-mcp

Crear una contraseña específica para la aplicación: inicie sesión en account.apple.com, vaya a "Inicio de sesión y seguridad" → "Contraseñas específicas para la aplicación". Apple puede limitar la cantidad de contraseñas específicas para la aplicación que pueden estar activas simultáneamente; al revocar una contraseña, este servicio recibirá AUTH_FAILED.

Configuración del cliente stdio:

{
  "mcpServers": {
    "icloud-calendar": {
      "command": "npx",
      "args": ["-y", "icloud-calendar-mcp"],
      "env": {
        "ICLOUD_USERNAME": "you@example.com",
        "ICLOUD_APP_PASSWORD": "xxxx-xxxx-xxxx-xxxx"
      }
    }
  }
}

stdout se usa solo para JSON-RPC; todos los registros se escriben en stderr.

Related MCP server: Chronos MCP

Herramientas y contenido MCP

Nombre

Descripción

list_calendars

Lista los calendarios de iCloud

list_events

Consulta por rango de tiempo explícito, zona horaria, cursor y límite; solicita al servidor CalDAV expandir ocurrencias

get_event

Lee un evento usando un identificador opaco persistente entre procesos

create_event

Crea de forma idempotente con request_id y UID estable

update_event

Actualiza con identificador persistente y If-Match

delete_event

Elimina con identificador persistente y If-Match

find_conflicts

Busca eventos con superposición horaria

free_busy

Calcula de forma fiable los intervalos ocupados desde el lado del cliente a partir de los eventos legibles actuales

Las herramientas devuelven tanto structuredContent como texto JSON, y declaran anotaciones de solo lectura/destructivas/idempotentes/mundo abierto. Recurso: calendar://calendars. Prompts de plantilla de usuario explícitos: schedule_event, reschedule_event, find_conflicts; no toman decisiones de agenda por el usuario.

Los eventos admiten programados/todo el día, título, descripción, ubicación, URL, RRULE, alarma DISPLAY y asistentes. El campo de asistentes está limitado por iCloud y los permisos de uso compartido del calendario; este servicio no informa falsamente que "escribir ATTENDEE" significa que la invitación se ha enviado correctamente.

Semántica de tiempo y eventos recurrentes

  • La entrada de eventos programados debe proporcionar hora ISO 8601 y timezone IANA; la salida también devuelve la zona horaria explícitamente.

  • Los eventos de todo el día usan YYYY-MM-DD para start/end, end no está incluido en el evento. Por ejemplo, un evento de todo el día el 18 de agosto sería start=2026-08-18, end=2026-08-19.

  • iCalendar se construye y analiza con ical.js, sin concatenar cadenas con campos de usuario; las pruebas cubren DST, UTC y los límites de todo el día.

  • list_events expande ocurrencias RRULE a través de la solicitud calendar-data/expand de CalDAV.

  • whole_series admite actualización/eliminación. single_occurrence, this_and_future devuelven UNSUPPORTED_OPERATION cuando no se ha verificado la capacidad de excepción de recurrencia de iCloud, nunca cambian silenciosamente a toda la serie.

Modo HTTP

HTTP está desactivado por defecto. Cuando está activado, solo escucha en loopback y el bearer token tiene al menos 24 caracteres:

ICLOUD_MCP_TRANSPORT=http \
ICLOUD_MCP_HTTP_TOKEN='replace-with-a-long-random-token' \
ICLOUD_MCP_HTTP_PORT=3000 \
npx icloud-calendar-mcp
  • Endpoint MCP: POST /mcp

  • Comprobación de estado: GET /healthz (no accede a Apple ni revela el estado de la cuenta)

  • Bearer token obligatorio; lista de hosts permitidos fija; Origen denegado por defecto; límite de solicitud predeterminado de 1 MiB; limitación de velocidad de lectura/escritura local; tiempo de espera y límites de encabezados de respuesta de seguridad.

  • Configure parámetros estables a través de ICLOUD_MCP_CONFIG=/absolute/path/config.json, por ejemplo, allowedHosts, allowedOrigins, timeoutMs, maxEvents, limitación de velocidad de lectura/escritura y límite de solicitud. Las credenciales no deben colocarse en este archivo.

Consulte el contrato de configuración completo en docs/tool-contracts.md y el modelo de seguridad en docs/security.md.

Fiabilidad

  • El UID de create es un derivado SHA-256 estable de request_id; las solicitudes duplicadas no generan un segundo evento.

  • create usa If-None-Match: *, update/delete usan If-Match con el ETag leído.

  • El diario se escribe con rename atómico en el directorio de datos del usuario (por defecto ~/.icloud-caldav-mcp/journal.json, con permisos restringidos), guardando la repetición de solicitudes y los identificadores opacos.

  • Los fallos temporales 429/5xx/red utilizan retroceso exponencial con jitter y respetan Retry-After; cuando falta el ETag de respuesta, se realiza un sondeo de visibilidad de lectura después de escritura.

  • Códigos de error estables: AUTH_FAILED, CALENDAR_NOT_FOUND, EVENT_NOT_FOUND, ETAG_CONFLICT, INVALID_EVENT, RATE_LIMITED, TEMPORARY_UNAVAILABLE, UNSUPPORTED_OPERATION.

Desarrollo y prueba smoke con cuenta real

pnpm install
pnpm check
pnpm pack

Los cambios orientados al usuario se registran con pnpm changeset. Al enviar a main, Changesets crea o actualiza automáticamente un Release PR; al fusionar ese PR, se publica automáticamente a través de npm Trusted Publishing con procedencia. Antes de la primera activación, configure .github/workflows/release.yml como Trusted Publisher en la configuración del paquete npm.

CI usa adaptadores falsos/fixtures HTTP, no necesita una cuenta real de Apple. Las pruebas reales opcionales solo se ejecutan localmente después de proporcionar explícitamente ICLOUD_USERNAME e ICLOUD_APP_PASSWORD: pnpm smoke:icloud. El conjunto de pruebas smoke actual omite las operaciones de escritura de forma predeterminada; para la primera verificación real, se recomienda verificar manualmente el descubrimiento/lista/creación/actualización/eliminación/comportamiento de excepción de recurrencia con un calendario de prueba dedicado.

Solución de problemas: 401/403 verifique la contraseña específica de la aplicación; 412 indica conflicto de concurrencia ETag, vuelva a ejecutar list_events/get_event; 429 espere y vuelva a intentarlo; identificador desconocido significa que el diario se eliminó o el directorio de datos cambió. No pegue la URL CalDAV completa, la Autorización ni el cuerpo del evento en un issue.

Licencia

MIT. Implementado como código original independiente; el proyecto público se utiliza únicamente para la investigación de diferencias de interfaz y arquitectura, sin copiar código fuente de terceros.

Install Server
A
license - permissive license
B
quality
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

View all related MCP servers

Related MCP Connectors

  • Hosted Google Calendar MCP server for AI agents. No self-hosting or Google Cloud setup.

  • Streamable HTTP MCP server for Google Calendar and Sheets with OAuth login.

  • Hosted MCP server for business-day math, deadline planning, meeting overlap, and SLA calculations.

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/IceyWu/icloud-calendar-mcp'

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