Apple Reminders
Un servidor para la integración nativa con Apple Reminders en macOS.
Documentación
Servidor MCP de Apple Events

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
- Requisitos Previos
- Inicio Rápido
- Configuración
- Permisos de macOS
- Ejemplos de Uso
- Herramientas MCP Disponibles
- Biblioteca de Prompts Estructurados
- Desarrollo
- Licencia
- Contribuciones
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:
-
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 RemindersEsto borra el acceso a Calendario/Recordatorios para todas las aplicaciones; otras aplicaciones volverán a solicitar permiso la próxima vez.
-
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.
| Herramienta | Acciones | Notas |
|---|---|---|
reminders_tasks | read, create, update, delete | Prioridad, 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_subtasks | read, create, update, delete, toggle, reorder | Almacenados en el campo de notas (legible en Recordatorios.app). |
reminders_lists | read, create, update, delete | Renombrar mediante name → newName. |
calendar_events | read, create, update, delete | Todo 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_calendars | read | Calendarios 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_IDyICLOUD_APP_PASSWORD, o estableceICLOUD_APPLE_IDy almacena la contraseña en el Llavero:security add-generic-password -a "you@icloud.com" -s "icloud-caldav-mcp" -wUsa 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/isAllDaydel 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_focusopcional; 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_ideaopcional; genera una estructura de recordatorios con programación óptima. - reminder-review-assistant —
review_focusopcional (p. ej.overdueo un nombre de lista); audita y optimiza recordatorios existentes. - weekly-planning-workflow —
user_ideasopcional; 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 + CLIeventincluida (requerido antes de ejecutar desde el código fuente)pnpm build:ts— solo TypeScriptpnpm build:event— solo CLIeventincluida (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 coberturapnpm lint— formato/corrección de Biome + verificación de tipos de TypeScriptpnpm check— lint + pruebas con cobertura
Licencia
MIT
Contribuciones
¡Las contribuciones son bienvenidas! Por favor, lee primero las pautas de contribución.