@lejangt/icloud-mcp
v0.1.0
Published
MCP server for iCloud Calendar, Contacts, and Mail via CalDAV/CardDAV/IMAP
Readme
icloud-mcp
An MCP server for iCloud Calendar, Contacts, and Mail — usable from any MCP-capable AI client (Claude Desktop, Claude Code, Cursor, Windsurf, etc.).
Only uses Apple's officially documented protocols: CalDAV (calendar), CardDAV (contacts), and IMAP/SMTP (mail). It does not touch Reminders, Notes, Find My, or Photos — those only have an undocumented, reverse-engineered API that's out of scope here (see Scope below).
Status
Early development. Not yet published to npm — see Development to run it from source in the meantime.
Tools
| Tool | Read/Write | Description |
| --- | --- | --- |
| health_check | read | Confirms the server is running |
| list_calendars | read | Lists iCloud calendars |
| list_events | read | Lists events in a calendar within a time range |
| get_event | read | Fetches a single event |
| create_event | write | Creates a calendar event |
| update_event | write | Updates an existing event |
| delete_event | write | Deletes an event |
| list_contacts | read | Lists contacts, optionally filtered |
| search_contacts | read | Searches contacts by name/org/email/phone |
| get_contact | read | Fetches a single contact |
| create_contact | write | Creates a contact |
| update_contact | write | Updates an existing contact |
| delete_contact | write | Deletes a contact |
| list_mailboxes | read | Lists IMAP mailboxes/folders |
| list_messages | read | Lists recent messages in a mailbox |
| search_messages | read | Searches messages by sender/subject/text |
| get_message | read | Fetches a single message's headers + text body |
| send_message | write | Sends an email |
Write tools are disabled by default. They only register when
ICLOUD_MCP_ALLOW_WRITE=true is set — see Security.
Setup
1. Generate an app-specific password
Apple requires a dedicated app-specific password for third-party CalDAV/CardDAV/IMAP access — never use your actual Apple ID password here.
- Go to appleid.apple.com → Sign-In and Security → App-Specific Passwords
- Generate one (e.g. named "icloud-mcp") and copy it
2. Configure environment variables
| Variable | Required | Description |
| --- | --- | --- |
| ICLOUD_APPLE_ID | yes | Your Apple ID email |
| ICLOUD_APP_SPECIFIC_PASSWORD | yes* | The app-specific password from step 1 |
| ICLOUD_MCP_ALLOW_WRITE | no | Set to true to enable write tools (default: read-only) |
| ICLOUD_CALDAV_URL | no | Override the CalDAV endpoint (default: https://caldav.icloud.com) |
| ICLOUD_CARDDAV_URL | no | Override the CardDAV endpoint (default: https://contacts.icloud.com) |
* Instead of ICLOUD_APP_SPECIFIC_PASSWORD, you can store the password in your OS keychain
under service icloud-mcp, account <your Apple ID> (macOS Keychain / libsecret via
keytar), and omit the env var.
3. Add it to your MCP client
Once published, the server runs via npx @lejangt/icloud-mcp over stdio.
Claude Code:
claude mcp add icloud --env [email protected] --env ICLOUD_APP_SPECIFIC_PASSWORD=xxxx-xxxx-xxxx-xxxx -- npx @lejangt/icloud-mcpClaude Desktop / Cursor / Windsurf / any client using mcpServers JSON config:
{
"mcpServers": {
"icloud": {
"command": "npx",
"args": ["@lejangt/icloud-mcp"],
"env": {
"ICLOUD_APPLE_ID": "[email protected]",
"ICLOUD_APP_SPECIFIC_PASSWORD": "xxxx-xxxx-xxxx-xxxx"
}
}
}
}Add "ICLOUD_MCP_ALLOW_WRITE": "true" to env if you want write tools enabled.
Security
- Write tools are opt-in. Without
ICLOUD_MCP_ALLOW_WRITE=true, the server only exposes read tools — reducing the blast radius if a client misbehaves or credentials leak. - Enabling write tools means the AI agent can send email and modify/delete calendar events and contacts on your behalf. Only enable it if you understand and accept that.
- All connections use TLS; credentials are never logged (see
src/logging.ts). - See SECURITY.md for the full threat model and how to report vulnerabilities.
Scope
Calendar, contacts, and mail are supported because Apple documents stable, official protocols
for them (CalDAV/CardDAV/IMAP+SMTP with an app-specific password). Reminders, Notes, Find My,
and Photos are intentionally out of scope: the only way to access them programmatically is
Apple's undocumented, reverse-engineered iCloud web API (as used by projects like pyicloud),
which requires your full Apple ID session (2FA included) and can break without warning when
Apple changes internals. That's a meaningfully different risk/maintenance profile and isn't
part of this project.
Development
Requires Node.js ≥ 18.
npm install
npm run build # compile TypeScript to dist/
npm run dev # watch mode
npm run lint
npm run typecheck
npm testRun the server directly against real credentials for manual testing:
[email protected] ICLOUD_APP_SPECIFIC_PASSWORD=xxxx-xxxx-xxxx-xxxx node dist/index.jsOr drive it interactively with the MCP Inspector:
[email protected] ICLOUD_APP_SPECIFIC_PASSWORD=xxxx-xxxx-xxxx-xxxx \
npx @modelcontextprotocol/inspector node dist/index.jsLicense
MIT — see LICENSE.
