icloud-calendar-mcp
# Remote iCloud calendar MCP Server
[](https://github.com/astral-sh/uv)
[](https://www.python.org/downloads/)
[](https://github.com/jlowin/fastmcp)
[](https://www.rfc-editor.org/rfc/rfc4791)
Remote MCP server so Claude Code (or any MCP-compatible client) can manage calendar events directly you can deploy at https://horizon.prefect.io/.
**Works with**
- Claude Code / Claude Desktop / Claude.ai
- ChatGpt
- Anything that supports Oauth MCP servers
## Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
| `ICLOUD_USERNAME` | Yes | — | iCloud account email address |
| `ICLOUD_PASSWORD` | Yes | — | iCloud [app-specific password](https://support.apple.com/en-us/102654) |
| `ICLOUD_CALENDAR` | No | `Alex Plugg` | Name of the target iCloud calendar |
Credentials are stored encrypted in `secrets.env` via [SOPS](https://github.com/getsops/sops) + [Age](https://github.com/FiloSottile/age) and loaded automatically by direnv.
## ICS Import (CLI)
Import an ICS file directly into iCloud:
```bash
uv run python main.py SchemaICAL.ics
# or, if inside the devenv shell:
import SchemaICAL.ics
```
Options:
```
usage: main.py [-h] [--username USERNAME] [--password PASSWORD] [--calendar CALENDAR] ics_file
positional arguments:
ics_file Path to the ICS file to import
options:
-u, --username USERNAME iCloud username (falls back to ICLOUD_USERNAME)
-p, --password PASSWORD iCloud app-specific password (falls back to ICLOUD_PASSWORD)
-c, --calendar CALENDAR Target calendar name (default: Alex Plugg)
```
## MCP Server
`server.py` is a [FastMCP](https://github.com/jlowin/fastmcp) server that exposes CRUD operations on iCloud calendar events.
### Tools
| Tool | Description |
|---|---|
| `list_events` | List events in a date range (defaults to current month) |
| `get_event` | Fetch a single event by UID |
| `create_event` | Create a new event with title, time, description, and location |
| `update_event` | Update any fields of an existing event by UID |
| `delete_event` | Delete an event by UID |
### Installation — Claude Code (user-level)
Register the server globally so it is available in every project:
```bash
claude mcp add --scope user icloud-calendar \
uv -- run fastmcp run /home/kog/repos/ics-icloud-import/server.py
```
The server reads `ICLOUD_USERNAME`, `ICLOUD_PASSWORD`, and `ICLOUD_CALENDAR` from the environment. These are already available in any shell that loads this repo's direnv config.
### Installation — Claude Desktop (macOS / Windows)
Add the following to your Claude Desktop config file:
- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
```json
{
"mcpServers": {
"icloud-calendar": {
"command": "uv",
"args": [
"run",
"--project", "/path/to/ics-icloud-import",
"fastmcp", "run", "/path/to/ics-icloud-import/server.py"
],
"env": {
"ICLOUD_USERNAME": "your@icloud.com",
"ICLOUD_PASSWORD": "xxxx-xxxx-xxxx-xxxx",
"ICLOUD_CALENDAR": "My Calendar"
}
}
}
}
```
Replace `/path/to/ics-icloud-import` with the actual path to this repository.
### Running the server manually
```bash
uv run fastmcp run server.py
```
TDQS
Scored across 7 tools
Each tool targets a distinct resource-action pair: calendars vs. events, and list/get/create/update/delete are clearly separated. No two tools overlap in purpose, and the parameter descriptions reinforce their differences.
All tools follow a consistent verb_noun snake_case pattern (list_calendars, create_event, delete_event, etc.). The naming convention is uniform and predictable across the entire set.
Seven tools is well-scoped for an iCloud calendar server, covering calendar listing/metadata and event CRUD without unnecessary bloat. Each tool has a clear role and the count feels intentional.
Event lifecycle is fully covered (list, get, create, update, delete), and calendar metadata can be updated. The main gap is lack of create/delete calendar operations, but that may not be supported by iCloud CalDAV and is a minor omission.