Skip to main content
Glama

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-mcp

Related MCP server: iCloud CalDAV MCP Connector

Configuration

Set these environment variables (or copy .env.example to .env):

Variable

Required

Description

ICAL_MCP_URL

Yes

CalDAV server URL (e.g. https://caldav.icloud.com)

ICAL_MCP_USERNAME

Yes

Your email / account ID

ICAL_MCP_PASSWORD

Yes

Password or app-specific password

ICAL_MCP_TIMEZONE

No

Default timezone (default: UTC)

ICAL_MCP_WRITABLE_CALENDARS

No

Calendars that allow writes (see Write protection)

iCloud setup

  1. Go to account.apple.com → Sign-In and Security → App-Specific Passwords

  2. Generate a new password (label it "ical-mcp")

  3. Set ICAL_MCP_URL=https://caldav.icloud.com

  4. Set ICAL_MCP_USERNAME to your Apple ID email

  5. Set ICAL_MCP_PASSWORD to the generated app-specific password

Tools

Tool

Description

list_calendars

List all available calendars (shows read/write access per calendar)

get_events

Query events by date range

create_event

Create a new event

update_event

Update an existing event (partial patch, only changed fields)

delete_event

Delete an event

get_freebusy

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-only

list_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 8093

Claude 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 tools
create_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.

ParametersJSON Schema
NameRequiredDescriptionDefault
titleYesEvent title
startYesStart datetime, ISO 8601 with timezone (e.g. 2026-06-10T14:00:00-04:00)
endYesEnd datetime, ISO 8601 with timezone (e.g. 2026-06-10T15:00:00-04:00)
calendarNoCalendar name or ID. Omit to use the default.
descriptionNoEvent description or notes
locationNoEvent location
all_dayNoWhether this is an all-day event. If true, start/end should be dates (e.g. 2026-06-10).

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
event_idYesEvent ID (UID) to delete
calendarNoCalendar name or ID where the event lives
etagNoETag for conflict detection (recommended but optional)

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
startYesStart of date range, ISO 8601 with timezone (e.g. 2026-06-10T00:00:00+00:00)
endYesEnd of date range, ISO 8601 with timezone (e.g. 2026-06-17T23:59:59+00:00)
calendarNoCalendar name or ID. Omit to use the default (only works if one calendar exists).

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
startYesStart of range, ISO 8601 with timezone
endYesEnd of range, ISO 8601 with timezone
calendarNoCalendar name or ID. Omit to check all calendars.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
event_idYesEvent ID (UID) from a previous get_events call
etagYesETag from a previous get_events call (for conflict detection)
calendarNoCalendar name or ID where the event lives
titleNoNew title (omit to keep current)
startNoNew start datetime, ISO 8601 with timezone (omit to keep current)
endNoNew end datetime, ISO 8601 with timezone (omit to keep current)
descriptionNoNew description (omit to keep current)
locationNoNew location (omit to keep current)

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

  1. 6 tool updatesv0.1.0
    • First observedcreate_event
    • First observeddelete_event
    • First observedget_events
    • First observedget_freebusy
    • First observedlist_calendars
    • First observedupdate_event

TDQS

A4.2/5.0

Scored across 6 tools

Disambiguation5/5

Each tool has a clear, distinct purpose: create, delete, get, update events, plus free/busy and list calendars. No overlap or ambiguity.

Naming Consistency5/5

All tools use a consistent verb_noun pattern in snake_case (e.g., create_event, list_calendars). No deviations or mixed conventions.

Tool Count5/5

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.

Completeness4/5

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

ActivityMaintained
ResponsivenessSyncing

Related MCP Connectors

Related MCP Servers

Appeared in Searches