Apple Reminders

Un servidor para la integración nativa con Apple Reminders en macOS.

Documentación

Servidor MCP de Apple Events Version 1.5.0 License: MIT

X Follow

Inglés | 简体中文

Un servidor del Protocolo de Contexto de Modelos (MCP) que proporciona integración nativa con Recordatorios y Calendario de Apple en macOS mediante el framework EventKit. Expone recordatorios, listas, subtareas y eventos de calendario a través de una interfaz estandarizada con operaciones CRUD completas.

El backend de EventKit es el event CLI Swift independiente, incluido como submódulo de git y compilado en bin/event durante pnpm install — no se requiere un brew install separado. Consulta docs/migration-to-event-cli.md para el cambio de backend en v1.5.0 y la lista de campos de escritura aún no expuestos por event.

Tabla de Contenidos

Características

  • CRUD completo para recordatorios, subtareas, listas de recordatorios y eventos de calendario
  • Prioridad (alta/media/baja/ninguna), etiquetas y subtareas de lista de verificación con seguimiento de progreso
  • Filtrado multicriterio: finalización, rango de fechas de vencimiento, prioridad, etiquetas, búsqueda de texto completo, recurrencia, basado en ubicación
  • Formatos de fecha flexibles (YYYY-MM-DD, YYYY-MM-DD HH:mm:ss, ISO 8601) con conocimiento de zona horaria
  • Integración nativa con macOS mediante EventKit — los valores configurados en Recordatorios.app / Calendario.app se reflejan en las respuestas de lectura
  • Detección y solicitud automática de permisos de macOS
  • Soporte Unicode completo con validación integral de entrada

Requisitos Previos

  • Node.js 20 o posterior
  • macOS (requerido para EventKit)
  • Herramientas de Línea de Comandos de Xcode (solo al compilar desde el código fuente)
  • pnpm (recomendado)

El paquete npm publicado incluye un binario bin/event universal, precompilado y firmado con código, por lo que los usuarios de npx no necesitan Xcode ni un toolchain de Swift. Compilar desde un clon de git requiere los elementos anteriores.

Inicio Rápido

npx mcp-server-apple-events

Configuración

Agrega el servidor a tu cliente MCP. La forma npx funciona para todos los clientes siguientes; para una compilación local, reemplaza command/args con node apuntando a dist/index.js.

Cursor

Configuración → MCP → Agregar nuevo servidor MCP global:

{
  "mcpServers": {
    "apple-reminders": {
      "command": "npx",
      "args": ["-y", "mcp-server-apple-events"]
    }
  }
}

ChatWise

Configuración → Herramientas → "+", luego:

  • Tipo: stdio
  • ID: apple-reminders
  • Comando: mcp-server-apple-events
  • Argumentos: (vacío)

Claude Desktop

Edita claude_desktop_config.json (ábrelo mediante Configuración → Opción de Desarrollador → Editar Configuración, o directamente en ~/Library/Application Support/Claude/claude_desktop_config.json en macOS / %APPDATA%\Claude\claude_desktop_config.json en Windows):

{
  "mcpServers": {
    "apple-reminders": {
      "command": "npx",
      "args": ["-y", "mcp-server-apple-events"]
    }
  }
}

Para una compilación local:

{
  "mcpServers": {
    "apple-reminders": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-server-apple-events/dist/index.js"]
    }
  }
}

Consulta la documentación oficial de MCP para conectar servidores locales. Reinicia Claude Desktop por completo (salir, no solo cerrar) para que los cambios surtan efecto.

Permisos de macOS

El CLI event incluido incorpora su propio Info.plist (ID de paquete me.frad.event) que declara todas las cadenas de privacidad de Recordatorios y Calendario, y se ejecuta a través del shim bin/event-disclaim incluido, que rechaza la responsabilidad de TCC al momento de la ejecución. Por lo tanto, macOS atribuye la solicitud de permiso a event en sí, no a la aplicación que inició el servidor MCP — así, la primera llamada a EventKit solicita "evento", la concesión aparece bajo System Settings > Privacy & Security > Reminders / Calendars como event, y una sola concesión cubre todos los clientes MCP en la máquina (Claude Desktop, Codex Desktop, Cursor, clientes de terminal, …). Consulta issue #93 para más contexto.

Cuando event detecta un estado notDetermined, llama a requestFullAccessToReminders / requestFullAccessToEvents, que muestran el aviso del sistema. Si el sistema operativo pierde el registro de permisos, ejecuta nuevamente ./check-permissions.sh para reabrir los diálogos.

Errores de lectura del Calendario

Si ves Failed to read calendar events, configura Calendario en Acceso Completo al Calendario bajo System Settings > Privacy & Security > Calendars, o ejecuta nuevamente ./check-permissions.sh (verifica tanto Recordatorios como Calendarios).

Recuperación de un estado TCC bloqueado (no aparece ningún aviso)

Si el diálogo de permisos nunca aparece y event falta en System Settings → Privacy & Security → Reminders / Calendars, tu máquina está en un estado TCC obsoleto/mal atribuido. La corrección de rechazo del lado del servidor previene esto en una máquina limpia, pero no puede eliminar entradas ya corruptas. Recuperación:

  1. Restablece las entradas TCC de Calendario y Recordatorios globalmente (el restablecimiento por aplicación frecuentemente no funciona — la forma simple borra todas las entradas, que es lo que elimina el estado defectuoso):

    tccutil reset Calendar
    tccutil reset Reminders
    

    Esto borra el acceso a Calendario/Recordatorios para todas las aplicaciones; otras aplicaciones volverán a solicitar permiso la próxima vez.

  2. Vuelve a activar el permiso desde una conversación de Claude (Claude Desktop o Claude Code) pidiendo, por ejemplo, "Usa AppleScript para verificar mi Calendario y Recordatorios." Concede el acceso y el servidor debería funcionar normalmente. Consulta issue #83.

Ejecuciones headless / launchd se cuelgan en lugar de fallar

Cuando el servidor se ejecuta desde un contexto sin sesión GUI (SSH, agente/daemon de launchd), la primera llamada a EventKit puede bloquearse indefinidamente esperando un aviso de permiso que nunca puede mostrarse — la solicitud MCP nunca se resuelve y se filtra un proceso hijo por llamada. El servidor ahora mata cualquier llamada event que exceda 30 s (SIGKILL) y devuelve un error legible en su lugar. Ajústalo con la variable de entorno EVENTKIT_CLI_TIMEOUT_MS (milisegundos; valores inválidos/cero vuelven al valor predeterminado — el tiempo de espera no se puede deshabilitar, aunque se aceptan valores enormes hasta 2^31-1 ms). El CLI event incluido (fijado mediante FradSer/event#15) además falla rápidamente cuando no hay sesión GUI y abandona un aviso sin respuesta después de 15 s (EVENT_PERMISSION_TIMEOUT_MS), reportando Permission denied: Timed out waiting for ... para que el host pueda mostrar un mensaje específico de permisos antes de que se active la terminación del servidor (15 s < 30 s). Consulta issue #113.

macOS 26 (Tahoe) could not build module 'Foundation'

Si pnpm build falla con could not build module 'Foundation' (o SDK is not supported by the compiler), tu toolchain de Swift es más antiguo de lo que requiere el SDK de macOS 26 — necesita Swift 6.3 o más reciente, pero las Herramientas de Línea de Comandos incluidas con las versiones iniciales de macOS 26 incluyen Swift 6.2.x. pnpm build:event detecta esto e imprime la misma corrección; consulta issue #85. Solución: instala Xcode 26.x desde la App Store, o actualiza las Herramientas de Línea de Comandos a una versión de Swift 6.3+:

softwareupdate --list
sudo softwareupdate -i "Command Line Tools for Xcode-<latest>"
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer   # if full Xcode is installed
xcrun swiftc --version    # should report Apple Swift version 6.3 or newer

Ejemplos de Uso

Una vez configurado, pide a Claude que interactúe con tus Recordatorios y Calendario de Apple. Ejemplos de prompts:

Create a reminder to "Buy groceries" for tomorrow at 5 PM with tags shopping and errands.
Add a high-priority reminder to "Finish quarterly report" due Friday in my "Work" list.
Create "Grocery shopping" with subtasks: milk, eggs, bread, butter.
Show me all high-priority reminders due today tagged "urgent".
Show subtasks for my "Grocery shopping" reminder and mark "milk" as complete.
Update "Buy groceries" — change the title to "Buy organic groceries" and set priority to high.
Show reminders from my "Work" list, and list all my reminder lists.
Create a calendar event "Team standup" tomorrow from 9:00 to 9:30 in "Work".
Show my calendar events for the next week.
Invite alex@example.com to my "Team standup" event.
Cancel just the September 21 occurrence of my weekly "Team standup".

El servidor procesa solicitudes en lenguaje natural, interactúa con las aplicaciones nativas de Recordatorios y Calendario de Apple, y devuelve resultados formateados.

Alarmas, reglas de recurrencia y disparadores de ubicación son de solo lectura mediante este servidor — configúralos en Recordatorios.app / Calendario.app. Aún aparecen en los resultados de lectura con indicadores visuales.

Herramientas MCP Disponibles

Las herramientas con ámbito de servicio reflejan los dominios de Recordatorios y Calendario de Apple. Todas toman un campo action más parámetros específicos de la acción (el cliente MCP inspecciona el esquema Zod completo; aquí solo se listan las acciones). Los campos de fecha aceptan YYYY-MM-DD, YYYY-MM-DD HH:mm:ss (hora local) o ISO 8601 con zona horaria.

HerramientaAccionesNotas
reminders_tasksread, create, update, deletePrioridad, etiquetas, subtareas. startDate se establece mediante update, no create; en read limita la ventana de fecha de vencimiento junto con endDate. Movimientos entre listas no compatibles.
reminders_subtasksread, create, update, delete, toggle, reorderAlmacenados en el campo de notas (legible en Recordatorios.app).
reminders_listsread, create, update, deleteRenombrar mediante name → newName.
calendar_eventsread, create, update, deleteTodo el día se infiere del formato de fecha. Movimientos entre calendarios no compatibles. span limita eliminaciones recurrentes. attendees (actualizar) invita direcciones; occurrenceDate (eliminar) exceptúa una ocurrencia de una serie — ambos requieren configuración adicional, consulta Asistentes y ocurrencias individuales.
calendar_calendarsreadCalendarios con ≥1 evento en la ventana (opcional) startDate/endDate.

Ejemplos de llamadas:

{
  "action": "create",
  "title": "Buy groceries",
  "dueDate": "2024-03-25 18:00:00",
  "targetList": "Shopping",
  "note": "Don't forget milk and eggs",
  "priority": 1,
  "tags": ["shopping", "errands"],
  "subtasks": ["Milk", "Eggs", "Bread"]
}
{ "action": "read", "filterList": "Work", "dueWithin": "today", "filterPriority": "high", "filterTags": ["urgent"] }
{ "action": "read", "startDate": "2026-08-01", "endDate": "2026-08-31" }
{ "action": "update", "id": "reminder-123", "completed": false, "addTags": ["followup"] }
{ "action": "toggle", "reminderId": "reminder-123", "subtaskId": "a1b2c3d4" }
{ "action": "create", "name": "Project Alpha" }
{ "action": "create", "title": "Team standup", "startDate": "2026-05-04 09:00:00", "endDate": "2026-05-04 09:30:00", "targetCalendar": "Work" }
{ "action": "update", "id": "event-123", "attendees": ["alex@example.com", "sam@example.com"] }
{ "action": "delete", "id": "event-123", "occurrenceDate": "2026-09-21T09:00:00" }

Asistentes y ocurrencias individuales

Estos dos parámetros calendar_events son las únicas escrituras que no pasan por el CLI event, porque EventKit no puede expresar ninguno de los dos. Cada uno necesita configuración que el resto del servidor no requiere.

attendees (actualizar) — invita direcciones de correo a un evento existente. EKCalendarItem.attendees es de solo lectura en el SDK de macOS y EventKit no tiene API de invitación, por lo que la escritura pasa por la interfaz de scripting de Calendario.app; agregar al asistente localmente es lo que hace que iCloud envíe la invitación.

  • Requiere una concesión de Automatización: la primera llamada solicita permiso, y la entrada aparece bajo System Settings > Privacy & Security > Automation. Necesita una sesión GUI, por lo que no funciona headless.
  • Los asistentes deben actualizarse solos. Viajan a través de Calendario.app mientras que todos los demás campos viajan a través de EventKit, y los dos no comparten token de concurrencia — una actualización combinada no tiene orden seguro, por lo que se rechaza. Haz dos llamadas.
  • Dos eventos que comparten título y fecha de inicio son rechazados, no adivinados. Calendario.app solo puede consultarse por título y fecha, y escribir en el incorrecto enviaría una invitación real para él.

occurrenceDate (eliminar) — exceptúa una ocurrencia de una serie recurrente. Cada ocurrencia comparte un identificador de EventKit, por lo que span: "this-event" solo puede exceptuar el inicio de la serie; dirigido a una ocurrencia posterior, no escribe nada y aún reporta éxito. Proporcionar occurrenceDate enruta la eliminación a través de CalDAV, que puede abordar la instancia directamente.

  • Requiere credenciales de iCloud. Establece ICLOUD_APPLE_ID y ICLOUD_APP_PASSWORD, o establece ICLOUD_APPLE_ID y almacena la contraseña en el Llavero:

    security add-generic-password -a "you@icloud.com" -s "icloud-caldav-mcp" -w
    

    Usa una contraseña específica de aplicación, nunca la contraseña de tu cuenta. Las credenciales se leen primero del entorno, luego del Llavero, nunca de la configuración del cliente MCP, y nunca se registran.

  • Solo los eventos sincronizados con iCloud califican — un evento sin identificador externo no tiene recurso CalDAV que localizar.

Forma de la respuesta de lectura

Las respuestas de lectura llevan indicadores visuales: 🔄 recurrente, 📍 basado en ubicación, 🏷️ tiene etiquetas, 📋 tiene subtareas. Ejemplo:

- [ ] Buy groceries 🏷️📋
  - List: Shopping
  - ID: reminder-123
  - Priority: high
  - Tags: #shopping #errands
  - Subtasks (1/3):
    - [x] Milk
    - [ ] Eggs
    - [ ] Bread
  - Due: 2024-03-25 18:00:00

El campo url se almacena en la propiedad nativa url (visible mediante el ícono "i" en Recordatorios.app) y también se agrega a las notas en un bloque estructurado URLs: para análisis y soporte de múltiples URLs. Las URLs aceptan cualquier esquema URI válido (http, https, mailto, tel, obsidian, shortcuts, …); file, javascript, data y esquemas peligrosos similares se rechazan, y los nombres de host http(s) se verifican contra una lista de bloqueo SSRF.

Campos de solo lectura: alarmas, reglas de recurrencia, disparadores de ubicación, ubicaciones estructuradas, url/availability/isAllDay del calendario y movimientos entre calendarios no se pueden escribir mediante este servidor — se reflejan desde los valores configurados en Recordatorios.app / Calendario.app. Consulta docs/migration-to-event-cli.md para la tabla completa de campos eliminados y soluciones alternativas.

Biblioteca de Prompts Estructurados

El servidor incluye un registro de plantillas expuesto a través de los endpoints MCP ListPrompts / GetPrompt. Cada plantilla comparte una misión, entradas de contexto, proceso numerado, restricciones, formato de salida y estándar de calidad para que los asistentes posteriores obtengan un andamiaje predecible.

  • daily-task-organizer — today_focus opcional; produce un plan de ejecución para el mismo día, equilibra el trabajo prioritario con la recuperación, crea automáticamente bloques de tiempo en el calendario para recordatorios con vencimiento hoy.
  • smart-reminder-creator — task_idea opcional; genera una estructura de recordatorios con programación óptima.
  • reminder-review-assistant — review_focus opcional (p. ej. overdue o un nombre de lista); audita y optimiza recordatorios existentes.
  • weekly-planning-workflow — user_ideas opcional; guía un reinicio de lunes a domingo con bloques de tiempo vinculados a listas existentes.

Las plantillas están limitadas a las capacidades nativas de Apple Reminders y solicitan contexto faltante antes de acciones irreversibles. Ejecuta pnpm test -- src/server/prompts.test.ts después de modificar el texto de la plantilla.

Desarrollo

pnpm install        # postinstall builds bin/event from vendor/event on macOS
pnpm build          # TypeScript + vendored event CLI
pnpm test           # Jest suite: repositories, schemas, build script, prompt templates
pnpm exec biome check   # lint + format

El punto de entrada de la CLI recorre hasta diez directorios para encontrar package.json, de modo que el servidor pueda iniciarse desde rutas anidadas (p. ej. dist/ o ejecutores de tareas del editor) sin perder bin/event. Mantén el manifiesto accesible dentro de esa profundidad si personalizas la estructura de carpetas.

Scripts

  • pnpm build — TypeScript + CLI event incluida (requerido antes de ejecutar desde el código fuente)
  • pnpm build:ts — solo TypeScript
  • pnpm build:event — solo CLI event incluida (swift build -c release → bin/event)
  • pnpm build:release — compilación más notarización (empaquetado de lanzamiento)
  • pnpm test / pnpm test:ci — suite Jest / con cobertura
  • pnpm lint — formato/corrección de Biome + verificación de tipos de TypeScript
  • pnpm check — lint + pruebas con cobertura

Licencia

MIT

Contribuciones

¡Las contribuciones son bienvenidas! Por favor, lee primero las pautas de contribución.