A local MCP server that gives Claude full CRUD access to the macOS Calendar and Reminders via Apple's EventKit framework — including real recurring-event operations.
Everything runs on your Mac. No cloud, no accounts, no external services — your calendar and reminder data never leaves the machine.
- macOS (uses EventKit / the native Calendar database)
- Python 3.10+ (the MCP SDK requires it)
- An MCP client — these instructions cover Claude Desktop
| Tool | What it does |
|---|---|
list_calendars |
All calendars: id, title, source, color, writable, default |
list_events |
Events in a date range, recurring events expanded to occurrences |
get_event |
Full detail for one event / occurrence |
create_event |
New event, optionally recurring |
update_event |
Change any field; retarget/reshape recurrence |
delete_event |
Delete one occurrence, "this and future", or the whole series |
detach_occurrence |
Make a standalone, non-recurring copy off a recurring series |
create_calendar |
New calendar in a chosen source, optional color |
set_calendar_color |
Recolor a calendar (hex, e.g. #FF3B30) |
delete_calendar |
Permanently delete a calendar + its events (guarded, id-only) |
Note on colors: Apple Calendar has no per-event color — events inherit their calendar's color. So coloring happens at the calendar level; there's no event-color tool because EventKit exposes no such property.
| Tool | What it does |
|---|---|
list_reminder_lists |
All reminder lists: id, title, color, writable, default |
list_reminders |
Reminders, filterable by list, completion, and due-date window |
get_reminder |
Full detail for one reminder |
create_reminder |
New reminder (due date, priority, notes, url, optional recurrence) |
update_reminder |
Change any field; mark complete/incomplete; reshape recurrence |
delete_reminder |
Permanently delete a reminder |
Reminders support the same recurrence spec as events, priority is
none/low/medium/high, and due accepts a date (2026-08-10, no
time-of-day) or a datetime (2026-08-10T14:30).
list_events returns each occurrence with its event_id and its own
start. To act on a specific occurrence, pass that start back as
occurrence_start, plus a span:
this— only that occurrence (detaches it from the series)future— that occurrence and every later oneall— the entire series
Change how an event recurs by passing a new recurrence spec to update_event;
turn a series into a one-off with clear_recurrence=True.
Recurrence spec shape:
{
"frequency": "weekly", // daily | weekly | monthly | yearly
"interval": 2, // every N periods
"days_of_week": ["MO","WE","FR"], // weekly only
"days_of_month": [1, -1], // monthly only (-1 = last day)
"count": 10, // total occurrences (or)
"end_date": "2026-12-31" // stop after this date
}git clone https://github.com/maxiscoding28/apple-calendar-mcp.git
cd apple-calendar-mcp
python3 -m venv .venv
.venv/bin/python -m pip install -r requirements.txtUse any Python 3.10+ interpreter to create the venv. If your default python3
is older, substitute a newer one (e.g. python3.12 -m venv .venv).
Add the server to your claude_desktop_config.json. You can open it from
Claude Desktop via Settings → Developer → Edit Config, or find it at:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json
Add an apple-calendar entry under mcpServers, using absolute paths to the
Python interpreter in your venv and to server.py:
{
"mcpServers": {
"apple-calendar": {
"command": "/absolute/path/to/apple-calendar-mcp/.venv/bin/python",
"args": ["/absolute/path/to/apple-calendar-mcp/server.py"]
}
}
}Replace /absolute/path/to/apple-calendar-mcp with wherever you cloned the repo
(run pwd in the project directory to get it). Then fully quit and reopen
Claude Desktop so it picks up the change.
The first time a tool runs, macOS shows a "Claude wants to access Calendar" prompt — approve it. Reminders are a separate permission, so the first time you use a reminders tool you'll get a second "Claude wants to access Reminders" prompt. Both grants are tied to the app that launches the server (Claude Desktop), not to Python.
If it was denied, re-enable it under System Settings → Privacy & Security → Calendars, enable your MCP client, then fully quit and reopen it.
Ask Claude things like:
- "What's on my calendar this week?"
- "Move my 3pm Friday meeting to 4pm and add a location."
- "Create a standup every weekday at 9am for the next two weeks."
- "Delete just next Tuesday's occurrence of that standup."
See DEMO.md for a copy-paste prompt that exercises every tool on a self-cleaning scratch calendar — safe to run against a real account.
server.py is a single-file FastMCP server
that talks to EventKit through PyObjC. It speaks
MCP over stdio, so any stdio-capable MCP client can use it — Claude Desktop is
just the documented example.
MIT — see LICENSE.