A Rust library and CLI for interacting with macOS Calendar events and Reminders via Apple's EventKit framework. Includes a built-in Model Context Protocol (MCP) server for AI assistant integration.
- Calendar Events — Create, read, update, and delete calendar events with alarms, recurrence, attendees, and structured location
- Reminders — Full CRUD for reminders with priority, alarms, recurrence, tags, and URL support
- MCP Server — Built-in MCP server (
--mcp) with structured JSON output, input/output schemas, and 26 tools - Calendar Management — Create, update (name + color), and delete both reminder lists and event calendars
- Batch Operations — Batch delete, move, and update across reminders and events
- Location — Get current location via CoreLocation for geofenced reminders
- In-Process Transport — Embed as a library with
serve_on()for DuplexStream-based in-process MCP - CLI + Dump — Command-line tool with JSON dump for debugging raw EventKit objects
- macOS 14+ (Sonoma)
- Rust 1.94+
cargo install eventkit-rs[dependencies]
eventkit-rs = "0.5"Without MCP dependencies:
[dependencies]
eventkit-rs = { version = "0.5", default-features = false, features = ["events", "reminders"] }use eventkit::{RemindersManager, EventsManager};
fn main() -> eventkit::Result<()> {
// Reminders
let reminders = RemindersManager::new();
reminders.request_access()?;
let reminder = reminders.create_reminder(
"Buy groceries",
Some("Milk, eggs, bread"),
None, Some(1), None, None,
)?;
for item in reminders.fetch_incomplete_reminders()? {
println!("- {}", item.title);
}
// Calendar Events
let events = EventsManager::new();
events.request_access()?;
for event in events.fetch_today_events()? {
println!("{} at {}", event.title, event.start_date);
}
Ok(())
}use tokio::io::duplex;
// One end for the MCP client, one for the server
let (client_stream, server_stream) = duplex(64 * 1024);
// Spawn the EventKit MCP server in-process
tokio::spawn(async move {
eventkit::mcp::serve_on(server_stream).await.unwrap();
});
// Connect your MCP client to client_stream...# MCP server (stdio transport)
eventkit --mcp
# Authorization status
eventkit status
eventkit status --events
# Reminders
eventkit reminders authorize
eventkit reminders lists
eventkit reminders list --all
eventkit reminders add "Call mom" --notes "Birthday" --priority 1
eventkit reminders show <id>
eventkit reminders update <id> --title "Call mom back" --priority 1
eventkit reminders complete <id>
eventkit reminders uncomplete <id>
eventkit reminders delete <id> --force
# Calendar Events
eventkit events authorize
eventkit events calendars
eventkit events list --today
eventkit events list --days 14 --all
eventkit events add "Meeting" --start "2026-03-22 14:00" --duration 60
eventkit events add "Holiday" --start "2026-03-25" --all-day
eventkit events show <id>
eventkit events delete <id> --force
# Dump objects as JSON (for debugging)
eventkit dump reminder-lists
eventkit dump calendars
eventkit dump sources
eventkit dump reminder <id>
eventkit dump reminders --list "Shopping"
eventkit dump event <id>
eventkit dump events --days 30All tools return structured JSON with typed output schemas. Responses use structured_content (MCP spec 2025-06-18) with text fallback for older clients.
| Tool | Description |
|---|---|
| Reminder Lists | |
list_reminder_lists |
List all reminder lists with color, source, permissions |
create_reminder_list |
Create a new reminder list |
update_reminder_list |
Update name and/or color (red, blue, green, purple, etc.) |
delete_reminder_list |
Delete a list and all its reminders |
| Reminders | |
list_reminders |
List reminders, filter by list and completion status |
create_reminder |
Create with inline alarms, recurrence, URL, tags, priority |
update_reminder |
Update any fields including alarms, recurrence, URL, tags |
get_reminder |
Get full detail (alarms, recurrence, tags inline) |
delete_reminder |
Delete a reminder |
complete_reminder |
Mark as completed |
uncomplete_reminder |
Mark as not completed |
| Event Calendars | |
list_calendars |
List all event calendars with color, source, permissions |
create_event_calendar |
Create a new calendar |
update_event_calendar |
Update name and/or color |
delete_event_calendar |
Delete a calendar and all its events |
| Events | |
list_events |
List events by date range, filter by calendar ID |
create_event |
Create with inline alarms, recurrence, URL |
update_event |
Update any fields including alarms, recurrence, URL |
get_event |
Get full detail (alarms, recurrence, attendees, organizer) |
delete_event |
Delete (with affect_future for recurring events) |
| Search & Location | |
search |
Search reminders and/or events by text (item_type optional) |
get_current_location |
Get lat/long via CoreLocation |
list_sources |
List accounts (iCloud, Local, Exchange) |
| Batch | |
batch_delete |
Delete multiple reminders or events at once |
batch_move |
Move multiple reminders between lists |
batch_update |
Update multiple items at once |
| Prompt | Description |
|---|---|
incomplete_reminders |
List all incomplete reminders (optionally by list) |
reminder_lists |
List all available reminder lists |
move_reminder |
Move a reminder to a different list |
create_detailed_reminder |
Create a reminder with notes, priority, and due date |
Add to your MCP client config (e.g. Claude Desktop):
{
"mcpServers": {
"eventkit": {
"command": "eventkit",
"args": ["--mcp"]
}
}
}Add to your Info.plist:
<key>NSRemindersFullAccessUsageDescription</key>
<string>This app needs access to your reminders.</string>
<key>NSCalendarsFullAccessUsageDescription</key>
<string>This app needs access to your calendar.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs your location for location-based reminders.</string>| Feature | Default | Description |
|---|---|---|
events |
Yes | Calendar event support |
reminders |
Yes | Reminders support |
location |
Yes | CoreLocation for geofenced reminders |
mcp |
Yes | MCP server, structured JSON output, dump command |
# Run all checks (same as CI)
./ci-check.sh
# Auto-fix formatting + clippy
./ci-check.sh --fix
# Build universal binary (arm64 + x86_64)
./build-universal.shApache 2.0 — see LICENSE.