ical-mcp
Provides tools for managing Apple Calendar events via CalDAV, including listing calendars, querying events, creating, updating, deleting events, and checking free/busy status.
Provides tools for managing iCloud calendars via CalDAV, supporting event CRUD operations and free/busy queries.
Provides tools for managing Nextcloud calendars via CalDAV, supporting event CRUD operations and free/busy queries.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ical-mcplist my events for today"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ical-mcp
MCP server for Apple Calendar and CalDAV providers.
Works with iCloud, Fastmail, Nextcloud, and any CalDAV-compatible calendar. No macOS dependency — runs headless on any platform.
Quick start
# Install
uvx ical-mcp
# Or from source
uv sync
uv run ical-mcpRelated MCP server: iCloud CalDAV MCP Connector
Configuration
Set these environment variables (or copy .env.example to .env):
Variable | Required | Description |
| Yes | CalDAV server URL (e.g. |
| Yes | Your email / account ID |
| Yes | Password or app-specific password |
| No | Default timezone (default: |
| No | Calendars that allow writes (see Write protection) |
iCloud setup
Go to account.apple.com → Sign-In and Security → App-Specific Passwords
Generate a new password (label it "ical-mcp")
Set
ICAL_MCP_URL=https://caldav.icloud.comSet
ICAL_MCP_USERNAMEto your Apple ID emailSet
ICAL_MCP_PASSWORDto the generated app-specific password
Tools
Tool | Description |
| List all available calendars (shows read/write access per calendar) |
| Query events by date range |
| Create a new event |
| Update an existing event (partial patch, only changed fields) |
| Delete an event |
| Check busy/free status for a time range |
Write protection
All calendars are read-only by default. You must explicitly opt in to writes:
# Single calendar (by name or ID)
ICAL_MCP_WRITABLE_CALENDARS=home
# Multiple calendars
ICAL_MCP_WRITABLE_CALENDARS=home,Work
# All calendars (use with caution)
ICAL_MCP_WRITABLE_CALENDARS=*
# Not set or empty — all calendars are read-onlylist_calendars shows "access": "read-only" or "access": "read-write" for each calendar, so the AI agent knows what it can and can't modify.
Using calendar IDs (UUIDs) instead of names avoids issues with spaces and renames.
Transport
# Local use with Claude Code / Claude Desktop (default)
ical-mcp
# Shared HTTP server for multi-agent access
ical-mcp --transport http --port 8093
# Bind to a specific address (e.g. Tailscale IP)
ical-mcp --transport http --host 100.64.0.1 --port 8093Claude Code configuration
Local (stdio)
{
"mcpServers": {
"ical-mcp": {
"command": "uvx",
"args": ["ical-mcp"],
"env": {
"ICAL_MCP_URL": "https://caldav.icloud.com",
"ICAL_MCP_USERNAME": "your@icloud.com",
"ICAL_MCP_PASSWORD": "xxxx-xxxx-xxxx-xxxx",
"ICAL_MCP_WRITABLE_CALENDARS": "your-calendar-id"
}
}
}
}Remote (HTTP)
{
"mcpServers": {
"ical-mcp": {
"url": "http://your-server:8093/mcp"
}
}
}Safety features
Per-calendar write protection — read-only by default, explicit opt-in per calendar
Backup before mutate — every update/delete logs the full iCal data to stderr
ETag concurrency — updates fail if the event was modified elsewhere since last fetch
Semantic errors — clear messages for auth failures, rate limits, conflicts, and read-only violations
License
MIT
Available Tools
6 toolscreate_eventA
Create a new calendar event.
Confirm the calendar, date, time, and details with the user before calling. Returns the created event with its ID and ETag for future updates.
| Name | Required | Description | Default |
|---|---|---|---|
| title | Yes | Event title | |
| start | Yes | Start datetime, ISO 8601 with timezone (e.g. 2026-06-10T14:00:00-04:00) | |
| end | Yes | End datetime, ISO 8601 with timezone (e.g. 2026-06-10T15:00:00-04:00) | |
| calendar | No | Calendar name or ID. Omit to use the default. | |
| description | No | Event description or notes | |
| location | No | Event location | |
| all_day | No | Whether this is an all-day event. If true, start/end should be dates (e.g. 2026-06-10). |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses that the tool returns the created event with ID and ETag, but does not reveal potential side effects, permission requirements, or error conditions. The description is adequate but not comprehensive.
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 concise with three sentences: first sentence declares purpose, second warns about user confirmation, third describes return value. It is front-loaded and every sentence adds 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?
Given 7 parameters, high schema coverage, and the presence of an output schema, the description is fairly complete. It covers creation, user confirmation, and return details. However, it could be improved by mentioning default calendar behavior or error handling. Still, it meets expectations for a creation tool.
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%, meaning the input schema already documents all parameters well. The description adds no additional meaning beyond the schema, such as clarifying complex parameter interactions or providing usage examples, so 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 clearly states 'Create a new calendar event', which is a specific verb and resource. It is distinct from sibling tools like delete_event, update_event, or get_events, leaving no ambiguity about the tool's function.
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 includes a usage tip to confirm calendar, date, time, and details with the user before calling, but it does not explicitly differentiate from sibling tools or provide when-not-to-use guidance. No alternatives are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_eventA
Delete a calendar event.
Confirm with the user before deleting. Pass the ETag from get_events to ensure you're deleting the right version.
| Name | Required | Description | Default |
|---|---|---|---|
| event_id | Yes | Event ID (UID) to delete | |
| calendar | No | Calendar name or ID where the event lives | |
| etag | No | ETag for conflict detection (recommended but optional) |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description bears full burden. Discloses need for confirmation and ETag usage, but does not mention permanence of deletion or error responses.
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 concise sentences: first states purpose, second adds usage instructions. No unnecessary words.
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?
Output schema exists, so return values not needed. Covers purpose, user confirmation, ETag usage. Lacks detail on failure scenarios, but adequate for a simple delete.
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%, baseline 3. Description adds value by explaining ETag's purpose (conflict detection via get_events), enhancing parameter semantics.
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?
Clearly states 'Delete a calendar event', specifying the verb and resource. Distinct from siblings like create_event or update_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?
Explicitly instructs to confirm with the user before deleting and to use ETag from get_events for version safety. Provides clear when-to and how-to guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_eventsA
Get events within a date range.
Returns events sorted by start time. Recurring events are returned as individual expanded occurrences within the requested range.
| Name | Required | Description | Default |
|---|---|---|---|
| start | Yes | Start of date range, ISO 8601 with timezone (e.g. 2026-06-10T00:00:00+00:00) | |
| end | Yes | End of date range, ISO 8601 with timezone (e.g. 2026-06-17T23:59:59+00:00) | |
| calendar | No | Calendar name or ID. Omit to use the default (only works if one calendar exists). |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description adds value by stating that results are sorted by start time and recurring events are expanded. It does not mention pagination, deletion status, or field specifics, but the output schema covers return structure.
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 concise sentences with no filler. Information is front-loaded and every sentence serves a purpose.
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 adequately explains core behavior, and the output schema covers return values. However, it lacks guidance on edge cases like empty results or permissions, but is complete enough for a listing tool.
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% with parameter descriptions already present. The description adds no additional semantic information about the parameters beyond the schema.
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 'Get events within a date range' with a specific verb and resource. It also provides additional detail about sorting and recurrence expansion, distinguishing it from sibling tools like get_freebusy or list_calendars.
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 implies usage when events are needed in a date range but does not explicitly exclude alternatives or provide when-not-to-use guidance. No mention of get_freebusy for busy time or other distinctions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_freebusyA
Check free/busy status for a time range.
Returns a list of busy time blocks within the requested range. Useful for finding available slots before scheduling.
| Name | Required | Description | Default |
|---|---|---|---|
| start | Yes | Start of range, ISO 8601 with timezone | |
| end | Yes | End of range, ISO 8601 with timezone | |
| calendar | No | Calendar name or ID. Omit to check all calendars. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must convey behavioral traits. It discloses that the tool returns busy blocks, but does not mention auth requirements, rate limits, or timezone handling. The description is minimal but sufficient for a straightforward query.
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 extremely concise with two short sentences and a third sentence for usage guidance. Every sentence adds value, and no extraneous information is present.
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 an output schema exists, the description does not need to explain return values. It covers the tool's purpose and a use case. Minor omissions like maximum range or timezone handling are acceptable for a simple tool.
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 schema description coverage is 100%, so the baseline is 3. The description adds context about 'time range' and 'busy time blocks', but does not provide additional meaning beyond the schema for parameters like start, end, and calendar.
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 tool's function: 'Check free/busy status for a time range' and specifies that it returns 'a list of busy time blocks'. This differentiates it from sibling tools like create_event or get_events.
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 provides a usage hint: 'Useful for finding available slots before scheduling', which indicates when to use it. However, it does not explicitly state when not to use it or mention alternatives like get_events for detailed event info.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_calendarsA
List all available calendars.
Returns calendar names and IDs for use with other tools. Call this first to discover which calendars exist before querying or creating events.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It discloses return values (names and IDs) but omits potential details like pagination or access restrictions. Adequate for a simple read-only tool.
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, front-loaded with purpose, no wasted words. Highly efficient.
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 tool has no parameters and an output schema, the description fully covers what the agent needs: purpose, return values, and usage order.
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?
No parameters, so baseline score of 4 applies. The description adds no parameter information because none exist.
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 tool lists all available calendars and returns their names and IDs. It distinguishes itself from sibling event-focused tools by emphasizing discovery before event operations.
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?
Explicitly instructs to call this first before other tools, providing clear context. Lacks explicit 'when not to use' but is sufficient for a zero-parameter discovery tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_eventA
Update an existing calendar event.
Only send the fields you want to change — unchanged fields are preserved. Requires the event's ETag for optimistic concurrency; if the event was modified elsewhere, the update will fail with a conflict error.
| Name | Required | Description | Default |
|---|---|---|---|
| event_id | Yes | Event ID (UID) from a previous get_events call | |
| etag | Yes | ETag from a previous get_events call (for conflict detection) | |
| calendar | No | Calendar name or ID where the event lives | |
| title | No | New title (omit to keep current) | |
| start | No | New start datetime, ISO 8601 with timezone (omit to keep current) | |
| end | No | New end datetime, ISO 8601 with timezone (omit to keep current) | |
| description | No | New description (omit to keep current) | |
| location | No | New location (omit to keep current) |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses partial update and concurrency conflict, but lacks details on idempotency, error conditions (e.g., event not found), or rate limits. No annotations to offset.
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, front-loaded with purpose, no filler. 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?
Output schema exists, so return values not required. Covers core behavior and conflict detection. Could mention field-clearing semantics more explicitly.
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%. Description adds value by clarifying partial update mechanism (send only changed fields) and ETag purpose. Slightly above baseline due to helpful context.
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?
Clear verb+resource: 'Update an existing calendar event.' Distinguishes from siblings like create_event, delete_event, get_events, get_freebusy, and list_calendars.
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?
Explicitly states partial update behavior and ETag requirement for optimistic concurrency. Provides clear guidance on usage context, though does not explicitly contrast with alternatives.
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.
6 tool updates
v0.1.0- First observed
create_event - First observed
delete_event - First observed
get_events - First observed
get_freebusy - First observed
list_calendars - First observed
update_event
TDQS
Scored across 6 tools
Each tool has a clear, distinct purpose: create, delete, get, update events, plus free/busy and list calendars. No overlap or ambiguity.
All tools use a consistent verb_noun pattern in snake_case (e.g., create_event, list_calendars). No deviations or mixed conventions.
With 6 tools, the set is well-scoped for a calendar MCP server: covers CRUD for events and essential utilities without being bloated or sparse.
Covers core calendar operations (CRUD events, free/busy, list calendars). Minor gap: lacks advanced event search (e.g., by title) but handles typical workflows well.
Maintenance
Related MCP Connectors
MCP server for Cronofy — read calendars, events and free/busy, and create, update or delete events.
A MCP server that works with Google Calendar to manage event listing, reading, and updates.
Hosted Google Calendar MCP server for AI agents. No self-hosting or Google Cloud setup.
A MCP server that works with Outlook Calendar to manage event listing, reading, and updates.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceMCP server for accessing macOS Calendar events2MIT
- AlicenseNot gradedqualityDmaintenanceAn MCP server that enables interaction with iCloud Calendars via the CalDAV protocol using an app-specific password. It allows users to list, create, update, and delete calendar events through MCP-aware clients like ChatGPT.2MIT
- AlicenseNot gradedqualityDmaintenanceMCP server for Apple Calendar via native EventKit API with proper recurring event support.10 npm10MIT
- AlicenseNot gradedqualityDmaintenanceMCP server for Apple Calendar, Mail, Reminders, and Files on macOS using native frameworks.14 npm18MIT