iCloud Calendar (CalDAV)

io.github.Glob0x17由 GitHub 帳號 Glob0x17 發布v0.2.1更新於 Oct 24, 2026

iCloud Calendar over CalDAV: list, create, update, move and delete events. Optional read-only mode.

已驗證STDIO僅桌面效率與工作流檔案與儲存

概覽

AI 產生的概覽

本機 MCP 伺服器,透過 CalDAV 讓助理存取 iCloud 行事曆,列出行事曆並讀取、建立、更新、移動和刪除活動。

可以做什麼
列出行事曆並讀取指定日期範圍內的活動,可依單一行事曆篩選並依開始時間排序,另有連線檢查(含近 7 天活動數)和列出行事曆的資源。建立活動,可設定標題、時間、全天、地點、備註、URL、提醒和重複規則。更新上述任一欄位,或將活動以原子方式移動到另一個行事曆。依識別碼刪除活動。
適用情境
適合在 Linux、macOS 或 Windows 的桌面 MCP 用戶端中,讓助理讀取或管理你的 iCloud 行事曆,而不必經過 macOS 行事曆應用程式。可先以唯讀模式試用,再開啟寫入。
執行需求
作為本機 stdio 程序由用戶端啟動,通常以 uvx 從 PyPI 執行。需要 Python 3.12 或更新版本與 uv、已啟用 iCloud 行事曆的 Apple ID,以及在 appleid.apple.com 產生的 App 專用密碼。需設定 ICLOUD_USERNAME 和 ICLOUD_PASSWORD;可選 CALDAV_SERVER_URL、MCP_ICAL_READ_ONLY 和 MCP_ICAL_LOG_LEVEL。僅支援桌面用戶端。
安裝前請注意
ICLOUD_PASSWORD 必須是 App 專用密碼而非 Apple ID 密碼;它同時可存取 CalDAV、CardDAV 和 IMAP,請勿提交到版本控制,外洩後立即撤銷。多數用戶端以明文儲存環境變數。建立、更新和刪除工具會改動真實行事曆資料;設定 MCP_ICAL_READ_ONLY=true 可移除這些工具。DEBUG 等級日誌可能記錄活動內容。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 iCloud Calendar (CalDAV),將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

iCloud Calendar MCP Server

[PyPI] [Python 3.12+] [License: MIT]

A Model Context Protocol server that gives MCP clients access to iCloud Calendar over CalDAV: list calendars, read, create, update, move and delete events. It works on Linux, macOS and Windows, since it talks to iCloud directly instead of going through the macOS Calendar app.

This is a maintained fork of zwrong/iCalendar, itself derived from the macOS mcp-ical server. See Changes in this fork.

Tools

ToolDescription
list_calendarsNames of the available calendars
list_eventsEvents in a date range, optionally for one calendar, sorted by start time
create_eventNew event: title, times, all-day, location, notes, URL, alarms, recurrence
update_eventChange any of those fields, or move the event to another calendar
delete_eventDelete an event by identifier
debug_calendar_connectionConnection check: calendars and event counts over the last 7 days

The calendars://list resource also lists the calendars. With MCP_ICAL_READ_ONLY=true, the three write tools are not registered at all.

Requirements

  • Python 3.12 or later and uv
  • An Apple ID with iCloud Calendar enabled
  • An app-specific password for that Apple ID

App-specific password

  1. Sign in to appleid.apple.com, open Sign-In and Security, then App-Specific Passwords.
  2. Generate a password, for example named mcp-icloud-caldav.

The username is your Apple ID address, which is not necessarily an @icloud.com address. An app-specific password gives access to iCloud CalDAV, CardDAV and IMAP: keep it out of version control and revoke it if it leaks.

Installation

The package is published on PyPI as mcp-icloud-caldav. With uv, MCP clients can start it directly, without a separate install step:

bash
uvx mcp-icloud-caldav

uvx downloads the package into a cached, isolated environment on first use. To install it permanently instead: uv tool install mcp-icloud-caldav (or pipx install mcp-icloud-caldav).

From source:

bash
git clone https://github.com/Glob0x17/mcp-icloud-caldav.git mcp-icloud-caldavcd mcp-icloud-caldavuv sync --no-devuv run mcp-icloud-caldav

Configuration

Credentials are read in this order:

  1. Environment variables (recommended)

    VariableRequiredDefault
    ICLOUD_USERNAMEyes
    ICLOUD_PASSWORDyes
    CALDAV_SERVER_URLnohttps://caldav.icloud.com/
  2. MCP_ICAL_CONFIG: path to a JSON file shaped like config.json.example

  3. config_private.json, then config.json, at the repository root (kept for compatibility)

Other settings:

VariableDefaultEffect
MCP_ICAL_READ_ONLYfalsetrue leaves out create_event, update_event and delete_event
MCP_ICAL_LOG_LEVELINFOTRACE, DEBUG, INFO, WARNING or ERROR. Logs go to stderr

The server speaks MCP over stdio and is started by the client. To check it by hand:

bash
[email protected] ICLOUD_PASSWORD=xxxx-xxxx-xxxx-xxxx uvx mcp-icloud-caldav

It waits on stdin and prints nothing on stdout.

Client setup

Use the absolute path of uvx (which uvx) if the client cannot find it: clients often start servers without your shell PATH, which shows up as spawn uvx ENOENT. Usual locations:

Installed withPath
The uv installer (Linux, macOS)~/.local/bin/uvx
Homebrew on Apple silicon/opt/homebrew/bin/uvx
Homebrew on Intel Macs/usr/local/bin/uvx

The command and its argument are separate fields: the command is uvx (or its path) and mcp-icloud-caldav is an argument. A config where the command is the single string "uvx mcp-icloud-caldav" fails with ENOENT, because the client looks for a program with that exact name, space included.

Keeping the password out of the client config

Most clients store env values in clear text in their config file. A small wrapper that reads an env file avoids that:

bash
mkdir -p ~/.config/mcp-icloud-caldav && chmod 700 ~/.config/mcp-icloud-caldavcat > ~/.config/mcp-icloud-caldav/env <<'EOF'[email protected]ICLOUD_PASSWORD=xxxx-xxxx-xxxx-xxxxMCP_ICAL_READ_ONLY=trueEOFchmod 600 ~/.config/mcp-icloud-caldav/env
cat > ~/.local/bin/mcp-icloud-caldav-run <<'EOF'#!/usr/bin/env bashset -euo pipefailset -a; source "$HOME/.config/mcp-icloud-caldav/env"; set +aexec /absolute/path/to/uvx mcp-icloud-caldavEOFchmod +x ~/.local/bin/mcp-icloud-caldav-run

Then point the client at ~/.local/bin/mcp-icloud-caldav-run. Starting read-only and switching to false once reading works is a sensible first step.

Claude Desktop

In claude_desktop_config.json (Settings, Developer, Edit Config). On macOS it is ~/Library/Application Support/Claude/claude_desktop_config.json:

json
{  "mcpServers": {    "icloud-calendar": {      "command": "uvx",      "args": ["mcp-icloud-caldav"],      "env": {        "ICLOUD_USERNAME": "[email protected]",        "ICLOUD_PASSWORD": "xxxx-xxxx-xxxx-xxxx"      }    }  }}

or, with the wrapper, "command": "/home/you/.local/bin/mcp-icloud-caldav-run" and no env. Quit Claude Desktop completely and start it again after editing. On macOS, server logs are in ~/Library/Logs/Claude/mcp-server-icloud-calendar.log.

Claude Code

bash
claude mcp add --scope user icloud-calendar \  -e [email protected] -e ICLOUD_PASSWORD=xxxx-xxxx-xxxx-xxxx \  -- uvx mcp-icloud-caldav

or, with the wrapper, claude mcp add --scope user icloud-calendar -- ~/.local/bin/mcp-icloud-caldav-run.

Do not quote what follows --: -- uvx mcp-icloud-caldav registers uvx as the command and mcp-icloud-caldav as its argument, while -- "uvx mcp-icloud-caldav" registers one program name and fails with ENOENT. To fix an existing entry, remove it with claude mcp remove icloud-calendar --scope user and add it again.

/mcp in a session shows the server state and its tools; claude mcp get icloud-calendar shows the registered command and arguments.

Other clients

Any MCP client that can start a stdio server works: run uvx mcp-icloud-caldav with the environment variables above. The server is also listed in the MCP Registry as io.github.Glob0x17/mcp-icloud-caldav.

Behavior worth knowing

  • Times. Event times are written in UTC. A time with an offset (2030-01-07T09:30:00+01:00) is converted, and a time without one is taken as the machine's local time. Times are shown back in the machine's timezone. All-day events are written as dates, with the end date exclusive as the iCalendar standard requires.
  • Moving between calendars. iCloud refuses the same event UID in two calendars, so a move cannot be "copy then delete". update_event with calendar_name uses a WebDAV MOVE, which is atomic on the server: if it fails, the event stays where it was. A move without other changes keeps the original iCalendar data untouched.
  • Finding events. Listings fill an in-memory index (UID to URL) that lives as long as the server process. Lookups then go straight to the event, falling back to the <calendar>/<UID>.ics URL iCloud uses for most events, and only then to a scan of all calendars. iCloud does not support CalDAV UID searches.
  • Volume. iCloud returns any number of events per request. The practical limit is the client: many cap a tool result at around 25,000 tokens, roughly 300 events in this server's output, so split long ranges.
  • Scope. Only calendars hosted on iCloud are visible. Exchange, Google or other accounts added to the Calendar app on a device are not reachable through iCloud CalDAV, and neither are read-only subscribed (ICS) calendars.

Privacy and security

  • The only network destination is the configured CalDAV server; there is no telemetry.
  • The password never appears in logs, at any level, nor in the configuration object's repr.
  • Logs go to stderr only, since stdout carries the MCP protocol. Event contents (titles, notes) are logged only at DEBUG or below; at INFO, only identifiers. Some clients save server stderr to disk, so keep DEBUG for troubleshooting.
  • Dependencies are locked in uv.lock and resolved from the official PyPI index only.

Troubleshooting

SymptomLikely cause
401 UnauthorizedRegular Apple ID password instead of an app-specific one, or a revoked one
spawn uvx ENOENT or ENOENTuvx is not on the client's PATH (use its absolute path), or the command and its argument were registered as one string (see Client setup)
No events returnedWrong date range, an event in a non-iCloud or subscribed calendar, or a timezone mix-up
Server does not respondSomething writes to stdout and breaks the stdio protocol
Calendar 'X' not foundCalendar names are case-sensitive: check list_calendars

debug_calendar_connection and MCP_ICAL_LOG_LEVEL=DEBUG help narrow things down.

Development

bash
uv syncuv run pytest -m "not integration"   # unit tests, CalDAV client mocked, no networkuv run ruff check .

Integration tests run against a real account, read-only, and are skipped unless credentials are set:

bash
ICLOUD_USERNAME=... ICLOUD_PASSWORD=... uv run pytest -m integration

Project layout:

mcp_icloud_caldav/├── server.py          # MCP server, tool registration, logging setup├── caldav_client.py   # CalDAV access: search, create, update, move, delete, event index├── ical.py            # Thin calendar manager used by the server├── models.py          # Event and request models, iCalendar parsing└── config.py          # Configuration loadingtests/                 # Unit teststests/integration/     # Read-only tests against a real account

Changes in this fork

0.2.1: documentation only (uvx locations, ENOENT causes, client paths on macOS).

0.2.0, compared with zwrong/iCalendar 0.1.0:

  • Dependencies. Lockfile regenerated from the official PyPI index (it resolved packages through a third-party mirror over plain HTTP). Upgrade to mcp 2.x (FastMCP became MCPServer) and caldav 3.x; the original code no longer starts against current releases.
  • Configuration. Environment variables, MCP_ICAL_CONFIG, read-only mode, configurable log level, no event contents in logs above DEBUG.
  • Fixes.
    • Creating an event with a timezone offset failed (Unable to guess TZID); all-day events and recurrence end dates were written incorrectly.
    • Alarms were never read back.
    • Updating an event without a location, notes or URL failed; changing its time produced invalid iCalendar data.
    • Moving an event deleted it before saving the copy, so a failed save lost it.
    • New events got a UID containing spaces and the machine's hostname.
  • Behavior. Events sorted by start time, compact output without empty fields, in-memory event index.
  • Tests. Unit tests for configuration, read-only mode, logging, iCalendar output, moves and lookups.
  • Packaging. Published on PyPI as mcp-icloud-caldav and listed in the MCP Registry. The Python package and the command are renamed from mcp_ical / mcp-ical, which clashed with the original macOS project. The unused mcp[cli] extra was dropped.

Credits and license

MIT, see LICENSE.

來源:README.md,提交 828041e

工具

0
SourceWeft 尚未在沙箱中啟動過該軟體包,因此其工具未知。

版本歷史

1
  1. v0.2.1最新Oct 11, 2026

評分

已滿足適用檢查項的 50%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分

    請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。

  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分