macOS Calendar & Reminders MCP server (29 tools) — native Swift EventKit for Claude Desktop & Code
FAQ (answers come from our records)
How do I install it?
We did not find an install command for this repository (our install coverage is only about 4%). Check its README or releases page.
Who is it for?
We filed it under these tags: 开源项目. The tags come from the entry itself, not a taxonomy we imposed.
Who maintains it?
repository PsychQuant/che-ical-mcp;first catalogued 2026-10-09;last seen 2026-10-16。There is no official certification or quality rating here — we record sources and dates only.
che-ical-mcp
以下摘录自该仓库的 README(片段) · 在 GitHub 读完整 README →
**Give Claude native control of macOS Calendar and Reminders.** A Swift MCP server built directly on EventKit — 29 tools for events, reminders, tags, batch operations, conflict detection, and undo/redo. Not just calendar events: it drives Reminders and tasks too.
English | 繁體中文
---
Install
**Claude Code** — register this repo as a marketplace, then install the plugin. The plugin bundles the /today, /week, /quick-event, /remind slash commands and a PreToolUse hook that verifies day-of-week on every event write:
**Claude Desktop** — download the latest .mcpb from Releases and double-click to install.
**Standalone MCP** — the 29-tool server on its own, no plugin extras:
On first use, macOS prompts for **Calendar** and **Reminders** access — click **Allow**. Building from source, upgrading in place, or running under SSH / launchd / VS Code? See Installation for the full guide.
---
Why che-ical-mcp?
| Feature | Other Calendar MCPs | che-ical-mcp |
|---------|---------------------|--------------|
| Calendar Events | Yes | Yes |
| **Reminders/Tasks** | No | **Yes** |
| **Reminder #Tags** | No | **Yes** (MCP-level) |
| **Multi-keyword Search** | No | **Yes** |
| **Duplicate Detection** | No | **Yes** |
| **Conflict Detection** | No | **Yes** |
| **Batch Operations** | No | **Yes** |
| **Local Timezone** | No | **Yes** |
| **Source Disambiguation** | No | **Yes** |
| Create Calendar | Some | Yes |
| Delete Calendar | Some | Yes |
| Event Reminders | Some | Yes |
| Location & URL | Some | Yes |
| Language | Python | **Swift (Native)** |
---
All 29 Tools
Calendars (4)
| Tool | Description |
|------|-------------|
| list_calendars | List all calendars and reminder lists (includes source_type) |
| create_calendar | Create a new calendar |
| delete_calendar | Delete a calendar |
| update_calendar | Rename a calendar or change its color (v0.9.0) |
Events (4)
| Tool | Description |
|------|-------------|
| list_events | List events with filter/sort/limit (v1.0.0) |
| create_event | Create an event (with reminders, location, URL, per-event timezone, recurrence with excluded dates) |
| update_event | Update an event (including timezone, recurrence, span for recurring) |
| delete_event | Delete an event (with occurrence support for recurring) |
> **Recurrence exclusions (#182)**: create_event (and each create_events_batch item) accepts recurrence.excluded_occurrence_dates to skip specific dates in a recurring series at creation time — applied with best-effort all-or-nothing semantics (any failure removes the entire new series via compensating delete; rollback failure is reported, never silent; the first occurrence cannot be excluded), and one undo removes the whole series including exclusions. The excluded dates are removed occurrences, not edited ones (checked on iCloud only, 2026-10-05; other stores were not checked), so they do not stop that undo; an occurrence edited on its own after the series was created does (#236). Known limitation: on idempotent retry, a duplicate recurring series with every requested date already absent is skipped, but extra exclusions already present on the existing series (beyond those requested) are not detected.
Reminders (8)
| Tool | Description |
|------|-------------|
| list_reminders | List reminders with filter/sort/limit, tags extraction (v1.0.0) |
| create_reminder | Create a reminder with due date, tags (v1.3.0); a bare YYYY-MM-DD due date makes it date-only (#267), and the response then carries date_sync with aligned judged on the saved reminder (#301) |
| update_reminder | Update a reminder (including tags, clear_due_date) (v1.3.0) |
| complete_reminder | Mark as completed/incomplete |
| delete_reminder | Delete a reminder |
| search_reminders | Search reminders by keyword(s) or tag (v1.3.0) |
| list_reminder_tags | List all unique tags with usage counts (v1.3.0) |
| cleanup_completed_reminders | Delete all completed reminders in one call, dry_run preview by default (v1.7.2); one undo recreates what it deleted (#243) |
**Recurring reminders (#194):** list/search include has_recurrence, complete public recurrence_rules, and precision-aware due. Completion adds operation (write outcome) and next_occurrence (confirmed/unknown/not_applicable). Use operation.status rather than legacy is_completed: a successful completion may leave the next occurrence incomplete. Unknown successor information must not trigger a second write. A different-ID or unconfirmable successor is reported as unknown, never as the series having ended. Undo of a recurring completion is identity-guarded (#204): once the identifier no longer resolves to the recorded occurrence it refuses explicitly and drops its history entry instead of jamming the stack. **Breaking (#205):** completed must be a JSON boolean on complete_reminder / list_reminders / search_reminders — strings and numbers are rejected; omit or null keeps the old meaning. **Breaking (#207, unreleased):** the same contract now applies to every boolean tool argument (all_day, clear_*, include_completed, dry_run, delete_original). See response contract and limitations.