MCP server for managing iCloud calendar events with support for searching, creating, updating, and deleting calendar events via CalDAV protocol
The server has 5 well-named tools with mostly strong descriptions and complete input schemas. Tool naming follows verb_noun convention (search_events, create_event, update_event, delete_event, list_calendars). Descriptions are substantive (90-200 chars) and guide LLM selection. All parameters have type declarations and descriptions. However, output schemas are not documented in the visible code, descriptions mention what fields are returned but JSON Schema for responses is not visible. Error handling is mentioned in code (context timeouts, audit logging) but specific error recovery guidance is missing from tool descriptions. The audit hook and timeout middleware show production-grade operational concerns, but the tool definitions themselves lack explicit error classification patterns. Baseline comparison: average tool name length ~18 chars (actual: 11-18 chars, solid); descriptions average 194 chars (actual: 150-300 chars, good); params per tool average 4 (actual: 1-7, within range). All tools are READ_ONLY or WRITE/DESTRUCTIVE with clear risk annotation, and required parameters are properly marked.
Create a new calendar event on iCloud. Returns the created event's unique ID on success. Use list_calendars first to discover valid calendarId values.
Permanently delete a calendar event. This action cannot be undone. Use search_events first to find the event's id and calendarId.
List all available iCloud calendars for the account.
Search for calendar events within a date range. Returns paginated results with event id, title, description, location, startTime, endTime, recurrence, timezone, and attendees. Use list_calendars first to discover valid calendarId values.
Update specific fields of an existing calendar event. Only include the fields you want to change. Omitted fields remain unchanged. Set a field to an empty string to clear it. Use search_events first to find the event's id.
Output schemas not documented in tool definitions. Descriptions mention returned fields (event id, title, description, location, startTime, endTime, recurrence, timezone, attendees) but there is no visible JSON Schema definition for response objects. LLMs cannot plan downstream tool calls without knowing the exact shape and types of returned data.
No error recovery guidance in tool descriptions. While code shows timeout handling and audit logging, tool descriptions lack explicit error classification (retryable vs user-fixable vs fatal) or recovery hints. E.g., create_event should indicate 'If attendee email is invalid, use list_calendars to verify account setup.' describe_event should guide: 'If event not found, try search_events with a wider date range.'
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 62 | <=2025-11-25 | v2 |
| 2026-03-09 | C | 63 | - | v1 |
delete_event lacks explicit confirmation or dry-run pattern. The description states 'This action cannot be undone' but provides no mechanism to preview consequences or confirm before executing. Per pattern:confirmation-request, irreversible operations should support a dry-run or multi-step confirmation.
list_calendars lacks result limit documentation. No mention of maximum calendars returned, pagination support, or result capping. If a user has thousands of calendars, returning all of them unpaginated wastes tokens and risks context window exhaustion. Description should state 'Returns up to 100 calendars; use limit/offset for pagination.' and similar structured guidance.
Parameter constraints not formalized. search_events limit defaults to 50 with min=1, max=500 (good), but offset's minimum=0 is not binding and max is undefined, LLMs could request offset=999999. update_event time parameters lack explicit 'startTime must be before endTime' validation hint in the schema. Descriptions mention it but JSON Schema oneOf or conditional constraints would be clearer.
attendees parameter in create_event is documented as 'JSON array...' but parameter type is 'string' rather than 'array'. This forces the LLM to serialize a JSON string manually, introducing parsing errors and wasting tokens. Should be type='array' with items schema of type='object' containing email (required, format=email), name (string), role (enum), status (enum).