icloud-mcp
README.md
# icloud-mcp
MCP server for iCloud Drive. It talks to iCloud directly, so it can list, read
and write files whether or not they have been synced to this machine. When a
full copy of a file does exist in the local iCloud Drive folder, reads use it
and skip the network.
## How it decides
| Operation | Where it goes |
| --- | --- |
| list, info, search | iCloud (the source of truth). Each entry carries a `local` field: `hydrated`, `placeholder`, or `absent`. |
| read_file, download | A hydrated local copy if there is one, otherwise streamed from iCloud. |
| upload, write_file, mkdir, rename, move, trash, restore | Always iCloud, so every device sees the change at once. |
If the saved session stops working, reads of hydrated local files still succeed
(with a `warning`); everything else returns one error telling you to sign in again.
Paths are forward-slash and relative to the Drive root, for example
`Documents/notes.txt`. An empty path is the root. `..` is rejected.
## Tools
| Tool | Purpose |
| --- | --- |
| `icloud_status` | Apple ID in use, whether the session works, local folder path |
| `icloud_list` | List a folder |
| `icloud_info` | Metadata for one item |
| `icloud_search` | Name search under a folder (substring, or glob with `*` `?` `[`) |
| `icloud_read_file` | Read a file as text, capped per call, page with `offset` |
| `icloud_download` | Save a file to a local path |
| `icloud_upload` | Upload a local file into a folder |
| `icloud_write_file` | Create a text file from a string |
| `icloud_mkdir` | Create a folder |
| `icloud_rename` | Rename in place |
| `icloud_move` | Move into another folder |
| `icloud_trash` | Move to the iCloud trash |
| `icloud_list_trash` | List the trash |
| `icloud_restore` | Restore from the trash by name |
Nothing is deleted permanently.
## Setup
Requires Python 3.12+ and [uv](https://docs.astral.sh/uv/).
Sign in once at a terminal. The password and 2FA code are typed there and never
stored; only Apple's session cookies are kept, under `~/.icloud-session`.
```
uv run icloud-mcp login
uv run icloud-mcp status
```
### Claude Code plugin
```
claude plugin marketplace add robworks-code/robworks-claude-code-plugins
claude plugin install icloud-mcp@robworks-claude-code-plugins
```
### Manual registration
```
claude mcp add icloud-mcp -- uv run --project /path/to/icloud-mcp icloud-mcp serve
```
## Configuration
| Variable | Default | Meaning |
| --- | --- | --- |
| `ICLOUD_APPLE_ID` | the ID saved by `login` | Apple ID to use |
| `ICLOUD_SESSION_DIR` | `~/.icloud-session` | Where session cookies live |
| `ICLOUD_LOCAL_ROOT` | `%USERPROFILE%\iCloudDrive` on Windows, `~/Library/Mobile Documents/com~apple~CloudDocs` on macOS | Local sync folder |
| `ICLOUD_MAX_READ_BYTES` | `200000` | Cap for one `icloud_read_file` call |
## Development
```
scripts/check.sh # ruff + unit tests (PowerShell: scripts/check.ps1)
scripts/check.sh --live # also runs a round-trip against the real account in _icloud-mcp-test
```
The unit tests use an in-memory stand-in for the Drive, so they need no account.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues