Prepare the server locally
Run this once before adding it to Claude Code.
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python server.pyRegister it in Claude Code
claude mcp add -e "APPLE_ID=${APPLE_ID}" -e "ICLOUD_APP_PASSWORD=${ICLOUD_APP_PASSWORD}" icloud-mcp -- python /path/to/server.pyReplace any placeholder paths in the command with the real path on your machine.
APPLE_IDICLOUD_APP_PASSWORD+ 2 optionalMake your agent remember this setup
icloud-mcp's config, env vars, and the gotchas you hit — recalled in every future Claude Code, Cursor, and Codex session.
npx conare@latestFree · one command · indexes the sessions already on disk. Set up in the browser instead →
What it does
- Full CalDAV support for listing, creating, updating, and deleting calendar events
- Optional IMAP/SMTP support for reading and sending emails
- Supports recurring event expansion and ISO datetime formatting
- Includes a read-only Deep Research profile for safe calendar querying
Tools 8
list_calendarsReturns a list of available iCloud calendars.list_calendars_with_eventsReturns calendars that contain at least one event in the given time window.list_eventsLists events for a specific calendar within a time window.create_eventCreates a new event in the specified calendar.update_eventUpdates an existing event in the specified calendar.delete_eventDeletes an event from the specified calendar.searchPerforms a basic text search over event summaries and descriptions.send_messageSends an email via SMTP.Environment Variables
APPLE_IDrequiredYour Apple ID email addressICLOUD_APP_PASSWORDrequirediCloud app-specific passwordMAIL_ENABLEDSet to 1 to enable mail toolsDR_PROFILESet to 1 to enable read-only Deep Research modeTry it
Original README from alexey-max-fedorov/icloud-mcp
iCloud MCP Connector
An HTTP Model Context Protocol (MCP) server exposing iCloud services to MCP-aware clients (e.g., ChatGPT custom connectors, IDEs) using an iCloud app-specific password.
Supported: iCloud Calendar (CalDAV) + iCloud Mail (IMAP/SMTP).
Unofficial. Keep this service private; it forwards your iCloud app-specific password to Apple’s servers.
Why did I build this?
I built this to use in ChatGPT Custom Connector, so I can change my iCloud Calendar compared to changing it manually. Came up with this idea on a Friday night before a TOP Pset was due, and this turned out to be a fun 1-day project.
Features
- HTTP MCP server (
/mcp) +GET /health - Calendar tools (default write-capable profile):
list_calendars()list_calendars_with_events(start, end, expand_recurring=True)list_events(calendar_name_or_url, start, end, expand_recurring=True)create_event(calendar_name_or_url, summary, start, end, tzid?, description?, location?, recurrence?)update_event(calendar_name_or_url, uid, summary?, start?, end?, tzid?, description?, location?, recurrence?, clear_recurrence=False)delete_event(calendar_name_or_url, uid)
- Calendar tools (Deep Research read-only profile,
DR_PROFILE=1):search(query)→ basic text search over SUMMARY/DESCRIPTION in a time windowfetch(ids)→ fetch rawtext/calendarICS blobs for search results
- Mail tools (opt-in,
MAIL_ENABLED=1):list_mailboxes()— list all folderslist_messages(mailbox, limit, unread_only)— list messages with headersget_message(uid, mailbox)— fetch full message with bodysearch_messages(query, mailbox, limit)— IMAP TEXT searchsend_message(to, subject, body, cc?, bcc?)— send via SMTPdelete_message(uid, mailbox)— move to Trashmark_message(uid, mailbox, read)— mark read/unread
- ISO datetime input (
YYYY-MM-DDTHH:MM:SS, with optionalZor timezone offset) - Minimal ICS generation (summary/description escaping), UID matching across a ±3-year window
Requirements
- Python 3.11+
- Apple ID (email identity, not phone number)
- iCloud app-specific password (revocable) — one password works for both calendar and mail
- Network access to
https://caldav.icloud.com,imap.mail.me.com,smtp.mail.me.com
Environment
Create a .env next to server.py (auto-loaded):
[email protected] # Use your Apple ID email
ICLOUD_APP_PASSWORD=xxxx-xxxx-xxxx-xxxx # App-specific password (works for both calendar and mail)
CALDAV_URL=https://caldav.icloud.com # optional, default shown
HOST=127.0.0.1 # optional
PORT=8000 # optional
TZID=America/New_York # default TZ for new/edited events
# Deep Research: read-only calendar profile (optional)
DR_PROFILE=0 # Set to 1 to enable DR mode (default 0)
SCAN_DAYS=1095 # Time window (days) scanned by DR search/fetch (default ~3 years)
# Mail (IMAP / SMTP) — optional, disabled by default
MAIL_ENABLED=1 # Set to 1 to enable mail tools
IMAP_HOST=imap.mail.me.com # optional, default shown
IMAP_PORT=993 # optional, default shown
SMTP_HOST=smtp.mail.me.com # optional, default shown
SMTP_PORT=587 # optional, default shown
ICLOUD_TRASH_FOLDER=Deleted Messages # optional, iCloud trash folder name
Required: APPLE_ID, ICLOUD_APP_PASSWORD.
Quick Start (local)
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
# Ensure .env exists (see above), then:
python server.py
# -> Listening on http://127.0.0.1:8000
curl http://127.0.0.1:8000/health # OK
MCP endpoint: http://127.0.0.1:8000/mcp
Tool Reference (functional details)
`list_calendars() -> List[Calendar]`
Returns:
name: str | nullurl: str(preferred identifier for other calls)id: str | null
`list_calendars_with_events(start, end, expand_recurring=True) -> List[Calendar]`
Returns only the calendars that contain at least one event in the given time window.
Args
start, end: str— ISO datetimes; search is [start, end)expand_recurring: bool— treat recurring series as concrete instances
Each returned calendar has the same shape as list_calendars().
`list_events(calendar_name_or_url, start, end, expand_recurring=True) -> List[Event]`
Args
calendar_name_or_url: str— display name or full CalDAV URLstart, end: str— ISO datetimes; search is [start, end)expand_recurring: bool— include concrete instances of recurring series
Returns each event with:
uid: strsummary: strstart: str(ISO)end: str | null(ISO)raw: str(original ICS text)