Skip to main content
Glama
atfinke
by atfinke

calendar-mcp

Local MCP server that exposes Apple Calendar data through an EventKit helper app.

Built entirely by OpenAI GPT-5.4 via Codex.

Install

git clone https://github.com/<your-account>/calendar-mcp.git
cd calendar-mcp
./bootstrap.sh

Related MCP server: mcp-eventkit

Run

npm run start

Permissions

Run calendar_permissions once with prompt: true and access: "full".

The helper app is intended to be built with the project’s normal code signing so macOS can attribute Calendar access to a stable app identity.

If the prompt does not appear from inside Codex, launch the helper app directly once:

open CalendarMCPHelperApp/build/Build/Products/Release/CalendarMCPHelperApp.app

When opened directly, the app will request Calendar access and show a status alert. After that initial grant, the MCP tools can read and write events normally.

Delete safety is intentionally narrow: each calendar_delete_event call can remove only one resolved target. Recurring deletes support one occurrence or one entire series, but not futureEvents or any bulk-delete shape.

calendar_update_event updates an event in place instead of forcing a delete-and-recreate flow. Omitted fields stay unchanged. To clear nullable fields, pass one of clearLocation, clearNotes, clearUrl, or clearTimeZone.

Date Inputs

All tool date inputs accept these wire formats:

  • 2026-04-02 for a local calendar day

  • 2026-04-02T09:30 or 2026-04-02T09:30:00 for a local wall-clock time

  • 2026-04-02T09:30:00-05:00 or 2026-04-02T14:30:00Z for an exact instant

Local date-only and local date-time inputs are interpreted in the helper app's current macOS time zone. Returned event payloads always use ISO-8601 timestamps with timezone offsets.

calendar_list_events treats start and end as the exact time window after parsing those inputs.

occurrenceDate for recurring-event lookups also accepts YYYY-MM-DD. In that case the helper matches the occurrence by local calendar day. When you already have an occurrenceDate timestamp from a previous tool response, prefer passing that exact timestamp back.

MCP config

{
  "mcpServers": {
    "calendar": {
      "command": "node",
      "args": ["/absolute/path/to/calendar-mcp/dist/index.js"],
      "env": {
        "CALENDAR_MCP_HELPER_APP_PATH": "/absolute/path/to/calendar-mcp/CalendarMCPHelperApp/build/Build/Products/Release/CalendarMCPHelperApp.app"
      }
    }
  }
}

Verify

npm run verify

Available Tools

7 tools
calendar_create_eventCreate EventA

Create a calendar event in the default calendar or a specified calendar. start and end accept local dates, local times, or timezone-bearing ISO-8601 timestamps.

ParametersJSON Schema
NameRequiredDescriptionDefault
endYesAccepts YYYY-MM-DD (local calendar day), YYYY-MM-DDTHH:mm[:ss][.SSS] (local time), or ISO-8601 / RFC 3339 with timezone like 2026-04-02T09:30:00-05:00.
urlNo
notesNo
startYesAccepts YYYY-MM-DD (local calendar day), YYYY-MM-DDTHH:mm[:ss][.SSS] (local time), or ISO-8601 / RFC 3339 with timezone like 2026-04-02T09:30:00-05:00.
titleYes
allDayNo
locationNo
timeZoneNo
calendarIdNo

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the burden of behavioral disclosure. It adds useful context about accepted date/time formats and calendar selection, but it does not mention permissions, default handling of missing fields, mutation effects, or what the response contains.

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 two sentences long, front-loaded with the primary action, and contains no filler. The first sentence states what the tool does and the second clarifies the important date/time input flexibility.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 9-parameter creation tool with no annotations and no output schema, this description is too thin. It lacks details on how optional fields interact, how calendarId selection works, what happens when allDay is set, and what a successful response contains.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 22%, and the description mostly repeats the start/end format guidance already present in the property descriptions. It does not explain the roles of calendarId, allDay, timeZone, location, notes, or url, leaving the agent without enough parameter-level guidance for constructing valid calls.

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 opens with the specific verb 'Create a calendar event' and clearly identifies the resource, distinguishing this tool from sibling tools like calendar_update_event and calendar_delete_event. It also notes the option of using the default or a specified calendar, adding useful scope.

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 makes it clear when to call this tool: to create a calendar event. It provides useful context about the default versus a specified calendar. However, it does not explicitly mention alternatives or state when not to use it (e.g., use update for existing events).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

calendar_delete_eventDelete EventA

Delete exactly one calendar target by identifier. For recurring events, choose whether to remove one occurrence or the entire series.

ParametersJSON Schema
NameRequiredDescriptionDefault
scopeNo
occurrenceDateNoAccepts YYYY-MM-DD to match a recurring occurrence by local calendar day, or a timestamp to match an exact occurrence start time. Prefer the exact timestamp returned by a previous read when available.
eventIdentifierNo
calendarItemIdentifierNo

TDQS

A3.7/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 does disclose the deletion behavior and the key choice for recurring events (occurrence vs. series). However, it omits other relevant behavioral traits such as irreversibility, permission requirements, or potential side effects on related items, which leaves some transparency gaps.

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: two sentences that front-load the core action and then add the most important variation (recurring events). Every word contributes meaning, with no fluff or repetition of schema fields.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has 4 parameters, no output schema, and no annotations. The description covers the main purpose and the recurring-event distinction, but it doesn't explain how to specify the target (which identifier is required), whether any parameter is mandatory, or what happens upon deletion. This leaves the description incomplete for a tool with such a parameter set.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 25% (only occurrenceDate is described). The description does not clarify the roles of eventIdentifier and calendarItemIdentifier, nor how they relate to the 'identifier' mentioned in the text. It only vaguely hints at the scope parameter, leaving most parameters semantically under-specified.

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 action ('Delete'), the resource ('calendar target'), and the precision ('exactly one', 'by identifier'). It also distinguishes the tool from its siblings (create, update, list, get) and adds specific nuance for recurring events, making the purpose unmistakable.

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 clear context on when to use this tool (to delete a calendar target) and addresses the recurring-event scenario by explaining the choice between occurrence and series. It doesn't explicitly name alternative tools or exclusions, but the sibling context and the clear deletion purpose provide enough practical guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

calendar_get_eventGet EventA
Read-only

Fetch a single event by identifier. Pass occurrenceDate when targeting one instance of a recurring series.

ParametersJSON Schema
NameRequiredDescriptionDefault
occurrenceDateNoAccepts YYYY-MM-DD to match a recurring occurrence by local calendar day, or a timestamp to match an exact occurrence start time. Prefer the exact timestamp returned by a previous read when available.
eventIdentifierNo
externalIdentifierNo
calendarItemIdentifierNo

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations supply readOnlyHint=true, so the read-only nature is already declared. The description adds behavioral context beyond annotations by explaining how occurrenceDate affects targeting a single instance of a recurring series. It doesn't cover error cases or permissions, but the annotation lowers the bar.

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 two sentences, front-loaded with the core purpose, and every clause adds value. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the primary use case and the recurring-series nuance, and the readOnly annotation helps. However, with no output schema and three undocumented identifier parameters, the description does not fully explain how to choose among identifiers or what the return looks like. It is adequate but with clear gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 25% (only occurrenceDate has a description). The main description mentions occurrenceDate but does not clarify the roles of eventIdentifier, externalIdentifier, and calendarItemIdentifier, which are left as bare names. This fails to compensate for the low schema coverage.

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 uses a specific verb ('Fetch') and resource ('a single event'), clearly distinguishing it from siblings like calendar_list_events (plural) and calendar_create_event. It also adds precision about targeting occurrences of a recurring series.

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 implies when to use the tool (to fetch a specific event by identifier, as opposed to listing events) and gives concrete guidance for a common edge case (occurrenceDate for recurring series). However, it does not explicitly name alternative tools or state when not to use this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

calendar_list_calendarsList CalendarsA
Read-only

List event calendars available to the helper app.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, so the read-only nature is known. The description adds the scope that these are calendars 'available to the helper app', which provides useful context about what will be listed. It does not mention return format or pagination, but this is acceptable given the simplicity and existing annotation coverage.

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 a single, well-formed sentence that immediately states the action and resource. Every word adds value, with no fluff or repetition.

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 extremely simple nature of the tool (no parameters, read-only, no output schema), the description is fully sufficient. It clearly states what the tool does without needing to elaborate on return values or side effects.

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?

The tool has zero parameters, so the baseline is 4 per the rubric. The description does not need to elaborate on parameter semantics as there are none.

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 event calendars available to the helper app, using a specific verb ('List') and resource ('event calendars'). It is distinct from sibling tools like calendar_list_events which lists events, and calendar_get_event which fetches a single event.

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: it is the way to discover which calendars exist before performing other calendar operations. However, it does not explicitly state when to use it versus alternatives or provide exclusions, so it relies on the obviousness of the sibling tool set.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

calendar_list_eventsList EventsA
Read-only

List calendar events in a time window. start and end accept local dates, local times, or timezone-bearing ISO-8601 timestamps.

ParametersJSON Schema
NameRequiredDescriptionDefault
endYesAccepts YYYY-MM-DD (local calendar day), YYYY-MM-DDTHH:mm[:ss][.SSS] (local time), or ISO-8601 / RFC 3339 with timezone like 2026-04-02T09:30:00-05:00.
startYesAccepts YYYY-MM-DD (local calendar day), YYYY-MM-DDTHH:mm[:ss][.SSS] (local time), or ISO-8601 / RFC 3339 with timezone like 2026-04-02T09:30:00-05:00.
calendarIdsNo

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, so the read-only nature is known. The description adds context about accepted time formats (local dates/times or timezone-bearing ISO-8601), which helps with behavior interpretation, but it does not disclose other behaviors like pagination, ordering, or limits. This is adequate given the annotation coverage.

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 two sentences, with the purpose in the first sentence and parameter formats in the second. Every word earns its place, with no redundancy or filler.

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?

For a list tool with three parameters and no output schema, the description plus annotations and schema provide a solid understanding. However, it does not mention return format, ordering, pagination, or whether calendarIds filtering is applied. These gaps are not severe given the tool's simplicity but prevent a perfect score.

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 descriptions already cover start and end with detailed format explanations, covering 67% of parameters. The description summarizes these formats but does not add meaning for calendarIds, which lacks a schema description. The concise summary adds some value, but the calendarIds parameter remains under-explained, relying on its self-explanatory name.

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 calendar events within a time window, which distinguishes it from sibling tools like calendar_get_event (single event) and calendar_create_event. The verb 'list' and resource 'calendar events' are specific and unambiguous.

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 time-window scope provides clear context for when to use this tool, but it does not explicitly mention alternatives or exclusions such as using calendar_get_event for a single event. The context is clear but lacks 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.

calendar_permissionsCalendar PermissionsB

Check and optionally prompt for Apple Calendar access used by the helper app.

ParametersJSON Schema
NameRequiredDescriptionDefault
accessNo
promptNo

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses the potential side effect of prompting the user, which is useful, but it does not explain what 'check' returns, how access levels map to outcomes, or whether the tool modifies permissions. Partial disclosure only.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence with no wasted words. However, the phrase 'used by the helper app' is vague and could be clarified without adding length. Still, overall structure is appropriately compact.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema, no annotations, and 0% parameter coverage, the description is too lean. It does not mention return values, error cases, or how the check result influences later calendar operations. A permissions tool that may prompt the user requires more context for safe and effective use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% and the description ignores both parameters. It does not explain the meaning of 'access' (full vs writeOnly) or 'prompt' (whether to show the prompt). For a tool with two undocumented parameters, this is a critical gap.

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 checks and optionally prompts for Apple Calendar access, a distinct resource/action not covered by sibling tools which handle list/get/create/update/delete of events/calendars. This unambiguously differentiates it as a permissions utility.

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 this tool is relevant for permission management before calendar operations, but it never explicitly states when to invoke it (e.g., before creating events) or what alternatives exist. Usage context is implied by sibling names rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

calendar_update_eventUpdate EventA

Update an existing calendar event in place. Omitted fields are left unchanged. Use clear flags to remove location, notes, url, or timeZone.

ParametersJSON Schema
NameRequiredDescriptionDefault
endNoAccepts YYYY-MM-DD (local calendar day), YYYY-MM-DDTHH:mm[:ss][.SSS] (local time), or ISO-8601 / RFC 3339 with timezone like 2026-04-02T09:30:00-05:00.
urlNo
notesNo
scopeNo
startNoAccepts YYYY-MM-DD (local calendar day), YYYY-MM-DDTHH:mm[:ss][.SSS] (local time), or ISO-8601 / RFC 3339 with timezone like 2026-04-02T09:30:00-05:00.
titleNo
allDayNo
clearUrlNo
locationNo
timeZoneNo
calendarIdNo
clearNotesNo
clearLocationNo
clearTimeZoneNo
occurrenceDateNoAccepts YYYY-MM-DD to match a recurring occurrence by local calendar day, or a timestamp to match an exact occurrence start time. Prefer the exact timestamp returned by a previous read when available.
eventIdentifierNo
externalIdentifierNo
calendarItemIdentifierNo

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden of disclosure. It transparently communicates that the update is in-place, that omitted fields are left unchanged, and that clear flags are necessary to remove values. This is valuable but not exhaustive—it does not cover recurrence handling, identifier precedence, or error behavior, which are relevant for a tool with 18 parameters.

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 two sentences long, front-loads the main purpose, and every clause adds value. It is concise without sacrificing essential update semantics, making it well-structured for quick agent consumption.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (18 parameters, no required fields, no output schema, no annotations), the description is far too brief. It omits critical context like how to choose an identifier, the meaning of scope, and what 'in place' means for recurring events. This leaves an agent underinformed about key operational details.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 17%, so the description must compensate. It does not explain most parameters, especially the identifier trio (eventIdentifier, externalIdentifier, calendarItemIdentifier) or scope/occurrenceDate. It only indirectly references clear flags. This is insufficient for a schema with 18 parameters and no descriptions for 15 of them.

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 updates an existing calendar event in place, with a specific verb and resource. It distinguishes this from sibling tools like create or delete by emphasizing 'existing' and 'in place'. The added detail 'Omitted fields are left unchanged' further clarifies its patch-like behavior.

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 offers clear usage context: use when you need to modify an existing event, with omitted fields preserved. It also provides key guidance on using clear flags to remove specific fields. However, it does not explicitly compare to alternatives or mention required identifiers like eventIdentifier, so it stops short of a 5.

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. 7 tool updatesv0.1.0
    • First observedcalendar_create_event
    • First observedcalendar_delete_event
    • First observedcalendar_get_event
    • First observedcalendar_list_calendars
    • First observedcalendar_list_events
    • First observedcalendar_permissions
    • First observedcalendar_update_event

TDQS

A4/5.0

Scored across 7 tools

Disambiguation5/5

Each tool targets a distinct action and resource: permissions for access, list_calendars for available calendars, list_events and get_event for reading events, and create/update/delete for writing events. No two tools perform the same function.

Naming Consistency4/5

All tools share the calendar_ prefix and use snake_case, with most following a verb_noun pattern (list_events, create_event). The exception is calendar_permissions, which is noun-only, causing a slight deviation from the otherwise consistent pattern.

Tool Count5/5

Seven tools is well within the ideal range for a focused domain. Each tool (permissions, list calendars, list events, get event, create, update, delete) serves a distinct purpose without redundancy or bloat.

Completeness5/5

The tool set covers the full lifecycle of calendar event management: permission check, listing calendars, listing/fetching events, and create/update/delete. It also handles recurrence edge cases in get/update/delete, leaving no obvious gaps for typical calendar tasks.

Maintenance

ActivityInactive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers