A TypeScript MCP server for iCloud Calendar with native multi-VALARM support.
caldav-mcp demonstrates solid tool design with clear naming, comprehensive descriptions, and proper schema definitions. All 6 tools follow verb_noun convention (list_*, get_*, create_*, update_*, delete_*). Descriptions are detailed (150-250 chars) and include prerequisites and usage guidance. Input schemas are well-typed with descriptions for all parameters. Tool annotations (readOnlyHint, destructiveHint, idempotentHint) are present. Key gaps: output schemas are referenced but not visible in source; error handling lacks actionable recovery guidance; no batch operations despite potential for multi-event workflows.
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.
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.
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.
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.
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.
Output schemas referenced in code but not visible in source. Cannot verify return type documentation completeness.
Error responses use generic error codes (VALIDATION_FAILED, WRITE_RESULT_UNKNOWN) without actionable recovery guidance. LLM cannot determine retry strategy or next steps.
create_event and update_event accept complex nested objects (start, end, alarms, patch) with minimal inline schema documentation. LLM must infer structure from type hints alone.
No batch operations for common multi-event workflows (e.g., create_events, delete_events). Agents must loop sequentially, wasting tokens and latency.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 65 | 2025-06-18+ | v2 |
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.
Timezone handling in list_events is optional but critical for all-day event interpretation. Description mentions this but does not guide LLM on when to provide it.