NestDaddy

Apple Icloud Mcp

io.github.chrischall/apple-icloud-mcp · v0.5.0

Unofficial: Apple Music, iCloud Calendar/Contacts/Mail, Apple Maps and WeatherKit, no Mac needed

Connect Runs on your machine

Terminal
claude mcp add apple-icloud-mcp -e APPLE_TEAM_ID=<APPLE_TEAM_ID> -e APPLE_KEY_ID=<APPLE_KEY_ID> -e APPLE_PRIVATE_KEY=<APPLE_PRIVATE_KEY> -e APPLE_PRIVATE_KEY_PATH=<APPLE_PRIVATE_KEY_PATH> -e APPLE_MUSIC_KEY_ID=<APPLE_MUSIC_KEY_ID> -e APPLE_MUSIC_PRIVATE_KEY=<APPLE_MUSIC_PRIVATE_KEY> -e APPLE_MAPS_KEY_ID=<APPLE_MAPS_KEY_ID> -e APPLE_MAPS_PRIVATE_KEY=<APPLE_MAPS_PRIVATE_KEY> -e APPLE_WEATHERKIT_KEY_ID=<APPLE_WEATHERKIT_KEY_ID> -e APPLE_WEATHERKIT_PRIVATE_KEY=<APPLE_WEATHERKIT_PRIVATE_KEY> -e APPLE_WEATHERKIT_SERVICE_ID=<APPLE_WEATHERKIT_SERVICE_ID> -e APPLE_MUSIC_DEVELOPER_TOKEN=<APPLE_MUSIC_DEVELOPER_TOKEN> -e APPLE_MUSIC_USER_TOKEN=<APPLE_MUSIC_USER_TOKEN> -e APPLE_MUSIC_WEB_USER_TOKEN=<APPLE_MUSIC_WEB_USER_TOKEN> -e APPLE_MUSIC_WEB_DEVELOPER_TOKEN=<APPLE_MUSIC_WEB_DEVELOPER_TOKEN> -e APPLE_MUSIC_STOREFRONT=<APPLE_MUSIC_STOREFRONT> -e ICLOUD_USERNAME=<ICLOUD_USERNAME> -e ICLOUD_APP_PASSWORD=<ICLOUD_APP_PASSWORD> -e ICLOUD_MAIL_ADDRESS=<ICLOUD_MAIL_ADDRESS> -e ICLOUD_DEFAULT_CALENDAR=<ICLOUD_DEFAULT_CALENDAR> -e APPLE_WRITE_MODE=<APPLE_WRITE_MODE> -e APPLE_SERVICES=<APPLE_SERVICES> -e DISPLAY_TZ=<DISPLAY_TZ> -e APPLE_UNITS=<APPLE_UNITS> -e APPLE_STATE_CACHE=<APPLE_STATE_CACHE> -e APPLE_REQUEST_TIMEOUT_MS=<APPLE_REQUEST_TIMEOUT_MS> -e APPLE_DEBUG_LOG=<APPLE_DEBUG_LOG> -e MCP_CONFIRM_MODE=<MCP_CONFIRM_MODE> -e MCP_CONFIRM_ELICITATION=<MCP_CONFIRM_ELICITATION> -e MCP_CONFIRM_TTL_SECONDS=<MCP_CONFIRM_TTL_SECONDS> -e MCP_CONFIRM_SECRET=<MCP_CONFIRM_SECRET> -- npx -y [email protected]
claude_desktop_config.json
{
  "mcpServers": {
    "apple-icloud-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "[email protected]"
      ],
      "env": {
        "APPLE_TEAM_ID": "<APPLE_TEAM_ID>",
        "APPLE_KEY_ID": "<APPLE_KEY_ID>",
        "APPLE_PRIVATE_KEY": "<APPLE_PRIVATE_KEY>",
        "APPLE_PRIVATE_KEY_PATH": "<APPLE_PRIVATE_KEY_PATH>",
        "APPLE_MUSIC_KEY_ID": "<APPLE_MUSIC_KEY_ID>",
        "APPLE_MUSIC_PRIVATE_KEY": "<APPLE_MUSIC_PRIVATE_KEY>",
        "APPLE_MAPS_KEY_ID": "<APPLE_MAPS_KEY_ID>",
        "APPLE_MAPS_PRIVATE_KEY": "<APPLE_MAPS_PRIVATE_KEY>",
        "APPLE_WEATHERKIT_KEY_ID": "<APPLE_WEATHERKIT_KEY_ID>",
        "APPLE_WEATHERKIT_PRIVATE_KEY": "<APPLE_WEATHERKIT_PRIVATE_KEY>",
        "APPLE_WEATHERKIT_SERVICE_ID": "<APPLE_WEATHERKIT_SERVICE_ID>",
        "APPLE_MUSIC_DEVELOPER_TOKEN": "<APPLE_MUSIC_DEVELOPER_TOKEN>",
        "APPLE_MUSIC_USER_TOKEN": "<APPLE_MUSIC_USER_TOKEN>",
        "APPLE_MUSIC_WEB_USER_TOKEN": "<APPLE_MUSIC_WEB_USER_TOKEN>",
        "APPLE_MUSIC_WEB_DEVELOPER_TOKEN": "<APPLE_MUSIC_WEB_DEVELOPER_TOKEN>",
        "APPLE_MUSIC_STOREFRONT": "<APPLE_MUSIC_STOREFRONT>",
        "ICLOUD_USERNAME": "<ICLOUD_USERNAME>",
        "ICLOUD_APP_PASSWORD": "<ICLOUD_APP_PASSWORD>",
        "ICLOUD_MAIL_ADDRESS": "<ICLOUD_MAIL_ADDRESS>",
        "ICLOUD_DEFAULT_CALENDAR": "<ICLOUD_DEFAULT_CALENDAR>",
        "APPLE_WRITE_MODE": "<APPLE_WRITE_MODE>",
        "APPLE_SERVICES": "<APPLE_SERVICES>",
        "DISPLAY_TZ": "<DISPLAY_TZ>",
        "APPLE_UNITS": "<APPLE_UNITS>",
        "APPLE_STATE_CACHE": "<APPLE_STATE_CACHE>",
        "APPLE_REQUEST_TIMEOUT_MS": "<APPLE_REQUEST_TIMEOUT_MS>",
        "APPLE_DEBUG_LOG": "<APPLE_DEBUG_LOG>",
        "MCP_CONFIRM_MODE": "<MCP_CONFIRM_MODE>",
        "MCP_CONFIRM_ELICITATION": "<MCP_CONFIRM_ELICITATION>",
        "MCP_CONFIRM_TTL_SECONDS": "<MCP_CONFIRM_TTL_SECONDS>",
        "MCP_CONFIRM_SECRET": "<MCP_CONFIRM_SECRET>"
      }
    }
  }
}
~/.cursor/mcp.json
{
  "mcpServers": {
    "apple-icloud-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "[email protected]"
      ],
      "env": {
        "APPLE_TEAM_ID": "<APPLE_TEAM_ID>",
        "APPLE_KEY_ID": "<APPLE_KEY_ID>",
        "APPLE_PRIVATE_KEY": "<APPLE_PRIVATE_KEY>",
        "APPLE_PRIVATE_KEY_PATH": "<APPLE_PRIVATE_KEY_PATH>",
        "APPLE_MUSIC_KEY_ID": "<APPLE_MUSIC_KEY_ID>",
        "APPLE_MUSIC_PRIVATE_KEY": "<APPLE_MUSIC_PRIVATE_KEY>",
        "APPLE_MAPS_KEY_ID": "<APPLE_MAPS_KEY_ID>",
        "APPLE_MAPS_PRIVATE_KEY": "<APPLE_MAPS_PRIVATE_KEY>",
        "APPLE_WEATHERKIT_KEY_ID": "<APPLE_WEATHERKIT_KEY_ID>",
        "APPLE_WEATHERKIT_PRIVATE_KEY": "<APPLE_WEATHERKIT_PRIVATE_KEY>",
        "APPLE_WEATHERKIT_SERVICE_ID": "<APPLE_WEATHERKIT_SERVICE_ID>",
        "APPLE_MUSIC_DEVELOPER_TOKEN": "<APPLE_MUSIC_DEVELOPER_TOKEN>",
        "APPLE_MUSIC_USER_TOKEN": "<APPLE_MUSIC_USER_TOKEN>",
        "APPLE_MUSIC_WEB_USER_TOKEN": "<APPLE_MUSIC_WEB_USER_TOKEN>",
        "APPLE_MUSIC_WEB_DEVELOPER_TOKEN": "<APPLE_MUSIC_WEB_DEVELOPER_TOKEN>",
        "APPLE_MUSIC_STOREFRONT": "<APPLE_MUSIC_STOREFRONT>",
        "ICLOUD_USERNAME": "<ICLOUD_USERNAME>",
        "ICLOUD_APP_PASSWORD": "<ICLOUD_APP_PASSWORD>",
        "ICLOUD_MAIL_ADDRESS": "<ICLOUD_MAIL_ADDRESS>",
        "ICLOUD_DEFAULT_CALENDAR": "<ICLOUD_DEFAULT_CALENDAR>",
        "APPLE_WRITE_MODE": "<APPLE_WRITE_MODE>",
        "APPLE_SERVICES": "<APPLE_SERVICES>",
        "DISPLAY_TZ": "<DISPLAY_TZ>",
        "APPLE_UNITS": "<APPLE_UNITS>",
        "APPLE_STATE_CACHE": "<APPLE_STATE_CACHE>",
        "APPLE_REQUEST_TIMEOUT_MS": "<APPLE_REQUEST_TIMEOUT_MS>",
        "APPLE_DEBUG_LOG": "<APPLE_DEBUG_LOG>",
        "MCP_CONFIRM_MODE": "<MCP_CONFIRM_MODE>",
        "MCP_CONFIRM_ELICITATION": "<MCP_CONFIRM_ELICITATION>",
        "MCP_CONFIRM_TTL_SECONDS": "<MCP_CONFIRM_TTL_SECONDS>",
        "MCP_CONFIRM_SECRET": "<MCP_CONFIRM_SECRET>"
      }
    }
  }
}
.vscode/mcp.json
{
  "servers": {
    "apple-icloud-mcp": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y",
        "[email protected]"
      ],
      "env": {
        "APPLE_TEAM_ID": "<APPLE_TEAM_ID>",
        "APPLE_KEY_ID": "<APPLE_KEY_ID>",
        "APPLE_PRIVATE_KEY": "<APPLE_PRIVATE_KEY>",
        "APPLE_PRIVATE_KEY_PATH": "<APPLE_PRIVATE_KEY_PATH>",
        "APPLE_MUSIC_KEY_ID": "<APPLE_MUSIC_KEY_ID>",
        "APPLE_MUSIC_PRIVATE_KEY": "<APPLE_MUSIC_PRIVATE_KEY>",
        "APPLE_MAPS_KEY_ID": "<APPLE_MAPS_KEY_ID>",
        "APPLE_MAPS_PRIVATE_KEY": "<APPLE_MAPS_PRIVATE_KEY>",
        "APPLE_WEATHERKIT_KEY_ID": "<APPLE_WEATHERKIT_KEY_ID>",
        "APPLE_WEATHERKIT_PRIVATE_KEY": "<APPLE_WEATHERKIT_PRIVATE_KEY>",
        "APPLE_WEATHERKIT_SERVICE_ID": "<APPLE_WEATHERKIT_SERVICE_ID>",
        "APPLE_MUSIC_DEVELOPER_TOKEN": "<APPLE_MUSIC_DEVELOPER_TOKEN>",
        "APPLE_MUSIC_USER_TOKEN": "<APPLE_MUSIC_USER_TOKEN>",
        "APPLE_MUSIC_WEB_USER_TOKEN": "<APPLE_MUSIC_WEB_USER_TOKEN>",
        "APPLE_MUSIC_WEB_DEVELOPER_TOKEN": "<APPLE_MUSIC_WEB_DEVELOPER_TOKEN>",
        "APPLE_MUSIC_STOREFRONT": "<APPLE_MUSIC_STOREFRONT>",
        "ICLOUD_USERNAME": "<ICLOUD_USERNAME>",
        "ICLOUD_APP_PASSWORD": "<ICLOUD_APP_PASSWORD>",
        "ICLOUD_MAIL_ADDRESS": "<ICLOUD_MAIL_ADDRESS>",
        "ICLOUD_DEFAULT_CALENDAR": "<ICLOUD_DEFAULT_CALENDAR>",
        "APPLE_WRITE_MODE": "<APPLE_WRITE_MODE>",
        "APPLE_SERVICES": "<APPLE_SERVICES>",
        "DISPLAY_TZ": "<DISPLAY_TZ>",
        "APPLE_UNITS": "<APPLE_UNITS>",
        "APPLE_STATE_CACHE": "<APPLE_STATE_CACHE>",
        "APPLE_REQUEST_TIMEOUT_MS": "<APPLE_REQUEST_TIMEOUT_MS>",
        "APPLE_DEBUG_LOG": "<APPLE_DEBUG_LOG>",
        "MCP_CONFIRM_MODE": "<MCP_CONFIRM_MODE>",
        "MCP_CONFIRM_ELICITATION": "<MCP_CONFIRM_ELICITATION>",
        "MCP_CONFIRM_TTL_SECONDS": "<MCP_CONFIRM_TTL_SECONDS>",
        "MCP_CONFIRM_SECRET": "<MCP_CONFIRM_SECRET>"
      }
    }
  }
}

Replace the values in angle brackets with your own. Keys stay on your machine; we never see them.

Tools

This server runs locally, so its tools are listed by your MCP client once it starts.

Environment variables

NameDescription
APPLE_TEAM_ID
Optional
Your Apple Developer Team ID (10 characters). Needed for Apple Music (official API), Apple Maps and WeatherKit.
APPLE_KEY_ID
Optional
Key ID of a private key created in Certificates, Identifiers & Profiles → Keys with Media Services (MusicKit), MapKit JS and/or WeatherKit enabled.
APPLE_PRIVATE_KEY
Optional, secret
Contents of that key's .p8 file (PEM; one-line values with \n escapes and base64 are accepted).
APPLE_PRIVATE_KEY_PATH
Optional
Local installs only: a path to the .p8 file instead of APPLE_PRIVATE_KEY.
APPLE_MUSIC_KEY_ID
Optional
Optional per-service override of APPLE_KEY_ID for Apple Music (pair with APPLE_MUSIC_PRIVATE_KEY).
APPLE_MUSIC_PRIVATE_KEY
Optional, secret
Optional per-service override of APPLE_PRIVATE_KEY for Apple Music.
APPLE_MAPS_KEY_ID
Optional
Optional per-service override of APPLE_KEY_ID for Apple Maps.
APPLE_MAPS_PRIVATE_KEY
Optional, secret
Optional per-service override of APPLE_PRIVATE_KEY for Apple Maps.
APPLE_WEATHERKIT_KEY_ID
Optional
Optional per-service override of APPLE_KEY_ID for WeatherKit.
APPLE_WEATHERKIT_PRIVATE_KEY
Optional, secret
Optional per-service override of APPLE_PRIVATE_KEY for WeatherKit.
APPLE_WEATHERKIT_SERVICE_ID
Optional
WeatherKit only: the Services ID registered for WeatherKit (e.g. com.example.weather).
APPLE_MUSIC_DEVELOPER_TOKEN
Optional, secret
Optional: a pre-minted Apple Music developer token (JWT) instead of signing one from the key above.
APPLE_MUSIC_USER_TOKEN
Optional, secret
Music User Token for your library (official API), from a one-time MusicKit sign-in: `npx apple-icloud-mcp music-auth`. Without the Apple Developer key, ask the owner for a developer token (music-auth --print-developer-token) and run it with APPLE_MUSIC_DEVELOPER_TOKEN set. Lasts ~6 months.
APPLE_MUSIC_WEB_USER_TOKEN
Optional, secret
Opt-in web-player mode (no developer account needed; unlocks rename/delete/remove/reorder): the media-user-token cookie from a signed-in music.apple.com tab.
APPLE_MUSIC_WEB_DEVELOPER_TOKEN
Optional, secret
Optional override for the web-player developer token (normally read automatically from music.apple.com).
APPLE_MUSIC_STOREFRONT
Optional
Two-letter Apple Music storefront (e.g. us, gb). Default: your account's storefront, else us.
ICLOUD_USERNAME
Optional
Your Apple ID email, for iCloud Calendar, Contacts and Mail.
ICLOUD_APP_PASSWORD
Optional, secret
An app-specific password from appleid.apple.com → Sign-In and Security → App-Specific Passwords (NOT your Apple ID password).
ICLOUD_MAIL_ADDRESS
Optional
Your @icloud.com address, only if your Apple ID email is not an iCloud address (needed for Mail).
ICLOUD_DEFAULT_CALENDAR
Optional
Calendar new events go to when none is named (default: the first writable event calendar).
APPLE_WRITE_MODE
Optional
"none" = read-only tools; "additive" = also create/append, never modify, delete or send; "all" = everything (default). Unrecognized values fail closed to "none".
APPLE_SERVICES
Optional
Comma-separated services to enable (music, calendar, contacts, mail, maps, weather, itunes). Default: all.
DISPLAY_TZ
Optional
IANA time zone (e.g. America/New_York) for displayed times and for dates you give without an offset. Set this on a hosted server, which runs in UTC.
APPLE_UNITS
Optional
"metric" (default) or "imperial" units for weather (Maps distances always show both).
APPLE_STATE_CACHE
Optional
Set to false to write nothing under $MCP_DATA_DIR/.apple-icloud-mcp: no web-player token or iCloud discovery cache, and the rejected-password latch and spent confirmation tokens then last only as long as the process.
APPLE_REQUEST_TIMEOUT_MS
Optional
Per-request timeout in milliseconds (default 30000).
APPLE_DEBUG_LOG
Optional
Set to 1 to log every upstream request line to stderr (credentials redacted).
MCP_CONFIRM_MODE
Optional
How confirm-gated writes (send mail, deletes, removing tracks, invitations) behave on a client with no prompt, like claude.ai: "ask-user" (default: preview + confirmToken, the model must get your OK), "auto", or "refuse". Unknown values mean refuse.
MCP_CONFIRM_ELICITATION
Optional
"off" never shows a confirmation prompt, so every client gets the MCP_CONFIRM_MODE flow. Set it for a client that says it can prompt but never does (the gated call hangs, e.g. opencode 2.0.x). Any other value stays "on" (with a stderr warning).
MCP_CONFIRM_TTL_SECONDS
Optional
Lifetime of a confirmToken in seconds (default 600).
MCP_CONFIRM_SECRET
Optional, secret
Signing key for confirmTokens. Random per process by default; set it so a token issued just before a restart or redeploy still works (spent tokens are recorded on disk, so none can be replayed).

Details

Package[email protected] (NPM, stdio)
First published11 Nov 2026
Last updated11 Nov 2026
Registry nameio.github.chrischall/apple-icloud-mcp

More productivity servers See all

Listing data from the official MCP registry. Status and tools from NestDaddy's daily check. Browse all MCP servers.