Apple Reminders
Um servidor para integração nativa com o Apple Reminders no macOS.
Documentação
Servidor MCP de Eventos da Apple

Inglês | 简体中文
Um servidor Model Context Protocol (MCP) que fornece integração nativa com Lembretes e Calendário da Apple no macOS por meio do framework EventKit. Expõe lembretes, listas, subtarefas e eventos de calendário por meio de uma interface padronizada com operações CRUD completas.
O backend EventKit é o event CLI Swift independente, incluído como submódulo git e compilado em bin/event durante pnpm install — nenhum brew install separado é necessário. Consulte docs/migration-to-event-cli.md para a troca de backend na v1.5.0 e a lista de campos de escrita ainda não expostos por event.
Sumário
- Recursos
- Pré-requisitos
- Início Rápido
- Configuração
- Permissões do macOS
- Exemplos de Uso
- Ferramentas MCP Disponíveis
- Biblioteca de Prompts Estruturados
- Desenvolvimento
- Licença
- Contribuição
Recursos
- CRUD completo para lembretes, subtarefas, listas de lembretes e eventos de calendário
- Prioridade (alta/média/baixa/nenhuma), tags e subtarefas de checklist com acompanhamento de progresso
- Filtragem por múltiplos critérios: conclusão, intervalo de datas de vencimento, prioridade, tags, pesquisa de texto completo, recorrência, baseada em localização
- Formatos de data flexíveis (
YYYY-MM-DD,YYYY-MM-DD HH:mm:ss, ISO 8601) com suporte a fusos horários - Integração nativa com macOS via EventKit — valores configurados no app Lembretes / Calendário são refletidos nas respostas de leitura
- Descoberta e solicitação automática de permissões do macOS
- Suporte completo a Unicode com validação abrangente de entrada
Pré-requisitos
- Node.js 20 ou posterior
- macOS (necessário para EventKit)
- Ferramentas de Linha de Comando do Xcode (apenas ao compilar a partir do código-fonte)
- pnpm (recomendado)
O pacote npm publicado inclui um binário bin/event universal, pré-compilado e assinado digitalmente, portanto usuários de npx não precisam de Xcode nem de toolchain Swift. Compilar a partir de um clone do git requer os itens acima.
Início Rápido
npx mcp-server-apple-events
Configuração
Adicione o servidor ao seu cliente MCP. A forma npx funciona para todos os clientes abaixo; para uma compilação local, substitua command/args por node apontando para dist/index.js.
Cursor
Configurações → MCP → Adicionar novo servidor MCP global:
{
"mcpServers": {
"apple-reminders": {
"command": "npx",
"args": ["-y", "mcp-server-apple-events"]
}
}
}
ChatWise
Configurações → Ferramentas → "+", então:
- Tipo:
stdio - ID:
apple-reminders - Comando:
mcp-server-apple-events - Argumentos: (vazio)
Claude Desktop
Edite claude_desktop_config.json (abra via Configurações → Opção de Desenvolvedor → Editar Config, ou diretamente em ~/Library/Application Support/Claude/claude_desktop_config.json no macOS / %APPDATA%\Claude\claude_desktop_config.json no Windows):
{
"mcpServers": {
"apple-reminders": {
"command": "npx",
"args": ["-y", "mcp-server-apple-events"]
}
}
}
Para uma compilação local:
{
"mcpServers": {
"apple-reminders": {
"command": "node",
"args": ["/absolute/path/to/mcp-server-apple-events/dist/index.js"]
}
}
}
Consulte a documentação oficial do MCP para conectar servidores locais. Reinicie o Claude Desktop completamente (saia, não apenas feche) para que as alterações tenham efeito.
Permissões do macOS
O event CLI incluído incorpora seu próprio Info.plist (bundle id me.frad.event) declarando todas as strings de privacidade de Lembretes e Calendário, e é iniciado por meio do shim bin/event-disclaim incluído, que isenta a responsabilidade TCC no momento da inicialização. Portanto, o macOS atribui a solicitação de permissão ao event em si, não ao aplicativo que iniciou o servidor MCP — assim, a primeira chamada EventKit solicita "evento", a concessão aparece em System Settings > Privacy & Security > Reminders / Calendars como event, e uma única concessão cobre todos os clientes MCP na máquina (Claude Desktop, Codex Desktop, Cursor, clientes de terminal, …). Consulte issue #93 para contexto.
Quando event detecta um status notDetermined, ele chama requestFullAccessToReminders / requestFullAccessToEvents, que exibem o prompt do sistema. Se o sistema operacional perder o controle das permissões, execute novamente ./check-permissions.sh para reabrir os diálogos.
Erros de leitura do Calendário
Se você vir Failed to read calendar events, defina o Calendário como Acesso Total ao Calendário em System Settings > Privacy & Security > Calendars, ou execute novamente ./check-permissions.sh (ele verifica tanto Lembretes quanto Calendários).
Recuperando um estado TCC travado (nenhum prompt aparece)
Se o diálogo de permissão nunca aparecer e event estiver ausente de System Settings → Privacy & Security → Reminders / Calendars, sua máquina está em um estado TCC obsoleto/atribuído incorretamente. A correção de isenção no lado do servidor evita isso em uma máquina limpa, mas não pode limpar entradas já corrompidas. Recuperação:
-
Redefina as entradas TCC de Calendário e Lembretes globalmente (a redefinição por aplicativo frequentemente não funciona — a forma simples limpa todas as entradas, que é o que limpa o estado ruim):
tccutil reset Calendar tccutil reset RemindersIsso limpa o acesso a Calendário/Lembretes para todos os aplicativos; outros aplicativos solicitarão permissão novamente na próxima vez.
-
Reative a permissão de dentro de uma conversa no Claude (Claude Desktop ou Claude Code) pedindo, por exemplo, "Use AppleScript para verificar meu Calendário e Lembretes." Conceda o acesso e o servidor deve funcionar normalmente. Consulte issue #83.
Execuções headless / launchd travam em vez de falhar
Quando o servidor é executado em um contexto sem sessão GUI (SSH, agente/daemon launchd), a primeira chamada EventKit pode bloquear para sempre aguardando um prompt de permissão que nunca pode ser renderizado — a solicitação MCP nunca é concluída e um processo filho vaza a cada chamada. O servidor agora encerra qualquer chamada event que exceda 30 s (SIGKILL) e retorna um erro legível. Ajuste com a variável de ambiente EVENTKIT_CLI_TIMEOUT_MS (milissegundos; valores inválidos/zero voltam ao padrão — o timeout não pode ser desabilitado, embora valores grandes de até 2^31-1 ms sejam aceitos). O event CLI incluído (fixado via FradSer/event#15) adicionalmente falha rapidamente quando não há sessão GUI e desiste de um prompt sem resposta após 15 s (EVENT_PERMISSION_TIMEOUT_MS), relatando Permission denied: Timed out waiting for ... para que o host possa mostrar uma mensagem específica de permissão antes do encerramento do servidor (15 s < 30 s). Consulte issue #113.
macOS 26 (Tahoe) could not build module 'Foundation'
Se pnpm build falhar com could not build module 'Foundation' (ou SDK is not supported by the compiler), seu toolchain Swift é mais antigo do que o exigido pelo SDK do macOS 26 — ele precisa de Swift 6.3 ou mais recente, mas as Ferramentas de Linha de Comando incluídas nas primeiras versões do macOS 26 incluem Swift 6.2.x. pnpm build:event detecta isso e imprime a mesma correção; consulte issue #85. Corrija instalando o Xcode 26.x da App Store, ou atualizando as Ferramentas de Linha de Comando para uma versão 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
Exemplos de Uso
Após configurado, peça ao Claude para interagir com seus Lembretes e Calendário da Apple. Exemplos 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".
O servidor processa solicitações em linguagem natural, interage com os aplicativos nativos Lembretes e Calendário da Apple e retorna resultados formatados.
Alarmes, regras de recorrência e gatilhos de localização são somente leitura por meio deste servidor — configure-os no app Lembretes / Calendário. Eles ainda aparecem nos resultados de leitura com indicadores visuais.
Ferramentas MCP Disponíveis
As ferramentas com escopo de serviço espelham os domínios de Lembretes e Calendário da Apple. Todas aceitam um campo action além de parâmetros específicos da ação (o cliente MCP inspeciona o esquema Zod completo; apenas as ações são listadas aqui). Campos de data aceitam YYYY-MM-DD, YYYY-MM-DD HH:mm:ss (hora local) ou ISO 8601 com fuso horário.
| Ferramenta | Ações | Notas |
|---|---|---|
reminders_tasks | read, create, update, delete | Prioridade, tags, subtarefas. startDate é definido via update, não create; em read ele limita a janela de data de vencimento junto com endDate. Movimentação entre listas não suportada. |
reminders_subtasks | read, create, update, delete, toggle, reorder | Armazenado no campo de notas (legível no app Lembretes). |
reminders_lists | read, create, update, delete | Renomear via name → newName. |
calendar_events | read, create, update, delete | Dia inteiro inferido pelo formato da data. Movimentação entre calendários não suportada. span limita exclusões recorrentes. attendees (atualização) convida endereços; occurrenceDate (exclusão) excetua uma ocorrência de uma série — ambos precisam de configuração extra, consulte Participantes e ocorrências únicas. |
calendar_calendars | read | Calendários com ≥1 evento na janela (opcional) startDate/endDate. |
Exemplos de chamadas:
{
"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" }
Participantes e ocorrências únicas
Estes dois parâmetros calendar_events são as únicas escritas que não passam pelo event CLI, porque o EventKit não pode expressar nenhum dos dois. Cada um precisa de configuração que o restante do servidor não faz.
attendees (atualização) — convida endereços de e-mail para um evento existente. EKCalendarItem.attendees é somente leitura no SDK do macOS e o EventKit não tem API de convite, então a escrita passa pela interface de script do app Calendário; adicionar o participante localmente é o que faz o iCloud enviar o convite.
- Requer uma concessão de Automação: a primeira chamada solicita, e a entrada aparece em
System Settings > Privacy & Security > Automation. Precisa de sessão GUI, portanto não funciona headless. - Os participantes devem ser atualizados sozinhos. Eles trafegam pelo app Calendário enquanto todos os outros campos trafegam pelo EventKit, e os dois não compartilham token de concorrência — uma atualização combinada não tem ordenação segura, então é recusada. Faça duas chamadas.
- Dois eventos compartilhando título e data de início são recusados, não adivinhados. O app Calendário só pode ser consultado por título e data, e escrever no errado enviaria um convite real para ele.
occurrenceDate (exclusão) — excetua uma ocorrência de uma série recorrente. Cada ocorrência compartilha um identificador EventKit, então span: "this-event" só pode excetuar o início da série; direcionado a uma ocorrência posterior, não escreve nada e ainda relata sucesso. Fornecer occurrenceDate roteia a exclusão via CalDAV, que pode endereçar a instância diretamente.
-
Requer credenciais iCloud. Defina
ICLOUD_APPLE_IDeICLOUD_APP_PASSWORD, ou definaICLOUD_APPLE_IDe armazene a senha no Keychain:security add-generic-password -a "you@icloud.com" -s "icloud-caldav-mcp" -wUse uma senha específica do app, nunca a senha da sua conta. As credenciais são lidas primeiro do ambiente, depois do Keychain, nunca da configuração do cliente MCP, e nunca são registradas em log.
-
Apenas eventos sincronizados com iCloud são elegíveis — um evento sem identificador externo não tem recurso CalDAV para localizar.
Formato da resposta de leitura
As respostas de leitura trazem indicadores visuais: 🔄 recorrente, 📍 baseado em localização, 🏷️ tem tags, 📋 tem subtarefas. Exemplo:
- [ ] 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
O campo url é armazenado na propriedade nativa url (visível pelo ícone "i" no app Lembretes) e também anexado às notas em um bloco estruturado URLs: para análise e suporte a múltiplas URLs. As URLs aceitam qualquer esquema de URI válido (http, https, mailto, tel, obsidian, shortcuts, …); file, javascript, data e esquemas perigosos semelhantes são rejeitados, e nomes de host http(s) são verificados contra uma lista de bloqueio SSRF.
Campos somente leitura: alarmes, regras de recorrência, gatilhos de localização, localizações estruturadas,
url/availability/isAllDaydo calendário e movimentações entre calendários não são graváveis por meio deste servidor — eles refletem valores configurados no app Lembretes / Calendário. Consulte docs/migration-to-event-cli.md para a tabela completa de campos removidos e soluções alternativas.
Biblioteca de Prompts Estruturados
O servidor inclui um registro de prompts exposto via endpoints MCP ListPrompts / GetPrompt. Cada template compartilha uma missão, entradas de contexto, processo numerado, restrições, formato de saída e padrão de qualidade para que assistentes downstream obtenham scaffolding previsível.
- daily-task-organizer —
today_focusopcional; produz um blueprint de execução para o mesmo dia, equilibra trabalho prioritário com recuperação, cria automaticamente blocos de tempo no calendário para lembretes com vencimento hoje. - smart-reminder-creator —
task_ideaopcional; gera uma estrutura de lembretes com agendamento otimizado. - reminder-review-assistant —
review_focusopcional (ex.:overdueou um nome de lista); audita e otimiza lembretes existentes. - weekly-planning-workflow —
user_ideasopcional; orienta um reset de segunda a domingo com blocos de tempo vinculados a listas existentes.
Os prompts são limitados aos recursos nativos do Apple Reminders e solicitam contexto ausente antes de ações irreversíveis. Execute pnpm test -- src/server/prompts.test.ts após alterar o texto do prompt.
Desenvolvimento
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
O ponto de entrada da CLI percorre até dez diretórios para encontrar package.json, permitindo que o servidor inicie a partir de caminhos aninhados (ex.: dist/ ou executores de tarefas do editor) sem perder bin/event. Mantenha o manifesto acessível dentro dessa profundidade se você personalizar o layout de pastas.
Scripts
pnpm build— TypeScript + CLIeventembutida (necessário antes de executar a partir do código-fonte)pnpm build:ts— apenas TypeScriptpnpm build:event— apenas CLIeventembutida (swift build -c release→bin/event)pnpm build:release— build mais notarização (empacotamento de release)pnpm test/pnpm test:ci— suíte Jest / com coberturapnpm lint— formatação/correção Biome + verificação de tipos TypeScriptpnpm check— lint + testes com cobertura
Licença
MIT
Contribuição
Contribuições são bem-vindas! Por favor, leia as diretrizes de contribuição primeiro.