CalDAV MCP Server
CalDAV MCP 서버
CalDAV MCP 서버는 iCloud 캘린더 이벤트를 관리하기 위한 Model Context Protocol 서버로, 단일 이벤트에 여러 개의 VALARM 알림을 기본 지원합니다.
iCloud 캘린더는 첫 번째 릴리스에서 공식적으로 지원되고 수동 검증된 유일한 제공자입니다. 이 서버는 stdio 또는 Streamable HTTP를 지원하는 모든 MCP 클라이언트에서 작동합니다.
이 독립 프로젝트는 Apple Inc.와 제휴, 승인, 후원 또는 보증 관계가 아닙니다. Apple 및 iCloud는 해당 소유자의 상표입니다.
목차
Related MCP server: DAV MCP Server
소개
이 서버는 구성된 하나의 계정을 CalDAV를 통해 iCloud에 연결합니다. 계정의 캘린더를 검색하고 정규화된 읽기 및 쓰기 작업을 MCP를 통해 노출합니다.
업데이트는 알 수 없는 속성, Apple 확장, VTIMEZONE, 반복 예외, 패치에서 생략된 알림을 포함한 완전한 iCalendar 리소스를 보존합니다. 쓰기는 CalDAV 파일 이름이 이벤트 UID와 일치한다고 가정하는 대신 불투명한 리소스 식별자와 ETag를 사용합니다.
캘린더 리소스는 메모리에서 처리됩니다. 이 서버는 원격 측정이나 애플리케이션 데이터베이스가 없으며, 원시 iCalendar는 명시적으로 요청된 경우에만 반환됩니다.
기능
구성된 iCloud 계정에서 사용 가능한 캘린더를 검색합니다.
반개방 시간 범위의 이벤트를 나열하고 반복 발생을 확장합니다.
시간 지정, 종일, 반복 이벤트를 생성합니다.
이벤트당 0개, 1개 또는 여러 개의 표시 알림을 지원합니다.
iCloud 캘린더가 기대하는 Apple 알림 확장을 생성합니다.
불투명한 리소스 ID 또는 캘린더 ID와 UID 조합으로 이벤트를 읽습니다.
생략되거나 알 수 없는 iCalendar 데이터를 보존하면서 부분 업데이트를 적용합니다.
업데이트 및 삭제 시 낙관적 동시성을 위해 ETag를 사용합니다.
전체 시리즈를 변경하는 대신 개별 반복 변경을 거부합니다.
로그와 오류에서 자격 증명, 원시 캘린더 콘텐츠, CalDAV 경로를 삭제합니다.
읽기 전용 루트 파일시스템 구성으로 비루트 컨테이너로 실행됩니다.
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
이벤트를 생성하고 서버가 저장한 표현을 다시 읽습니다.
알림 두 개가 있는 시간 지정 이벤트:
{
"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은 nullable 필드를 제거하며, alarms: []는 모든 알림을 제거합니다. 선택적 expected_etag는 최신 서버 버전을 덮어쓰는 것을 방지합니다.
delete_event
이벤트 또는 전체 반복 시리즈를 삭제하며, 선택적으로 관찰된 ETag를 요구합니다. 단일 확장 발생 삭제는 현재 릴리스에서 지원되지 않습니다.
기술 스택
엄격한 프로젝트 규칙을 사용하는 TypeScript
설치
사전 요구 사항
캘린더가 활성화된 iCloud 계정.
Apple 계정에 2단계 인증이 활성화되어 있어야 합니다.
컨테이너 배포를 위한 Docker 및 Docker Compose, 또는 로컬 설치를 위한 Node.js 24+ 및 pnpm.
Docker Compose
권장 설치는 게시된 멀티 아키텍처 이미지를 사용합니다:
ghcr.io/lukegskw/caldav-mcp:latestCompose 예제를 다운로드합니다:
curl -O https://raw.githubusercontent.com/lukegskw/caldav-mcp/main/compose.example.yamlApple 계정 이메일과 앱별 암호를 제공한 후 서비스를 시작합니다:
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 -dlatest 태그는 기본 브랜치의 가장 최근 성공적인 빌드를 따릅니다. 통제된 배포 또는 롤백을 위해 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 stdiostdio 모드에서 stdout은 MCP 메시지 전용으로 예약됩니다. Streamable HTTP를 로컬에서 실행하려면:
CALDAV_MCP_TRANSPORT=streamable-http pnpm start구성
모든 설정은 CALDAV_ 또는 CALDAV_MCP_ 접두사를 사용합니다.
변수 | 필수 | 기본값 | 설명 |
| 아니요 |
| 제공자 정책. iCloud가 지원되는 프로필입니다. |
| 아니요 |
| CalDAV 검색 URL. |
| 예 | 없음 | Apple 계정 이메일. |
| 예 | 없음 | 앱별 암호. 계정 암호가 아닙니다. |
| 아니요 |
|
|
| 아니요 |
| HTTP 바인드 주소. |
| 아니요 |
| HTTP 수신 포트. |
| 아니요 |
| 애플리케이션 로그 수준. |
| 아니요 |
| 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 클라이언트로 연결하여 여섯 개의 도구가 모두 나열되는지 확인합니다. 릴리스 전에 테스트 캘린더를 대상으로 전용 iCloud 수동 검증을 실행합니다.
제한 사항
서버 프로세스 또는 컨테이너당 하나의 iCloud 계정이 구성됩니다.
Streamable HTTP 엔드포인트는 현재 릴리스에서 인증이 없습니다. 신뢰할 수 있는 LAN, VPN 또는 사설 컨테이너 네트워크로 제한하고 인터넷에 직접 노출하지 마십시오.
개별 반복 발생은 읽기 전용입니다. 전체 시리즈 업데이트 및 삭제는 지원됩니다.
ACTION:DISPLAY알림만 생성됩니다.개별 iCalendar 리소스는 5MiB로 제한됩니다.
이벤트 목록 범위는 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 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