Skip to main content
Glama

CalDAV MCP Server

TypeScript CI Container License

CalDAV MCP Server は、iCloud カレンダーのイベントを管理するための Model Context Protocol サーバーです。1 つのイベントに複数の VALARM リマインダーをネイティブに設定できます。

iCloud カレンダーは、最初のリリースで公式にサポートされ、手動検証が行われた唯一のプロバイダーです。このサーバーは、stdio または Streamable HTTP をサポートする任意の MCP クライアントで動作します。

この独立したプロジェクトは、Apple Inc. とは提携、承認、後援、または承認を受けておらず、Apple および iCloud はそれぞれの所有者の商標です。

ナビゲーション

Related MCP server: DAV MCP Server

概要

このサーバーは、設定された 1 つのアカウントを CalDAV 経由で iCloud に接続します。アカウントのカレンダーを検出し、正規化された読み取りおよび書き込み操作を MCP を通じて公開します。

更新時には、未知のプロパティ、Apple 拡張、VTIMEZONE、繰り返し例外、パッチで省略されたアラームなど、完全な iCalendar リソースが保持されます。書き込みでは、CalDAV のファイル名がイベント UID と一致することを前提とせず、不透明なリソース識別子と ETag を使用します。

カレンダーリソースはメモリ内で処理されます。このサーバーにはテレメトリもアプリケーションデータベースもなく、生の iCalendar は明示的に要求された場合にのみ返されます。

機能

  • 設定された iCloud アカウントで利用可能なカレンダーを検出します。

  • 半開区間の時間範囲でイベントを一覧表示し、繰り返しの発生を展開します。

  • 時刻指定、終日、繰り返しイベントを作成します。

  • イベントごとに 0 個、1 個、または複数の表示アラームをサポートします。

  • iCloud カレンダーが期待する Apple アラーム拡張を出力します。

  • 不透明なリソース ID、またはカレンダー ID と UID のペアでイベントを読み取ります。

  • 省略されたデータや未知の iCalendar データを保持しながら部分更新を適用します。

  • 更新と削除の際に楽観的並行性制御のために ETag を使用します。

  • 完全な繰り返しシリーズを変更する代わりに、単一の繰り返し変更を拒否します。

  • ログとエラーから資格情報、生のカレンダーコンテンツ、CalDAV パスを編集します。

  • 読み取り専用のルートファイルシステム構成を持つ非 root コンテナとして実行されます。

  • stdio および Streamable HTTP MCP トランスポートをサポートします。

MCP ツール

list_calendars

設定されたアカウントで検出されたカレンダーを一覧表示します。各結果には、不透明な calendar_id、表示名、説明、タイムゾーン、およびベストエフォートの書き込みステータスが含まれます。

list_events

半開区間のイベントを一覧表示し、繰り返しの発生を展開します。最大範囲は 366 日、デフォルトのページサイズは 100、最大ページサイズは 500 です。結果は決定的な時系列順で返されます。ページネーションカーソルは不透明であり、走査中にイベントが変更された場合にスナップショットを表すものではありません。

入力例:

{
  "calendar_id": "opaque-calendar-id",
  "start": "2026-09-01T00:00:00Z",
  "end": "2026-10-01T00:00:00Z",
  "timezone": "Europe/Berlin",
  "limit": 100
}

get_event

resource_id、または calendar_id と UID のペアでイベントを読み取ります。生の iCalendar はデフォルトで除外され、制御された診断のために include_raw_ical: true で要求できます。

create_event

イベントを作成し、サーバーが保存した表現を読み戻します。

2 つのアラームを持つ時刻指定イベント:

{
  "calendar_id": "opaque-calendar-id",
  "summary": "Buy Shinkansen tickets",
  "start": {
    "date_time": "2026-09-06T03:00:00+02:00",
    "timezone": "Europe/Berlin"
  },
  "end": {
    "date_time": "2026-09-06T03:30:00+02:00",
    "timezone": "Europe/Berlin"
  },
  "description": "Smart-EX",
  "location": null,
  "alarms": [
    { "minutes_before": 1440, "action": "DISPLAY" },
    { "minutes_before": 0, "action": "DISPLAY" }
  ],
  "rrule": null
}

排他的な終了日を持つ終日イベント:

{
  "calendar_id": "opaque-calendar-id",
  "summary": "Trip",
  "start": { "date": "2026-09-06" },
  "end": { "date": "2026-09-08" },
  "alarms": []
}

繰り返しイベントは、RRULE: プレフィックスなしの RFC 5545 ルールを受け入れます:

{
  "calendar_id": "opaque-calendar-id",
  "summary": "Weekly planning",
  "start": {
    "date_time": "2026-09-07T09:00:00+02:00",
    "timezone": "Europe/Berlin"
  },
  "end": {
    "date_time": "2026-09-07T09:30:00+02:00",
    "timezone": "Europe/Berlin"
  },
  "rrule": "FREQ=WEEKLY;BYDAY=MO;COUNT=10"
}

update_event

イベントまたは完全な繰り返しシリーズをパッチします。省略されたフィールドは保持され、null は null 許容フィールドを削除し、alarms: [] はすべてのアラームを削除します。オプションの expected_etag は、より新しいサーバーバージョンの上書きを防ぎます。

delete_event

イベントまたは完全な繰り返しシリーズを削除し、オプションで観測された ETag を要求します。単一の展開された発生の削除は、現在のリリースではサポートされていません。

技術スタック

インストール

前提条件

  • カレンダーが有効な iCloud アカウント。

  • Apple アカウントで 2 要素認証が有効になっていること。

  • アプリ固有のパスワード

  • コンテナ展開用の Docker と Docker Compose、またはローカルインストール用の Node.js 24+ と pnpm。

Docker Compose

推奨されるインストール方法は、公開されているマルチアーキテクチャイメージを使用します:

ghcr.io/lukegskw/caldav-mcp:latest

Compose の例をダウンロードします:

curl -O https://raw.githubusercontent.com/lukegskw/caldav-mcp/main/compose.example.yaml

Apple アカウントのメールアドレスとアプリ固有のパスワードを指定し、サービスを開始します:

export CALDAV_USERNAME='user@example.com'
export CALDAV_PASSWORD='xxxx-xxxx-xxxx-xxxx'
docker compose -f compose.example.yaml up -d

異なるホストポートを公開するには、次を設定します:

export CALDAV_MCP_PUBLISHED_PORT=18100
docker compose -f compose.example.yaml up -d

latest タグは、デフォルトブランチからの最新の成功したビルドに追従します。管理された展開またはロールバックの場合は、Compose ファイル内のタグを公開されたバージョンまたは不変の sha-* タグに置き換えます。

Streamable HTTP エンドポイントは、次の場所で利用可能になります:

http://<host>:8100/mcp

ホストポートは、コンテナ内のポート 8100 を変更せずに変更できます。永続ボリュームは不要です。カレンダーデータは iCloud に残ります。

Docker run

同じ強化されたコンテナ構成を直接開始できます:

docker run -d \
  --name caldav-mcp \
  --restart unless-stopped \
  --read-only \
  --user 10001:10001 \
  --cap-drop ALL \
  --security-opt no-new-privileges:true \
  --tmpfs /tmp:size=16m,mode=1777 \
  -e CALDAV_PROVIDER=icloud \
  -e CALDAV_USERNAME \
  -e CALDAV_PASSWORD \
  -e CALDAV_MCP_TRANSPORT=streamable-http \
  -e CALDAV_MCP_HOST=0.0.0.0 \
  -p 8100:8100 \
  ghcr.io/lukegskw/caldav-mcp:latest

ソースからコンテナをビルドする

ローカルでのビルドはオプションです。コンテナビルドを変更または監査する必要がない限り、公開されたイメージを優先してください。

git clone https://github.com/lukegskw/caldav-mcp.git
cd caldav-mcp
docker buildx build --load -t caldav-mcp:local .

ローカル Node.js インストール

git clone https://github.com/lukegskw/caldav-mcp.git
cd caldav-mcp
pnpm install --frozen-lockfile
cp .env.example .env
pnpm build
pnpm start -- --transport stdio

stdio モードでは、stdout は MCP メッセージ専用に予約されています。Streamable HTTP をローカルで実行するには:

CALDAV_MCP_TRANSPORT=streamable-http pnpm start

設定

すべての設定は CALDAV_ または CALDAV_MCP_ プレフィックスを使用します。

変数

必須

デフォルト

説明

CALDAV_PROVIDER

いいえ

icloud

プロバイダーポリシー。iCloud がサポートされるプロファイルです。

CALDAV_URL

いいえ

https://caldav.icloud.com

CalDAV 検出 URL。

CALDAV_USERNAME

はい

なし

Apple アカウントのメールアドレス。

CALDAV_PASSWORD

はい

なし

アプリ固有のパスワード。アカウントのパスワードではありません。

CALDAV_MCP_TRANSPORT

いいえ

stdio

stdio または streamable-http

CALDAV_MCP_HOST

いいえ

0.0.0.0

HTTP バインドアドレス。

CALDAV_MCP_PORT

いいえ

8100

HTTP リッスンポート。

CALDAV_MCP_LOG_LEVEL

いいえ

INFO

アプリケーションログレベル。

CALDAV_MCP_REQUEST_TIMEOUT_MS

いいえ

30000

CalDAV リクエストタイムアウト。

コアは、Apple 拡張を共有の iCalendar 実装から分離するために、実験的な generic プロバイダーポリシーと設定可能な URL を保持しています。現在、他のプロバイダーとの互換性は主張されていません。

シークレットは、デプロイメントプラットフォームまたは環境を通じて提供する必要があります。.env をコミットしたり、資格情報を MCP ツールの引数として渡したり、診断レポートに含めたりしないでください。

MCP クライアントのセットアップ

Streamable HTTP サーバー定義を受け入れる任意の MCP クライアントで、URL を設定します:

mcp_servers:
  caldav:
    url: http://<host>:8100/mcp

クライアントが Compose ネットワークを共有している場合は、サービス名と内部ポートを使用します:

mcp_servers:
  caldav:
    url: http://caldav-mcp:8100/mcp

ローカルの stdio サーバーを起動するクライアントの場合は、必要な環境変数を使用して node /absolute/path/to/caldav-mcp/dist/main.js を実行するようにコマンドを設定します。

Claude Desktop (Docker、stdio)

Claude Desktop は、ローカルの stdio サーバーをサブプロセスとして起動します。公開されたコンテナをこの方法で実行すると、アプリ固有のパスワードがクライアントマシンに保持され、ネットワークポートが開かれず、制限事項 のトランスポートガイダンスに一致します。

claude_desktop_config.json にサーバーを追加します:

{
  "mcpServers": {
    "icloud-calendar": {
      "command": "/absolute/path/to/docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "--env-file",
        "/absolute/path/to/caldav-mcp.env",
        "-e",
        "CALDAV_PROVIDER=icloud",
        "-e",
        "CALDAV_MCP_TRANSPORT=stdio",
        "ghcr.io/lukegskw/caldav-mcp@sha256:<digest>"
      ]
    }
  }
}

-i は必須です。アタッチされた stdin がないと、クライアントはコンテナと MCP 通信できません。--rm は、クライアントがコンテナを停止するとコンテナを削除します。

資格情報は -e ではなく --env-file で指定します。docker run に渡された引数はホストのプロセスリストに表示されますが、env ファイルの内容は表示されません。ファイルには 設定 で説明されている変数が含まれます:

CALDAV_USERNAME=user@example.com
CALDAV_PASSWORD=xxxx-xxxx-xxxx-xxxx

latest の代わりにダイジェストでイメージを固定すると、クライアントの再起動時に異なるバージョンが静かに起動するのを防げます:

docker pull ghcr.io/lukegskw/caldav-mcp:latest
docker images --digests ghcr.io/lukegskw/caldav-mcp

設定ファイルを編集した後、Claude Desktop を完全に再起動します。

Windows

設定 -> 開発者 -> 設定の編集 から設定ファイルを作成して配置します。パスを推測しないでください。Claude Desktop が Microsoft Store からインストールされている場合、Windows は %APPDATA%\Claude をパッケージコンテナにリダイレクトし、ファイルは次の場所にあります:

%LOCALAPPDATA%\Packages\Claude_<package-id>\LocalCache\Roaming\Claude\claude_desktop_config.json

その場合、dir %APPDATA%\Claude は何も報告しません。サーバーログは設定ファイルの隣の logs\mcp-server-<server-name>.log に書き込まれます。

パッケージコンテナ内の PATH は信頼できないため、docker.exe への絶対パスを使用します。where docker でパスが表示されます。通常は C:\Program Files\Docker\Docker\resources\bin\docker.exe です。JSON ではバックスラッシュをエスケープする必要があります。

設定形式は MCP クライアントによって異なります。クライアントのドキュメントで正確なスキーマを確認し、サーバー定義を変更した後はリロードまたは再起動してください。

検証

コンテナの状態とログを確認します:

docker compose -f compose.example.yaml ps
docker compose -f compose.example.yaml logs caldav-mcp

コンテナは healthy を報告するはずです。TCP ヘルスチェックはサーバープロセスを検証し、iCloud の資格情報は検証しません。

リポジトリの検証スイートを実行します:

pnpm install --frozen-lockfile
pnpm format:check
pnpm lint
pnpm typecheck
pnpm test:unit
pnpm test:integration
pnpm build

最後に、MCP クライアントで接続し、6 つのツールすべてが一覧表示されることを確認します。リリース前に、専用の iCloud 手動検証 をテストカレンダーに対して実行します。

制限事項

  • サーバープロセスまたはコンテナごとに 1 つの iCloud アカウントが設定されます。

  • Streamable HTTP エンドポイントには、現在のリリースでは認証がありません。信頼できる LAN、VPN、またはプライベートコンテナネットワークに制限し、インターネットに直接公開しないでください。

  • 個々の繰り返しの発生は読み取り専用です。完全なシリーズの更新または削除はサポートされています。

  • ACTION:DISPLAY アラームのみが作成されます。

  • 個々の iCalendar リソースは 5 MiB に制限されています。

  • イベント一覧の範囲は 366 日、ページは 500 件に制限されています。

  • イベントには最大 20 個のアラームを含めることができます。

  • 参加者のスケジューリングは現在の範囲外です。

  • iCloud 以外のプロバイダーは公式にはサポートされていません。

検出、認証、ETag、および Apple 拡張のガイダンスについては、トラブルシューティング を参照してください。セキュリティの問題を報告したり、診断情報を添付したりする前に、SECURITY.md を確認してください。

コントリビューション

コントリビューションを歓迎します。プルリクエストを開く前に:

pnpm install --frozen-lockfile
pnpm format:check
pnpm lint
pnpm typecheck
pnpm test
pnpm build
docker buildx build --load -t caldav-mcp:test .

CalDAV 書き込みまたは iCalendar シリアライゼーションへの変更は、ETag チェック、不透明なリソース境界、未知のプロパティ、繰り返し例外、パッチで省略されたアラームを保持する必要があります。TypeScript の変更は、.codex/rules/typescript.md のルールを引き続き満たす必要があります。

ライセンス

MIT。 LICENSE を参照してください。

Available Tools

6 tools
create_eventCreate calendar eventA

Create a new event in a writable iCloud calendar and return the stored representation; existing events are not changed. Use list_calendars first to obtain calendar_id, and use update_event when the event already exists. Timed values require matching offsets and timezones, all-day end dates are exclusive, and recurrence rules omit the RRULE: prefix.

ParametersJSON Schema
NameRequiredDescriptionDefault
endYesEvent end using the same temporal type and timezone as start; an all-day end date is exclusive.
rruleNoRFC 5545 recurrence rule without the RRULE: prefix; defaults to null.
startYesEvent start as a timed date-time or all-day date.
alarmsNoDisplay reminders; defaults to an empty array.
summaryYesEvent title, between 1 and 1,024 characters.
locationNoEvent location; defaults to null.
calendar_idYesOpaque destination calendar ID returned by list_calendars.
descriptionNoEvent notes; defaults to null.

Output Schema

ParametersJSON Schema
NameRequiredDescription
endYesNormalized event end.
uidYesStored iCalendar UID.
etagYesCurrent ETag for optimistic concurrency, when available.
hrefYesRedacted fingerprint of the CalDAV resource URL.
rruleYesStored RFC 5545 recurrence rule without the RRULE: prefix.
startYesNormalized event start.
alarmsYesNormalized alarms attached to the event.
summaryYesStored event title.
locationYesStored event location.
raw_icalNoRaw iCalendar resource, included only when explicitly requested.
recurringYesWhether this event belongs to a recurring series.
calendar_idYesOpaque ID of the containing calendar.
descriptionYesStored event notes.
resource_idYesOpaque event ID accepted by get_event, update_event, and delete_event.
recurrence_idYesOccurrence identifier for an expanded recurring event.
recurrence_exceptionYesWhether this result is an overridden recurrence instance.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond annotations, the description adds meaningful behavioral context: it requires a writable calendar, returns the stored representation, guarantees existing events are unchanged, and warns about timezone offset matching, exclusive all-day end dates, and RRULE prefix omission. These constraints are not deducible from the annotations (readOnlyHint=false, destructiveHint=false).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences with no filler. The core purpose is front-loaded, and each subsequent sentence adds distinct, high-value guidance: prerequisites, alternative tool, and tricky format constraints. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex create tool with 8 parameters, the description covers prerequisites, alternatives, return behavior, and the most error-prone input constraints. Since an output schema exists, it appropriately does not need to describe return structure further.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all parameters in detail. The description reinforces key constraints like timezone matching, exclusive all-day ends, and RRULE prefix omission, but these largely restate what the schema properties already say, adding limited new meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource—'Create a new event in a writable iCloud calendar'—and explicitly contrasts with update_event by noting 'existing events are not changed.' This clearly differentiates the tool from its siblings like list_events and get_event.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit when-to-use guidance: 'Use list_calendars first to obtain calendar_id, and use update_event when the event already exists.' This directly routes an agent to prerequisites and alternatives, leaving no ambiguity about the tool's appropriate context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_eventDelete calendar eventA
DestructiveIdempotent

Permanently delete an event or entire recurring series; individual expanded occurrences are not supported. Target it by resource_id or by calendar_id with uid, and supply expected_etag when available to prevent deleting a concurrently changed event.

ParametersJSON Schema
NameRequiredDescriptionDefault
uidNoiCalendar UID of the event. Provide it together with calendar_id when resource_id is unavailable.
calendar_idNoOpaque calendar ID returned by list_calendars. Provide it together with uid when resource_id is unavailable.
resource_idNoOpaque event resource ID returned by list_events or get_event. Provide it alone instead of calendar_id and uid.
expected_etagNoETag previously returned for the event. When supplied, deletion fails if the event changed since it was read.

Output Schema

ParametersJSON Schema
NameRequiredDescription
deletedYesConfirms that the resource was deleted.
resource_idYesOpaque ID of the deleted event resource.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark destructiveHint=true and readOnlyHint=false, but the description adds important context beyond them: 'Permanently delete' emphasizes irreversibility, 'entire recurring series' expands the blast radius, and the expected_etag note explains concurrency behavior. No contradiction with annotations; the description makes the destructive semantics vivid and accurate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences carry all essential information with no filler: the action first, then scope, then targeting alternatives, then expected_etag usage. Every clause earns its place, and the most important constraints are front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the essential behavior, the full targeting mechanism, a concurrency safety mechanism, and a key unsupported edge case. An output schema is present, so return-value details need not be described, and the tool is simple enough that nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, and each parameter already has a detailed description, including the 'provide it together/alone' relationship between uid, calendar_id, and resource_id. The description essentially paraphrases the same targeting and etag guidance without adding substantial new meaning, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with the specific verb 'delete' and resource 'event or entire recurring series', clearly distinguishing this destructive operation from create/update siblings. It explicitly calls out a key behavioral nuance (expanded occurrences not supported) that makes the tool's scope unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives concrete targeting instructions: use resource_id, or calendar_id with uid, and optionally expected_etag to guard against concurrent changes. It also states the exclusion for individual expanded occurrences, but it doesn't explicitly compare against alternatives like update_event when modification is desired. This is clear context with minor missing explicit 'when-not-to-use' guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_eventGet calendar eventA
Read-onlyIdempotent

Read one event by resource_id, preferably from a previous result, or by the calendar_id and uid pair. Use list_events for range searches. Request raw iCalendar only for controlled diagnostics because it may contain sensitive calendar data.

ParametersJSON Schema
NameRequiredDescriptionDefault
uidNoiCalendar UID of the event. Provide it together with calendar_id when resource_id is unavailable.
calendar_idNoOpaque calendar ID returned by list_calendars. Provide it together with uid when resource_id is unavailable.
resource_idNoOpaque event resource ID returned by list_events or get_event. Provide it alone instead of calendar_id and uid.
include_raw_icalNoInclude the raw iCalendar resource for controlled diagnostics; it may contain sensitive calendar data. Defaults to false.

Output Schema

ParametersJSON Schema
NameRequiredDescription
endYesNormalized event end.
uidYesStored iCalendar UID.
etagYesCurrent ETag for optimistic concurrency, when available.
hrefYesRedacted fingerprint of the CalDAV resource URL.
rruleYesStored RFC 5545 recurrence rule without the RRULE: prefix.
startYesNormalized event start.
alarmsYesNormalized alarms attached to the event.
summaryYesStored event title.
locationYesStored event location.
raw_icalNoRaw iCalendar resource, included only when explicitly requested.
recurringYesWhether this event belongs to a recurring series.
calendar_idYesOpaque ID of the containing calendar.
descriptionYesStored event notes.
resource_idYesOpaque event ID accepted by get_event, update_event, and delete_event.
recurrence_idYesOccurrence identifier for an expanded recurring event.
recurrence_exceptionYesWhether this result is an overridden recurrence instance.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint, so the safety profile is clear. The description adds valuable behavioral context beyond annotations by warning that raw iCalendar may contain sensitive data and should only be requested for controlled diagnostics, and by noting that resource_id should preferably come from a previous result.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three concise, front-loaded sentences with no fluff. Each sentence earns its place: the primary lookup method, the alternative, and the sensitive-data caveat.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the annotations, rich schema, and output schema, the description covers the main operational concerns: how to identify the event, when to use list_events, and the sensitive nature of raw iCalendar. It could be slightly more explicit about the fact that at least one identifier must be provided since the schema lists no required parameters, but the 'by... or by...' phrasing implies this.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and each parameter already has a detailed explanation in the schema. The description restates the resource_id-vs-calendar_id+uid relationship and the raw iCalendar caution, but does not add substantial new parameter-level meaning beyond what the schema already provides, so a baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description begins with the specific verb 'Read one event' and identifies the resource as a calendar event, clearly distinguishing this from sibling tools. It also names the alternative lookup paths (resource_id vs calendar_id+uid pair), making the tool's purpose unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says to use list_events for range searches, which is a direct routing instruction to an alternative sibling. It also advises using resource_id from a previous result preferentially and restricts raw iCalendar requests to controlled diagnostics, giving clear when-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_calendarsList calendarsA
Read-onlyIdempotent

List calendars available in the configured iCloud account. Use this first to obtain the opaque calendar_id required by list_events and create_event; writable is a best-effort capability indicator.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
calendarsYesCalendars available to the configured account.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already establish read-only, idempotent, and non-destructive behavior, and the description adds meaningful context: the writable field is only a best-effort capability indicator, and calendar IDs are opaque. This helps the agent avoid over-trusting the writable flag and treating IDs as human-readable.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two concise sentences with no filler. It leads with the core function and then adds the most important usage detail, making it easy to scan and act on.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given that the tool takes no parameters, has a rich set of annotations, and has an output schema, the description covers all necessary context: what is being listed, the account scope, the purpose of the returned IDs, and the reliability of the writable indicator.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has no parameters, so the baseline for this dimension is 4. The description does not need to explain any parameter semantics because there are none.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states that this tool lists calendars in the configured iCloud account, using a specific verb and resource. It also distinguishes itself from the sibling event tools by explaining that it provides the calendar_id needed by list_events and create_event.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly instructs the agent to use this tool first in order to obtain the opaque calendar_id required by event operations. This gives clear sequencing guidance and explains the purpose of the tool relative to its siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_eventsList calendar eventsA
Read-onlyIdempotent

List events that overlap the start-inclusive, end-exclusive interval and expand recurring series into occurrences, across at most 366 days. Use list_calendars first to obtain calendar_id and use get_event instead for one known event. Continue with next_cursor and unchanged query filters when more results are available.

ParametersJSON Schema
NameRequiredDescriptionDefault
endYesExclusive end of the event search interval; must be after start and no more than 366 days later.
limitNoMaximum events to return in this page, from 1 to 500; defaults to 100.
startYesInclusive start of the event search interval as an ISO 8601 instant.
cursorNoOpaque next_cursor from the preceding page. Reuse it with the same calendar, interval, and timezone.
timezoneNoFallback IANA timezone used when an event lacks timezone metadata during recurrence expansion.
calendar_idYesOpaque calendar ID returned by list_calendars.

Output Schema

ParametersJSON Schema
NameRequiredDescription
eventsYesEvents in deterministic chronological order for this page.
next_cursorYesOpaque cursor for the next page, or null when this is the last page.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate read-only, idempotent, non-destructive behavior, and the description adds substantial behavioral context: interval inclusivity, recurring series expansion, the 366-day maximum, and pagination continuation. This goes well beyond the structured annotation data and discloses important operation semantics.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two dense sentences cover core behavior, prerequisites, alternative selection, and pagination without repetition or filler. The most critical semantic details are front-loaded, and every clause carries operational value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a paginated list operation with six parameters and an output schema, the description covers the required workflow (list_calendars, get_event), recurrence behavior, interval constraints, and pagination instructions. The output schema handles return-value details, and annotations cover the safety profile, so nothing essential is missing from the description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds value on top by explaining that calendar_id comes from list_calendars, that cursor must be reused with unchanged query filters, and that interval boundaries are inclusive/exclusive. This helps agents understand how the parameters relate to workflow even though the schema already documents each field.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource ('List events') and defines precise interval semantics ('start-inclusive, end-exclusive') plus recurrence expansion. It also differentiates from related tools by saying to use 'get_event instead for one known event' and to use 'list_calendars first'. An agent can clearly understand what this tool does and how it differs from siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit workflow guidance: call list_calendars first for calendar_id, use get_event for a single known event, and paginate with next_cursor using unchanged filters. This directly tells the agent when to use this tool versus alternatives and how to handle multi-page results.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_eventUpdate calendar eventA
Destructive

Modify an existing event or entire recurring series; individual expanded occurrences are not supported. Target it by resource_id or by calendar_id with uid. Omitted patch fields are preserved, null clears nullable fields, an empty alarms array removes alarms, and expected_etag can prevent a stale write.

ParametersJSON Schema
NameRequiredDescriptionDefault
uidNoiCalendar UID of the event. Provide it together with calendar_id when resource_id is unavailable.
patchYesFields to replace. Omitted fields are preserved; null clears nullable values and an empty alarms array removes all alarms.
calendar_idNoOpaque calendar ID returned by list_calendars. Provide it together with uid when resource_id is unavailable.
resource_idNoOpaque event resource ID returned by list_events or get_event. Provide it alone instead of calendar_id and uid.
expected_etagNoETag previously returned for the event. When supplied, the update fails if the event changed since it was read.

Output Schema

ParametersJSON Schema
NameRequiredDescription
endYesNormalized event end.
uidYesStored iCalendar UID.
etagYesCurrent ETag for optimistic concurrency, when available.
hrefYesRedacted fingerprint of the CalDAV resource URL.
rruleYesStored RFC 5545 recurrence rule without the RRULE: prefix.
startYesNormalized event start.
alarmsYesNormalized alarms attached to the event.
summaryYesStored event title.
locationYesStored event location.
raw_icalNoRaw iCalendar resource, included only when explicitly requested.
recurringYesWhether this event belongs to a recurring series.
calendar_idYesOpaque ID of the containing calendar.
descriptionYesStored event notes.
resource_idYesOpaque event ID accepted by get_event, update_event, and delete_event.
recurrence_idYesOccurrence identifier for an expanded recurring event.
recurrence_exceptionYesWhether this result is an overridden recurrence instance.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and readOnlyHint=false, and the description adds valuable behavioral context: patch semantics ('Omitted patch fields are preserved'), null clearing, empty alarms array behavior, and expected_etag preventing stale writes. This goes beyond what annotations provide and helps an agent predict side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. It front-loads the core action and limitations, then packs targeting and patch semantics into a dense but readable second sentence. Every clause adds useful information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the rich input schema, output schema, and annotations, this description covers the essential operational details: what can be modified, how to identify the target, how patches behave, and how to prevent stale writes. No critical calling context appears missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description earns a 4 by adding cross-parameter semantics not obvious from individual field descriptions: preservation of omitted fields, null clearing, empty alarms removal, and the optimistic concurrency role of expected_etag.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb and resource: 'Modify an existing event or entire recurring series.' It also adds a critical scope limitation ('individual expanded occurrences are not supported') and distinguishes the tool from create/delete/list siblings by focusing on modification of existing entities.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives concrete targeting guidance ('by resource_id or by calendar_id with uid') and a clear exclusion ('individual expanded occurrences are not supported'). It does not explicitly name alternatives like create_event or delete_event, but the context is clear enough for an agent to know when this tool applies.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 5 tool updatesv0.1.7
    • Changedcreate_event14 fields changed
      • removedOutput schema / properties / alarms / items / properties / description / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / alarms / items / properties / description / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / alarms / items / properties / uid / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / alarms / items / properties / uid / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / description / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / description / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / etag / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / etag / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / location / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / location / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / recurrence_id / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / recurrence_id / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / rrule / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / rrule / type
        Added value: +[
        +  "string",
        +  "null"
        +]
    • Changedget_event14 fields changed
      • removedOutput schema / properties / alarms / items / properties / description / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / alarms / items / properties / description / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / alarms / items / properties / uid / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / alarms / items / properties / uid / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / description / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / description / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / etag / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / etag / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / location / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / location / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / recurrence_id / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / recurrence_id / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / rrule / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / rrule / type
        Added value: +[
        +  "string",
        +  "null"
        +]
    • Changedlist_calendars6 fields changed
      • removedOutput schema / properties / calendars / items / properties / description / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / calendars / items / properties / description / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / calendars / items / properties / timezone / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / calendars / items / properties / timezone / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / calendars / items / properties / writable / anyOf
        Removed value: -[
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / calendars / items / properties / writable / type
        Added value: +[
        +  "boolean",
        +  "null"
        +]
    • Changedlist_events18 fields changed
      • changedInput schema / properties / end / pattern
        Previous value: -"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"New value: +"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
      • changedInput schema / properties / start / pattern
        Previous value: -"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"New value: +"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
      • removedOutput schema / properties / events / items / properties / alarms / items / properties / description / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / events / items / properties / alarms / items / properties / description / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / events / items / properties / alarms / items / properties / uid / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / events / items / properties / alarms / items / properties / uid / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / events / items / properties / description / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / events / items / properties / description / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / events / items / properties / etag / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / events / items / properties / etag / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / events / items / properties / location / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / events / items / properties / location / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / events / items / properties / recurrence_id / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / events / items / properties / recurrence_id / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / events / items / properties / rrule / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / events / items / properties / rrule / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / next_cursor / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / next_cursor / type
        Added value: +[
        +  "string",
        +  "null"
        +]
    • Changedupdate_event14 fields changed
      • removedOutput schema / properties / alarms / items / properties / description / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / alarms / items / properties / description / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / alarms / items / properties / uid / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / alarms / items / properties / uid / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / description / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / description / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / etag / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / etag / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / location / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / location / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / recurrence_id / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / recurrence_id / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / rrule / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / rrule / type
        Added value: +[
        +  "string",
        +  "null"
        +]
  2. 6 tool updatesv0.1.1
    • Changedcreate_event37 fields changed
      • addedInput schema / properties / alarms / description
        Added value: +"Display reminders; defaults to an empty array."
      • addedInput schema / properties / alarms / items / description
        Added value: +"A display reminder attached to an event."
      • addedInput schema / properties / alarms / items / properties / action / description
        Added value: +"Alarm action; only DISPLAY is supported."
      • addedInput schema / properties / alarms / items / properties / description / description
        Added value: +"Optional notification text for this alarm."
      • addedInput schema / properties / alarms / items / properties / minutes_before / description
        Added value: +"Whole minutes before the event start; use 0 for an alarm at start time."
      • addedInput schema / properties / calendar_id / description
        Added value: +"Opaque destination calendar ID returned by list_calendars."
      • addedInput schema / properties / description / description
        Added value: +"Event notes; defaults to null."
      • changedInput schema / properties / end / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "date_time": {
        -        "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:Z|[+-]\\d{2}:\\d{2})$",
        -        "type": "string"
        -      },
        -      "timezone": {
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "date_time",
        -      "timezone"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "date": {
        -        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "date"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "description": "A timed calendar value with an explicit offset and IANA timezone.",
        +    "properties": {
        +      "date_time": {
        +        "description": "ISO 8601 date-time with seconds and an explicit UTC offset or Z.",
        +        "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:Z|[+-]\\d{2}:\\d{2})$",
        +        "type": "string"
        +      },
        +      "timezone": {
        +        "description": "IANA timezone for the local event time; its offset must match date_time.",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "date_time",
        +      "timezone"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "description": "An all-day calendar value.",
        +    "properties": {
        +      "date": {
        +        "description": "Calendar date in YYYY-MM-DD format.",
        +        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "date"
        +    ],
        +    "type": "object"
        +  }
        +]
      • addedInput schema / properties / end / description
        Added value: +"Event end using the same temporal type and timezone as start; an all-day end date is exclusive."
      • addedInput schema / properties / location / description
        Added value: +"Event location; defaults to null."
      • addedInput schema / properties / rrule / description
        Added value: +"RFC 5545 recurrence rule without the RRULE: prefix; defaults to null."
      • changedInput schema / properties / start / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "date_time": {
        -        "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:Z|[+-]\\d{2}:\\d{2})$",
        -        "type": "string"
        -      },
        -      "timezone": {
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "date_time",
        -      "timezone"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "date": {
        -        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "date"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "description": "A timed calendar value with an explicit offset and IANA timezone.",
        +    "properties": {
        +      "date_time": {
        +        "description": "ISO 8601 date-time with seconds and an explicit UTC offset or Z.",
        +        "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:Z|[+-]\\d{2}:\\d{2})$",
        +        "type": "string"
        +      },
        +      "timezone": {
        +        "description": "IANA timezone for the local event time; its offset must match date_time.",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "date_time",
        +      "timezone"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "description": "An all-day calendar value.",
        +    "properties": {
        +      "date": {
        +        "description": "Calendar date in YYYY-MM-DD format.",
        +        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "date"
        +    ],
        +    "type": "object"
        +  }
        +]
      • addedInput schema / properties / start / description
        Added value: +"Event start as a timed date-time or all-day date."
      • addedInput schema / properties / summary / description
        Added value: +"Event title, between 1 and 1,024 characters."
      • addedOutput schema / properties / alarms / description
        Added value: +"Normalized alarms attached to the event."
      • addedOutput schema / properties / alarms / items / description
        Added value: +"A normalized alarm returned by iCloud Calendar."
      • addedOutput schema / properties / alarms / items / properties / action / description
        Added value: +"Stored iCalendar alarm action."
      • addedOutput schema / properties / alarms / items / properties / description / description
        Added value: +"Stored alarm notification text, when available."
      • addedOutput schema / properties / alarms / items / properties / minutes_before / description
        Added value: +"Whole minutes before event start, when representable."
      • addedOutput schema / properties / alarms / items / properties / uid / description
        Added value: +"Stored alarm UID, when available."
      • addedOutput schema / properties / calendar_id / description
        Added value: +"Opaque ID of the containing calendar."
      • addedOutput schema / properties / description / description
        Added value: +"Stored event notes."
      • changedOutput schema / properties / end / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "date_time": {
        -        "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:Z|[+-]\\d{2}:\\d{2})$",
        -        "type": "string"
        -      },
        -      "timezone": {
        -        "maxLength": 4096,
        -        "minLength": 1,
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "date_time",
        -      "timezone"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "date": {
        -        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "date"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "description": "A stored timed calendar value.",
        +    "properties": {
        +      "date_time": {
        +        "description": "Stored ISO 8601 date-time with seconds and an explicit UTC offset or Z.",
        +        "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:Z|[+-]\\d{2}:\\d{2})$",
        +        "type": "string"
        +      },
        +      "timezone": {
        +        "description": "IANA timezone associated with the stored date-time.",
        +        "maxLength": 4096,
        +        "minLength": 1,
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "date_time",
        +      "timezone"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "description": "An all-day calendar value.",
        +    "properties": {
        +      "date": {
        +        "description": "Calendar date in YYYY-MM-DD format.",
        +        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "date"
        +    ],
        +    "type": "object"
        +  }
        +]
      • addedOutput schema / properties / end / description
        Added value: +"Normalized event end."
      • addedOutput schema / properties / etag / description
        Added value: +"Current ETag for optimistic concurrency, when available."
      • addedOutput schema / properties / href / description
        Added value: +"Redacted fingerprint of the CalDAV resource URL."
      • addedOutput schema / properties / location / description
        Added value: +"Stored event location."
      • addedOutput schema / properties / raw_ical / description
        Added value: +"Raw iCalendar resource, included only when explicitly requested."
      • addedOutput schema / properties / recurrence_exception / description
        Added value: +"Whether this result is an overridden recurrence instance."
      • addedOutput schema / properties / recurrence_id / description
        Added value: +"Occurrence identifier for an expanded recurring event."
      • addedOutput schema / properties / recurring / description
        Added value: +"Whether this event belongs to a recurring series."
      • addedOutput schema / properties / resource_id / description
        Added value: +"Opaque event ID accepted by get_event, update_event, and delete_event."
      • addedOutput schema / properties / rrule / description
        Added value: +"Stored RFC 5545 recurrence rule without the RRULE: prefix."
      • changedOutput schema / properties / start / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "date_time": {
        -        "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:Z|[+-]\\d{2}:\\d{2})$",
        -        "type": "string"
        -      },
        -      "timezone": {
        -        "maxLength": 4096,
        -        "minLength": 1,
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "date_time",
        -      "timezone"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "date": {
        -        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "date"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "description": "A stored timed calendar value.",
        +    "properties": {
        +      "date_time": {
        +        "description": "Stored ISO 8601 date-time with seconds and an explicit UTC offset or Z.",
        +        "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:Z|[+-]\\d{2}:\\d{2})$",
        +        "type": "string"
        +      },
        +      "timezone": {
        +        "description": "IANA timezone associated with the stored date-time.",
        +        "maxLength": 4096,
        +        "minLength": 1,
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "date_time",
        +      "timezone"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "description": "An all-day calendar value.",
        +    "properties": {
        +      "date": {
        +        "description": "Calendar date in YYYY-MM-DD format.",
        +        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "date"
        +    ],
        +    "type": "object"
        +  }
        +]
      • addedOutput schema / properties / start / description
        Added value: +"Normalized event start."
      • addedOutput schema / properties / summary / description
        Added value: +"Stored event title."
      • addedOutput schema / properties / uid / description
        Added value: +"Stored iCalendar UID."
    • Changeddelete_event6 fields changed
      • addedInput schema / properties / calendar_id / description
        Added value: +"Opaque calendar ID returned by list_calendars. Provide it together with uid when resource_id is unavailable."
      • addedInput schema / properties / expected_etag / description
        Added value: +"ETag previously returned for the event. When supplied, deletion fails if the event changed since it was read."
      • addedInput schema / properties / resource_id / description
        Added value: +"Opaque event resource ID returned by list_events or get_event. Provide it alone instead of calendar_id and uid."
      • addedInput schema / properties / uid / description
        Added value: +"iCalendar UID of the event. Provide it together with calendar_id when resource_id is unavailable."
      • addedOutput schema / properties / deleted / description
        Added value: +"Confirms that the resource was deleted."
      • addedOutput schema / properties / resource_id / description
        Added value: +"Opaque ID of the deleted event resource."
    • Changedget_event27 fields changed
      • addedInput schema / properties / calendar_id / description
        Added value: +"Opaque calendar ID returned by list_calendars. Provide it together with uid when resource_id is unavailable."
      • addedInput schema / properties / include_raw_ical / description
        Added value: +"Include the raw iCalendar resource for controlled diagnostics; it may contain sensitive calendar data. Defaults to false."
      • addedInput schema / properties / resource_id / description
        Added value: +"Opaque event resource ID returned by list_events or get_event. Provide it alone instead of calendar_id and uid."
      • addedInput schema / properties / uid / description
        Added value: +"iCalendar UID of the event. Provide it together with calendar_id when resource_id is unavailable."
      • addedOutput schema / properties / alarms / description
        Added value: +"Normalized alarms attached to the event."
      • addedOutput schema / properties / alarms / items / description
        Added value: +"A normalized alarm returned by iCloud Calendar."
      • addedOutput schema / properties / alarms / items / properties / action / description
        Added value: +"Stored iCalendar alarm action."
      • addedOutput schema / properties / alarms / items / properties / description / description
        Added value: +"Stored alarm notification text, when available."
      • addedOutput schema / properties / alarms / items / properties / minutes_before / description
        Added value: +"Whole minutes before event start, when representable."
      • addedOutput schema / properties / alarms / items / properties / uid / description
        Added value: +"Stored alarm UID, when available."
      • addedOutput schema / properties / calendar_id / description
        Added value: +"Opaque ID of the containing calendar."
      • addedOutput schema / properties / description / description
        Added value: +"Stored event notes."
      • changedOutput schema / properties / end / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "date_time": {
        -        "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:Z|[+-]\\d{2}:\\d{2})$",
        -        "type": "string"
        -      },
        -      "timezone": {
        -        "maxLength": 4096,
        -        "minLength": 1,
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "date_time",
        -      "timezone"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "date": {
        -        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "date"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "description": "A stored timed calendar value.",
        +    "properties": {
        +      "date_time": {
        +        "description": "Stored ISO 8601 date-time with seconds and an explicit UTC offset or Z.",
        +        "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:Z|[+-]\\d{2}:\\d{2})$",
        +        "type": "string"
        +      },
        +      "timezone": {
        +        "description": "IANA timezone associated with the stored date-time.",
        +        "maxLength": 4096,
        +        "minLength": 1,
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "date_time",
        +      "timezone"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "description": "An all-day calendar value.",
        +    "properties": {
        +      "date": {
        +        "description": "Calendar date in YYYY-MM-DD format.",
        +        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "date"
        +    ],
        +    "type": "object"
        +  }
        +]
      • addedOutput schema / properties / end / description
        Added value: +"Normalized event end."
      • addedOutput schema / properties / etag / description
        Added value: +"Current ETag for optimistic concurrency, when available."
      • addedOutput schema / properties / href / description
        Added value: +"Redacted fingerprint of the CalDAV resource URL."
      • addedOutput schema / properties / location / description
        Added value: +"Stored event location."
      • addedOutput schema / properties / raw_ical / description
        Added value: +"Raw iCalendar resource, included only when explicitly requested."
      • addedOutput schema / properties / recurrence_exception / description
        Added value: +"Whether this result is an overridden recurrence instance."
      • addedOutput schema / properties / recurrence_id / description
        Added value: +"Occurrence identifier for an expanded recurring event."
      • addedOutput schema / properties / recurring / description
        Added value: +"Whether this event belongs to a recurring series."
      • addedOutput schema / properties / resource_id / description
        Added value: +"Opaque event ID accepted by get_event, update_event, and delete_event."
      • addedOutput schema / properties / rrule / description
        Added value: +"Stored RFC 5545 recurrence rule without the RRULE: prefix."
      • changedOutput schema / properties / start / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "date_time": {
        -        "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:Z|[+-]\\d{2}:\\d{2})$",
        -        "type": "string"
        -      },
        -      "timezone": {
        -        "maxLength": 4096,
        -        "minLength": 1,
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "date_time",
        -      "timezone"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "date": {
        -        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "date"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "description": "A stored timed calendar value.",
        +    "properties": {
        +      "date_time": {
        +        "description": "Stored ISO 8601 date-time with seconds and an explicit UTC offset or Z.",
        +        "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:Z|[+-]\\d{2}:\\d{2})$",
        +        "type": "string"
        +      },
        +      "timezone": {
        +        "description": "IANA timezone associated with the stored date-time.",
        +        "maxLength": 4096,
        +        "minLength": 1,
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "date_time",
        +      "timezone"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "description": "An all-day calendar value.",
        +    "properties": {
        +      "date": {
        +        "description": "Calendar date in YYYY-MM-DD format.",
        +        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "date"
        +    ],
        +    "type": "object"
        +  }
        +]
      • addedOutput schema / properties / start / description
        Added value: +"Normalized event start."
      • addedOutput schema / properties / summary / description
        Added value: +"Stored event title."
      • addedOutput schema / properties / uid / description
        Added value: +"Stored iCalendar UID."
    • Changedlist_calendars6 fields changed
      • addedOutput schema / properties / calendars / description
        Added value: +"Calendars available to the configured account."
      • addedOutput schema / properties / calendars / items / properties / calendar_id / description
        Added value: +"Opaque calendar ID used by event tools."
      • addedOutput schema / properties / calendars / items / properties / description / description
        Added value: +"Calendar description."
      • addedOutput schema / properties / calendars / items / properties / display_name / description
        Added value: +"Calendar display name."
      • addedOutput schema / properties / calendars / items / properties / timezone / description
        Added value: +"Calendar timezone, when advertised by the server."
      • addedOutput schema / properties / calendars / items / properties / writable / description
        Added value: +"Best-effort writable status; null means unknown."
    • Changedlist_events31 fields changed
      • addedInput schema / properties / calendar_id / description
        Added value: +"Opaque calendar ID returned by list_calendars."
      • addedInput schema / properties / cursor / description
        Added value: +"Opaque next_cursor from the preceding page. Reuse it with the same calendar, interval, and timezone."
      • addedInput schema / properties / end / description
        Added value: +"Exclusive end of the event search interval; must be after start and no more than 366 days later."
      • addedInput schema / properties / limit / description
        Added value: +"Maximum events to return in this page, from 1 to 500; defaults to 100."
      • addedInput schema / properties / start / description
        Added value: +"Inclusive start of the event search interval as an ISO 8601 instant."
      • addedInput schema / properties / timezone / description
        Added value: +"Fallback IANA timezone used when an event lacks timezone metadata during recurrence expansion."
      • addedOutput schema / properties / events / description
        Added value: +"Events in deterministic chronological order for this page."
      • addedOutput schema / properties / events / items / properties / alarms / description
        Added value: +"Normalized alarms attached to the event."
      • addedOutput schema / properties / events / items / properties / alarms / items / description
        Added value: +"A normalized alarm returned by iCloud Calendar."
      • addedOutput schema / properties / events / items / properties / alarms / items / properties / action / description
        Added value: +"Stored iCalendar alarm action."
      • addedOutput schema / properties / events / items / properties / alarms / items / properties / description / description
        Added value: +"Stored alarm notification text, when available."
      • addedOutput schema / properties / events / items / properties / alarms / items / properties / minutes_before / description
        Added value: +"Whole minutes before event start, when representable."
      • addedOutput schema / properties / events / items / properties / alarms / items / properties / uid / description
        Added value: +"Stored alarm UID, when available."
      • addedOutput schema / properties / events / items / properties / calendar_id / description
        Added value: +"Opaque ID of the containing calendar."
      • addedOutput schema / properties / events / items / properties / description / description
        Added value: +"Stored event notes."
      • changedOutput schema / properties / events / items / properties / end / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "date_time": {
        -        "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:Z|[+-]\\d{2}:\\d{2})$",
        -        "type": "string"
        -      },
        -      "timezone": {
        -        "maxLength": 4096,
        -        "minLength": 1,
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "date_time",
        -      "timezone"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "date": {
        -        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "date"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "description": "A stored timed calendar value.",
        +    "properties": {
        +      "date_time": {
        +        "description": "Stored ISO 8601 date-time with seconds and an explicit UTC offset or Z.",
        +        "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:Z|[+-]\\d{2}:\\d{2})$",
        +        "type": "string"
        +      },
        +      "timezone": {
        +        "description": "IANA timezone associated with the stored date-time.",
        +        "maxLength": 4096,
        +        "minLength": 1,
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "date_time",
        +      "timezone"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "description": "An all-day calendar value.",
        +    "properties": {
        +      "date": {
        +        "description": "Calendar date in YYYY-MM-DD format.",
        +        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "date"
        +    ],
        +    "type": "object"
        +  }
        +]
      • addedOutput schema / properties / events / items / properties / end / description
        Added value: +"Normalized event end."
      • addedOutput schema / properties / events / items / properties / etag / description
        Added value: +"Current ETag for optimistic concurrency, when available."
      • addedOutput schema / properties / events / items / properties / href / description
        Added value: +"Redacted fingerprint of the CalDAV resource URL."
      • addedOutput schema / properties / events / items / properties / location / description
        Added value: +"Stored event location."
      • addedOutput schema / properties / events / items / properties / raw_ical / description
        Added value: +"Raw iCalendar resource, included only when explicitly requested."
      • addedOutput schema / properties / events / items / properties / recurrence_exception / description
        Added value: +"Whether this result is an overridden recurrence instance."
      • addedOutput schema / properties / events / items / properties / recurrence_id / description
        Added value: +"Occurrence identifier for an expanded recurring event."
      • addedOutput schema / properties / events / items / properties / recurring / description
        Added value: +"Whether this event belongs to a recurring series."
      • addedOutput schema / properties / events / items / properties / resource_id / description
        Added value: +"Opaque event ID accepted by get_event, update_event, and delete_event."
      • addedOutput schema / properties / events / items / properties / rrule / description
        Added value: +"Stored RFC 5545 recurrence rule without the RRULE: prefix."
      • changedOutput schema / properties / events / items / properties / start / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "date_time": {
        -        "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:Z|[+-]\\d{2}:\\d{2})$",
        -        "type": "string"
        -      },
        -      "timezone": {
        -        "maxLength": 4096,
        -        "minLength": 1,
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "date_time",
        -      "timezone"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "date": {
        -        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "date"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "description": "A stored timed calendar value.",
        +    "properties": {
        +      "date_time": {
        +        "description": "Stored ISO 8601 date-time with seconds and an explicit UTC offset or Z.",
        +        "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:Z|[+-]\\d{2}:\\d{2})$",
        +        "type": "string"
        +      },
        +      "timezone": {
        +        "description": "IANA timezone associated with the stored date-time.",
        +        "maxLength": 4096,
        +        "minLength": 1,
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "date_time",
        +      "timezone"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "description": "An all-day calendar value.",
        +    "properties": {
        +      "date": {
        +        "description": "Calendar date in YYYY-MM-DD format.",
        +        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "date"
        +    ],
        +    "type": "object"
        +  }
        +]
      • addedOutput schema / properties / events / items / properties / start / description
        Added value: +"Normalized event start."
      • addedOutput schema / properties / events / items / properties / summary / description
        Added value: +"Stored event title."
      • addedOutput schema / properties / events / items / properties / uid / description
        Added value: +"Stored iCalendar UID."
      • addedOutput schema / properties / next_cursor / description
        Added value: +"Opaque cursor for the next page, or null when this is the last page."
    • Changedupdate_event41 fields changed
      • addedInput schema / properties / calendar_id / description
        Added value: +"Opaque calendar ID returned by list_calendars. Provide it together with uid when resource_id is unavailable."
      • addedInput schema / properties / expected_etag / description
        Added value: +"ETag previously returned for the event. When supplied, the update fails if the event changed since it was read."
      • addedInput schema / properties / patch / description
        Added value: +"Fields to replace. Omitted fields are preserved; null clears nullable values and an empty alarms array removes all alarms."
      • addedInput schema / properties / patch / properties / alarms / description
        Added value: +"Replacement alarm set; use an empty array to remove all alarms."
      • addedInput schema / properties / patch / properties / alarms / items / description
        Added value: +"A display reminder attached to an event."
      • addedInput schema / properties / patch / properties / alarms / items / properties / action / description
        Added value: +"Alarm action; only DISPLAY is supported."
      • addedInput schema / properties / patch / properties / alarms / items / properties / description / description
        Added value: +"Optional notification text for this alarm."
      • addedInput schema / properties / patch / properties / alarms / items / properties / minutes_before / description
        Added value: +"Whole minutes before the event start; use 0 for an alarm at start time."
      • addedInput schema / properties / patch / properties / description / description
        Added value: +"Replacement notes; use null to clear the description."
      • changedInput schema / properties / patch / properties / end / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "date_time": {
        -        "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:Z|[+-]\\d{2}:\\d{2})$",
        -        "type": "string"
        -      },
        -      "timezone": {
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "date_time",
        -      "timezone"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "date": {
        -        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "date"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "description": "A timed calendar value with an explicit offset and IANA timezone.",
        +    "properties": {
        +      "date_time": {
        +        "description": "ISO 8601 date-time with seconds and an explicit UTC offset or Z.",
        +        "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:Z|[+-]\\d{2}:\\d{2})$",
        +        "type": "string"
        +      },
        +      "timezone": {
        +        "description": "IANA timezone for the local event time; its offset must match date_time.",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "date_time",
        +      "timezone"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "description": "An all-day calendar value.",
        +    "properties": {
        +      "date": {
        +        "description": "Calendar date in YYYY-MM-DD format.",
        +        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "date"
        +    ],
        +    "type": "object"
        +  }
        +]
      • addedInput schema / properties / patch / properties / end / description
        Added value: +"Replacement end; provide together with start. An all-day end date is exclusive."
      • addedInput schema / properties / patch / properties / location / description
        Added value: +"Replacement location; use null to clear it."
      • addedInput schema / properties / patch / properties / rrule / description
        Added value: +"Replacement RFC 5545 recurrence rule without RRULE:, or null to make the event non-recurring."
      • changedInput schema / properties / patch / properties / start / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "date_time": {
        -        "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:Z|[+-]\\d{2}:\\d{2})$",
        -        "type": "string"
        -      },
        -      "timezone": {
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "date_time",
        -      "timezone"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "date": {
        -        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "date"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "description": "A timed calendar value with an explicit offset and IANA timezone.",
        +    "properties": {
        +      "date_time": {
        +        "description": "ISO 8601 date-time with seconds and an explicit UTC offset or Z.",
        +        "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:Z|[+-]\\d{2}:\\d{2})$",
        +        "type": "string"
        +      },
        +      "timezone": {
        +        "description": "IANA timezone for the local event time; its offset must match date_time.",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "date_time",
        +      "timezone"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "description": "An all-day calendar value.",
        +    "properties": {
        +      "date": {
        +        "description": "Calendar date in YYYY-MM-DD format.",
        +        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "date"
        +    ],
        +    "type": "object"
        +  }
        +]
      • addedInput schema / properties / patch / properties / start / description
        Added value: +"Replacement start; provide together with end."
      • addedInput schema / properties / patch / properties / summary / description
        Added value: +"Replacement event title."
      • addedInput schema / properties / resource_id / description
        Added value: +"Opaque event resource ID returned by list_events or get_event. Provide it alone instead of calendar_id and uid."
      • addedInput schema / properties / uid / description
        Added value: +"iCalendar UID of the event. Provide it together with calendar_id when resource_id is unavailable."
      • addedOutput schema / properties / alarms / description
        Added value: +"Normalized alarms attached to the event."
      • addedOutput schema / properties / alarms / items / description
        Added value: +"A normalized alarm returned by iCloud Calendar."
      • addedOutput schema / properties / alarms / items / properties / action / description
        Added value: +"Stored iCalendar alarm action."
      • addedOutput schema / properties / alarms / items / properties / description / description
        Added value: +"Stored alarm notification text, when available."
      • addedOutput schema / properties / alarms / items / properties / minutes_before / description
        Added value: +"Whole minutes before event start, when representable."
      • addedOutput schema / properties / alarms / items / properties / uid / description
        Added value: +"Stored alarm UID, when available."
      • addedOutput schema / properties / calendar_id / description
        Added value: +"Opaque ID of the containing calendar."
      • addedOutput schema / properties / description / description
        Added value: +"Stored event notes."
      • changedOutput schema / properties / end / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "date_time": {
        -        "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:Z|[+-]\\d{2}:\\d{2})$",
        -        "type": "string"
        -      },
        -      "timezone": {
        -        "maxLength": 4096,
        -        "minLength": 1,
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "date_time",
        -      "timezone"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "date": {
        -        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "date"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "description": "A stored timed calendar value.",
        +    "properties": {
        +      "date_time": {
        +        "description": "Stored ISO 8601 date-time with seconds and an explicit UTC offset or Z.",
        +        "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:Z|[+-]\\d{2}:\\d{2})$",
        +        "type": "string"
        +      },
        +      "timezone": {
        +        "description": "IANA timezone associated with the stored date-time.",
        +        "maxLength": 4096,
        +        "minLength": 1,
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "date_time",
        +      "timezone"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "description": "An all-day calendar value.",
        +    "properties": {
        +      "date": {
        +        "description": "Calendar date in YYYY-MM-DD format.",
        +        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "date"
        +    ],
        +    "type": "object"
        +  }
        +]
      • addedOutput schema / properties / end / description
        Added value: +"Normalized event end."
      • addedOutput schema / properties / etag / description
        Added value: +"Current ETag for optimistic concurrency, when available."
      • addedOutput schema / properties / href / description
        Added value: +"Redacted fingerprint of the CalDAV resource URL."
      • addedOutput schema / properties / location / description
        Added value: +"Stored event location."
      • addedOutput schema / properties / raw_ical / description
        Added value: +"Raw iCalendar resource, included only when explicitly requested."
      • addedOutput schema / properties / recurrence_exception / description
        Added value: +"Whether this result is an overridden recurrence instance."
      • addedOutput schema / properties / recurrence_id / description
        Added value: +"Occurrence identifier for an expanded recurring event."
      • addedOutput schema / properties / recurring / description
        Added value: +"Whether this event belongs to a recurring series."
      • addedOutput schema / properties / resource_id / description
        Added value: +"Opaque event ID accepted by get_event, update_event, and delete_event."
      • addedOutput schema / properties / rrule / description
        Added value: +"Stored RFC 5545 recurrence rule without the RRULE: prefix."
      • changedOutput schema / properties / start / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "date_time": {
        -        "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:Z|[+-]\\d{2}:\\d{2})$",
        -        "type": "string"
        -      },
        -      "timezone": {
        -        "maxLength": 4096,
        -        "minLength": 1,
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "date_time",
        -      "timezone"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "date": {
        -        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "date"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "description": "A stored timed calendar value.",
        +    "properties": {
        +      "date_time": {
        +        "description": "Stored ISO 8601 date-time with seconds and an explicit UTC offset or Z.",
        +        "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:Z|[+-]\\d{2}:\\d{2})$",
        +        "type": "string"
        +      },
        +      "timezone": {
        +        "description": "IANA timezone associated with the stored date-time.",
        +        "maxLength": 4096,
        +        "minLength": 1,
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "date_time",
        +      "timezone"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "description": "An all-day calendar value.",
        +    "properties": {
        +      "date": {
        +        "description": "Calendar date in YYYY-MM-DD format.",
        +        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "date"
        +    ],
        +    "type": "object"
        +  }
        +]
      • addedOutput schema / properties / start / description
        Added value: +"Normalized event start."
      • addedOutput schema / properties / summary / description
        Added value: +"Stored event title."
      • addedOutput schema / properties / uid / description
        Added value: +"Stored iCalendar UID."
  3. 6 tool updatesv0.1.0
    • First observedcreate_event
    • First observeddelete_event
    • First observedget_event
    • First observedlist_calendars
    • First observedlist_events
    • First observedupdate_event

TDQS

A4.7/5.0
Disambiguation5/5

Each tool has a clear, distinct purpose: calendar discovery, range listing, single-event retrieval, create, update, and delete. get_event and list_events are explicitly differentiated as single-item lookup versus range search.

Naming Consistency5/5

All tool names follow a consistent verb_noun snake_case pattern, with appropriate pluralization for list operations. This makes the tool set predictable and easy to navigate.

Tool Count5/5

Six tools is well-scoped for a CalDAV server: calendar discovery plus full event CRUD. There is no bloat and no unnecessary overlap.

Completeness5/5

The tool set covers the full event lifecycle: list, get, create, update, and delete, with calendar discovery and handling for recurring series and ETags. No obvious gaps exist for typical calendar event workflows.

Maintenance

ActivityMaintained
ResponsivenessWithin a week

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/lukegskw/caldav-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server