AgentStack
MCP verified MIT Self-run

Mcp Icloud Calendar

mcp-roygabriel-mcp-icloud-calendar · by roygabriel

A Go-based MCP server for Apple iCloud Calendar via CalDAV — manage calendars and events through AI assistants with cross-platform support.

No reviews yet
0 installs
2 views
0.0% view→install

Install

$ agentstack add mcp-roygabriel-mcp-icloud-calendar

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Mcp Icloud Calendar? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

iCloud Calendar MCP Server

A Model Context Protocol server that gives AI assistants full access to Apple iCloud Calendar through CalDAV. List calendars, search events, create, update, and delete events -- all from Claude or any MCP-compatible client.

Built with Go and the mcp-go SDK. Ships as a single static binary for Linux, macOS, and Windows.


Table of Contents

  • [Features](#features)
  • [Quick Start](#quick-start)
  • [Prerequisites](#prerequisites)
  • [Installation](#installation)
  • [Configuration](#configuration)
  • [Usage with Claude Desktop](#usage-with-claude-desktop)
  • [Available Tools](#available-tools)
  • [Development](#development)
  • [Architecture](#architecture)
  • [Security](#security)
  • [Troubleshooting](#troubleshooting)
  • [Contributing](#contributing)
  • [License](#license)

Features

Calendar Operations

  • List all iCloud calendars with paths, names, descriptions, and colors
  • Search events with date range filters and pagination
  • Create events with title, time, description, location, and attendees
  • Update individual fields on existing events (partial update with pointer fields)
  • Delete events permanently

Recurring Events & Attendees

  • Expand recurring events (RRULE) into individual occurrences within a date range
  • Manage attendees with roles (CHAIR, REQ-PARTICIPANT, OPT-PARTICIPANT) and statuses

Multi-Account Support

  • Manage multiple iCloud accounts from a single server instance
  • Configure via ACCOUNTS_FILE JSON or single-account environment variables
  • Per-account rate limiting and retry logic

Operational

  • Structured JSON logging with UUID request correlation
  • Configurable timeout middleware on every tool call (default 25s)
  • Automatic retry with exponential backoff for transient failures
  • Rate limiting per account to avoid iCloud throttling
  • Health endpoint (/healthz, /readyz) and Prometheus metrics (/metrics)
  • Audit logging for mutating operations (no PII)
  • Input validation for all tool parameters
  • MCP tool annotations (read-only, destructive, idempotent) for client-side safety
  • Graceful shutdown on SIGTERM/SIGINT
  • mTLS and custom CA support for enterprise deployments
  • file:// credential loading for Docker/Kubernetes secrets
  • CI pipeline with tests, linting, and vulnerability scanning

Quick Start

# Install
go install github.com/rgabriel/mcp-icloud-calendar@latest

# Set credentials (app-specific password, not your main iCloud password)
export ICLOUD_EMAIL="you@icloud.com"
export ICLOUD_PASSWORD="xxxx-xxxx-xxxx-xxxx"

# Run
mcp-icloud-calendar

Or download a prebuilt binary from the Releases page.


Prerequisites

  • Go 1.21+ -- install (only needed when building from source)
  • iCloud account with two-factor authentication enabled
  • App-specific password -- required for CalDAV access

Generating an App-Specific Password

  1. Go to appleid.apple.com and sign in
  2. Navigate to Sign-In and Security > App-Specific Passwords
  3. Click Generate an app-specific password
  4. Enter a label (e.g. "MCP Calendar Server") and click Create
  5. Copy the generated password (xxxx-xxxx-xxxx-xxxx) and store it securely

Notes:

  • Your Apple ID must have two-factor authentication enabled
  • You can create up to 25 active app-specific passwords
  • Changing your main Apple ID password revokes all app-specific passwords
  • Never use your main iCloud password for CalDAV access

Installation

From Source

git clone https://github.com/rgabriel/mcp-icloud-calendar.git
cd mcp-icloud-calendar
make build

Using go install

go install github.com/rgabriel/mcp-icloud-calendar@latest

Docker

docker build -t mcp-icloud-calendar .

docker run \
  -e ICLOUD_EMAIL="you@icloud.com" \
  -e ICLOUD_PASSWORD="xxxx-xxxx-xxxx-xxxx" \
  mcp-icloud-calendar

The Docker image uses a multi-stage build with a distroless base image and runs as a non-root user.

Prebuilt Binaries

Download the binary for your platform from the Releases page. Binaries are available for:

| Platform | Architecture | Binary | |----------|-------------|--------| | Linux | x8664 | mcp-icloud-calendar-linux-amd64 | | Linux | ARM64 | mcp-icloud-calendar-linux-arm64 | | macOS | Intel | mcp-icloud-calendar-macos-amd64 | | macOS | Apple Silicon | mcp-icloud-calendar-macos-arm64 | | Windows | x8664 | mcp-icloud-calendar-windows-amd64.exe |

SHA256 checksums are provided alongside each binary.


Configuration

Single Account

The server requires two environment variables at minimum:

| Variable | Required | Default | Description | |----------|----------|---------|-------------| | ICLOUD_EMAIL | Yes | | Your iCloud email address (Apple ID) | | ICLOUD_PASSWORD | Yes | | App-specific password from appleid.apple.com | | ICLOUD_CALENDAR_ID | No | | Default calendar path (e.g., /1234567/calendars/home/) | | LOG_LEVEL | No | INFO | Logging verbosity: DEBUG, INFO, WARN, ERROR | | TOOL_TIMEOUT | No | 25s | Timeout per tool call (Go duration, e.g., 30s, 1m) | | MAX_RETRIES | No | 3 | Retry attempts for transient CalDAV failures | | RETRY_BASE_DELAY | No | 1s | Base delay for exponential backoff | | RATE_LIMIT_RPS | No | 10 | CalDAV requests per second per account | | RATE_LIMIT_BURST | No | 20 | Burst allowance for rate limiter | | MAX_CONNS_PER_HOST | No | 10 | Max HTTP connections to iCloud per account | | HEALTH_PORT | No | | Port for health/metrics HTTP server (e.g., 8080) | | TLS_CERT_FILE | No | | Client TLS certificate for mTLS | | TLS_KEY_FILE | No | | Client TLS key for mTLS | | TLS_CA_FILE | No | | Custom CA certificate |

You can set these as environment variables or place them in a .env file:

cp .env.example .env
# Edit .env with your credentials

Credentials support file:// prefixes for Docker/Kubernetes secrets (e.g., ICLOUD_PASSWORD=file:///run/secrets/password).

Multi-Account

To manage multiple iCloud accounts, set the ACCOUNTS_FILE environment variable pointing to a JSON file:

{
  "accounts": [
    {
      "name": "personal",
      "email": "personal@icloud.com",
      "password": "xxxx-xxxx-xxxx-xxxx",
      "calendarId": "/1234567/calendars/home/"
    },
    {
      "name": "work",
      "email": "work@icloud.com",
      "password": "yyyy-yyyy-yyyy-yyyy"
    }
  ]
}

Each tool accepts an optional account parameter. Omit it to use the default account.


Usage with Claude Desktop

Add the server to your Claude Desktop configuration file.

macOS -- ~/Library/Application Support/Claude/claude_desktop_config.json

Linux -- ~/.config/claude/claude_desktop_config.json

Windows -- %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "icloud-calendar": {
      "command": "/path/to/mcp-icloud-calendar",
      "env": {
        "ICLOUD_EMAIL": "you@icloud.com",
        "ICLOUD_PASSWORD": "xxxx-xxxx-xxxx-xxxx"
      }
    }
  }
}

Restart Claude Desktop after saving.


Available Tools

The server exposes 5 MCP tools. Each tool includes schema constraints and annotations indicating whether it is read-only, destructive, or idempotent.

list_calendars

List all available iCloud calendars. Returns each calendar's path, display name, description, and color. Call this first to discover valid calendarId values.

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | account | string | | Account name for multi-account setups |

search_events

Search for calendar events within a date range. Returns paginated results with event details including recurrence info and attendees.

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | account | string | | Account name for multi-account setups | | calendarId | string | (server default) | Calendar path from list_calendars | | startTime | string | | Start of date range (RFC 3339, e.g., 2025-03-01T00:00:00Z) | | endTime | string | | End of date range (RFC 3339) | | limit | number | 50 | Max events to return (1-500) | | offset | number | 0 | Events to skip for pagination | | expandRecurrence | boolean | false | Expand recurring events into individual occurrences (requires both startTime and endTime) |

create_event

Create a new calendar event. Returns the created event's unique ID.

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | account | string | | Account name for multi-account setups | | title | string | (required) | Event title or summary | | startTime | string | (required) | Start time (RFC 3339) | | endTime | string | (required) | End time (RFC 3339) | | description | string | | Event description or notes | | location | string | | Event location | | calendarId | string | (server default) | Calendar path to create the event in | | attendees | string | | JSON array of attendee objects (see below) |

Attendee format:

[
  {"email": "alice@example.com", "name": "Alice", "role": "REQ-PARTICIPANT"},
  {"email": "bob@example.com", "name": "Bob", "role": "OPT-PARTICIPANT", "status": "TENTATIVE"}
]

Supported roles: CHAIR, REQ-PARTICIPANT, OPT-PARTICIPANT. Supported statuses: NEEDS-ACTION, ACCEPTED, DECLINED, TENTATIVE.

update_event

Update specific fields of an existing event. Only include the fields you want to change -- omitted fields remain unchanged.

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | account | string | | Account name for multi-account setups | | eventId | string | (required) | Event ID (UID) from search_events | | calendarId | string | (server default) | Calendar path containing the event | | title | string | | Updated title | | description | string | | Updated description | | location | string | | Updated location | | startTime | string | | Updated start time (RFC 3339) | | endTime | string | | Updated end time (RFC 3339) |

delete_event

Permanently delete a calendar event. This action cannot be undone.

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | account | string | | Account name for multi-account setups | | eventId | string | (required) | Event ID (UID) from search_events | | calendarId | string | (required) | Calendar path containing the event |


Development

Building

make build          # Build binary with version embedding
make test           # Run tests with race detector
make lint           # Run golangci-lint
make clean          # Remove build artifacts
make docker         # Build Docker image
make run            # Build and run

Running Locally

export ICLOUD_EMAIL="you@icloud.com"
export ICLOUD_PASSWORD="xxxx-xxxx-xxxx-xxxx"
make run

Testing

The project includes 88 table-driven tests across 14 test files, covering all tool handlers, CalDAV client logic, input validation, retry/rate-limiting wrappers, recurrence expansion, attendee parsing, and error paths. Tests use mock implementations of the CalendarService interface -- no live CalDAV connection required.

make test

Testing with MCP Inspector

Use the MCP Inspector to interactively test the server:

npx @modelcontextprotocol/inspector mcp-icloud-calendar

CI Pipeline

Every push to main or dev and every pull request runs:

  • go vet and go test -race -- correctness and data race detection
  • golangci-lint -- static analysis (errcheck, govet, staticcheck, gosec, gocritic, and more)
  • govulncheck -- known vulnerability scanning

Tagged releases (v*.*.*) trigger automated cross-platform builds with SHA256 checksums.


Architecture

mcp-icloud-calendar/
  main.go                Server setup, multi-account init, tool registration, middleware chain
  config/
    config.go            Environment variable loading, validation, file:// credential support
    accounts.go          Multi-account JSON configuration
  caldav/
    interface.go         CalendarService interface
    client.go            CalDAV client (caldav.icloud.com, TLS/mTLS)
    retry.go             Retry wrapper with exponential backoff
    ratelimit.go         Rate-limiting wrapper (token bucket)
    recurrence.go        RRULE expansion for recurring events
    attendees.go         Attendee parsing and serialization
    validation.go        Input validation for CalDAV parameters
  tools/
    accounts.go          AccountClients multi-account resolver
    list_calendars.go    list_calendars handler
    search_events.go     search_events handler
    create_event.go      create_event handler
    update_event.go      update_event handler
    delete_event.go      delete_event handler
  health/server.go       Health check and readiness endpoints
  metrics/               Prometheus metrics and tool call middleware
  middleware/             Request ID middleware (UUID correlation)
  logging/               Structured JSON logging (slog)

Client chain: Each account gets its own pipeline: realClient -> RateLimitedClient -> RetryClient

Middleware chain: Each tool call passes through RequestID -> Timeout -> Metrics -> handler. The request ID middleware assigns a UUID for log correlation. The timeout middleware enforces a configurable deadline. The metrics middleware records tool call duration and outcome.

Audit logging: Mutating operations (create_event, update_event, delete_event) are logged via a post-call hook with tool name, account, calendar ID, and status -- no PII (titles, descriptions, locations) is included.

Dependencies

| Package | Purpose | |---------|---------| | mcp-go | MCP SDK -- tool registration, stdio transport | | go-webdav | CalDAV protocol client | | go-ical | iCalendar (RFC 5545) parsing | | rrule-go | Recurrence rule expansion | | godotenv | .env file loading | | uuid | Event UID and request ID generation | | prometheus/clientgolang | Prometheus metrics | | x/time/rate | Token bucket rate limiter |


Security

  • App-specific passwords only -- never accepts or stores your main iCloud password
  • TLS everywhere -- all CalDAV communication uses HTTPS with TLS verification
  • mTLS support -- optional client certificate authentication for enterprise environments
  • Input validation -- all tool parameters are validated for type, range, and format
  • Size and format limits -- title length, time range, and parameter constraints enforced via MCP schema
  • Credential file loading -- file:// prefix for secure secret injection (Docker, Kubernetes)
  • Distroless Docker image -- minimal attack surface, runs as non-root
  • No third-party data sharing -- the server runs locally and communicates only with iCloud servers
  • Revocable access -- app-specific passwords can be revoked at any time from appleid.apple.com
  • Audit trail -- mutating operations are logged without PII for compliance

Never commit your .env file to version control. The .gitignore already excludes it.


Troubleshooting

Authentication Failed

  • Verify you are using an app-specif

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.