Read-only Mac Calendar MCP server with indexed archive search.
Project description
Mac Calendar MCP
Read-only Mac Calendar MCP server with indexed archive search. It exposes Apple Calendar data to MCP clients through a small read surface for listing calendars, browsing event ranges, reading event details, searching archived events, and building agendas.
This package is developed in the
apple-app-mcp workspace alongside
Mac Mail MCP.
Quick Start
pipx install mac-calendar-mcp
Add to your MCP client:
{
"mcpServers": {
"calendar": {
"command": "mac-calendar-mcp",
"args": ["--watch", "serve"]
}
}
}
Build the Search Index (Recommended)
# Requires Full Calendar Access for Terminal or your MCP client
# System Settings -> Privacy & Security -> Calendars
mac-calendar-mcp index
The index enables fast archive search and date-range reads from a local SQLite and FTS5 database.
Rebuilds use Calendar's local database when it is readable, then fall back to Apple's supported EventKit API. Calendar.app scripting is retained only as a legacy final fallback. A failed or suspiciously empty refresh never replaces a previously healthy index.
Run the MCP server with watch mode to keep the index current while events change in Calendar.app:
mac-calendar-mcp serve --watch
The server performs a background sync at startup. Watch mode then checks
Calendar's local SQLite database, WAL, and SHM files every 3600 seconds and
refreshes the index when those files change. Override the interval with
--watch-interval SECONDS when you need faster or slower updates.
Configure (Optional)
mac-calendar-mcp init # writes ~/.mac-calendar-mcp/config.toml
Mac Calendar MCP reads settings from environment variables and an optional
TOML config file at $HOME/.mac-calendar-mcp/config.toml. The init
command writes a commented template with every available key and refuses to
overwrite an existing config unless --force is passed.
Common environment variables:
| Variable | Purpose |
|---|---|
APPLE_CALENDAR_INDEX_PATH |
Override the SQLite index location. |
APPLE_CALENDAR_INDEX_SOURCE |
Snapshot source: auto (default), store, eventkit, or jxa. |
APPLE_CALENDAR_INDEX_STALENESS_HOURS |
Hours before an index is considered stale. |
APPLE_CALENDAR_INDEX_CALENDARS |
Comma-separated calendar names or IDs to index; unset indexes all calendars. |
APPLE_CALENDAR_INDEX_PAST_YEARS |
Historical indexing window; defaults to 1 year. |
APPLE_CALENDAR_INDEX_FUTURE_YEARS |
Limit future indexing window. |
APPLE_CALENDAR_DEFAULT_CALENDARS |
Comma-separated tool-default calendar names or IDs when calendar_ids is omitted. |
[defaults].calendars only controls MCP tool defaults. [index].calendars
controls which calendars are stored in the local search index.
Tools
| Tool | Purpose |
|---|---|
list_calendars() |
List accessible calendars |
get_events(start, end, calendar_ids?, limit?, offset?) |
List event occurrences in a date range |
get_event(event_id, occurrence_start?) |
Get full event or occurrence detail |
search_events(query, start?, end?, calendar_ids?, fields?, limit?, offset?) |
Search indexed event archives |
get_agenda(start?, days?, calendar_ids?) |
Chronological agenda helper |
calendar_index_status() |
Index health and coverage summary |
All tools are read-only. The server does not create, update, delete, RSVP, subscribe to calendars, or open Calendar.app UI in v1.
Search and Indexing
Calendar search is backed by SQLite and FTS5. Indexed fields include event title, location, notes, URL, attendee names/emails, and calendar name.
Recurring events are expanded into occurrence rows for listing and search. The
current recurrence layer supports common daily, weekly, monthly, and yearly
patterns, including intervals, counts, until dates, weekly BYDAY, and Calendar
exception dates. Unsupported recurrence rules are counted in index status
instead of being silently treated as complete.
Configuration
Per-client env overrides via the MCP client's launch config work:
{
"mcpServers": {
"calendar": {
"command": "mac-calendar-mcp",
"env": {
"APPLE_CALENDAR_DEFAULT_CALENDARS": "Work,Personal",
"APPLE_CALENDAR_INDEX_FUTURE_YEARS": "2"
}
}
}
}
The default index path is $HOME/.mac-calendar-mcp/index.db.
CLI Usage
All read tools are also available as standalone CLI commands:
mac-calendar-mcp calendars
mac-calendar-mcp init
mac-calendar-mcp index
mac-calendar-mcp status
mac-calendar-mcp search "quarterly planning" --limit 10
mac-calendar-mcp events 2026-05-01 2026-06-01 --limit 50
mac-calendar-mcp agenda --days 7
mac-calendar-mcp rebuild
mac-calendar-mcp rebuild --verbose # source and snapshot counts
All data commands output JSON where practical.
Development
git clone https://github.com/wagamama/apple-app-mcp
cd apple-app-mcp
uv sync
uv run ruff check packages/mac-calendar-mcp/src
uv run --package mac-calendar-mcp pytest packages/mac-calendar-mcp/tests
uv build --package mac-calendar-mcp
See CALENDAR.md for domain architecture, tool design,
testing guidance, and implementation notes.
License
GPL-3.0-or-later
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mac_calendar_mcp-0.5.13.tar.gz.
File metadata
- Download URL: mac_calendar_mcp-0.5.13.tar.gz
- Upload date:
- Size: 34.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f0ca46a18e3a1cb10d49d42d81c6dd789ede931694bf679d2c1d758a74ce0d2b
|
|
| MD5 |
ac45a0ac78e82532efcc241a30d5b266
|
|
| BLAKE2b-256 |
e0392275f2a9b1a5ad58ec1ce3ff5ae0fd231258c50e56f9ce49799c22573340
|
Provenance
The following attestation bundles were made for mac_calendar_mcp-0.5.13.tar.gz:
Publisher:
release.yml on wagamama/apple-app-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mac_calendar_mcp-0.5.13.tar.gz -
Subject digest:
f0ca46a18e3a1cb10d49d42d81c6dd789ede931694bf679d2c1d758a74ce0d2b - Sigstore transparency entry: 2171595140
- Sigstore integration time:
-
Permalink:
wagamama/apple-app-mcp@2a7c8994ef99d15b52fe9a6103f449f7d7253302 -
Branch / Tag:
refs/tags/v0.5.13 - Owner: https://github.com/wagamama
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2a7c8994ef99d15b52fe9a6103f449f7d7253302 -
Trigger Event:
push
-
Statement type:
File details
Details for the file mac_calendar_mcp-0.5.13-py3-none-any.whl.
File metadata
- Download URL: mac_calendar_mcp-0.5.13-py3-none-any.whl
- Upload date:
- Size: 31.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
17dd8c61e664a9853785d4d67dfc552ff60becdebdc969c964b7908e534d7c74
|
|
| MD5 |
aa63e5227b9e2489ee0e951d8d530a46
|
|
| BLAKE2b-256 |
6cf1524b816b825dd59f337d3aeaa7a4970b41b916b80f6f7eedeb38c5b8ca3a
|
Provenance
The following attestation bundles were made for mac_calendar_mcp-0.5.13-py3-none-any.whl:
Publisher:
release.yml on wagamama/apple-app-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mac_calendar_mcp-0.5.13-py3-none-any.whl -
Subject digest:
17dd8c61e664a9853785d4d67dfc552ff60becdebdc969c964b7908e534d7c74 - Sigstore transparency entry: 2171595152
- Sigstore integration time:
-
Permalink:
wagamama/apple-app-mcp@2a7c8994ef99d15b52fe9a6103f449f7d7253302 -
Branch / Tag:
refs/tags/v0.5.13 - Owner: https://github.com/wagamama
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2a7c8994ef99d15b52fe9a6103f449f7d7253302 -
Trigger Event:
push
-
Statement type: