Skip to main content
Glama
macOS Ecosystem MCP Server

macOS Ecosystem MCP Server

macOS Ecosystem MCP Server

A fast, native Model Context Protocol (MCP) server for Claude that provides direct access to macOS productivity apps: Reminders, Calendar, and Notes.

Why This Rewrite?

The original Node.js/TypeScript server shelled out to osascript for every tool call — adding 300–800 ms of process-startup overhead each time.

This Swift rewrite:

  • Uses EventKit natively for Reminders and Calendar (no subprocess)

  • Only shells out to osascript for Notes (Notes.framework is private)

  • Compiles to a single self-contained binary — no Node.js runtime required

  • Speaks the MCP stdio protocol directly via the official Swift SDK

Related MCP server: macos-mcp

Features

🗓️ Reminders (4 tools — EventKit)

  • reminders_add — Create reminders with title, notes, due date, priority

  • reminders_list — List reminders, filter by list and completion status

  • reminders_complete — Mark a reminder as completed (by ID or title)

  • reminders_search — Search reminders by keyword

📅 Calendar (5 tools — EventKit)

  • calendar_create_event — Create events with location, notes, alerts

  • calendar_list_events — List events within a date range

  • calendar_find_free_time — Find available time slots

  • calendar_update_event — Modify existing events

  • calendar_delete_event — Delete events

📝 Notes (3 tools — osascript)

  • notes_create — Create notes with title and body (HTML supported)

  • notes_append — Append content to existing notes

  • notes_search — Search notes by keyword

💬 iMessage (4 tools — SQLite reads + osascript sends)

  • imessage_list_chats — List recent conversations with participants and a last-message preview

  • imessage_read — Read a conversation by chat_guid or handle; includes attachment paths

  • imessage_search — Search message text across all conversations

  • imessage_send — Send text and/or a file attachment to an allowlisted contact

Reads query the local ~/Library/Messages/chat.db directly (read-only). Sends go through AppleScript and are gated by a fail-closed contact allowlist — sending is disabled until you configure one:

  • Env var: MACOS_MCP_IMESSAGE_ALLOWLIST="+15551234567,friend@example.com"

  • And/or file ~/.config/macos-mcp/imessage-allowlist.json:

    { "allow": ["+15551234567", "friend@example.com"] }

Phone numbers are matched loosely (last 10 digits), so formatting/country-code differences still match. Attachments from protected directories (the config dir, ~/Library/Messages) are refused.

Requirements

  • macOS 13 Ventura or later

  • Xcode 15+ / Swift 5.9+ (build only)

  • Reminders, Calendar, Contacts, and Notes access granted in System Settings → Privacy & Security

  • Full Disk Access for the app running this server (Terminal, your MCP client, etc.) — required to read chat.db and to send via Messages. Grant it under System Settings → Privacy & Security → Full Disk Access. Without it, the iMessage tools return an actionable error.

Build from Source

git clone https://github.com/neverprepared/macos-ecosystem-mcp.git
cd macos-ecosystem-mcp
swift build -c release

The binary is placed at:

.build/release/macos-mcp

Install it system-wide:

sudo cp .build/release/macos-mcp /usr/local/bin/macos-mcp

macOS Permissions

The first time the binary runs it will request access. You can also grant it in advance:

  1. System Settings → Privacy & Security → Reminders — add macos-mcp

  2. System Settings → Privacy & Security → Calendars — add macos-mcp

  3. System Settings → Privacy & Security → Automation → Notes — add macos-mcp

Claude Desktop Configuration

Add this to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "macos-ecosystem": {
      "command": "/usr/local/bin/macos-mcp"
    }
  }
}

Or using the local build path:

{
  "mcpServers": {
    "macos-ecosystem": {
      "command": "/path/to/macos-ecosystem-mcp/.build/release/macos-mcp"
    }
  }
}

Restart Claude Desktop after editing the config.

Tool Reference

reminders_add

Parameter

Type

Required

Default

Description

title

string

✓

—

Reminder title

list

string

"Reminders"

List name

notes

string

—

Body text

dueDate

string

—

ISO 8601 date-time

priority

none|low|medium|high

"none"

Priority

reminders_list

Parameter

Type

Required

Default

Description

list

string

—

Filter by list

includeCompleted

boolean

false

Include completed

limit

integer

50

Max results (1–100)

reminders_complete

Parameter

Type

Required

Description

reminderId

string

(one of)

EventKit calendarItemIdentifier

title

string

(one of)

Reminder title

list

string

Narrow search to list

Parameter

Type

Required

Default

Description

query

string

✓

—

Search keyword

list

string

—

Restrict to list

includeCompleted

boolean

false

Include completed

limit

integer

20

Max results

calendar_create_event

Parameter

Type

Required

Default

Description

title

string

✓

—

Event title

startDate

string

✓

—

ISO 8601 start

endDate

string

✓

—

ISO 8601 end

calendar

string

system default

Calendar name

location

string

—

Location

notes

string

—

Description

allDay

boolean

false

All-day event

alerts

integer[]

—

Alert offsets in minutes

calendar_list_events

Parameter

Type

Required

Default

Description

startDate

string

✓

—

ISO 8601 range start

endDate

string

✓

—

ISO 8601 range end

calendar

string

—

Filter by calendar

limit

integer

50

Max results

calendar_find_free_time

Parameter

Type

Required

Default

Description

date

string

✓

—

ISO 8601 day to search

duration

integer

✓

—

Required slot (15–480 min)

workingHoursStart

integer

9

Start hour (0–23)

workingHoursEnd

integer

17

End hour (0–23)

calendar

string

—

Restrict to calendar

calendar_update_event

Parameter

Type

Required

Description

eventId

string

✓

EKEvent eventIdentifier

title

string

New title

startDate

string

New ISO 8601 start

endDate

string

New ISO 8601 end

location

string

New location

notes

string

New description

calendar_delete_event

Parameter

Type

Required

Description

eventId

string

(one of)

EKEvent eventIdentifier

title

string

(one of)

Event title

date

string

ISO 8601 date to narrow search

notes_create

Parameter

Type

Required

Default

Description

title

string

✓

—

Note title

body

string

✓

—

Note body

folder

string

"Notes"

Folder name

notes_append

Parameter

Type

Required

Description

noteId

string

(one of)

AppleScript note ID

title

string

(one of)

Note title

folder

string

Narrow search

content

string

✓

Content to append

Parameter

Type

Required

Default

Description

query

string

✓

—

Search keyword

folder

string

—

Restrict to folder

limit

integer

20

Max results

Architecture

Sources/macos-mcp/
├── App.swift              # @main entry — MCP server setup and tool dispatcher
├── ToolDefinitions.swift  # JSON Schema definitions for all 12 tools
├── EventKitManager.swift  # Swift actor wrapping EKEventStore (reminders + calendar)
└── NotesHandler.swift     # osascript runner for Notes operations

Notes on Flagged Reminders

EventKit does not expose the "flagged" status of reminders (it is a Reminders-app-specific attribute not in the EventKit API). The flagged parameter is accepted but silently ignored when creating reminders.

License

MIT

Available Tools

12 tools
calendar_create_eventB

Create a new event in Apple Calendar. Supports all-day and timed events with optional location, notes, attendees, and alerts.

Inputs: title (required), startDate (required), endDate (required), calendar, +5 more.

calendar_delete_eventB

Delete a calendar event. Can find by event ID (most reliable) or by title with optional date filter.

Inputs: eventId, title, date.

calendar_find_free_timeB

Find available time slots in your calendar for scheduling meetings. Analyzes existing events and returns free gaps.

Inputs: date (required), duration (required), workingHoursStart, workingHoursEnd, +1 more.

calendar_list_eventsB

List calendar events within a date range. Can filter by specific calendar. Returns up to 100 events.

Inputs: startDate (required), endDate (required), calendar, limit.

calendar_update_eventC

Update an existing calendar event. Can modify title, dates, location, or notes.

Inputs: eventId (required), title, startDate, endDate, +2 more.

notes_appendA

Append content to an existing note. Can find by note ID (most reliable) or by title with optional folder filter.

Inputs: content (required), noteId, title, folder.

notes_createA

Create a new note in Apple Notes app with title and body content. Supports HTML formatting in the body.

Inputs: title (required), body (required), folder.

reminders_addA

Create a new reminder in Apple Reminders app. Supports title, list, notes, due date, priority (none/low/medium/high), and flagged status.

Inputs: title (required), list, notes, dueDate, +2 more.

reminders_completeA

Mark a reminder as completed. Can find by reminder ID (most reliable) or by title with optional list filter.

Inputs: reminderId, title, list.

reminders_listA

List reminders from Apple Reminders app with optional filtering by list name and completion status. Returns up to 100 reminders.

Inputs: list, includeCompleted, limit.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.8/5.0

    Scored across 12 tools

    Disambiguation5/5

    Every tool has a clearly distinct purpose with no ambiguity, as each is scoped to a specific app (calendar, notes, reminders) and action (create, delete, update, list/search, etc.). For example, calendar_find_free_time is unique for scheduling, while notes_append is distinct from notes_create. The descriptions reinforce this by detailing specific functionalities, ensuring agents can easily differentiate between tools.

    Naming Consistency5/5

    Tool names follow a highly consistent verb_noun pattern throughout, with a clear structure of app_action (e.g., calendar_create_event, notes_search). All tools use snake_case uniformly, and the naming convention is predictable, making it easy for agents to infer functionality. There are no deviations in style or verb usage across the set.

    Tool Count5/5

    The 12 tools are well-scoped for the macOS ecosystem server, covering three key apps (calendar, notes, reminders) with a balanced set of operations. Each tool earns its place by providing essential CRUD and utility functions, such as calendar_find_free_time for scheduling. The count is neither too sparse nor bloated, fitting the domain appropriately.

    Completeness5/5

    The tool set offers complete CRUD/lifecycle coverage for each app domain, with no obvious gaps. For calendar, it includes create, delete, update, list, and find_free_time. For notes, it covers create, append, and search. For reminders, it has add, complete, list, and search. This comprehensive surface allows agents to handle all core workflows without dead ends.

    Maintenance

    ActivitySlowing
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      Transforms macOS calendar management into a conversational experience using natural language, allowing users to create, manage, and update calendar events seamlessly through an MCP-compatible client.
      333
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      Enables AI assistants to read, create, update, and delete data in macOS apps (Reminders, Calendar, Notes, Mail, Messages, Contacts) via natural language, using EventKit, JXA, and SQLite backends.
      493 npm
      11
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables AI assistants to interact with local Apple Calendar, Notes, and Contacts on macOS. Provides tools for creating, reading, updating, and deleting events, notes, and contacts through natural language.
      MIT