Skip to main content
Glama

dav-mcp

CI

An MCP server for Apple iCloud Calendar and Contacts, over CalDAV and CardDAV. One Apple ID, one app-specific password, one endpoint.

It exposes the same calendar surface the Fastmail MCP server does — list, search, create, update, delete, RSVP — so a model that has driven one can drive the other without relearning field names, plus find_free_time for scheduling. It runs over stdio locally, or over authenticated HTTP for a remote client such as a Claude connector.

No local app, no EventKit, no AppleScript: it talks to caldav.icloud.com directly, so it does not need to run on the machine your calendar is synced to, and it needs none of the macOS privacy grants that an EventKit-based server does.

Tools

Tool

What it does

list_calendars

Calendar ids, names and colors. Event calendars only; reminder lists are out of scope.

search_events

List a period or search it. Recurring events come back expanded, one result per occurrence, each independently addressable.

create_event

Create a timed, all-day, or recurring event.

update_event

Change any field. Given an occurrence id, edits that occurrence alone; given the series id, edits the series.

delete_event

Delete an event. Given an occurrence id, cancels that occurrence and leaves the series intact.

rsvp_event

Respond to an invitation: accepted, tentative or declined.

find_free_time

Find openings long enough for something, honoring working hours and what actually counts as busy.

search_contacts

Name, email, phone or organization → contacts with every way of reaching them.

create_contact

Add a contact.

update_contact

Change a contact. Emails and phones use add/remove deltas.

delete_contact

Remove a contact.

list_address_books

Address book ids. Most accounts have exactly one.

GET /health is served unauthenticated alongside them, for monitoring.

Invitations send real mail

create_event(participants=…), update_event(addParticipants=…/removeParticipants=…) and rsvp_event all cause iCloud to send iMIP email, immediately and irrevocably. iCloud advertises calendar-auto-schedule, so it does the sending itself the moment a PUT lands — this server never touches SMTP and has no way to recall anything.

Two consequences worth knowing before wiring this to a model:

  • Any edit to an event that already has guests mails all of them, including a one-word title fix. The tools say so in their replies rather than presenting such an edit as silent.

  • The organizer address must be one of the account's own calendar-user-addresses. iCloud accepts a PUT naming a foreign organizer and then silently sends nothing, which is indistinguishable from success — so from is validated against the account's real identities before writing.

  • Sending is not the same as delivering. After a write that touches participants, the event is re-read and iCloud's per-attendee SCHEDULE-STATUS is reported: who it reached, and who it did not. An address whose mail server refuses the message comes back 5.1, and the tool says so rather than claiming the invitation was sent.

What counts as busy

find_free_time exists because slot arithmetic across a week is exactly what models get wrong, and because "am I free" is not the same question as "what is on my calendar". Three kinds of event are deliberately not treated as busy:

  • Events marked freeTRANSP:TRANSPARENT, the standard "on my calendar but not occupying me" signal — and cancelled events.

  • Invitations the user declined. Apple leaves them on the calendar, and counting a meeting you refused would block the week with things you are not attending. Not having replied yet still counts as busy.

  • All-day events. Whether one occupies the day is genuinely ambiguous — a birthday does not, a multi-day trip does — so rather than guess, they are excluded from the arithmetic and listed separately in the reply.

Openings are reported at their full length rather than trimmed to the requested duration: knowing a two-hour gap exists is more useful than being told an hour fits somewhere in it.

Related MCP server: iCloud CalDAV MCP Connector

Setup

Requires Python 3.12+ and uv.

uv sync
cp .env.example .env      # then fill in the two credentials

APPLE_APP_PASSWORD is an app-specific password generated at appleid.apple.com, not your Apple ID password. A two-factor account rejects the account password outright.

uv run dav-mcp                              # stdio
DAV_MCP_TRANSPORT=http uv run dav-mcp  # http on 127.0.0.1:18790

To use it from Claude Code over stdio:

claude mcp add calendar -- uv --directory /path/to/dav-mcp run dav-mcp

Configuration

Everything is environment variables; nothing is read from .env by the server itself, which only documents them.

Variable

Default

Meaning

APPLE_ID

Apple ID email. Required.

APPLE_APP_PASSWORD

App-specific password. Required.

DAV_MCP_DEFAULT_CALENDAR

first writable

Calendar create_event writes to when the caller names none, by id or display name.

DAV_MCP_TIMEZONE

host zone

IANA zone assumed when a caller omits timeZone.

DAV_MCP_CALDAV_ROOT

https://caldav.icloud.com

CalDAV entry point.

DAV_MCP_TRANSPORT

stdio

stdio or http.

DAV_MCP_HOST

127.0.0.1

HTTP bind address.

DAV_MCP_PORT

18790

HTTP bind port.

DAV_MCP_STATELESS

true

false restores per-client sessions.

DAV_MCP_AUTH

none

none or password. HTTP only.

DAV_MCP_PASSWORD

Shared password. Required when AUTH=password.

DAV_MCP_BASE_URL

Public URL; becomes the OAuth issuer. Required when AUTH=password.

DAV_MCP_STATE_DIR

~/.dav-mcp

Where OAuth state is persisted.

Set DAV_MCP_DEFAULT_CALENDAR. iCloud does not publish schedule-default-calendar-URL — it comes back empty — so with nothing configured the only available tie-break is the order the server happens to list collections in, which changes the moment you add a calendar to the account.

Authentication

A remote MCP client has one input field: a URL. There is nowhere to put an API key. So DAV_MCP_AUTH=password starts a self-contained OAuth 2.1 authorization server whose only credential is one shared password — the client discovers it, registers itself, and gets redirected to a password form.

Dynamic client registration, PKCE, discovery metadata and the 401 challenge come from FastMCP and the MCP SDK. This project adds the login screen and the credential check. Registered clients and tokens persist across restarts; authorization codes and in-flight logins are deliberately memory-only.

Bind to localhost and put a tunnel or reverse proxy in front of it. See docs/deployment-macos.md.

Notes on iCloud

Findings that shaped the implementation, each verified against a live account rather than taken from the spec:

  • Recurrence is expanded server-side. calendar-query honors <C:expand>, so occurrences arrive individually with their own RECURRENCE-ID. There is no local expansion and no cache — ranged queries are fast enough not to need one.

  • Text search and time ranges are mutually exclusive. RFC 4791 permits a prop-filter alongside a time-range, but iCloud silently ignores the text match when both are present, and rejects the reverse order with a 412. So query is matched client-side, which also lets it cover descriptions, locations and participants rather than titles alone.

  • RECURRENCE-ID comes back in UTC while DTSTART stays in the event's own zone. Event ids therefore carry the literal server form of the key and only ever round-trip it; the human-readable recurrenceId is converted for display.

  • Scheduling is the server's job, not ours. OPTIONS advertises calendar-auto-schedule, so an ORGANIZER plus ATTENDEEs on a PUT is all it takes to send invitations, and changing your own PARTSTAT is all it takes to reply.

  • CardDAV under-reports, where CalDAV over-reported. The address book's supported-report-set lists only addressbook-multiget and sync-collection — yet addressbook-query works and genuinely filters (1 match out of 913 cards). Believing the advertisement would have meant downloading the whole book to filter locally. The rule for iCloud is to test the behavior, in either direction.

  • A contact card carries far more than any tool surface models — photos, social profiles, related names, Apple's own bookkeeping. So update_contact mutates the parsed card in place and never rebuilds it from a dict, which would silently delete all of that.

  • Writability is reported differently per protocol: calendars come back with the write-content privilege, address books with plain write. Checking only one marks the other read-only and refuses every write.

Development

uv sync --extra test
uv run pytest

The suite is entirely offline — no test touches iCloud. Fixtures reproduce the exact payload shapes iCloud returns, with identities replaced.

For manual verification against a real account, create a scratch calendar and point calendarId at it. Do not run write experiments against a calendar you care about.

License

MIT

Available Tools

7 tools
create_eventA

Create a calendar event. Returns the new event's id.

Use update_event to change an existing event.

ParametersJSON Schema
NameRequiredDescriptionDefault
fromNoEmail address to organize the event from when inviting participants. Must match one of the account's own addresses. If omitted, the account's primary address is used.
colorNoDisplay color, as a six-digit hex value (e.g. "#ff0000").
startYesStart date-time in ISO 8601 format (e.g. "2026-03-15T14:00:00").
titleYesEvent title.
durationNoDuration in ISO 8601 format, e.g. "PT1H" (1 hour) or "PT30M" (30 minutes). For an all-day event set isAllDay and give a whole-day duration like "P1D" or "P2D". Defaults to PT1H, or P1D when isAllDay.
isAllDayNoSet true for a true all-day (date-only) event such as a birthday, holiday, or multi-day trip. All-day events float: they have no time of day and no time zone, and never shift when viewed in another zone. Give 'start' as a date ("2026-07-03"; any time part is ignored) and 'duration' in whole days. (Note: a midnight start with duration P1D is NOT an all-day event -- it is a 24-hour timed block. Use this flag instead.)
locationNoLocation name or address.
timeZoneNoIANA time zone (e.g. "America/New_York"). Defaults to the server's zone. Ignored for all-day events, which have no time zone.
calendarIdNoCalendar to add the event to. Use list_calendars to find calendar IDs. Defaults to the user's first writable calendar.
recurrenceNoMake this a recurring event. Properties: frequency (required, one of "daily", "weekly", "monthly", "yearly"), interval (repeat every N, default 1), byDay (array of day codes for weekly: ["mo","tu","we","th","fr","sa","su"]), count (stop after N occurrences), until (stop after this date-time). Examples: {"frequency": "weekly"}; {"frequency": "weekly", "interval": 2, "byDay": ["mo","we","fr"]}.
descriptionNoEvent description or notes.
participantsNoInvitees, e.g. [{"name": "Jo", "email": "jo@example.com"}]. The account is added automatically as organizer; do not include it here. THIS SENDS REAL INVITATION EMAILS immediately, and they cannot be recalled -- omit this argument unless the user asked for guests.

TDQS

A3.8/5.0
Behavior2/5

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

With no annotations, the description carries the full burden, but it only mentions creating an event and returning an id. It omits important behavioral traits such as the permanence of creation, that non-default parameters like participants may send irreversible invitation emails, or any permission requirements.

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 primary action, and includes only essential supplementary guidance. No filler or redundant information.

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?

Despite a rich schema, the tool has 12 parameters and no annotations, and the description lacks critical context such as the participant email side effect, calendar selection default, or all-day event nuances. These details exist in the schema but are not surfaced in the description, making it insufficient for an agent to safely invoke the tool without deep parameter inspection.

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%, with detailed parameter descriptions for all 12 fields, so the baseline is 3. The tool description itself adds no parameter-level meaning beyond what the schema already provides.

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 calendar event' with a specific verb and resource, and notes it returns the new event's id. This distinguishes it from sibling tools like list_calendars, search_events, and update_event, especially with the explicit pointer to update_event for modifications.

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?

It explicitly states when to use the tool (to create a new calendar event) and gives an alternative for a related operation: 'Use update_event to change an existing event.' This provides a clear when-not and alternative, covering the main ambiguity.

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.

For recurring events, pass an occurrence id to cancel just that occurrence, or the master id to delete the entire series.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesThe event ID to delete, as returned by search_events.

TDQS

A4.4/5.0
Behavior4/5

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

No annotations are provided, so the description must carry the burden of behavioral disclosure. It does so by explaining the destructive difference between deleting one occurrence versus the entire series. It doesn't mention permissions or irreversibility, but the verb 'delete' plus the series nuance covers the main risk.

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: the first states the action, the second provides the only necessary conditional guidance. No filler or repetition of schema details.

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 single-parameter delete tool with no output schema and no annotations, the description sufficiently covers the key scenario (recurring events) and the source of the ID is in the schema. Minor missing details like return value or explicit irreversibility are not critical given the tool's simplicity.

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% and the schema describes 'id' as 'the event ID to delete, as returned by search_events.' The description adds meaning by explaining that the same parameter can be an occurrence id or a master id, which is critical for recurring events and goes beyond the schema description.

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?

Description uses a specific verb and resource: 'Delete a calendar event.' The recurring-event clause clarifies the scope of deletion, distinguishing it from siblings like update_event (modification) and search_events (querying).

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?

Provides explicit operational guidance for recurring events: 'pass an occurrence id to cancel just that occurrence, or the master id to delete the entire series.' This tells the agent when to use which ID, though it doesn't explicitly list alternative tools for other use cases.

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

find_free_timeA

Find open slots on the user's calendars that are long enough for something.

Use this to answer "when am I free for X" or to pick a time before calling create_event. To ask what is already scheduled, use search_events instead.

Openings are reported at their full length, not trimmed to 'duration', so a two-hour gap is reported as two hours even when asked for one.

Not counted as busy: events marked free (TRANSP:TRANSPARENT), cancelled events, and invitations the user declined. All-day events are also not counted -- a birthday does not occupy the day -- but any that overlap the search are listed separately so they can be taken into account.

ParametersJSON Schema
NameRequiredDescriptionDefault
afterNoEarliest time to consider. ISO 8601 or a relative expression ("today", "tomorrow", "2 weeks from now"). Defaults to now.
limitNoMaximum number of openings to return (default 10, max 50).
beforeNoLatest time to consider. Same formats. Defaults to two weeks from now.
dayEndNoLatest hour of day to offer, "HH:MM". Defaults to "17:00".
dayStartNoEarliest hour of day to offer, "HH:MM". Defaults to "09:00". Pass "00:00" together with dayEnd "23:59" to search around the clock.
durationYesHow long the slot needs to be, ISO 8601, e.g. "PT1H" or "PT30M".
calendarIdsNoRestrict to these calendars. Defaults to all of them.
includeWeekendsNoOffer Saturday and Sunday too. Defaults to false.

TDQS

A4.6/5.0
Behavior4/5

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

Since no annotations are provided, the description carries the full burden of behavioral transparency. It discloses important behaviors: openings reported at full length, not trimmed to duration; events not counted as busy (free, cancelled, declined), and all-day events not counted but listed separately. The only missing detail is the exact return format, but the description covers key edge cases.

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 well-structured and appropriately sized. It is front-loaded with the core purpose, then provides usage guidance, then behavioral details. Every sentence earns its place, covering purpose, usage, alternative, and behavioral nuances without redundancy or fluff.

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 the parameter count of 8, no output schema, and no annotations, the description is quite comprehensive. It addresses key behavioral edge cases (full-length reporting, non-counted events, all-day events) that are not apparent from the schema. Minor gap: it does not explain the default time range or how openings are returned (e.g., start/end times), but the input schema covers defaults. Overall, it provides sufficient context for an agent to use the tool effectively.

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 schema already has 100% coverage for parameters, so the baseline is 3. The description adds value by explaining the semantics of the 'duration' parameter in relation to output behavior (full length not trimmed), which informs interpretation of the duration input. It also clarifies the treatment of all-day events, which relates to how parameters like includeWeekends and dayStart/dayEnd might interact. The description does not repeat parameter descriptions but adds contextual meaning.

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 finds open slots on the user's calendars, specifying the requirement of sufficient length. It distinguishes from search_events, which is about existing events, by noting the intended use for availability queries and pre-event planning. The verb 'find' is specific to the resource 'open slots' and the scope is user's calendars.

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?

The description explicitly provides when to use the tool: to answer 'when am I free for X' or to pick a time before calling create_event. It also gives an explicit alternative: 'To ask what is already scheduled, use search_events instead.' This is clear usage guidance with exclusions and alternative, matching the highest benchmark.

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

list_calendarsA

List the user's calendars.

Returns calendar IDs, names, and colors. Use this to find which calendar to add events to. Only calendars that hold events are listed; reminder lists are not part of this server's surface.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden. It states the key behavioral nuance that only calendars holding events are returned, and reminder lists are excluded. It does not explicitly state it is read-only, but that is implicitly clear from the verb 'list.' A slightly stronger disclosure of side-effect-free behavior would warrant a 5.

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 primary purpose, and every clause adds value. No redundant or filler wording.

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?

Despite having no output schema, the description explains the return values (IDs, names, colors) and the filtering behavior. It is complete for a simple list operation with no parameters.

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 schema fully covers this aspect. The description adds no parameter-specific information, but none is needed. A baseline of 4 is given per instructions for zero-parameter tools.

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 purpose: 'List the user's calendars.' It specifies the resource (calendars), the action (list), and the returned data (IDs, names, colors). It also distinguishes itself from sibling event-management tools by noting its role in finding a calendar to add events to.

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?

The description explicitly instructs when to use it: 'Use this to find which calendar to add events to.' It also provides an exclusion—'Only calendars that hold events are listed; reminder lists are not part of this server's surface'—which helps avoid misuse.

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

rsvp_eventA

Respond to a calendar event invitation.

Sets your participation status and sends a reply to the organizer.

For a recurring event, pass an occurrence id to respond for that occurrence alone, or the series id to respond to the whole series.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesThe event ID to RSVP to, as returned by search_events.
statusYesYour response: accepted (going), tentative (maybe), or declined (not going).

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 carries the burden of disclosing behavior. It states that it 'sets your participation status and sends a reply to the organizer,' which implies a write operation and communication side effect. However, it doesn't mention any potential consequences (e.g., whether the reply is sent to all attendees, if there are any restrictions on changing status, or if there's a confirmation step). The description is adequate but not rich in behavioral detail.

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 and well-structured. It opens with a clear one-sentence purpose, then adds a brief note about the side effect (sending a reply), and finally provides specific guidance for recurring events. Every sentence adds value without unnecessary fluff.

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 the tool's simplicity (2 parameters, no output schema, no nested objects), the description is fairly complete. It covers the main action, the side effect, and the special case of recurring events. It could mention whether the tool is idempotent or if there are any prerequisites (e.g., must be an invitee), but for a simple RSVP tool, this is sufficient.

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 input schema already provides 100% coverage for both parameters: 'id' is described as 'The event ID to RSVP to, as returned by search_events' and 'status' is described with the allowed values. The description adds context about recurring events (occurrence id vs series id) but doesn't add much beyond the schema. Since schema coverage is high, a baseline of 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 the tool's purpose: 'Respond to a calendar event invitation' and specifies the action of setting participation status and sending a reply to the organizer. It distinguishes itself from sibling tools like create_event, update_event, and delete_event by focusing on the RSVP action.

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 (responding to an invitation) and includes specific guidance for recurring events, explaining how to handle occurrences vs. the whole series. It doesn't explicitly mention when not to use it or name alternatives, but the context is sufficient for most cases.

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

search_eventsA

List or search calendar events.

To list a period (e.g. "what's on tomorrow"), pass only 'after'/'before' and omit 'query'. Recurring events are expanded into individual occurrences, so each occurrence has its own ID and can be updated or deleted independently.

Returns full details including title, start, duration, time zone, description, locations, participants with RSVP status, and recurrence info.

ParametersJSON Schema
NameRequiredDescriptionDefault
afterNoOnly return events starting at or after this time. Accepts ISO 8601 ("2026-03-15", "2026-03-15T14:00:00") or a relative expression ("now", "today", "tomorrow", "yesterday", "3 days ago", "2 weeks from now"). Defaults to 3 months ago.
limitNoMaximum number of results (default 10, max 50).
queryNoOptional free-text filter against titles, descriptions, locations and participants. Omit to return everything in the range; never pass a placeholder like "a" or "*".
beforeNoOnly return events starting before this time. Same formats as 'after'. Defaults to 12 months from now.
calendarIdNoRestrict the search to one calendar. Defaults to all of them.

TDQS

A4.5/5.0
Behavior4/5

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

No annotations are provided, so the description carries the transparency burden. It discloses non-obvious behavior—'Recurring events are expanded into individual occurrences, so each occurrence has its own ID and can be updated or deleted independently'—which is critical for an agent to know. It also enumerates the return fields, compensating for the lack of an output schema. This goes beyond the name and provides meaningful behavioral context.

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 compact and information-dense: a short purpose statement, a usage tip, a key behavioral note, and a return-details list. No sentences are redundant, and the most relevant facts appear early.

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?

For a search/list tool with five optional parameters and no output schema, the description covers the essential guidance: how to invoke, what behavior to expect (recurring expansion), and what results will contain. It does not spell out every default (those are in the schema) or mention ordering/result sorting, but for the tool's complexity it is sufficiently complete. The absence of annotations is compensated by this content.

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%, so the baseline is 3. The description adds a semantic distinction between passing 'query' versus only after/before to switch between search and list modes, which complements the schema descriptions. This helps the agent select the right combination of parameters for the user's intent.

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 'List or search calendar events,' clearly identifying the action and resource. It distinguishes this from siblings like create_event/update_event/delete_event by focusing on listing/searching, and from list_calendars by targeting events. The recurring-event detail also clarifies a distinct 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 gives explicit guidance on when to use listing vs searching: 'To list a period... pass only after/before and omit query.' This instructs the agent how to select parameters based on intent. It does not explicitly name alternative tools for other operations, but the context is clear enough; the absence of exclusions is why it isn't a 5.

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.

Use create_event for new events. Only specified fields are changed. For recurring events, pass an occurrence ID (from search_events) to modify just that single occurrence, or the master ID to change the whole series.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesID of the event to update, as returned by search_events.
fromNoEmail address to organize from when adding the first participants. Must match one of the account's own addresses. Has no effect when the event already has an organizer.
colorNoSix-digit hex color. Pass an empty string to clear it and inherit from the calendar.
startNoStart date-time in ISO 8601 format (e.g. "2026-03-15T14:00:00").
titleNoEvent title.
durationNoDuration in ISO 8601 format, e.g. "PT1H" or "P1D".
isAllDayNoSet true to convert this into a true all-day (date-only, floating) event, or false to convert one back into a timed event.
locationNoLocation name or address. Pass an empty string to clear.
timeZoneNoIANA time zone. Ignored for all-day events.
recurrenceNoRecurrence rules, same shape as create_event's recurrence. Only meaningful on a series master.
descriptionNoEvent description or notes. Pass an empty string to clear.
addParticipantsNoInvitees to add, e.g. [{"name": "Jo", "email": "jo@example.com"}]. Duplicates against existing invitees are skipped. SENDS REAL INVITATION EMAILS.
removeParticipantsNoInvitees to uninvite, by email or display name. Matching is case-insensitive; a name matching more than one invitee is an error, so pass the email to disambiguate. The organizer is never removed. SENDS REAL CANCELLATIONS.

TDQS

A4.6/5.0
Behavior4/5

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

The description discloses that only specified fields are changed, giving transparency about its mutation behavior. It does not explicitly mention potential side effects like sending invitation emails, but that is detailed in parameter descriptions; given no annotations, the description provides reasonable transparency.

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, using two sentences to convey the core function and key usage instructions without unnecessary detail.

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 covers the essential context: update existing, create for new, only specified fields, and recurring event handling. It does not discuss output or errors, but given the simple update operation and no output schema, it is sufficiently complete.

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 description adds value to the id parameter by clarifying that a recurrence ID targets a single occurrence while the master ID affects the whole series, enhancing understanding beyond the schema's basic description.

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, and distinguishes it from create_event for new events, making the purpose unambiguous.

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?

It provides explicit guidance on when to use this tool (update) versus create_event, and explains how to handle recurring events by specifying occurrence vs master ID, covering the main usage scenarios.

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. Dates show when Glama detected each change.

  1. 7 tool updatesv0.1.0
    • First observedcreate_event
    • First observeddelete_event
    • First observedfind_free_time
    • First observedlist_calendars
    • First observedrsvp_event
    • First observedsearch_events
    • First observedupdate_event

TDQS

A4.4/5.0
Disambiguation5/5

Each tool has a distinct purpose. list_calendars handles calendar metadata, search_events and find_free_time are clearly separated (scheduled events vs open slots), and CRUD operations plus RSVP are all unique. No overlapping or ambiguous tools.

Naming Consistency5/5

All tools use snake_case with a consistent verb_noun pattern: list_calendars, create_event, search_events, find_free_time, update_event, rsvp_event, delete_event. The naming is predictable and uniform.

Tool Count5/5

7 tools is well-scoped for a calendar server. The count covers essential operations without bloat, each tool earning its place in the surface.

Completeness5/5

The surface provides full lifecycle coverage: create, read (search), update, delete, plus calendar enumeration, free-time discovery, and event RSVP. No critical operations are missing for typical calendar workflows.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/duanefields/dav-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server