CalDAV MCP Server
CalDAV MCP Server
CalDAV MCP Server ist ein Model Context Protocol Server zur Verwaltung von iCloud-Kalenderereignissen, einschließlich nativer Unterstützung für mehrere VALARM-Erinnerungen an einem Ereignis.
iCloud-Kalender ist der einzige Anbieter, der in der ersten Version offiziell unterstützt und manuell validiert wird. Der Server funktioniert mit jedem MCP-Client, der stdio oder Streamable HTTP unterstützt.
Dieses unabhängige Projekt ist nicht mit Apple Inc. verbunden, von ihr autorisiert, gesponsert oder genehmigt. Apple und iCloud sind Marken ihrer jeweiligen Eigentümer.
Navigation
Related MCP server: DAV MCP Server
Über
Der Server verbindet ein konfiguriertes Konto über CalDAV mit iCloud. Er erkennt die Kalender des Kontos und stellt normalisierte Lese- und Schreiboperationen über MCP bereit.
Updates bewahren die vollständige iCalendar-Ressource, einschließlich unbekannter Eigenschaften, Apple-Erweiterungen, VTIMEZONE, Ausnahmen bei Serien und Alarme, die in einem Patch ausgelassen wurden. Schreibvorgänge verwenden undurchsichtige Ressourcen-IDs und ETags, anstatt anzunehmen, dass ein CalDAV-Dateiname mit einer Ereignis-UID übereinstimmt.
Kalenderressourcen werden im Speicher verarbeitet. Der Server hat keine Telemetrie und keine Anwendungsdatenbank, und rohes iCalendar wird nur auf ausdrückliche Anfrage zurückgegeben.
Funktionen
Erkennt Kalender, die für das konfigurierte iCloud-Konto verfügbar sind.
Listet Ereignisse in halboffenen Zeiträumen auf und expandiert wiederkehrende Vorkommen.
Erstellt terminierte, ganztägige und wiederkehrende Ereignisse.
Unterstützt null, ein oder mehrere Anzeigealarme pro Ereignis.
Gibt die Apple-Alarmerweiterungen aus, die von iCloud-Kalender erwartet werden.
Liest Ereignisse über undurchsichtige Ressourcen-ID oder über Kalender-ID und UID.
Wendet Teilaktualisierungen an, während ausgelassene und unbekannte iCalendar-Daten erhalten bleiben.
Verwendet ETags für optimistische Nebenläufigkeit bei Aktualisierungen und Löschungen.
Lehnt isolierte Änderungen an Serienvorkommen ab, anstatt die gesamte Serie zu ändern.
Schwärzt Anmeldedaten, rohen Kalenderinhalt und CalDAV-Pfade aus Protokollen und Fehlern.
Läuft als Nicht-Root-Container mit einer schreibgeschützten Root-Dateisystemkonfiguration.
Unterstützt
stdio- und Streamable-HTTP-MCP-Transports.
MCP-Tools
list_calendars
Listet die für das konfigurierte Konto erkannten Kalender auf. Jedes Ergebnis enthält eine undurchsichtige calendar_id, Anzeigename, Beschreibung, Zeitzone und einen Best-Effort-Schreibstatus.
list_events
Listet Ereignisse in einem halboffenen Intervall auf und expandiert wiederkehrende Vorkommen. Der maximale Bereich beträgt 366 Tage, die Standardseitengröße ist 100, und die maximale Seitengröße ist 500. Ergebnisse verwenden eine deterministische chronologische Reihenfolge. Paginierungscursor sind undurchsichtig und stellen keinen Snapshot dar, wenn Ereignisse während der Durchquerung geändert werden.
Beispieleingabe:
{
"calendar_id": "opaque-calendar-id",
"start": "2026-09-01T00:00:00Z",
"end": "2026-10-01T00:00:00Z",
"timezone": "Europe/Berlin",
"limit": 100
}get_event
Liest ein Ereignis über resource_id oder über ein Paar aus calendar_id und UID. Rohes iCalendar ist standardmäßig ausgeschlossen und kann mit include_raw_ical: true für kontrollierte Diagnosen angefordert werden.
create_event
Erstellt ein Ereignis und liest die vom Server gespeicherte Darstellung zurück.
Terminiertes Ereignis mit zwei Alarmen:
{
"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
}Ganztägiges Ereignis mit einem exklusiven Enddatum:
{
"calendar_id": "opaque-calendar-id",
"summary": "Trip",
"start": { "date": "2026-09-06" },
"end": { "date": "2026-09-08" },
"alarms": []
}Wiederkehrende Ereignisse akzeptieren eine RFC-5545-Regel ohne das Präfix RRULE::
{
"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
Patched ein Ereignis oder eine vollständige wiederkehrende Serie. Ausgelassene Felder bleiben erhalten, null entfernt ein nullable Feld, und alarms: [] entfernt alle Alarme. Ein optionales expected_etag verhindert das Überschreiben einer neueren Serverversion.
delete_event
Löscht ein Ereignis oder eine vollständige wiederkehrende Serie, optional mit einem beobachteten ETag. Das Löschen eines einzelnen expandierten Vorkommens wird in der aktuellen Version nicht unterstützt.
Technologie-Stack
TypeScript mit strengen Projektregeln
Installation
Voraussetzungen
Ein iCloud-Konto mit aktiviertem Kalender.
Zwei-Faktor-Authentifizierung für das Apple-Konto aktiviert.
Docker und Docker Compose für die Containerbereitstellung oder Node.js 24+ und pnpm für eine lokale Installation.
Docker Compose
Die empfohlene Installation verwendet das veröffentlichte Multi-Architektur-Image:
ghcr.io/lukegskw/caldav-mcp:latestLaden Sie das Compose-Beispiel herunter:
curl -O https://raw.githubusercontent.com/lukegskw/caldav-mcp/main/compose.example.yamlGeben Sie die Apple-Konto-E-Mail und das App-spezifische Passwort an und starten Sie dann den Dienst:
export CALDAV_USERNAME='user@example.com'
export CALDAV_PASSWORD='xxxx-xxxx-xxxx-xxxx'
docker compose -f compose.example.yaml up -dUm einen anderen Host-Port zu veröffentlichen, setzen Sie:
export CALDAV_MCP_PUBLISHED_PORT=18100
docker compose -f compose.example.yaml up -dDas latest-Tag folgt dem neuesten erfolgreichen Build aus dem Standard-Branch. Für eine kontrollierte Bereitstellung oder ein Rollback ersetzen Sie es in der Compose-Datei durch eine veröffentlichte Version oder ein unveränderliches sha-*-Tag.
Der Streamable-HTTP-Endpunkt ist verfügbar unter:
http://<host>:8100/mcpDer Host-Port kann sich ändern, ohne Port 8100 im Container zu ändern. Es ist kein persistentes Volume erforderlich; Kalenderdaten bleiben in iCloud.
Docker run
Die gleiche gehärtete Container-Konfiguration kann direkt gestartet werden:
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:latestContainer aus dem Quellcode erstellen
Das lokale Erstellen ist optional. Bevorzugen Sie das veröffentlichte Image, es sei denn, Sie müssen den Container-Build ändern oder prüfen.
git clone https://github.com/lukegskw/caldav-mcp.git
cd caldav-mcp
docker buildx build --load -t caldav-mcp:local .Lokale Node.js-Installation
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 stdioIm stdio-Modus ist stdout ausschließlich für MCP-Nachrichten reserviert. Um Streamable HTTP lokal auszuführen:
CALDAV_MCP_TRANSPORT=streamable-http pnpm startKonfiguration
Alle Einstellungen verwenden das Präfix CALDAV_ oder CALDAV_MCP_.
Variable | Erforderlich | Standard | Beschreibung |
| Nein |
| Anbieterrichtlinie. iCloud ist das unterstützte Profil. |
| Nein |
| CalDAV-Erkennungs-URL. |
| Ja | Keine | Apple-Konto-E-Mail. |
| Ja | Keine | App-spezifisches Passwort, nicht das Kontopasswort. |
| Nein |
|
|
| Nein |
| HTTP-Bind-Adresse. |
| Nein |
| HTTP-Listening-Port. |
| Nein |
| Anwendungsprotokollstufe. |
| Nein |
| CalDAV-Anfrage-Timeout. |
Der Kern behält eine experimentelle generic-Anbieterrichtlinie und eine konfigurierbare URL bei, um Apple-Erweiterungen von der gemeinsamen iCalendar-Implementierung zu isolieren. Derzeit wird keine Kompatibilität mit anderen Anbietern beansprucht.
Geheimnisse müssen über die Bereitstellungsplattform oder die Umgebung bereitgestellt werden. Committen Sie niemals .env, übergeben Sie Anmeldedaten nicht als MCP-Tool-Argumente und nehmen Sie sie nicht in Diagnoseberichte auf.
MCP-Client-Einrichtung
Für jeden MCP-Client, der Streamable-HTTP-Serverdefinitionen akzeptiert, konfigurieren Sie die URL:
mcp_servers:
caldav:
url: http://<host>:8100/mcpWenn der Client das Compose-Netzwerk teilt, verwenden Sie den Dienstnamen und den internen Port:
mcp_servers:
caldav:
url: http://caldav-mcp:8100/mcpFür Clients, die lokale stdio-Server starten, konfigurieren Sie den Befehl, um node /absolute/path/to/caldav-mcp/dist/main.js mit den erforderlichen Umgebungsvariablen auszuführen.
Claude Desktop (Docker, stdio)
Claude Desktop startet lokale stdio-Server als Unterprozesse. Das Ausführen des veröffentlichten Containers auf diese Weise hält das App-spezifische Passwort auf dem Client-Computer und öffnet keinen Netzwerkport, was den Transportrichtlinien in Einschränkungen entspricht.
Fügen Sie den Server zu claude_desktop_config.json hinzu:
{
"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 ist erforderlich. Ohne angehängtes stdin kann der Client nicht mit dem Container über MCP kommunizieren. --rm entfernt den Container, sobald der Client ihn stoppt.
Stellen Sie Anmeldedaten über --env-file bereit, nicht über -e. Argumente, die an docker run übergeben werden, sind im Host-Prozessverzeichnis sichtbar; der Inhalt einer Env-Datei ist es nicht. Die Datei enthält die in Konfiguration beschriebenen Variablen:
CALDAV_USERNAME=user@example.com
CALDAV_PASSWORD=xxxx-xxxx-xxxx-xxxxPinnen Sie das Image per Digest anstelle von latest, damit ein Neustart des Clients nicht stillschweigend eine andere Version startet:
docker pull ghcr.io/lukegskw/caldav-mcp:latest
docker images --digests ghcr.io/lukegskw/caldav-mcpStarten Sie Claude Desktop nach dem Bearbeiten der Konfigurationsdatei vollständig neu.
Windows
Erstellen und finden Sie die Konfigurationsdatei über Einstellungen -> Entwickler -> Konfiguration bearbeiten. Gehen Sie nicht von einem Pfad aus. Wenn Claude Desktop aus dem Microsoft Store installiert ist, leitet Windows %APPDATA%\Claude in den Paketcontainer um, und die Datei befindet sich unter:
%LOCALAPPDATA%\Packages\Claude_<package-id>\LocalCache\Roaming\Claude\claude_desktop_config.jsonIn diesem Fall meldet dir %APPDATA%\Claude nichts. Serverprotokolle werden neben der Konfigurationsdatei in logs\mcp-server-<server-name>.log geschrieben.
Verwenden Sie den absoluten Pfad zu docker.exe, da PATH im Paketcontainer nicht zuverlässig ist. where docker gibt ihn aus, typischerweise C:\Program Files\Docker\Docker\resources\bin\docker.exe. Backslashes müssen in JSON maskiert werden.
Die Konfigurationsformate unterscheiden sich zwischen MCP-Clients. Konsultieren Sie die Dokumentation des Clients für das genaue Schema und laden Sie es neu oder starten Sie es neu, nachdem Sie die Serverdefinition geändert haben.
Verifizierung
Überprüfen Sie den Containerstatus und die Protokolle:
docker compose -f compose.example.yaml ps
docker compose -f compose.example.yaml logs caldav-mcpDer Container sollte healthy melden. Der TCP-Healthcheck validiert den Serverprozess, nicht die iCloud-Anmeldedaten.
Führen Sie die Repository-Verifizierungssuite aus:
pnpm install --frozen-lockfile
pnpm format:check
pnpm lint
pnpm typecheck
pnpm test:unit
pnpm test:integration
pnpm buildVerbinden Sie sich schließlich mit einem MCP-Client und bestätigen Sie, dass alle sechs Tools aufgelistet sind. Vor einer Veröffentlichung führen Sie die dedizierte iCloud-Manualvalidierung gegen einen Testkalender durch.
Einschränkungen
Pro Serverprozess oder Container ist ein iCloud-Konto konfiguriert.
Der Streamable-HTTP-Endpunkt hat in der aktuellen Version keine Authentifizierung. Beschränken Sie ihn auf ein vertrauenswürdiges LAN, VPN oder privates Containernetzwerk; setzen Sie ihn nicht direkt dem Internet aus.
Einzelne Serienvorkommen sind schreibgeschützt. Das Aktualisieren oder Löschen der vollständigen Serie wird unterstützt.
Es werden nur
ACTION:DISPLAY-Alarme erstellt.Einzelne iCalendar-Ressourcen sind auf 5 MiB begrenzt.
Ereignislistenbereiche sind auf 366 Tage und Seiten auf 500 Ergebnisse begrenzt.
Ereignisse dürfen höchstens 20 Alarme enthalten.
Teilnehmerscheduling liegt außerhalb des aktuellen Umfangs.
Andere Anbieter als iCloud werden nicht offiziell unterstützt.
Siehe Fehlerbehebung für Hinweise zu Erkennung, Authentifizierung, ETag und Apple-Erweiterungen. Lesen Sie SECURITY.md, bevor Sie ein Sicherheitsproblem melden oder Diagnosen anhängen.
Mitwirken
Beiträge sind willkommen. Bevor Sie einen Pull-Request öffnen:
pnpm install --frozen-lockfile
pnpm format:check
pnpm lint
pnpm typecheck
pnpm test
pnpm build
docker buildx build --load -t caldav-mcp:test .Änderungen an CalDAV-Schreibvorgängen oder iCalendar-Serialisierung müssen ETag-Prüfungen, undurchsichtige Ressourcengrenzen, unbekannte Eigenschaften, Serienausnahmen und in Patches ausgelassene Alarme bewahren. TypeScript-Änderungen müssen weiterhin die Regeln in .codex/rules/typescript.md erfüllen.
Lizenz
MIT. Siehe LICENSE.
Available Tools
6 toolscreate_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.
| Name | Required | Description | Default |
|---|---|---|---|
| end | Yes | Event end using the same temporal type and timezone as start; an all-day end date is exclusive. | |
| rrule | No | RFC 5545 recurrence rule without the RRULE: prefix; defaults to null. | |
| start | Yes | Event start as a timed date-time or all-day date. | |
| alarms | No | Display reminders; defaults to an empty array. | |
| summary | Yes | Event title, between 1 and 1,024 characters. | |
| location | No | Event location; defaults to null. | |
| calendar_id | Yes | Opaque destination calendar ID returned by list_calendars. | |
| description | No | Event notes; defaults to null. |
Output Schema
| Name | Required | Description |
|---|---|---|
| end | Yes | Normalized event end. |
| uid | Yes | Stored iCalendar UID. |
| etag | Yes | Current ETag for optimistic concurrency, when available. |
| href | Yes | Redacted fingerprint of the CalDAV resource URL. |
| rrule | Yes | Stored RFC 5545 recurrence rule without the RRULE: prefix. |
| start | Yes | Normalized event start. |
| alarms | Yes | Normalized alarms attached to the event. |
| summary | Yes | Stored event title. |
| location | Yes | Stored event location. |
| raw_ical | No | Raw iCalendar resource, included only when explicitly requested. |
| recurring | Yes | Whether this event belongs to a recurring series. |
| calendar_id | Yes | Opaque ID of the containing calendar. |
| description | Yes | Stored event notes. |
| resource_id | Yes | Opaque event ID accepted by get_event, update_event, and delete_event. |
| recurrence_id | Yes | Occurrence identifier for an expanded recurring event. |
| recurrence_exception | Yes | Whether this result is an overridden recurrence instance. |
TDQS
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.
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.
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.
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.
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.
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 eventADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| uid | No | iCalendar UID of the event. Provide it together with calendar_id when resource_id is unavailable. | |
| calendar_id | No | Opaque calendar ID returned by list_calendars. Provide it together with uid when resource_id is unavailable. | |
| resource_id | No | Opaque event resource ID returned by list_events or get_event. Provide it alone instead of calendar_id and uid. | |
| expected_etag | No | ETag previously returned for the event. When supplied, deletion fails if the event changed since it was read. |
Output Schema
| Name | Required | Description |
|---|---|---|
| deleted | Yes | Confirms that the resource was deleted. |
| resource_id | Yes | Opaque ID of the deleted event resource. |
TDQS
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.
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.
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.
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.
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.
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 eventARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| uid | No | iCalendar UID of the event. Provide it together with calendar_id when resource_id is unavailable. | |
| calendar_id | No | Opaque calendar ID returned by list_calendars. Provide it together with uid when resource_id is unavailable. | |
| resource_id | No | Opaque event resource ID returned by list_events or get_event. Provide it alone instead of calendar_id and uid. | |
| include_raw_ical | No | Include the raw iCalendar resource for controlled diagnostics; it may contain sensitive calendar data. Defaults to false. |
Output Schema
| Name | Required | Description |
|---|---|---|
| end | Yes | Normalized event end. |
| uid | Yes | Stored iCalendar UID. |
| etag | Yes | Current ETag for optimistic concurrency, when available. |
| href | Yes | Redacted fingerprint of the CalDAV resource URL. |
| rrule | Yes | Stored RFC 5545 recurrence rule without the RRULE: prefix. |
| start | Yes | Normalized event start. |
| alarms | Yes | Normalized alarms attached to the event. |
| summary | Yes | Stored event title. |
| location | Yes | Stored event location. |
| raw_ical | No | Raw iCalendar resource, included only when explicitly requested. |
| recurring | Yes | Whether this event belongs to a recurring series. |
| calendar_id | Yes | Opaque ID of the containing calendar. |
| description | Yes | Stored event notes. |
| resource_id | Yes | Opaque event ID accepted by get_event, update_event, and delete_event. |
| recurrence_id | Yes | Occurrence identifier for an expanded recurring event. |
| recurrence_exception | Yes | Whether this result is an overridden recurrence instance. |
TDQS
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.
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.
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.
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.
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.
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 calendarsARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| calendars | Yes | Calendars available to the configured account. |
TDQS
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.
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.
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.
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.
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.
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 eventsARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| end | Yes | Exclusive end of the event search interval; must be after start and no more than 366 days later. | |
| limit | No | Maximum events to return in this page, from 1 to 500; defaults to 100. | |
| start | Yes | Inclusive start of the event search interval as an ISO 8601 instant. | |
| cursor | No | Opaque next_cursor from the preceding page. Reuse it with the same calendar, interval, and timezone. | |
| timezone | No | Fallback IANA timezone used when an event lacks timezone metadata during recurrence expansion. | |
| calendar_id | Yes | Opaque calendar ID returned by list_calendars. |
Output Schema
| Name | Required | Description |
|---|---|---|
| events | Yes | Events in deterministic chronological order for this page. |
| next_cursor | Yes | Opaque cursor for the next page, or null when this is the last page. |
TDQS
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.
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.
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.
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.
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.
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 eventADestructive
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.
| Name | Required | Description | Default |
|---|---|---|---|
| uid | No | iCalendar UID of the event. Provide it together with calendar_id when resource_id is unavailable. | |
| patch | Yes | Fields to replace. Omitted fields are preserved; null clears nullable values and an empty alarms array removes all alarms. | |
| calendar_id | No | Opaque calendar ID returned by list_calendars. Provide it together with uid when resource_id is unavailable. | |
| resource_id | No | Opaque event resource ID returned by list_events or get_event. Provide it alone instead of calendar_id and uid. | |
| expected_etag | No | ETag previously returned for the event. When supplied, the update fails if the event changed since it was read. |
Output Schema
| Name | Required | Description |
|---|---|---|
| end | Yes | Normalized event end. |
| uid | Yes | Stored iCalendar UID. |
| etag | Yes | Current ETag for optimistic concurrency, when available. |
| href | Yes | Redacted fingerprint of the CalDAV resource URL. |
| rrule | Yes | Stored RFC 5545 recurrence rule without the RRULE: prefix. |
| start | Yes | Normalized event start. |
| alarms | Yes | Normalized alarms attached to the event. |
| summary | Yes | Stored event title. |
| location | Yes | Stored event location. |
| raw_ical | No | Raw iCalendar resource, included only when explicitly requested. |
| recurring | Yes | Whether this event belongs to a recurring series. |
| calendar_id | Yes | Opaque ID of the containing calendar. |
| description | Yes | Stored event notes. |
| resource_id | Yes | Opaque event ID accepted by get_event, update_event, and delete_event. |
| recurrence_id | Yes | Occurrence identifier for an expanded recurring event. |
| recurrence_exception | Yes | Whether this result is an overridden recurrence instance. |
TDQS
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.
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.
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.
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.
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.
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.
5 tool updates
v0.1.7- Changed
create_event14 fields changed- removed
Output schema / properties / alarms / items / properties / description / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / alarms / items / properties / description / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / alarms / items / properties / uid / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / alarms / items / properties / uid / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / description / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / description / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / etag / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / etag / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / location / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / location / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / recurrence_id / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / recurrence_id / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / rrule / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / rrule / typeAdded value: +[ + "string", + "null" +]
- Changed
get_event14 fields changed- removed
Output schema / properties / alarms / items / properties / description / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / alarms / items / properties / description / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / alarms / items / properties / uid / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / alarms / items / properties / uid / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / description / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / description / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / etag / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / etag / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / location / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / location / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / recurrence_id / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / recurrence_id / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / rrule / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / rrule / typeAdded value: +[ + "string", + "null" +]
- Changed
list_calendars6 fields changed- removed
Output schema / properties / calendars / items / properties / description / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / calendars / items / properties / description / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / calendars / items / properties / timezone / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / calendars / items / properties / timezone / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / calendars / items / properties / writable / anyOfRemoved value: -[ - { - "type": "boolean" - }, - { - "type": "null" - } -] - added
Output schema / properties / calendars / items / properties / writable / typeAdded value: +[ + "boolean", + "null" +]
- Changed
list_events18 fields changed- changed
Input schema / properties / end / patternPrevious 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)))$" - changed
Input schema / properties / start / patternPrevious 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)))$" - removed
Output schema / properties / events / items / properties / alarms / items / properties / description / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / events / items / properties / alarms / items / properties / description / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / events / items / properties / alarms / items / properties / uid / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / events / items / properties / alarms / items / properties / uid / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / events / items / properties / description / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / events / items / properties / description / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / events / items / properties / etag / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / events / items / properties / etag / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / events / items / properties / location / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / events / items / properties / location / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / events / items / properties / recurrence_id / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / events / items / properties / recurrence_id / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / events / items / properties / rrule / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / events / items / properties / rrule / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / next_cursor / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / next_cursor / typeAdded value: +[ + "string", + "null" +]
- Changed
update_event14 fields changed- removed
Output schema / properties / alarms / items / properties / description / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / alarms / items / properties / description / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / alarms / items / properties / uid / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / alarms / items / properties / uid / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / description / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / description / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / etag / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / etag / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / location / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / location / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / recurrence_id / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / recurrence_id / typeAdded value: +[ + "string", + "null" +] - removed
Output schema / properties / rrule / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / rrule / typeAdded value: +[ + "string", + "null" +]
6 tool updates
v0.1.1- Changed
create_event37 fields changed- added
Input schema / properties / alarms / descriptionAdded value: +"Display reminders; defaults to an empty array." - added
Input schema / properties / alarms / items / descriptionAdded value: +"A display reminder attached to an event." - added
Input schema / properties / alarms / items / properties / action / descriptionAdded value: +"Alarm action; only DISPLAY is supported." - added
Input schema / properties / alarms / items / properties / description / descriptionAdded value: +"Optional notification text for this alarm." - added
Input schema / properties / alarms / items / properties / minutes_before / descriptionAdded value: +"Whole minutes before the event start; use 0 for an alarm at start time." - added
Input schema / properties / calendar_id / descriptionAdded value: +"Opaque destination calendar ID returned by list_calendars." - added
Input schema / properties / description / descriptionAdded value: +"Event notes; defaults to null." - changed
Input schema / properties / end / anyOfPrevious 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" + } +] - added
Input schema / properties / end / descriptionAdded value: +"Event end using the same temporal type and timezone as start; an all-day end date is exclusive." - added
Input schema / properties / location / descriptionAdded value: +"Event location; defaults to null." - added
Input schema / properties / rrule / descriptionAdded value: +"RFC 5545 recurrence rule without the RRULE: prefix; defaults to null." - changed
Input schema / properties / start / anyOfPrevious 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" + } +] - added
Input schema / properties / start / descriptionAdded value: +"Event start as a timed date-time or all-day date." - added
Input schema / properties / summary / descriptionAdded value: +"Event title, between 1 and 1,024 characters." - added
Output schema / properties / alarms / descriptionAdded value: +"Normalized alarms attached to the event." - added
Output schema / properties / alarms / items / descriptionAdded value: +"A normalized alarm returned by iCloud Calendar." - added
Output schema / properties / alarms / items / properties / action / descriptionAdded value: +"Stored iCalendar alarm action." - added
Output schema / properties / alarms / items / properties / description / descriptionAdded value: +"Stored alarm notification text, when available." - added
Output schema / properties / alarms / items / properties / minutes_before / descriptionAdded value: +"Whole minutes before event start, when representable." - added
Output schema / properties / alarms / items / properties / uid / descriptionAdded value: +"Stored alarm UID, when available." - added
Output schema / properties / calendar_id / descriptionAdded value: +"Opaque ID of the containing calendar." - added
Output schema / properties / description / descriptionAdded value: +"Stored event notes." - changed
Output schema / properties / end / anyOfPrevious 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" + } +] - added
Output schema / properties / end / descriptionAdded value: +"Normalized event end." - added
Output schema / properties / etag / descriptionAdded value: +"Current ETag for optimistic concurrency, when available." - added
Output schema / properties / href / descriptionAdded value: +"Redacted fingerprint of the CalDAV resource URL." - added
Output schema / properties / location / descriptionAdded value: +"Stored event location." - added
Output schema / properties / raw_ical / descriptionAdded value: +"Raw iCalendar resource, included only when explicitly requested." - added
Output schema / properties / recurrence_exception / descriptionAdded value: +"Whether this result is an overridden recurrence instance." - added
Output schema / properties / recurrence_id / descriptionAdded value: +"Occurrence identifier for an expanded recurring event." - added
Output schema / properties / recurring / descriptionAdded value: +"Whether this event belongs to a recurring series." - added
Output schema / properties / resource_id / descriptionAdded value: +"Opaque event ID accepted by get_event, update_event, and delete_event." - added
Output schema / properties / rrule / descriptionAdded value: +"Stored RFC 5545 recurrence rule without the RRULE: prefix." - changed
Output schema / properties / start / anyOfPrevious 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" + } +] - added
Output schema / properties / start / descriptionAdded value: +"Normalized event start." - added
Output schema / properties / summary / descriptionAdded value: +"Stored event title." - added
Output schema / properties / uid / descriptionAdded value: +"Stored iCalendar UID."
- Changed
delete_event6 fields changed- added
Input schema / properties / calendar_id / descriptionAdded value: +"Opaque calendar ID returned by list_calendars. Provide it together with uid when resource_id is unavailable." - added
Input schema / properties / expected_etag / descriptionAdded value: +"ETag previously returned for the event. When supplied, deletion fails if the event changed since it was read." - added
Input schema / properties / resource_id / descriptionAdded value: +"Opaque event resource ID returned by list_events or get_event. Provide it alone instead of calendar_id and uid." - added
Input schema / properties / uid / descriptionAdded value: +"iCalendar UID of the event. Provide it together with calendar_id when resource_id is unavailable." - added
Output schema / properties / deleted / descriptionAdded value: +"Confirms that the resource was deleted." - added
Output schema / properties / resource_id / descriptionAdded value: +"Opaque ID of the deleted event resource."
- Changed
get_event27 fields changed- added
Input schema / properties / calendar_id / descriptionAdded value: +"Opaque calendar ID returned by list_calendars. Provide it together with uid when resource_id is unavailable." - added
Input schema / properties / include_raw_ical / descriptionAdded value: +"Include the raw iCalendar resource for controlled diagnostics; it may contain sensitive calendar data. Defaults to false." - added
Input schema / properties / resource_id / descriptionAdded value: +"Opaque event resource ID returned by list_events or get_event. Provide it alone instead of calendar_id and uid." - added
Input schema / properties / uid / descriptionAdded value: +"iCalendar UID of the event. Provide it together with calendar_id when resource_id is unavailable." - added
Output schema / properties / alarms / descriptionAdded value: +"Normalized alarms attached to the event." - added
Output schema / properties / alarms / items / descriptionAdded value: +"A normalized alarm returned by iCloud Calendar." - added
Output schema / properties / alarms / items / properties / action / descriptionAdded value: +"Stored iCalendar alarm action." - added
Output schema / properties / alarms / items / properties / description / descriptionAdded value: +"Stored alarm notification text, when available." - added
Output schema / properties / alarms / items / properties / minutes_before / descriptionAdded value: +"Whole minutes before event start, when representable." - added
Output schema / properties / alarms / items / properties / uid / descriptionAdded value: +"Stored alarm UID, when available." - added
Output schema / properties / calendar_id / descriptionAdded value: +"Opaque ID of the containing calendar." - added
Output schema / properties / description / descriptionAdded value: +"Stored event notes." - changed
Output schema / properties / end / anyOfPrevious 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" + } +] - added
Output schema / properties / end / descriptionAdded value: +"Normalized event end." - added
Output schema / properties / etag / descriptionAdded value: +"Current ETag for optimistic concurrency, when available." - added
Output schema / properties / href / descriptionAdded value: +"Redacted fingerprint of the CalDAV resource URL." - added
Output schema / properties / location / descriptionAdded value: +"Stored event location." - added
Output schema / properties / raw_ical / descriptionAdded value: +"Raw iCalendar resource, included only when explicitly requested." - added
Output schema / properties / recurrence_exception / descriptionAdded value: +"Whether this result is an overridden recurrence instance." - added
Output schema / properties / recurrence_id / descriptionAdded value: +"Occurrence identifier for an expanded recurring event." - added
Output schema / properties / recurring / descriptionAdded value: +"Whether this event belongs to a recurring series." - added
Output schema / properties / resource_id / descriptionAdded value: +"Opaque event ID accepted by get_event, update_event, and delete_event." - added
Output schema / properties / rrule / descriptionAdded value: +"Stored RFC 5545 recurrence rule without the RRULE: prefix." - changed
Output schema / properties / start / anyOfPrevious 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" + } +] - added
Output schema / properties / start / descriptionAdded value: +"Normalized event start." - added
Output schema / properties / summary / descriptionAdded value: +"Stored event title." - added
Output schema / properties / uid / descriptionAdded value: +"Stored iCalendar UID."
- Changed
list_calendars6 fields changed- added
Output schema / properties / calendars / descriptionAdded value: +"Calendars available to the configured account." - added
Output schema / properties / calendars / items / properties / calendar_id / descriptionAdded value: +"Opaque calendar ID used by event tools." - added
Output schema / properties / calendars / items / properties / description / descriptionAdded value: +"Calendar description." - added
Output schema / properties / calendars / items / properties / display_name / descriptionAdded value: +"Calendar display name." - added
Output schema / properties / calendars / items / properties / timezone / descriptionAdded value: +"Calendar timezone, when advertised by the server." - added
Output schema / properties / calendars / items / properties / writable / descriptionAdded value: +"Best-effort writable status; null means unknown."
- Changed
list_events31 fields changed- added
Input schema / properties / calendar_id / descriptionAdded value: +"Opaque calendar ID returned by list_calendars." - added
Input schema / properties / cursor / descriptionAdded value: +"Opaque next_cursor from the preceding page. Reuse it with the same calendar, interval, and timezone." - added
Input schema / properties / end / descriptionAdded value: +"Exclusive end of the event search interval; must be after start and no more than 366 days later." - added
Input schema / properties / limit / descriptionAdded value: +"Maximum events to return in this page, from 1 to 500; defaults to 100." - added
Input schema / properties / start / descriptionAdded value: +"Inclusive start of the event search interval as an ISO 8601 instant." - added
Input schema / properties / timezone / descriptionAdded value: +"Fallback IANA timezone used when an event lacks timezone metadata during recurrence expansion." - added
Output schema / properties / events / descriptionAdded value: +"Events in deterministic chronological order for this page." - added
Output schema / properties / events / items / properties / alarms / descriptionAdded value: +"Normalized alarms attached to the event." - added
Output schema / properties / events / items / properties / alarms / items / descriptionAdded value: +"A normalized alarm returned by iCloud Calendar." - added
Output schema / properties / events / items / properties / alarms / items / properties / action / descriptionAdded value: +"Stored iCalendar alarm action." - added
Output schema / properties / events / items / properties / alarms / items / properties / description / descriptionAdded value: +"Stored alarm notification text, when available." - added
Output schema / properties / events / items / properties / alarms / items / properties / minutes_before / descriptionAdded value: +"Whole minutes before event start, when representable." - added
Output schema / properties / events / items / properties / alarms / items / properties / uid / descriptionAdded value: +"Stored alarm UID, when available." - added
Output schema / properties / events / items / properties / calendar_id / descriptionAdded value: +"Opaque ID of the containing calendar." - added
Output schema / properties / events / items / properties / description / descriptionAdded value: +"Stored event notes." - changed
Output schema / properties / events / items / properties / end / anyOfPrevious 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" + } +] - added
Output schema / properties / events / items / properties / end / descriptionAdded value: +"Normalized event end." - added
Output schema / properties / events / items / properties / etag / descriptionAdded value: +"Current ETag for optimistic concurrency, when available." - added
Output schema / properties / events / items / properties / href / descriptionAdded value: +"Redacted fingerprint of the CalDAV resource URL." - added
Output schema / properties / events / items / properties / location / descriptionAdded value: +"Stored event location." - added
Output schema / properties / events / items / properties / raw_ical / descriptionAdded value: +"Raw iCalendar resource, included only when explicitly requested." - added
Output schema / properties / events / items / properties / recurrence_exception / descriptionAdded value: +"Whether this result is an overridden recurrence instance." - added
Output schema / properties / events / items / properties / recurrence_id / descriptionAdded value: +"Occurrence identifier for an expanded recurring event." - added
Output schema / properties / events / items / properties / recurring / descriptionAdded value: +"Whether this event belongs to a recurring series." - added
Output schema / properties / events / items / properties / resource_id / descriptionAdded value: +"Opaque event ID accepted by get_event, update_event, and delete_event." - added
Output schema / properties / events / items / properties / rrule / descriptionAdded value: +"Stored RFC 5545 recurrence rule without the RRULE: prefix." - changed
Output schema / properties / events / items / properties / start / anyOfPrevious 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" + } +] - added
Output schema / properties / events / items / properties / start / descriptionAdded value: +"Normalized event start." - added
Output schema / properties / events / items / properties / summary / descriptionAdded value: +"Stored event title." - added
Output schema / properties / events / items / properties / uid / descriptionAdded value: +"Stored iCalendar UID." - added
Output schema / properties / next_cursor / descriptionAdded value: +"Opaque cursor for the next page, or null when this is the last page."
- Changed
update_event41 fields changed- added
Input schema / properties / calendar_id / descriptionAdded value: +"Opaque calendar ID returned by list_calendars. Provide it together with uid when resource_id is unavailable." - added
Input schema / properties / expected_etag / descriptionAdded value: +"ETag previously returned for the event. When supplied, the update fails if the event changed since it was read." - added
Input schema / properties / patch / descriptionAdded value: +"Fields to replace. Omitted fields are preserved; null clears nullable values and an empty alarms array removes all alarms." - added
Input schema / properties / patch / properties / alarms / descriptionAdded value: +"Replacement alarm set; use an empty array to remove all alarms." - added
Input schema / properties / patch / properties / alarms / items / descriptionAdded value: +"A display reminder attached to an event." - added
Input schema / properties / patch / properties / alarms / items / properties / action / descriptionAdded value: +"Alarm action; only DISPLAY is supported." - added
Input schema / properties / patch / properties / alarms / items / properties / description / descriptionAdded value: +"Optional notification text for this alarm." - added
Input schema / properties / patch / properties / alarms / items / properties / minutes_before / descriptionAdded value: +"Whole minutes before the event start; use 0 for an alarm at start time." - added
Input schema / properties / patch / properties / description / descriptionAdded value: +"Replacement notes; use null to clear the description." - changed
Input schema / properties / patch / properties / end / anyOfPrevious 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" + } +] - added
Input schema / properties / patch / properties / end / descriptionAdded value: +"Replacement end; provide together with start. An all-day end date is exclusive." - added
Input schema / properties / patch / properties / location / descriptionAdded value: +"Replacement location; use null to clear it." - added
Input schema / properties / patch / properties / rrule / descriptionAdded value: +"Replacement RFC 5545 recurrence rule without RRULE:, or null to make the event non-recurring." - changed
Input schema / properties / patch / properties / start / anyOfPrevious 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" + } +] - added
Input schema / properties / patch / properties / start / descriptionAdded value: +"Replacement start; provide together with end." - added
Input schema / properties / patch / properties / summary / descriptionAdded value: +"Replacement event title." - added
Input schema / properties / resource_id / descriptionAdded value: +"Opaque event resource ID returned by list_events or get_event. Provide it alone instead of calendar_id and uid." - added
Input schema / properties / uid / descriptionAdded value: +"iCalendar UID of the event. Provide it together with calendar_id when resource_id is unavailable." - added
Output schema / properties / alarms / descriptionAdded value: +"Normalized alarms attached to the event." - added
Output schema / properties / alarms / items / descriptionAdded value: +"A normalized alarm returned by iCloud Calendar." - added
Output schema / properties / alarms / items / properties / action / descriptionAdded value: +"Stored iCalendar alarm action." - added
Output schema / properties / alarms / items / properties / description / descriptionAdded value: +"Stored alarm notification text, when available." - added
Output schema / properties / alarms / items / properties / minutes_before / descriptionAdded value: +"Whole minutes before event start, when representable." - added
Output schema / properties / alarms / items / properties / uid / descriptionAdded value: +"Stored alarm UID, when available." - added
Output schema / properties / calendar_id / descriptionAdded value: +"Opaque ID of the containing calendar." - added
Output schema / properties / description / descriptionAdded value: +"Stored event notes." - changed
Output schema / properties / end / anyOfPrevious 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" + } +] - added
Output schema / properties / end / descriptionAdded value: +"Normalized event end." - added
Output schema / properties / etag / descriptionAdded value: +"Current ETag for optimistic concurrency, when available." - added
Output schema / properties / href / descriptionAdded value: +"Redacted fingerprint of the CalDAV resource URL." - added
Output schema / properties / location / descriptionAdded value: +"Stored event location." - added
Output schema / properties / raw_ical / descriptionAdded value: +"Raw iCalendar resource, included only when explicitly requested." - added
Output schema / properties / recurrence_exception / descriptionAdded value: +"Whether this result is an overridden recurrence instance." - added
Output schema / properties / recurrence_id / descriptionAdded value: +"Occurrence identifier for an expanded recurring event." - added
Output schema / properties / recurring / descriptionAdded value: +"Whether this event belongs to a recurring series." - added
Output schema / properties / resource_id / descriptionAdded value: +"Opaque event ID accepted by get_event, update_event, and delete_event." - added
Output schema / properties / rrule / descriptionAdded value: +"Stored RFC 5545 recurrence rule without the RRULE: prefix." - changed
Output schema / properties / start / anyOfPrevious 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" + } +] - added
Output schema / properties / start / descriptionAdded value: +"Normalized event start." - added
Output schema / properties / summary / descriptionAdded value: +"Stored event title." - added
Output schema / properties / uid / descriptionAdded value: +"Stored iCalendar UID."
6 tool updates
v0.1.0- First observed
create_event - First observed
delete_event - First observed
get_event - First observed
list_calendars - First observed
list_events - First observed
update_event
TDQS
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.
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.
Six tools is well-scoped for a CalDAV server: calendar discovery plus full event CRUD. There is no bloat and no unnecessary overlap.
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
Related MCP Connectors
Model Context Protocol server for todo.vu task management and time tracking.
MCP server for Cronofy — read calendars, events and free/busy, and create, update or delete events.
Streamable HTTP MCP server for Google Calendar and Sheets with OAuth login.
Model Context Protocol server for Studex tools, notifications, and profile integrations
Related MCP Servers
- AlicenseCqualityDmaintenanceA Model Context Protocol server for AI models to access and manipulate Apple Calendar data on macOS through a standardized interface.71015MIT
- AlicenseDqualityDmaintenanceA Model Context Protocol server that allows users to interact with their CalDAV, CardDAV, and WebDAV services (calendars, contacts, and files) from Fastmail and Apple iCloud accounts.6623MIT
- AlicenseNot gradedqualityDmaintenanceAn HTTP Model Context Protocol (MCP) server exposing iCloud Calendar (CalDAV) tools so MCP-aware clients can list calendars, read events, and create/update/delete events using an iCloud app-specific password.3MIT
- AlicenseNot gradedqualityDmaintenanceMCP server for Apple Calendar via native EventKit API with proper recurring event support.2610MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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