Skip to main content
Glama
IceyWu

icloud-calendar-mcp

by IceyWu

icloud-calendar-mcp

Reliable, lightweight Apple iCloud Calendar MCP Server. Native TypeScript/Node.js, connects directly to iCloud via CalDAV; no dependency on Java, Python, Go, AppleScript, macOS, or Calendar.app.

English summary: A production-oriented, cross-platform TypeScript MCP server for Apple iCloud Calendar. It provides guarded CalDAV CRUD, persistent opaque handles, idempotent writes, ETag concurrency control, recurrence expansion, stdio and secured Streamable HTTP transports.

Installation

Requires Node.js 20 or higher. Must use Apple's "App-Specific Password", do not use the Apple account master password.

npx icloud-calendar-mcp

Create an app-specific password: Log in to account.apple.com, go to "Sign-In and Security" → "App-Specific Passwords". Apple may limit the number of simultaneously active app-specific passwords; revoking a password will cause this service to receive AUTH_FAILED.

stdio client configuration:

{
  "mcpServers": {
    "icloud-calendar": {
      "command": "npx",
      "args": ["-y", "icloud-calendar-mcp"],
      "env": {
        "ICLOUD_USERNAME": "you@example.com",
        "ICLOUD_APP_PASSWORD": "xxxx-xxxx-xxxx-xxxx"
      }
    }
  }
}

stdout is only for JSON-RPC; all logs are written to stderr.

Related MCP server: Chronos MCP

Tools and MCP Content

Name

Description

list_calendars

List iCloud calendars

list_events

Query by explicit time range, timezone, cursor, and limit; request CalDAV server-side expansion of occurrences

get_event

Read an event using a cross-process persistent opaque handle

create_event

Idempotent creation with request_id and stable UID

update_event

Update using a persistent handle and If-Match

delete_event

Delete using a persistent handle and If-Match

find_conflicts

Find time-overlapping events

free_busy

Reliably compute busy intervals client-side from currently readable events

Tools return both structuredContent and text JSON, and declare read-only/destructive/idempotent/open-world annotations. Resource: calendar://calendars. Explicit user template prompts: schedule_event, reschedule_event, find_conflicts; they do not autonomously make scheduling decisions for the user.

Events support timed/all-day, title, description, location, URL, RRULE, DISPLAY alarm, and participants. Participant fields are subject to iCloud and calendar sharing permissions; this service will not falsely report that writing ATTENDEE has successfully sent an invitation.

Time and Recurrence Event Semantics

  • Timed event input must provide ISO 8601 time and IANA timezone; output also explicitly returns the timezone.

  • All-day events use YYYY-MM-DD for start/end, with end not included in the event. For example, an all-day event on August 18 is start=2026-08-18, end=2026-08-19.

  • iCalendar is built and parsed using ical.js, not by string concatenation of user fields; tests cover DST, UTC, and all-day boundaries.

  • list_events expands RRULE occurrences via CalDAV calendar-data/expand request.

  • whole_series supports update/delete. single_occurrence, this_and_future return UNSUPPORTED_OPERATION when iCloud recurrence exception capability is unverified, and never silently change to the whole series.

HTTP Mode

HTTP is disabled by default. When enabled, it only listens on loopback, and the bearer token is at least 24 characters:

ICLOUD_MCP_TRANSPORT=http \
ICLOUD_MCP_HTTP_TOKEN='replace-with-a-long-random-token' \
ICLOUD_MCP_HTTP_PORT=3000 \
npx icloud-calendar-mcp
  • MCP endpoint: POST /mcp

  • Health check: GET /healthz (does not access Apple or leak account status)

  • Enforced bearer token; fixed Host allowlist; Origin denied by default; 1 MiB default request limit; local read/write rate limiting; timeout and security response header boundaries.

  • Set stable parameters via ICLOUD_MCP_CONFIG=/absolute/path/config.json, such as allowedHosts, allowedOrigins, timeoutMs, maxEvents, read/write rate limits, and request limits. Credentials must not be placed in this file.

See docs/tool-contracts.md for the full configuration contract, and docs/security.md for the security model.

Reliability

  • The UID for create is a stable SHA-256 derivation of request_id; duplicate requests will not create a second event.

  • Create uses If-None-Match: *, update/delete use If-Match with the already-read ETag.

  • Journal is written to the user data directory (default ~/.icloud-caldav-mcp/journal.json, with tightened permissions) via atomic rename, preserving request replay and opaque handles.

  • 429/5xx/transient network failures use jittered exponential backoff and respect Retry-After; when response ETag is missing, perform read-after-write visibility polling.

  • Stable error codes: AUTH_FAILED, CALENDAR_NOT_FOUND, EVENT_NOT_FOUND, ETAG_CONFLICT, INVALID_EVENT, RATE_LIMITED, TEMPORARY_UNAVAILABLE, UNSUPPORTED_OPERATION.

Development and Real Account Smoke Test

pnpm install
pnpm check
pnpm pack

User-facing changes are recorded using pnpm changeset. After pushing to main, Changesets automatically creates or updates a Release PR; after merging that PR, it is automatically published with provenance via npm Trusted Publishing. Before first enabling, configure .github/workflows/release.yml as a Trusted Publisher in the npm package settings.

CI uses fake adapter/HTTP fixtures and does not require a real Apple account. Optional real tests run only when ICLOUD_USERNAME and ICLOUD_APP_PASSWORD are explicitly provided locally: pnpm smoke:icloud. The current smoke suite skips write operations by default; for first real verification, it is recommended to manually verify discovery/list/create/update/delete/recurrence exception behavior using a dedicated test calendar.

Troubleshooting: 401/403 check the app-specific password; 412 indicates ETag concurrency conflict, please re-run list_events/get_event; 429 wait and retry; unknown handle means the journal has been deleted or the data directory has changed. Do not paste full CalDAV URLs, Authorization, or event bodies into issues.

License

MIT. Implemented as independent original code; public projects are used only for interface and architecture gap research, with no copying of third-party source code.

Install Server
A
license - permissive license
B
quality
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Hosted Google Calendar MCP server for AI agents. No self-hosting or Google Cloud setup.

  • Streamable HTTP MCP server for Google Calendar and Sheets with OAuth login.

  • Hosted MCP server for business-day math, deadline planning, meeting overlap, and SLA calculations.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/IceyWu/icloud-calendar-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server