# io.github.chrischall/apple-icloud-mcp (npm · apple-icloud-mcp)

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

- Trust score: 81/100 (high trust)
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-10-02

## Components

- npm · `apple-icloud-mcp`: 81/100 (this document), [markdown](https://verifymcp.io/servers/chrischall-apple-icloud-mcp/apple-icloud-mcp.md), [page](https://verifymcp.io/servers/chrischall-apple-icloud-mcp/apple-icloud-mcp)

## Channel facts

- Registry: `npm`
- Package: `apple-icloud-mcp`
- Version: `0.3.0`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-10-02.

- **Supply Chain Security**: 99/100
  - No malware found by supply-chain analysis.
  - No known CVEs affecting this package version or its production dependencies.
  - No install/post-install scripts declared.
  - 7 of 35 dependencies flagged as unhealthy.
- **Provenance & Transparency**: 97/100
  - Source repository is publicly reachable at the declared URL.
  - Cryptographically verified build provenance (signed, bound to chrischall/apple-icloud-mcp).
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 2 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 65/100
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 16686 tokens (~282/item across 59 items; 59 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 17/100
  - Stability observed for 5 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - All 7 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.
  - An AI judge read all 59 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a current MCP spec version (2026-07-28).

## Install

### How do I install the io.github.chrischall/apple-icloud-mcp server?

io.github.chrischall/apple-icloud-mcp runs locally as an npm package, launched with npx -y apple-icloud-mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add chrischall-apple-icloud-mcp -- npx -y apple-icloud-mcp
```

### Cursor

```json
{
  "mcpServers": {
    "chrischall-apple-icloud-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "apple-icloud-mcp"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "chrischall-apple-icloud-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "apple-icloud-mcp"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add chrischall-apple-icloud-mcp -- npx -y apple-icloud-mcp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "chrischall-apple-icloud-mcp": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "apple-icloud-mcp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add chrischall-apple-icloud-mcp --command npx --arg -y --arg apple-icloud-mcp
```

### Hermes

```yaml
mcp_servers:
  chrischall-apple-icloud-mcp:
    command: "npx"
    args: ["-y", "apple-icloud-mcp"]
```

### Netclaw

```json
{
  "McpServers": {
    "chrischall-apple-icloud-mcp": {
      "Transport": "stdio",
      "Command": "npx",
      "Arguments": [
        "-y",
        "apple-icloud-mcp"
      ]
    }
  }
}
```

### Vellum

```bash
assistant mcp add chrischall-apple-icloud-mcp -t stdio -c npx -a -y apple-icloud-mcp
```

### Other

```json
{
  "mcpServers": {
    "chrischall-apple-icloud-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "apple-icloud-mcp"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-10-01 (score 81, +16)

- [security improvement] Malware scan: unverified → pass

### 2026-09-30 (score 65, −15)

- [security regression] Malware scan: pass → unverified
- [functional] Package version: 0.2.1 → 0.3.0

### 2026-09-29 (score 80, +16)

- [security improvement] Malware scan: unverified → pass

### 2026-09-28 (score 64, −15)

- [security regression] Malware scan: pass → unverified
- [security regression] Tool safety: pass → unverified
- [security] Stability: Stability not yet verified: we do not have a sandbox capture of the MCP schema this version of the package serves yet.
- [functional regression] Capabilities: pass → unverified
- [functional regression] Tool coverage: 100 → unverified
- [functional improvement] Stability: unverified → 0.03
- [functional] First check of Schema quality: unverified
- [functional] Package version: 0.1.0 → 0.2.1
- [functional] Package version: 0.1.0 → 0.2.0
- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-09-27 (score 79)

First indexed and scored.

## MCP tools (59)

### `apple_healthcheck` (~110 tokens)

Check Apple service credentials and connectivity

Check which Apple services (Apple Music, iCloud Calendar, Contacts, Mail, Apple Maps, WeatherKit, iTunes) are configured and reachable. For each: whether credentials are set (and which variables to set if not), and whether Apple accepted them on a cheap read-only request. Also reports the write mode and display time zone. Run this first when a tool fails or to see what this server can do.

Input parameters:

- `services` (array): Only check these services (default: every enabled service).

### `apple_music_search_catalog` (~312 tokens)

Search the Apple Music catalog

Search Apple Music's catalog by text for songs, albums, artists, playlists, music videos or stations. Results are grouped by type, each group with its own returned/hasMore/nextOffset, and carry catalog ids other tools take (e.g. to add songs to a playlist). Up to 25 per type per call. Needs an Apple Developer key (APPLE_TEAM_ID, APPLE_KEY_ID, APPLE_PRIVATE_KEY) or web-player mode (APPLE_MUSIC_WEB_USER_TOKEN).

Input parameters:

- `limit` (integer): Results per type (default 10, max 25).
- `offset` (integer): Skip this many results per type (use a group's nextOffset).
- `storefront` (string): Two-letter Apple Music storefront (country catalog), e.g. us, gb, jp. Default: APPLE_MUSIC_STOREFRONT, else your account's storefront, else us.
- `term` (string, required): What to search for, e.g. "bohemian rhapsody queen". Prefer "title artist" over "title - artist".
- `types` (array): Which kinds of results (default songs, albums, artists, playlists).
- `view` (string): Response shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact keeps ids (library and catalog), names, artist/alb…

### `apple_music_get_catalog_items` (~382 tokens)

Look up Apple Music catalog items

Look up Apple Music catalog songs, albums, artists, playlists, music videos or stations by id — or songs/music videos by ISRC, albums by UPC. A single album or playlist also returns its track list (paged); a single artist can include views such as top-songs or latest-release. Reports ids Apple did not return. Needs an Apple Developer key or web-player mode.

Input parameters:

- `ids` (array): Catalog ids (numeric; pl.… for playlists, ra.… for stations). Max per call: songs 300, albums/music-videos/stations 100, artists/playlists 25.
- `isrc` (array): ISRC codes (songs or music-videos only; one ISRC can match several items).
- `storefront` (string): Two-letter Apple Music storefront (country catalog), e.g. us, gb, jp. Default: APPLE_MUSIC_STOREFRONT, else your account's storefront, else us.
- `tracksLimit` (integer): For one album or playlist: tracks to return (default 100, max 300).
- `tracksOffset` (integer): For one album or playlist: skip this many tracks (use tracksPage.nextOffset).
- `type` (string, required): What the ids are.
- `upc` (array): UPC barcodes (albums only).
- `view` (string): Response shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact keeps ids (library and catalog), names, artist/alb…
- `views` (array): For ONE artist: extra lists to include, e.g. top-songs, latest-release, full-albums, similar-artists, featured-playlists.

### `apple_music_get_charts` (~288 tokens)

Get Apple Music charts

Get Apple Music's top charts (most played songs, albums, playlists, music videos) for a storefront, optionally for one genre. Each chart has its own returned/hasMore/nextOffset and ranked items with catalog ids. Needs an Apple Developer key or web-player mode.

Input parameters:

- `chart` (string): Which chart, e.g. most-played (default: every chart Apple offers for the type).
- `genre` (string): Numeric genre id (e.g. 20 = Alternative, 21 = Rock) to chart one genre.
- `limit` (integer): Items per chart (default 20, max 50).
- `offset` (integer): Skip this many items per chart (use a chart's nextOffset).
- `storefront` (string): Two-letter Apple Music storefront (country catalog), e.g. us, gb, jp. Default: APPLE_MUSIC_STOREFRONT, else your account's storefront, else us.
- `types` (array): Which charts (default songs, albums, playlists).
- `view` (string): Response shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact keeps ids (library and catalog), names, artist/alb…

### `apple_music_list_playlists` (~237 tokens)

List your Apple Music playlists

List the playlists in your Apple Music library (alphabetical), or the contents of one playlist folder (folders and playlists). Each has its library id (p.…), name, description, canEdit, isPublic, hasCatalog, dateAdded and lastModifiedDate. Paged. Needs APPLE_MUSIC_USER_TOKEN with an Apple Developer key, or web-player mode (APPLE_MUSIC_WEB_USER_TOKEN).

Input parameters:

- `folderId` (string): List this folder's children instead ("root" or a folder id p.… from apple_music_list_folders).
- `limit` (integer): Maximum items to return (default 50, max 100).
- `offset` (integer): Zero-based index of the first item to return (default 0). Use the nextOffset from the previous page.
- `view` (string): Response shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact keeps ids (library and catalog), names, artist/alb…

### `apple_music_get_playlist` (~288 tokens)

Read an Apple Music playlist and its tracks

Read one playlist — a library playlist (p.…) or a catalog playlist (pl.…) — with its tracks in order. Each track has its 1-based position, library id, catalogId, name, artist, album and duration. Paged (up to 300 per call), or allTracks for the whole list (up to 5000); a complete read returns a revision (for reorder/remove tracks' expectedRevision). Library playlists need APPLE_MUSIC_USER_TOKEN or web-player mode.

Input parameters:

- `allTracks` (boolean): Read every track (up to 5000) instead of one page. Do not combine with limit/offset.
- `limit` (integer): Tracks to return (default 100, max 300).
- `offset` (integer): Skip this many tracks (use nextOffset).
- `playlistId` (string, required): Library playlist id (p.…, from apple_music_list_playlists) or catalog playlist id (pl.…).
- `storefront` (string): Catalog playlists only: storefront to read it in.
- `view` (string): Response shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact keeps ids (library and catalog), names, artist/alb…

### `apple_music_list_folders` (~115 tokens)

List your Apple Music playlist folders

List the playlist folders in your Apple Music library: the top level, or the sub-folders of one folder. Each has its folder id (p.…, for apple_music_list_playlists folderId, apple_music_create_folder parentFolderId and apple_music_move_playlist), name and dateAdded, plus how many playlists sit directly in the folder. Needs APPLE_MUSIC_USER_TOKEN or web-player mode.

Input parameters:

- `folderId` (string): List this folder's sub-folders (default "root", the top level).

### `apple_music_search_library` (~219 tokens)

Search your Apple Music library

Search YOUR Apple Music library (not the whole catalog) by text for songs, albums, artists, playlists or music videos. Results are grouped by type with library ids (i.… songs, l.… albums, p.… playlists) and each group's returned/hasMore/nextOffset. Up to 25 per type. Needs APPLE_MUSIC_USER_TOKEN or web-player mode.

Input parameters:

- `limit` (integer): Results per type (default 10, max 25).
- `offset` (integer): Skip this many results per type.
- `term` (string, required): What to search for in your library.
- `types` (array): Kinds of items (default songs, albums, artists, playlists).
- `view` (string): Response shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact keeps ids (library and catalog), names, artist/alb…

### `apple_music_list_library` (~191 tokens)

List your Apple Music library

List what is in your Apple Music library: all songs, albums, artists or music videos (alphabetical, paged), or recently-added items. Items carry library ids and, for songs, the catalogId. Needs APPLE_MUSIC_USER_TOKEN or web-player mode.

Input parameters:

- `kind` (string, required): What to list.
- `limit` (integer): Maximum items to return (default 50, max 100).
- `offset` (integer): Zero-based index of the first item to return (default 0). Use the nextOffset from the previous page.
- `view` (string): Response shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact keeps ids (library and catalog), names, artist/alb…

### `apple_music_get_history` (~223 tokens)

Get your Apple Music listening history

Your recent Apple Music listening: recently-played (albums, playlists, stations), recently-played-tracks (songs), recent-stations, or heavy-rotation. Apple gives no play timestamps or counts here and pages recently-played 10 at a time and tracks 30 at a time (this tool pages for you; only about the last 50 items are reachable). Needs APPLE_MUSIC_USER_TOKEN or web-player mode.

Input parameters:

- `feed` (string, required): Which history list.
- `limit` (integer): Maximum items to return (default 10, max 50).
- `offset` (integer): Zero-based index of the first item to return (default 0). Use the nextOffset from the previous page.
- `view` (string): Response shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact keeps ids (library and catalog), names, artist/alb…

### `apple_music_get_recommendations` (~159 tokens)

Get your Apple Music recommendations

Your personal Apple Music recommendations ("Made for You", "Recently Played" and similar groups), each with its title and the albums, playlists or stations in it (catalog ids). Needs APPLE_MUSIC_USER_TOKEN or web-player mode.

Input parameters:

- `limit` (integer): Recommendation groups to return (default 10, max 30).
- `offset` (integer): Zero-based index of the first item to return (default 0). Use the nextOffset from the previous page.
- `view` (string): Response shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact gives each group its title, kind and compact conte…

### `apple_music_get_replay` (~213 tokens)

Get your Apple Music Replay

Apple Music Replay: your top songs, albums and artists for the latest Replay year, or for a given year (with play counts where Apple provides them). Needs APPLE_MUSIC_USER_TOKEN or web-player mode; a specific year uses an undocumented Apple endpoint that works most reliably in web-player mode.

Input parameters:

- `limit` (integer): For a specific year: items per list (default 25, max 100). The latest summary returns Apple's own list sizes.
- `view` (string): Response shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact keeps ids (library and catalog), names, artist/alb…
- `views` (array): Which top lists (default all three).
- `year` (string): "latest" (default: the most recent year with enough listening) or a year like "2025".

### `apple_music_get_ratings` (~97 tokens)

Get your Apple Music ratings (love / dislike)

Whether you have loved or disliked songs, albums, playlists, music videos or stations — catalog or library ids — returning love, dislike or none per id. Needs APPLE_MUSIC_USER_TOKEN or web-player mode.

Input parameters:

- `ids` (array, required): Up to 100 ids of that type.
- `type` (string, required): What the ids are: catalog types (songs, albums, …) or library-* types for library ids.

### `apple_music_create_playlist` (~189 tokens)

Create an Apple Music playlist

Create a new playlist in your Apple Music library, optionally with tracks (up to 500 catalog or library song ids; added 100 at a time), a description, a folder and public visibility (not in APPLE_WRITE_MODE=additive). Returns the new playlist id (p.…) and checks it by re-reading (Apple can take a few seconds to show it). Needs APPLE_MUSIC_USER_TOKEN or web-player mode.

Input parameters:

- `description` (string): Playlist description.
- `folderId` (string): Create it inside this folder (p.… from apple_music_list_folders; default the top level).
- `isPublic` (boolean): Show it on your Apple Music profile (default false; needs APPLE_WRITE_MODE=all).
- `name` (string, required): Playlist name.
- `tracks` (array): Songs to put in it, in order (up to 500).

### `apple_music_add_playlist_tracks` (~153 tokens)

Add tracks to an Apple Music playlist

Append songs (up to 500 catalog or library ids) to the end of one of your library playlists. By default skips songs already in the playlist (matched by catalog id; refused while Apple does not show your last change to it yet). Refuses playlists you cannot edit (Apple-curated or collaborative). Verifies the new tracks show. Needs APPLE_MUSIC_USER_TOKEN or web-player mode.

Input parameters:

- `playlistId` (string, required): Library playlist id (p.…) from apple_music_list_playlists.
- `skipDuplicates` (boolean): Skip songs already in the playlist or repeated in this request (default true).
- `tracks` (array, required): Songs to append, in order (up to 500).

### `apple_music_create_folder` (~95 tokens)

Create an Apple Music playlist folder

Create a playlist folder in your Apple Music library, at the top level or inside another folder. Returns the new folder id (p.…) for apple_music_create_playlist / apple_music_move_playlist. Needs APPLE_MUSIC_USER_TOKEN or web-player mode.

Input parameters:

- `name` (string, required): Folder name.
- `parentFolderId` (string): Create it inside this folder (p.…; default "root", the top level).

### `apple_music_add_to_library` (~157 tokens)

Add songs, albums or playlists to your Apple Music library

Add catalog songs, albums, playlists or music videos to your Apple Music library by catalog id (up to 100 per type). Apple answers only "accepted": it silently ignores ids it cannot add and new items can take a while to appear, so check later with apple_music_search_library. Needs APPLE_MUSIC_USER_TOKEN or web-player mode.

Input parameters:

- `albums` (array): Catalog albums ids (up to 100) — numeric.
- `musicVideos` (array): Catalog music-videos ids (up to 100) — numeric.
- `playlists` (array): Catalog playlists ids (up to 100) — pl.….
- `songs` (array): Catalog songs ids (up to 100) — numeric.

### `apple_music_add_favorites` (~172 tokens)

Favorite songs, albums, playlists or artists in Apple Music

Mark catalog songs, albums, playlists, artists or music videos as favorites (the star in Apple Music; favorite songs go to your Favorite Songs playlist), by catalog id, up to 100 per type. Apple answers only "accepted" and silently ignores ids it cannot favorite. Needs APPLE_MUSIC_USER_TOKEN or web-player mode.

Input parameters:

- `albums` (array): Catalog albums ids (up to 100) — numeric.
- `artists` (array): Catalog artists ids (up to 100) — numeric.
- `musicVideos` (array): Catalog music-videos ids (up to 100) — numeric.
- `playlists` (array): Catalog playlists ids (up to 100) — pl.….
- `songs` (array): Catalog songs ids (up to 100) — numeric.

### `apple_music_set_rating` (~133 tokens)

Love or dislike an Apple Music item

Set your rating on a song, album, playlist, music video or station (catalog or library id): love, dislike, or none to clear it. Always sends the rating (Apple's reads can lag its writes); returns the previous rating as read and verifies the new one. Needs APPLE_MUSIC_USER_TOKEN or web-player mode.

Input parameters:

- `id` (string, required): The item id.
- `rating` (string, required): love, dislike, or none to remove your rating.
- `type` (string, required): What the id is: catalog types (songs, albums, …) or library-* types for library ids.

### `apple_music_update_playlist` (~149 tokens)

Rename an Apple Music playlist or change its description

Rename one of your Apple Music library playlists, change its description, or make it public/private. Returns the previous values and verifies the change. Refused while Apple does not show your last change to the playlist yet (the update sends every field back, so it would undo it). Uses Apple's web-player API (unofficial; needs APPLE_MUSIC_WEB_USER_TOKEN).

Input parameters:

- `description` (string): New description ("" clears it).
- `isPublic` (boolean): Show it on your Apple Music profile (true) or not (false).
- `name` (string): New name.
- `playlistId` (string, required): Library playlist id (p.…) from apple_music_list_playlists.

### `apple_music_remove_playlist_tracks` (~354 tokens)

Remove tracks from an Apple Music playlist

Remove tracks from one of your library playlists by library track id and/or 1-based position (from apple_music_get_playlist). Apple removes EVERY copy of a track, so removing one copy of a duplicate is refused (use apple_music_reorder_playlist). Takes expectedRevision, returns the new revision. Uses Apple's web-player API (unofficial; needs APPLE_MUSIC_WEB_USER_TOKEN). Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call performs NO write and returns a preview of exactly what would happen plus a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE).

Input parameters:

- `confirmToken` (string): ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has se…
- `expectedRevision` (string): The playlist revision you expect: from apple_music_get_playlist (a complete read) or from the previous change's result. Refused if the playlist no longer reads as that revision. (A change is also ref…
- `playlistId` (string, required): Library playlist id (p.…).
- `positions` (array): 1-based positions of tracks to remove (as listed by apple_music_get_playlist).
- `trackIds` (array): Library ids of the tracks to remove (every copy of each).

### `apple_music_reorder_playlist` (~472 tokens)

Reorder, sort, dedupe or rewrite an Apple Music playlist

Reorder one of your library playlists: move tracks, sort (name, artist, album, release date, duration, date added), reverse, dedupe (keep the first copy of each song), or replace with a complete new order of its track ids (can drop tracks). Takes expectedRevision, returns the new revision. Uses Apple's web-player API (unofficial; needs APPLE_MUSIC_WEB_USER_TOKEN). Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call performs NO write and returns a preview of exactly what would happen plus a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE).

Input parameters:

- `by` (string): sort: the key (dateAdded is when the song entered your library; Apple often omits it on playlist tracks, and a key no track has is refused).
- `confirmToken` (string): ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has se…
- `count` (integer): move: how many consecutive tracks to move (default 1).
- `descending` (boolean): sort: largest/latest/Z first (default false).
- `expectedRevision` (string): The playlist revision you expect: from apple_music_get_playlist (a complete read) or from the previous change's result. Refused if the playlist no longer reads as that revision. (A change is also ref…
- `fromPosition` (integer): move: 1-based position of the first track to move.
- `operation` (string, required): What to do.
- `playlistId` (string, required): Library playlist id (p.…).
- `toPosition` (integer): move: 1-based position the first moved track should end up at.
- `trackIds` (array): replace: the complete new order as library track ids from apple_music_get_playlist; ids left out are removed.

### `apple_music_move_playlist` (~103 tokens)

Move an Apple Music playlist into a folder

Move one of your library playlists into a playlist folder, or back to the top level ("root"). Checks the folder exists and verifies the playlist appears in it. Uses Apple's web-player API (unofficial; needs APPLE_MUSIC_WEB_USER_TOKEN).

Input parameters:

- `folderId` (string, required): Destination folder id (p.… from apple_music_list_folders), or "root" for the top level.
- `playlistId` (string, required): Library playlist id (p.…).

### `apple_music_delete_playlist` (~225 tokens)

Delete an Apple Music playlist

Delete one of your library playlists (songs stay in your library). For an Apple playlist saved to your library, this removes it from your library. The preview shows its name, track count and date added; verifies it is gone. Uses Apple's web-player API (unofficial; needs APPLE_MUSIC_WEB_USER_TOKEN). Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call performs NO write and returns a preview of exactly what would happen plus a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE).

Input parameters:

- `confirmToken` (string): ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has se…
- `playlistId` (string, required): Library playlist id (p.…).

### `apple_music_remove_from_library` (~243 tokens)

Remove songs, albums or playlists from your Apple Music library

Remove songs, albums, music videos or playlists from your Apple Music library by LIBRARY id (i.…, l.…, p.… from apple_music_list_library / apple_music_search_library), up to 50 at a time; the preview names each item. Uses Apple's web-player API (unofficial; needs APPLE_MUSIC_WEB_USER_TOKEN). Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call performs NO write and returns a preview of exactly what would happen plus a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE).

Input parameters:

- `confirmToken` (string): ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has se…
- `ids` (array, required): Library ids (up to 50).
- `type` (string, required): What the ids are.

### `apple_music_remove_favorites` (~168 tokens)

Unfavorite songs, albums, playlists or artists in Apple Music

Remove the favorite (star) from catalog songs, albums, playlists, artists or music videos, by catalog id, up to 100 per type. Apple answers only "accepted" and offers no way to read favorites back. Uses Apple's web-player API (unofficial; needs APPLE_MUSIC_WEB_USER_TOKEN).

Input parameters:

- `albums` (array): Catalog albums ids (up to 100) — numeric.
- `artists` (array): Catalog artists ids (up to 100) — numeric.
- `musicVideos` (array): Catalog music-videos ids (up to 100) — numeric.
- `playlists` (array): Catalog playlists ids (up to 100) — pl.….
- `songs` (array): Catalog songs ids (up to 100) — numeric.

### `apple_calendar_list_calendars` (~96 tokens)

List your iCloud calendars

List your iCloud calendars (event calendars only): id, name, color, whether you can add events to it, whether it is shared (shared: with you by someone else; sharedByYou: by you with others), and which one new events go into by default. Use the name or id with the other apple_calendar_* tools. Needs ICLOUD_USERNAME and ICLOUD_APP_PASSWORD (an app-specific password).

### `apple_calendar_list_events` (~492 tokens)

List iCloud Calendar events in a date range

List iCloud Calendar events (appointments, meetings) in a date window, recurring events expanded into occurrences, sorted by start. Window: fromDate (default today) + toDate (exclusive) or daysAhead (default 7), max 366 days; the window is always stated. Filter by calendars; page with limit/offset (totalMatched, nextOffset). Rows are compact by default (see view). Each event has an id for get/update/delete. Dates are ISO-8601: YYYY-MM-DD or YYYY-MM-DDTHH:MM[:SS], optional Z or ±HH:MM. An offset-less time is wall clock in timeZone (default DISPLAY_TZ), never UTC; a stored floating one is read in DISPLAY_TZ.

Input parameters:

- `calendars` (array): Calendars to include, by name or id (from apple_calendar_list_calendars). Default: every event calendar.
- `daysAhead` (integer): Window length in days from fromDate (instead of toDate).
- `fromDate` (string): Start of the window (inclusive). Default: the start of today.
- `limit` (integer): Maximum items to return (default 100, max 500).
- `offset` (integer): Zero-based index of the first item to return (default 0). Use the nextOffset from the previous page.
- `timeZone` (string): IANA time zone (e.g. America/New_York) for dates you pass without an offset and for the times returned. Default: DISPLAY_TZ. Events stored without a zone of their own (floating) are always read in DI…
- `toDate` (string): End of the window (EXCLUSIVE). Do not combine with daysAhead.
- `view` (string): Response shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact drops the attendee list (keeps attendeeCount, and…

### `apple_calendar_search_events` (~499 tokens)

Search iCloud Calendar events

Search iCloud Calendar events by text (case-insensitive match in title, location or notes) within a date window: fromDate (default today; may be in the past) + toDate or daysAhead (default 30), max 366 days. Only that window is searched, and the response says so. Returns matching occurrences sorted by start, with ids; rows are compact by default (see view). Dates are ISO-8601: YYYY-MM-DD or YYYY-MM-DDTHH:MM[:SS], optional Z or ±HH:MM. An offset-less time is wall clock in timeZone (default DISPLAY_TZ), never UTC; a stored floating one is read in DISPLAY_TZ.

Input parameters:

- `calendars` (array): Calendars to include, by name or id (from apple_calendar_list_calendars). Default: every event calendar.
- `daysAhead` (integer): Window length in days from fromDate (instead of toDate).
- `fromDate` (string): Start of the window (inclusive). Default: the start of today.
- `limit` (integer): Maximum items to return (default 50, max 500).
- `offset` (integer): Zero-based index of the first item to return (default 0). Use the nextOffset from the previous page.
- `query` (string, required): Text to find in the title, location or notes.
- `timeZone` (string): IANA time zone (e.g. America/New_York) for dates you pass without an offset and for the times returned. Default: DISPLAY_TZ. Events stored without a zone of their own (floating) are always read in DI…
- `toDate` (string): End of the window (EXCLUSIVE). Do not combine with daysAhead.
- `view` (string): Response shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact drops the attendee list (keeps attendeeCount, and…

### `apple_calendar_get_event` (~214 tokens)

Get an iCloud Calendar event

Get one iCloud Calendar event in full (notes untruncated, attendees, alerts, recurrence rule in plain English) by the id list/search returned. An id ending in "#occ=…" is that one occurrence; a bare recurring id describes the series. includeIcs adds the raw iCalendar (lines unfolded, account ids redacted).

Input parameters:

- `eventId` (string, required): Event id exactly as list/search printed it. A recurring occurrence's id ends in "#occ=…".
- `includeIcs` (boolean): Also return the raw iCalendar text of the whole event resource.
- `timeZone` (string): IANA time zone (e.g. America/New_York) for dates you pass without an offset and for the times returned. Default: DISPLAY_TZ. Events stored without a zone of their own (floating) are always read in DI…

### `apple_calendar_create_event` (~529 tokens)

Create an iCloud Calendar event

Create an iCloud Calendar event: title, startDate/endDate (timed default 1 hour; all-day endDate = last day), location, notes, url, alarms, recurrence, attendees. Goes into calendar, else ICLOUD_DEFAULT_CALENDAR, else the first writable calendar not shared with others; a shared one is named (APPLE_WRITE_MODE=additive refuses it, and attendees). With attendees it asks first (iCloud emails them): a prompt where the client supports one, else the first call performs NO write and returns a preview plus a confirmToken for a repeat call (MCP_CONFIRM_MODE). Without attendees the first call creates the event immediately.

Input parameters:

- `alarms` (array): Alerts, in minutes before the start (0–40320, at most 5).
- `attendees` (array): People to invite. iCloud emails each one an invitation.
- `calendar` (string): Calendar name or id. Default: ICLOUD_DEFAULT_CALENDAR, else the first writable calendar not shared with others.
- `confirmToken` (string): ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has se…
- `endDate` (string): End (timed; default start + 1 hour) or LAST day (all-day, inclusive; default the start day).
- `isAllDay` (boolean): All-day event. Default: true when startDate is a bare date.
- `location` (string): Location (one line).
- `notes` (string): Notes (may span lines).
- `recurrence` (object): Make it repeat.
- `startDate` (string, required): Start: YYYY-MM-DDTHH:MM (timed) or YYYY-MM-DD (all-day).
- `timeZone` (string): IANA time zone (e.g. America/New_York) for dates you pass without an offset and for the times returned. Default: DISPLAY_TZ. Events stored without a zone of their own (floating) are always read in DI…
- `title` (string, required): Event title.
- `url` (string): A link to attach (http, https or mailto).

### `apple_calendar_update_event` (~598 tokens)

Change an iCloud Calendar event

Change an iCloud Calendar event: title, startDate/endDate, isAllDay, location, notes, url ("" clears), alarms, attendees (full new list), calendar (moves it). Recurring: span thisEvent (default, "#occ=" id), futureEvents (splits the series) or allEvents. Returns before/after. If the event has or gets attendees it asks first (iCloud emails them): a prompt where the client supports one, else the first call performs NO write and returns a preview plus a confirmToken for a repeat call (MCP_CONFIRM_MODE). Without attendees the first call changes the event immediately.

Input parameters:

- `alarms` (array): Alerts, in minutes before the start (0–40320, at most 5).
- `attendees` (array): The complete new list of invitees ([] removes everyone). iCloud emails them.
- `calendar` (string): Move the event to this calendar (name or id).
- `confirmToken` (string): ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has se…
- `endDate` (string): New end (all-day: the LAST day, inclusive).
- `eventId` (string, required): Event id exactly as list/search printed it. A recurring occurrence's id ends in "#occ=…".
- `isAllDay` (boolean): Switch between all-day and timed (not for recurring events).
- `location` (string): New location, one line ("" clears).
- `notes` (string): New notes, may span lines ("" clears).
- `span` (string): For a recurring event: thisEvent (default, the one occurrence the id names), futureEvents (it and every later one), or allEvents (the whole series; required when eventId has no "#occ=").
- `startDate` (string): New start. Moving only the start keeps the event's length.
- `timeZone` (string): IANA time zone. With startDate/endDate: offset-less dates are read in it AND the event is stored in it from now on (a repeating event then follows its daylight-saving changes). Omit it to keep the ev…
- `title` (string): New title.
- `url` (string): New link: http, https or mailto ("" clears).

### `apple_calendar_delete_event` (~371 tokens)

Delete an iCloud Calendar event

Delete an iCloud Calendar event. Recurring: span thisEvent (default; the one occurrence an "#occ=" id names), futureEvents (it and all later ones) or allEvents (the whole series). Calendar has no trash. If the event has attendees iCloud emails them a cancellation. Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call performs NO write and returns a preview of exactly what would happen plus a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE).

Input parameters:

- `confirmToken` (string): ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has se…
- `eventId` (string, required): Event id exactly as list/search printed it. A recurring occurrence's id ends in "#occ=…".
- `span` (string): For a recurring event: thisEvent (default, the one occurrence the id names), futureEvents (it and every later one), or allEvents (the whole series; required when eventId has no "#occ=").
- `timeZone` (string): IANA time zone (e.g. America/New_York) for dates you pass without an offset and for the times returned. Default: DISPLAY_TZ. Events stored without a zone of their own (floating) are always read in DI…

### `apple_calendar_find_free_time` (~452 tokens)

Find free time in your iCloud Calendar

Find free time in your iCloud calendars: open slots per day within working hours (workdayStart/workdayEnd, default 09:00–17:00, weekdays only by default) at least minDurationMinutes long (default 30). Busy = events not marked free, not cancelled and not declined by you; all-day events block only with includeAllDay (then even marked free). Nothing before now is offered. Window max 31 days. Dates are ISO-8601: YYYY-MM-DD or YYYY-MM-DDTHH:MM[:SS], optional Z or ±HH:MM. An offset-less time is wall clock in timeZone (default DISPLAY_TZ), never UTC; a stored floating one is read in DISPLAY_TZ.

Input parameters:

- `calendars` (array): Calendars to include, by name or id (from apple_calendar_list_calendars). Default: every event calendar.
- `daysAhead` (integer): Window length in days from fromDate (default 7).
- `fromDate` (string): Start of the window (inclusive). Default: the start of today.
- `includeAllDay` (boolean): Let all-day events block the whole day, even ones marked free (Apple Calendar marks all-day events free by default). Default false.
- `minDurationMinutes` (integer): Shortest slot worth reporting (default 30).
- `timeZone` (string): IANA time zone (e.g. America/New_York) for dates you pass without an offset and for the times returned. Default: DISPLAY_TZ. Events stored without a zone of their own (floating) are always read in DI…
- `toDate` (string): End of the window (EXCLUSIVE). Do not combine with daysAhead.
- `weekdaysOnly` (boolean): Skip Saturdays and Sundays (default true).
- `workdayEnd` (string): Working day end, HH:MM (default 17:00).
- `workdayStart` (string): Working day start, HH:MM (default 09:00).

### `apple_contacts_search` (~214 tokens)

Search iCloud Contacts

Search the user's iCloud Contacts (address book) by name, nickname, company, job title, email, or phone number digits — optionally only within one contact group. Omit query to list everyone. Returns the total number of matches and a page of rows sorted by name: id, name, organization, job title, emails and phones with labels. Use apple_contacts_get with an id for addresses, birthday, note and entryIds. Requires ICLOUD_USERNAME + ICLOUD_APP_PASSWORD (an app-specific password).

Input parameters:

- `group` (string): Only contacts in this group (its name, as apple_contacts_list_groups shows it).
- `limit` (integer): Maximum items to return (default 25, max 200).
- `offset` (integer): Zero-based index of the first item to return (default 0). Use the nextOffset from the previous page.
- `query` (string): Text to find (case- and accent-insensitive; every word must match). Omit or "" to list all contacts.

### `apple_contacts_get` (~134 tokens)

Get an iCloud contact

Get one iCloud contact in full by id (from apple_contacts_search): names, organization, job title, emails, phones, postal addresses and URLs — each with its label and an entryId that apple_contacts_update can target — birthday, note, the contact groups it belongs to, whether it has a photo, and when it was last modified. Requires ICLOUD_USERNAME + ICLOUD_APP_PASSWORD (an app-specific password).

Input parameters:

- `contactId` (string, required): The contact id from apple_contacts_search or apple_contacts_create.
- `timeZone` (string): IANA time zone for lastModified (default: DISPLAY_TZ).

### `apple_contacts_list_groups` (~63 tokens)

List iCloud contact groups

List the contact groups in iCloud Contacts (e.g. Family, Work): each group's id, name and member count. Pass a group name to apple_contacts_search to list its members. Requires ICLOUD_USERNAME + ICLOUD_APP_PASSWORD (an app-specific password).

### `apple_contacts_create` (~275 tokens)

Create an iCloud contact

Create a new contact in iCloud Contacts. Needs a givenName, familyName or organization; optional middleName, nickname, department, jobTitle, note, birthday (YYYY-MM-DD, or --MM-DD without a year), and lists of emails, phones, urls and postal addresses, each with an optional label (home, work, mobile, other or custom text). Returns the new contact's id and details as re-read from iCloud (verified). Requires ICLOUD_USERNAME + ICLOUD_APP_PASSWORD (an app-specific password). Available when APPLE_WRITE_MODE is additive or all.

Input parameters:

- `addresses` (array): Postal addresses.
- `birthday` (string): Birthday as YYYY-MM-DD, or --MM-DD when the year is unknown.
- `department` (string): Department within the organization.
- `emails` (array): Email addresses.
- `familyName` (string): Last (family) name.
- `givenName` (string): First (given) name.
- `jobTitle` (string): Job title.
- `middleName` (string): Middle name.
- `nickname` (string): Nickname.
- `note` (string): Free-text note (may span lines).
- `organization` (string): Company or organization.
- `phones` (array): Phone numbers.
- `urls` (array): Web addresses.

### `apple_contacts_update` (~400 tokens)

Edit an iCloud contact

Edit an existing iCloud contact in place. Scalar fields (givenName, familyName, middleName, nickname, organization, department, jobTitle, note, birthday) replace the current value; "" clears it. emails/phones/urls/addresses take change objects {action: add|remove|replace} aimed at one entry by entryId (from apple_contacts_get) or current value; an absent target is a reported no-op listing what is there. The rest of the card is kept byte-for-byte. Returns before/after, re-read to verify. Requires ICLOUD_USERNAME + ICLOUD_APP_PASSWORD (an app-specific password). Needs APPLE_WRITE_MODE=all.

Input parameters:

- `addresses` (array): Changes to postal addresses, applied in order. replace merges the given fields; "" clears one.
- `birthday` (string): Birthday as YYYY-MM-DD, or --MM-DD when the year is unknown. An empty string clears it.
- `contactId` (string, required): The contact id from apple_contacts_search or apple_contacts_create.
- `department` (string): Department within the organization. An empty string clears it.
- `emails` (array): Changes to email addresses, applied in order.
- `familyName` (string): Last (family) name. An empty string clears it.
- `givenName` (string): First (given) name. An empty string clears it.
- `jobTitle` (string): Job title. An empty string clears it.
- `middleName` (string): Middle name. An empty string clears it.
- `nickname` (string): Nickname. An empty string clears it.
- `note` (string): Free-text note (may span lines). An empty string clears it.
- `organization` (string): Company or organization. An empty string clears it.
- `phones` (array): Changes to phone numbers, applied in order.
- `urls` (array): Changes to web addresses, applied in order.

### `apple_contacts_delete` (~217 tokens)

Delete an iCloud contact

Permanently delete one contact from iCloud Contacts (on every device) by id. The preview shows its name, organization, emails and phones. Requires ICLOUD_USERNAME + ICLOUD_APP_PASSWORD (an app-specific password). Needs APPLE_WRITE_MODE=all. Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call performs NO write and returns a preview of exactly what would happen plus a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE).

Input parameters:

- `confirmToken` (string): ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has se…
- `contactId` (string, required): The contact id from apple_contacts_search or apple_contacts_create.

### `apple_mail_list_mailboxes` (~134 tokens)

List iCloud Mail mailboxes

List the iCloud Mail mailboxes (folders): path, name, special use (inbox, sent, drafts, trash, junk, archive) and, by default, message and unread counts. Use the path (or an alias) as `mailbox` in the other apple_mail_* tools. Needs ICLOUD_USERNAME + ICLOUD_APP_PASSWORD (app-specific password), and ICLOUD_MAIL_ADDRESS unless the Apple ID is an @icloud.com/@me.com/@mac.com address.

Input parameters:

- `counts` (boolean): Include total and unread counts (default true; one STATUS request per mailbox, first 50 only).

### `apple_mail_search` (~427 tokens)

Search iCloud Mail

Search emails in one iCloud Mail mailbox (default INBOX) by sender, recipient, subject, full text, received date range, unread and flagged state. Returns newest first with paging (total, nextOffset) and, per message: uid, date, from, replyTo (when it differs from from; confirm which to answer), to, cc, subject, seen, flagged, hasAttachments, size. Criteria combine with AND. Reading results never marks mail read. Use the uid with apple_mail_get_message. Needs ICLOUD_USERNAME + ICLOUD_APP_PASSWORD (app-specific password), and ICLOUD_MAIL_ADDRESS unless the Apple ID is an @icloud.com/@me.com/@mac.com address.

Input parameters:

- `before` (string): Only mail RECEIVED before this date/time (exclusive); same formats as since.
- `flagged` (boolean): true = only flagged, false = only unflagged.
- `from` (string): Sender contains this text (name or address).
- `limit` (integer): Maximum items to return (default 20, max 100).
- `mailbox` (string): Mailbox path as listed by apple_mail_list_mailboxes (e.g. "INBOX", "Sent Messages", "Work/Receipts"), or an alias: inbox, sent, drafts, trash, junk, archive.
- `offset` (integer): Zero-based index of the first item to return (default 0). Use the nextOffset from the previous page.
- `since` (string): Only mail RECEIVED at or after this date/time: YYYY-MM-DD or YYYY-MM-DDTHH:MM (local time in timeZone), or with Z/offset.
- `subject` (string): Subject contains this text.
- `text` (string): Full-text match anywhere in the message (body or headers).
- `timeZone` (string): IANA time zone for dates you pass and dates returned (default: DISPLAY_TZ).
- `to` (string): A To recipient contains this text.
- `unread` (boolean): true = only unread, false = only read.

### `apple_mail_get_message` (~262 tokens)

Read an iCloud Mail message

Read one iCloud Mail message by uid (from apple_mail_search): headers (from, to, cc, reply-to, date, subject, message-id), the body as plain text (HTML converted to readable text when there is no text part), a truncated flag, and attachment names/types/sizes (no attachment contents). Never marks the message read; to do that, use apple_mail_update_flags with seen:true. Needs ICLOUD_USERNAME + ICLOUD_APP_PASSWORD (app-specific password), and ICLOUD_MAIL_ADDRESS unless the Apple ID is an @icloud.com/@me.com/@mac.com address.

Input parameters:

- `mailbox` (string): Mailbox holding the message (default inbox); path or alias.
- `maxChars` (integer): Most body characters to return (default 20000, max 100000); longer bodies are cut and flagged truncated.
- `timeZone` (string): IANA time zone for dates you pass and dates returned (default: DISPLAY_TZ).
- `uid` (integer, required): The message UID from apple_mail_search.
- `uidValidity` (integer): The mailbox uidValidity returned alongside the uids. When given, the call is refused if the mailbox was renumbered since (an old uid could then name a different message).

### `apple_mail_download_attachment` (~218 tokens)

Download an iCloud Mail attachment

Download one attachment from an iCloud Mail message as an embedded binary resource. Use the 1-based index shown by apple_mail_get_message. Reads the message without marking it read. Defaults to a 10 MiB attachment limit (maximum 20 MiB). Needs ICLOUD_USERNAME + ICLOUD_APP_PASSWORD (app-specific password), and ICLOUD_MAIL_ADDRESS unless the Apple ID is an @icloud.com/@me.com/@mac.com address.

Input parameters:

- `attachmentIndex` (integer, required): 1-based attachment index from apple_mail_get_message.
- `mailbox` (string): Mailbox holding the message (default inbox); path or alias.
- `maxBytes` (integer): Maximum decoded attachment bytes to return (default 10485760; maximum 20971520).
- `uid` (integer, required): The message UID from apple_mail_search.
- `uidValidity` (integer): The mailbox uidValidity returned alongside the uids. When given, the call is refused if the mailbox was renumbered since (an old uid could then name a different message).

### `apple_mail_send` (~485 tokens)

Send an email from iCloud Mail

Send a plain-text email from your iCloud Mail address (to/cc/bcc, subject, body; no attachments). Body ≤ 20,000 chars, all shown for confirmation. inReplyTo {mailbox, uid} threads a reply ("Re:" subject; quoteOriginal quotes it), warning if the original's Reply-To is not a recipient. Saved to Sent. Needs ICLOUD_USERNAME + ICLOUD_APP_PASSWORD. Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call performs NO write and returns a preview of exactly what would happen plus a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE).

Input parameters:

- `bcc` (array): Bcc recipients (hidden from the others). Each entry is one address: name@example.com or "Name <name@example.com>".
- `body` (string, required): The message text (plain text, up to 20000 characters; a longer one is refused, not cut).
- `cc` (array): Cc recipients. Each entry is one address: name@example.com or "Name <name@example.com>".
- `confirmToken` (string): ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has se…
- `inReplyTo` (object): The message this answers (from apple_mail_search): threads the reply to it. It does not choose the recipients; when the original shows a replyTo, check with the user which address to answer.
- `quoteOriginal` (boolean): With inReplyTo: append the original text, quoted (default false).
- `subject` (string): Subject line. Required unless inReplyTo is given (then it defaults to "Re: <original subject>").
- `timeZone` (string): IANA time zone for dates you pass and dates returned (default: DISPLAY_TZ).
- `to` (array, required): Recipients (1–100 across to, cc and bcc). Each entry is one address: name@example.com or "Name <name@example.com>".

### `apple_mail_update_flags` (~229 tokens)

Mark iCloud Mail read/unread or flagged

Mark iCloud Mail messages read or unread, and flag or unflag them, by uid (1–100 uids from apple_mail_search, one mailbox). Only messages not already in the requested state are changed; the result is re-read to verify and lists each message's state and any uids that were not found. Needs ICLOUD_USERNAME + ICLOUD_APP_PASSWORD (app-specific password), and ICLOUD_MAIL_ADDRESS unless the Apple ID is an @icloud.com/@me.com/@mac.com address.

Input parameters:

- `flagged` (boolean): true = flag, false = unflag.
- `mailbox` (string): Mailbox holding the messages (default inbox); path or alias.
- `seen` (boolean): true = mark read, false = mark unread.
- `uidValidity` (integer): The mailbox uidValidity returned alongside the uids. When given, the call is refused if the mailbox was renumbered since (an old uid could then name a different message).
- `uids` (array, required): Message UIDs from apple_mail_search, all in the same mailbox (1–100).

### `apple_mail_move` (~235 tokens)

Move iCloud Mail messages

Move iCloud Mail messages (1–100 uids from apple_mail_search, one mailbox) to another mailbox: a path from apple_mail_list_mailboxes or an alias (inbox, archive, trash, junk, sent, drafts). Moving to trash is recoverable from Deleted Messages. Returns the new uids and verifies the messages left the source. Needs ICLOUD_USERNAME + ICLOUD_APP_PASSWORD (app-specific password), and ICLOUD_MAIL_ADDRESS unless the Apple ID is an @icloud.com/@me.com/@mac.com address.

Input parameters:

- `destination` (string, required): Where to move them: a mailbox path or alias (inbox, archive, trash, junk, sent, drafts).
- `mailbox` (string): Mailbox the messages are in now (default inbox); path or alias.
- `uidValidity` (integer): The mailbox uidValidity returned alongside the uids. When given, the call is refused if the mailbox was renumbered since (an old uid could then name a different message).
- `uids` (array, required): Message UIDs from apple_mail_search, all in the same mailbox (1–100).

### `apple_maps_geocode` (~308 tokens)

Geocode an address (Apple Maps)

Turn an address or place name into coordinates with Apple Maps (geocoding). Returns matching places with latitude/longitude, a one-line address, country code and a place id (for apple_maps_lookup_place). Use it first when a tool needs coordinates (apple_maps_etas, apple_weather_get). Optional: limit to countries, bias toward a nearby point, response language. Needs an Apple Developer key with MapKit JS enabled: APPLE_TEAM_ID + APPLE_KEY_ID + APPLE_PRIVATE_KEY (or APPLE_MAPS_KEY_ID / APPLE_MAPS_PRIVATE_KEY).

Input parameters:

- `address` (string, required): The address or place name, e.g. "1 Apple Park Way, Cupertino, CA" or "Eiffel Tower".
- `lang` (string): Language for names and addresses, as a BCP 47 tag such as en-US, fr-FR or ja-JP (default en-US).
- `limitToCountries` (array): Only return results in these countries: ISO 3166-1 alpha-2 codes, e.g. ["US","CA"].
- `near` (object): Bias results toward this point (e.g. where the user is). A hint, not a filter: farther results can still appear.
- `view` (string): Response shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. "full" adds Apple's structured address, display region and…

### `apple_maps_reverse_geocode` (~218 tokens)

Find the address at coordinates (Apple Maps)

Find the street address at a latitude/longitude with Apple Maps (reverse geocoding) — e.g. "where is 37.33,-122.01?". Returns the place(s) at that point: one-line address, name, country code and place id. Needs an Apple Developer key with MapKit JS enabled: APPLE_TEAM_ID + APPLE_KEY_ID + APPLE_PRIVATE_KEY (or APPLE_MAPS_KEY_ID / APPLE_MAPS_PRIVATE_KEY).

Input parameters:

- `lang` (string): Language for names and addresses, as a BCP 47 tag such as en-US, fr-FR or ja-JP (default en-US).
- `latitude` (number, required): Latitude, -90 to 90.
- `longitude` (number, required): Longitude, -180 to 180.
- `view` (string): Response shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. "full" adds Apple's structured address, display region and…

### `apple_maps_search` (~410 tokens)

Search for places (Apple Maps)

Search Apple Maps for places: businesses, points of interest, addresses, landmarks (e.g. "coffee", "EV charger", "Golden Gate Bridge"). Bias toward a point with near; filter by Apple POI category (Restaurant, Cafe, GasStation, EVCharger, Hotel, Parking, Pharmacy…), result type or country. Returns places (name, category, coordinates, address, phone, website, place id) and nextPageToken for the next page. Needs an Apple Developer key with MapKit JS enabled: APPLE_TEAM_ID + APPLE_KEY_ID + APPLE_PRIVATE_KEY (or APPLE_MAPS_KEY_ID / APPLE_MAPS_PRIVATE_KEY).

Input parameters:

- `categories` (array): Only these Apple point-of-interest categories (exact names, e.g. ["Restaurant","Cafe"]).
- `lang` (string): Language for names and addresses, as a BCP 47 tag such as en-US, fr-FR or ja-JP (default en-US).
- `limitToCountries` (array): Only return results in these countries: ISO 3166-1 alpha-2 codes, e.g. ["US","CA"].
- `near` (object): Bias results toward this point (e.g. where the user is). A hint, not a filter: farther results can still appear.
- `pageToken` (string): nextPageToken from a previous call, to get the next page. Repeat the same query and filters with it.
- `query` (string, required): What to search for, e.g. "pizza", "Louvre", "hardware store".
- `resultTypes` (array): Only these kinds of result: poi (businesses, landmarks), address, physicalFeature (mountains, lakes…), pointOfInterest.
- `view` (string): Response shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. "full" adds Apple's structured address, display region and…

### `apple_maps_directions` (~506 tokens)

Get directions (Apple Maps)

Driving, walking or cycling directions between two places with Apple Maps (addresses or "lat,lng"). Traffic-aware travel time for now or a given departure/arrival time. Returns each route's distance (mi and km), duration, tolls, estimated arrival (or leave-by time) and turn-by-turn steps; view "full" adds route geometry. Options: avoid tolls (a preference, not a guarantee), alternate routes. Needs an Apple Developer key with MapKit JS enabled: APPLE_TEAM_ID + APPLE_KEY_ID + APPLE_PRIVATE_KEY (or APPLE_MAPS_KEY_ID / APPLE_MAPS_PRIVATE_KEY).

Input parameters:

- `alternateRoutes` (boolean): Also return alternative routes when Apple has them (default false).
- `arrivalDate` (string): Desired arrival time for traffic-aware estimates: YYYY-MM-DDTHH:MM (local time in timeZone) or ISO with Z/offset. Give departureDate or arrivalDate, not both.
- `avoidTolls` (boolean): Prefer routes without tolls. Apple may still return toll routes — check each route's hasTolls.
- `departureDate` (string): Desired departure time for traffic-aware estimates: YYYY-MM-DDTHH:MM (local time in timeZone) or ISO with Z/offset. Default: now. Give departureDate or arrivalDate, not both.
- `destination` (string, required): End: an address, a place name, or "latitude,longitude".
- `lang` (string): Language for names and addresses, as a BCP 47 tag such as en-US, fr-FR or ja-JP (default en-US).
- `near` (object): Bias results toward this point (e.g. where the user is). A hint, not a filter: farther results can still appear.
- `origin` (string, required): Start: an address, a place name, or "latitude,longitude".
- `timeZone` (string): IANA time zone (e.g. America/New_York) used to read a date without an offset and to display times. Default: the server display zone (DISPLAY_TZ).
- `transportType` (string): automobile (default), walking or cycling.
- `view` (string): Response shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. "full" returns Apple's response verbatim, including every…

### `apple_maps_etas` (~370 tokens)

Travel times to several destinations (Apple Maps)

Travel time and distance from one point to up to 10 destinations at once with Apple Maps — driving with live traffic, transit, walking or cycling (e.g. "which of these stores is closest by car?"). Coordinates only ("lat,lng"): geocode addresses first with apple_maps_geocode. Returns per destination: distance, travel time with and without traffic, and estimated arrival. Needs an Apple Developer key with MapKit JS enabled: APPLE_TEAM_ID + APPLE_KEY_ID + APPLE_PRIVATE_KEY (or APPLE_MAPS_KEY_ID / APPLE_MAPS_PRIVATE_KEY).

Input parameters:

- `arrivalDate` (string): Desired arrival time for traffic-aware estimates: YYYY-MM-DDTHH:MM (local time in timeZone) or ISO with Z/offset. Give departureDate or arrivalDate, not both.
- `departureDate` (string): Desired departure time for traffic-aware estimates: YYYY-MM-DDTHH:MM (local time in timeZone) or ISO with Z/offset. Default: now. Give departureDate or arrivalDate, not both.
- `destinations` (array, required): 1–10 destinations, each "latitude,longitude".
- `origin` (string, required): Start point as "latitude,longitude".
- `timeZone` (string): IANA time zone (e.g. America/New_York) used to read a date without an offset and to display times. Default: the server display zone (DISPLAY_TZ).
- `transportType` (string): automobile (default, with traffic), transit, walking or cycling.
- `view` (string): Response shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. "full" returns Apple's ETA records verbatim, each tagged w…

### `apple_maps_lookup_place` (~214 tokens)

Look up places by id (Apple Maps)

Look up Apple Maps places by place id — the id field from apple_maps_search, apple_maps_geocode or apple_maps_reverse_geocode results — 1 to 50 at once. Returns each place's name, category, coordinates, address, phone and website; ids Apple could not resolve are listed with the reason. Needs an Apple Developer key with MapKit JS enabled: APPLE_TEAM_ID + APPLE_KEY_ID + APPLE_PRIVATE_KEY (or APPLE_MAPS_KEY_ID / APPLE_MAPS_PRIVATE_KEY).

Input parameters:

- `lang` (string): Language for names and addresses, as a BCP 47 tag such as en-US, fr-FR or ja-JP (default en-US).
- `placeIds` (array, required): 1–50 Apple Maps place ids.
- `view` (string): Response shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. "full" adds Apple's structured address, display region and…

### `apple_maps_snapshot_url` (~376 tokens)

Make a static map image link (Apple Maps)

Make a signed link to a static Apple Maps image (PNG): centred on an address or "lat,lng", and/or with pins (each with an optional label, colour and one-character glyph; the map fits the pins when no center is given). Choose zoom, size (up to 640x640), scale, map type (standard, hybrid, satellite, mutedStandard) and light/dark. Returns the URL only — nothing is downloaded; the link can be made to expire. Uses the same Apple Developer key (MapKit JS): APPLE_TEAM_ID, APPLE_KEY_ID, APPLE_PRIVATE_KEY.

Input parameters:

- `annotations` (array): Up to 50 pins, drawn in this order.
- `center` (string): Map centre: an address or "latitude,longitude". Omit to fit the map around the annotations.
- `colorScheme` (string): light (default) or dark; dark applies to standard and mutedStandard only.
- `expiresInMinutes` (integer): Make the link stop working after this many minutes (max 30 days). Default: no expiry.
- `lang` (string): Language for names and addresses, as a BCP 47 tag such as en-US, fr-FR or ja-JP (default en-US).
- `mapType` (string): Map style (default standard).
- `scale` (integer): Pixel density 1–3 (2 for retina screens; default 1).
- `showPointsOfInterest` (boolean): Show businesses and landmarks on the map (default true).
- `size` (string): Image size "WIDTHxHEIGHT" in points, each 50–640 (default 600x400).
- `zoom` (number): Zoom level 3 (continent) to 20 (building); Apple default 12. Needs center.

### `apple_weather_get` (~582 tokens)

Get the weather forecast (Apple Weather)

Weather forecast for a place from Apple Weather (WeatherKit): current conditions, hourly (up to 240 h), daily (up to 10 days), next-hour rain, severe-weather alerts (need countryCode). Returns temperature, feels-like, rain/snow chance and amount, wind, humidity, UV, sunrise/sunset. Takes latitude/longitude — use apple_maps_geocode first to turn a place name into coordinates. Days roll over in timeZone: pass the place's own zone when it differs from yours. Needs APPLE_TEAM_ID, APPLE_KEY_ID, APPLE_PRIVATE_KEY and APPLE_WEATHERKIT_SERVICE_ID. Show the returned attribution with the data.

Input parameters:

- `countryCode` (string): Two-letter ISO country code of the location (e.g. US, GB). Required for severe-weather alerts; without it alerts are skipped, with a note.
- `dataSets` (array): What to fetch (default current, hourly, daily, alerts): current = conditions now; hourly = hour by hour; daily = day by day; nextHour = minute-level precipitation for the next hour (some regions only…
- `days` (integer): Days of daily forecast starting today in timeZone (default 7, max 10). Needs "daily" in dataSets.
- `hours` (integer): Hours of hourly forecast from the current hour (default 24, max 240). Needs "hourly" in dataSets.
- `lang` (string): Language of alert descriptions, as a BCP 47 tag such as en, en-GB, fr or ja (default en). Condition words are always English.
- `latitude` (number, required): Latitude in decimal degrees, -90 to 90 (e.g. 40.7128).
- `longitude` (number, required): Longitude in decimal degrees, -180 to 180 (e.g. -74.006).
- `timeZone` (string): IANA time zone (e.g. America/New_York) that times are shown in and that days roll over in. Default: the server's display zone (DISPLAY_TZ). For a place in another zone pass that place's zone.
- `units` (string): metric (°C, km/h, mm, hPa, km) or imperial (°F, mph, in, inHg, mi). Default: APPLE_UNITS, else metric.
- `view` (string): Response shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact converts units, rounds, turns fractions into perce…

### `apple_weather_get_alert` (~264 tokens)

Get a severe-weather alert (Apple Weather)

Get one severe-weather alert's full official text from Apple Weather (WeatherKit), unmodified, by its id (the alerts[].id from apple_weather_get called with countryCode). Returns the issuing agency (source), severity, effective/expiry times, detailsUrl and the messages verbatim. Apple serves an alert only while it is active; an expired one is NOT_FOUND. Needs APPLE_TEAM_ID, APPLE_KEY_ID, APPLE_PRIVATE_KEY and APPLE_WEATHERKIT_SERVICE_ID.

Input parameters:

- `alertId` (string, required): The alert id (a UUID), from alerts[].id in an apple_weather_get result.
- `lang` (string): Language of the alert text, as a BCP 47 tag such as en, en-GB, fr or ja (default en).
- `timeZone` (string): IANA time zone (e.g. America/New_York) the alert's times are shown in. Default: the server's display zone (DISPLAY_TZ).
- `view` (string): Response shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact drops the alert area geometry (GeoJSON) and bookke…

### `apple_itunes_search` (~556 tokens)

Search the iTunes Store catalog

Search Apple's iTunes Store catalog — songs, albums, artists, podcasts and podcast episodes, audiobooks, apps and ebooks — with no Apple account or key. Returns ids, names, artist, release date, duration and store links. trackId/collectionId/artistId are the SAME ids Apple Music's catalog uses (handy for adding songs to playlists); podcasts include feedUrl. Narrow with media, entity and attribute; country picks the store (default APPLE_MUSIC_STOREFRONT, else us). Apple serves only the top 200 matches; it allows about 20 searches a minute.

Input parameters:

- `attribute` (string): Match the term against one field only, e.g. artistTerm, songTerm, albumTerm (music); titleTerm, authorTerm (podcast, audiobook); softwareDeveloper (software). Must be valid for media.
- `country` (string): Two-letter country code of the store to use, e.g. us, gb, jp (default: APPLE_MUSIC_STOREFRONT, else us).
- `entity` (string): Result type within media, e.g. song, album, musicArtist (music); podcast, podcastEpisode (podcast); software, iPadSoftware, desktopSoftware (software); audiobook; ebook. Must be valid for media.
- `explicit` (boolean): false leaves out explicit content (default: included).
- `lang` (string): Language of the results: en_us (default) or ja_jp.
- `limit` (integer): Maximum items to return (default 25, max 200).
- `media` (string): Kind of content: music, podcast, audiobook, software (apps), ebook, musicVideo, or all. Default: all, or the media the entity/attribute belongs to (entity song → music, podcastEpisode → podcast).
- `offset` (integer): Zero-based index of the first result (default 0, below 200); pass nextOffset from the previous page.
- `term` (string, required): Words to search for, e.g. a title, artist, author, show or app name.
- `view` (string): Response shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact keeps ids (trackId/collectionId/artistId), names,…

### `apple_itunes_lookup` (~534 tokens)

Look up iTunes Store items by id, UPC, ISBN or bundle id

Look up iTunes Store items (no Apple account or key) by ids — 1–200 trackId/collectionId/artistId values, e.g. from apple_itunes_search or an Apple Music link — or by one UPC/EAN (album), ISBN (book) or bundleId (app). With one item and entity, lists its related items: an album's songs (song), an artist's albums (album), a podcast's episodes (podcastEpisode, newest first; Apple serves at most 200 and fewer for some shows). Ids match Apple Music catalog ids; ids not found are listed. Episode ids cannot be looked up directly.

Input parameters:

- `bundleId` (string): An app bundle identifier, e.g. com.apple.Pages.
- `country` (string): Two-letter country code of the store to use, e.g. us, gb, jp (default: APPLE_MUSIC_STOREFRONT, else us).
- `entity` (string): List the item's related items of this type: song (an album's or artist's songs), album (an artist's albums), podcastEpisode (a podcast's episodes), musicVideo, ebook, audiobook, software, …
- `ids` (array): 1–200 iTunes ids (trackId, collectionId or artistId). Only one id when entity is set.
- `isbn` (string): A book ISBN, 13-digit or 10-digit (hyphens allowed; ISBN-10 is converted).
- `limit` (integer): With entity: maximum related items to return (default 50, max 200; Apple serves only the first 200).
- `offset` (integer): With entity: zero-based index of the first related item (default 0, below 200); pass nextOffset from the previous page.
- `sort` (string): With entity: "recent" returns the newest related items first.
- `upc` (string): An album or video UPC/EAN (8–14 digits).
- `view` (string): Response shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact keeps ids (trackId/collectionId/artistId), names,…

### `apple_charts_get` (~357 tokens)

Get Apple top charts

Apple's current top charts (no Apple account or key): most-played songs, albums, music videos and playlists on Apple Music; top podcasts, trending podcast episodes and top subscriber channels; top free/paid apps and books; top audiobooks. Returns ranked entries (rank, id, name, artist, release date, genres, store link) for one storefront (two-letter country code; default APPLE_MUSIC_STOREFRONT, else us), up to the top 100. Song, album and podcast ids work with apple_itunes_lookup and Apple Music.

Input parameters:

- `chart` (string, required): Which chart: music-songs, music-albums, music-videos, music-playlists, podcasts, podcast-episodes, podcast-channels, apps-free, apps-paid, books-free, books-paid, audiobooks.
- `limit` (integer): Maximum items to return (default 25, max 100).
- `offset` (integer): Zero-based chart position to start at (default 0, below 100); pass nextOffset from the previous page.
- `storefront` (string): Two-letter country code of the chart, e.g. us, gb, jp (default: APPLE_MUSIC_STOREFRONT, else us).
- `view` (string): Response shape: "compact" (default) drops fields the response already carries elsewhere; "full" returns every field this server understands. compact gives rank, id, name, artistName/artistId, collect…

## Diagnostics

Captured diagnostic sections: Provenance, Dependencies. The full working is on the page: https://verifymcp.io/servers/chrischall-apple-icloud-mcp/apple-icloud-mcp#diagnostics

## Score history

- 2026-10-02: 81
- 2026-10-01: 81
- 2026-09-30: 65
- 2026-09-29: 80
- 2026-09-28: 64
- 2026-09-27: 79

## Common questions

### What is the io.github.chrischall/apple-icloud-mcp server?

io.github.chrischall/apple-icloud-mcp is listed in the public MCP registry as io.github.chrischall/apple-icloud-mcp. Unofficial: Apple Music, iCloud Calendar/Contacts/Mail, Apple Maps and WeatherKit, no Mac needed. This page covers its npm package (apple-icloud-mcp).

### Is the io.github.chrischall/apple-icloud-mcp server safe to use?

io.github.chrischall/apple-icloud-mcp scores 81 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 2 October 2026. It declares no install or post-install scripts. Its build provenance is signed and verified. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the io.github.chrischall/apple-icloud-mcp server expose?

io.github.chrischall/apple-icloud-mcp exposes 59 tools: apple_healthcheck, apple_music_search_catalog, apple_music_get_catalog_items, apple_music_get_charts, apple_music_list_playlists, and 54 more. Their descriptions and schemas cost roughly 16,686 tokens of context every time the server is loaded.

### Is the io.github.chrischall/apple-icloud-mcp server still maintained?

io.github.chrischall/apple-icloud-mcp is still listed as active in the MCP registry. We last reached this channel on 2 October 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

### What licence is the io.github.chrischall/apple-icloud-mcp server under?

io.github.chrischall/apple-icloud-mcp declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

## Links

- npm package: https://www.npmjs.com/package/apple-icloud-mcp
- Socket report: https://socket.dev/npm/package/apple-icloud-mcp
- Repository: https://github.com/chrischall/apple-icloud-mcp
- Changelog RSS feed: https://verifymcp.io/servers/chrischall-apple-icloud-mcp/apple-icloud-mcp.xml
- Changelog JSON feed: https://verifymcp.io/servers/chrischall-apple-icloud-mcp/apple-icloud-mcp.json
- HTML version of this page: https://verifymcp.io/servers/chrischall-apple-icloud-mcp/apple-icloud-mcp
