Skip to main content
Glama

One thin, local MCP server for all your calendars. Nextcloud · iCloud · Google · any CalDAV, merged into a single view your agent can read and manage.

npm CI MCP Registry Node Platforms License: MIT

Quick start · Accounts · Connect · Tools · Guardrails · Providers · Contributing

 you   › Find me an hour on Thursday afternoon and put the dentist there.

 agent › find_free_time  start=Thu 12:00  end=Thu 18:00  duration_minutes=60
         ↳ 13:00–15:30 · 16:15–18:00
       › create_event    calendar="icloud/personal"  title="Dentist"  start=Thu 13:00
         ↳ ✓ created  Thu 13:00–14:00  · icloud/personal

         Done. Thursday 13:00 is booked; you're free again from 14:00.

✨ Why

🗂️ One merged view Every calendar on every account in one sorted list, with recurring events expanded. No more "which account was that in?"

🧳 Portable One TOML file with no secrets in it. Secrets are references to your OS secret store, env vars or a password manager, so the same config works on every machine.

🪶 Thin and local Your agent client starts it over stdio when needed. Nothing runs in the background, there's no port open, and no cloud sits in between.

🛡️ Safe by default Deleting events and anything that emails other people stay off until you allow them. Edits never overwrite changes made elsewhere.

Related MCP server: Radicale CalDAV MCP Server

🧭 How it works

flowchart LR
    A["🤖 Agent<br><sub>Claude Code · Claude Desktop · Cursor</sub>"] -- "MCP · stdio" --> P["<b>pim-mcp</b><br><sub>on your machine</sub>"]
    S[("🔐 OS secret store<br><sub>Keychain · Secret Service · DPAPI</sub>")] -. "app passwords / tokens" .-> P
    P -- CalDAV --> N["☁️ Nextcloud"]
    P -- CalDAV --> I["🍎 iCloud"]
    P -- "CalDAV + OAuth" --> G["📅 Google"]
    P -- CalDAV --> O["🌐 any CalDAV"]

🚀 Quick start

Requires Node.js 22+.

npm install -g pim-mcp                         # 1 · install (or prefix commands with `npx -y`)
pim-mcp init                                   # 2 · write ~/.config/pim-mcp/config.toml
pim-mcp secret set pim-mcp/icloud              # 3 · store an app password (prompted, not echoed)
pim-mcp check                                  # 4 · verify every account
claude mcp add pim -s user -- npx -y pim-mcp   # 5 · connect your agent

pim-mcp check lists what it found:

✓ nextcloud (nextcloud) — 3 calendar(s)
    nextcloud/personal               Personal
    nextcloud/work                   Work
✓ icloud (icloud) — 2 calendar(s)
    icloud/family                    Family
    icloud/travel                    Travel

The config lives at ~/.config/pim-mcp/config.toml on every OS (C:\Users\<you>\.config\pim-mcp\config.toml on Windows). Set PIM_MCP_CONFIG to use another path.

🔐 Secrets

Passwords and tokens never go in the config. It holds a reference instead:

Reference

Resolves to

keychain:service/account

your OS secret store. Easiest: pim-mcp secret set service/account

env:NAME

an environment variable

cmd:<command>

a command's output, e.g. cmd:op read op://Private/iCloud/password, cmd:pass show icloud, cmd:bw get password icloud

Stored as generic passwords in your login Keychain. You can also manage them in Keychain Access, or with security add-generic-password -s pim-mcp -a icloud -w.

Needs secret-tool:

sudo apt install libsecret-tools     # Debian / Ubuntu
sudo dnf install libsecret           # Fedora
sudo pacman -S libsecret             # Arch

On a headless machine there's usually no keyring running. Use env: refs (set them in your MCP client's env block) or pass:

password = "cmd:pass show pim-mcp/icloud"

Secrets are encrypted with DPAPI, the per-user encryption Credential Manager also uses. They're stored under %APPDATA%\pim-mcp\secrets\, and only your Windows user on this machine can decrypt them. Nothing to install. cmd: refs run in cmd.exe.

👤 Accounts

  1. Nextcloud → Settings → Security → Devices & sessions → Create new app password

  2. pim-mcp secret set pim-mcp/nextcloud

[[accounts]]
id = "nextcloud"
provider = "nextcloud"
url = "https://your.next.cloud/remote.php/dav"
username = "your-login"
password = "keychain:pim-mcp/nextcloud"
  1. account.apple.com → Sign-In and Security → App-Specific Passwords

  2. pim-mcp secret set pim-mcp/icloud

[[accounts]]
id = "icloud"
provider = "icloud"
username = "you@icloud.com"   # the email you sign into your Apple Account with
password = "keychain:pim-mcp/icloud"

Google only allows OAuth for CalDAV:

  1. Google Cloud Console: create a project and enable the CalDAV API.

  2. OAuth consent screen: choose External and add yourself as a test user. Then set the publishing status to In production, because tokens issued in "Testing" mode expire after 7 days. An "unverified app" warning at sign-in is expected for a personal app.

  3. Credentials → Create OAuth client ID → Desktop app. Put the client ID in the config and store the secret: pim-mcp secret set pim-mcp/google-client-secret

  4. pim-mcp auth google --account google opens your browser and stores the refresh token in your OS secret store.

[[accounts]]
id = "google"
provider = "google"
username = "you@gmail.com"
client_id = "xxxx.apps.googleusercontent.com"
client_secret = "keychain:pim-mcp/google-client-secret"
refresh_token = "keychain:pim-mcp/google"
[[accounts]]
id = "fastmail"
provider = "caldav"
url = "https://caldav.fastmail.com/"
username = "you@fastmail.com"
password = "keychain:pim-mcp/fastmail"

Known URLs are in Providers.

🔌 Connect your agent

Claude Code (any OS)

claude mcp add pim -s user -- npx -y pim-mcp

Claude Desktop, Cursor and other GUI clients. Add this to the client's MCP config:

{
  "mcpServers": {
    "pim": { "command": "npx", "args": ["-y", "pim-mcp"] }
  }
}

GUI apps don't always see your shell's PATH. If the server fails to start, replace npx with the full path from which npx, e.g. /opt/homebrew/bin/npx.

{
  "mcpServers": {
    "pim": { "command": "cmd", "args": ["/c", "npx", "-y", "pim-mcp"] }
  }
}

npx is a batch script on Windows, so it runs through cmd /c.

Claude Desktop isn't available for Linux; use Claude Code or another MCP client with the same command / args as macOS. env: refs go in the client's env block:

"pim": {
  "command": "npx",
  "args": ["-y", "pim-mcp"],
  "env": { "ICLOUD_PASSWORD": "…" }
}

🧰 Tools

Tool

What it does

📚

list_calendars

All calendars and their ids (icloud/work). Anywhere a tool takes a calendar, a plain name works too.

🗓️

list_events

Events from all calendars in a range, merged and sorted. Defaults to today through the next 7 days.

🔎

search_events

Text search over title, location and description.

📄

get_event

Full details: description, attendees, organizer, recurrence rule.

🕐

find_free_time

Free windows of at least N minutes, optionally within working hours.

➕

create_event

Timed or all-day, with recurrence, a reminder, and busy/free status.

✏️

update_event

Changes only the fields you pass. Recurring events take scope: instance or series.

🗑️

delete_event

Off unless allow_delete = true.

What agents see:

  • Times without an offset are in your configured timezone.

  • Output is ISO 8601 with offsets.

  • All-day events use YYYY-MM-DD, and their end date is inclusive.

🛡️ Guardrails

timezone = "Europe/Amsterdam"            # default: the system timezone

[guardrails]
allow_delete  = false                    # delete_event is refused
allow_invites = false                    # no adding attendees, no editing/deleting events that have them

[[accounts]]
# …
read_only           = true               # no writes to this account at all
read_only_calendars = ["Family"]         # protect specific calendars
hide_calendars      = ["Birthdays"]      # don't show these at all
  • Refusals explain themselves. When a guardrail blocks something, the agent is told which setting would allow it, so it asks you instead of retrying.

  • No lost edits. Every write checks the event's ETag. If the event changed elsewhere since it was read, the write fails instead of overwriting.

🌍 Providers

Provider

Status

Setup

Nextcloud / ownCloud

✅&nbsp;tested

nextcloud · https://<host>/remote.php/dav

iCloud

✅&nbsp;tested

icloud · app-specific password

Google Calendar

🧪&nbsp;beta

google · OAuth. Not yet tried with a real account; reports welcome

Fastmail

🟡&nbsp;untested

caldav · https://caldav.fastmail.com/

Yahoo

🟡&nbsp;untested

caldav · https://caldav.calendar.yahoo.com

mailbox.org

🟡&nbsp;untested

caldav · https://dav.mailbox.org/

Posteo

🟡&nbsp;untested

caldav · https://posteo.de:8443/

Radicale · Baïkal · SOGo · Synology

🟡&nbsp;untested

caldav · your server's DAV URL

Outlook · Microsoft 365 · Exchange

🚧&nbsp;wanted

no CalDAV; needs a Microsoft Graph backend

Proton Calendar

❌&nbsp;n/a

no CalDAV or public API

🟡 untested means standard CalDAV that should just work but hasn't been confirmed with pim-mcp yet. Tried one? A PR updating this table is very welcome.

🗺️ Roadmap

  • Calendars over CalDAV: Nextcloud, iCloud, Google, generic

  • macOS · Linux · Windows secret stores

  • Outlook / Microsoft 365 via Microsoft Graph

  • Mail: IMAP / SMTP, same accounts and config

  • Files: WebDAV (Nextcloud, …)

🤝 Contributing

New providers, bug fixes and "it works with X" confirmations are all welcome. See CONTRIBUTING.md for dev setup, a throwaway local CalDAV server for testing, and how to add a provider.

Available Tools

8 tools
create_eventA

Create an event. start as a date makes an all-day event. Without end, timed events last 1 hour and all-day events 1 day.

NameRequiredDescriptionDefault
endNoYYYY-MM-DD for all-day, or YYYY-MM-DDTHH:MM (local to the configured timezone unless it has Z/±HH:MM). For all-day events the end date is inclusive.
busyNoWhether the event blocks time (default: true for timed, false for all-day).
rruleNoiCalendar RRULE, e.g. "FREQ=WEEKLY;BYDAY=MO,WE;COUNT=10". null removes recurrence.
startYesYYYY-MM-DD for all-day, or YYYY-MM-DDTHH:MM (local to the configured timezone unless it has Z/±HH:MM)
titleYes
calendarYesCalendar id (from list_calendars) or exact name.
locationNo
attendeesNoEmail addresses. The server may email invitations.
descriptionNo
alarm_minutesNoReminder N minutes before start; null removes reminders.

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 full burden and does disclose important behavioral rules: a bare date on `start` creates an all-day event, and omitted `end` yields a 1-hour timed event or 1-day all-day event. It omits other side effects such as whether invitations are sent or whether recurrence changes propagate, so it falls short of full disclosure.

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 short sentences, front-loaded with the action, then the two highest-value edge-case rules. No 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 10-parameter mutation tool with no annotations and no output schema, the description covers the two behaviors most likely to cause a wrong call (all-day inference and implicit duration). The remaining parameters are well documented in the schema, so the gap is small but present — side effects like invitation emails and recurrence interaction are not addressed.

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 70%, and the description adds meaning the schema does not: the type of `start` changes the event kind, and the default duration depends on that kind. It says nothing about `busy`, `rrule`, `attendees`, or `alarm_minutes` beyond what the schema already documents.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening 'Create an event' states a specific verb and resource, and the following sentences clarify the scope of the operation via date-type semantics. It is clearly distinguishable from siblings like update_event and delete_event by verb alone, though it never names them.

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?

There is no explicit when-to-use / when-not-to-use statement and no reference to alternatives such as update_event for modifying an existing event. Usage is implied by the verb 'create' and the defaults it describes.

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

delete_eventA
Destructive

Delete an event. For recurring events pass scope ("instance" removes one occurrence, "series" removes all).

NameRequiredDescriptionDefault
idYes
scopeNoRequired for recurring events: "instance" = only this occurrence, "series" = every occurrence.

TDQS

A3.7/5.0
Behavior4/5

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

With destructiveHint=true already declaring the mutation, the description adds the most important missing detail: the blast radius, i.e. that "series" removes every occurrence while "instance" removes only one. What it does not disclose is irreversibility/undo, or what happens when `scope` is omitted on a recurring event — a real ambiguity since scope is not in the required list.

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 short sentences with zero filler; the destructive action is stated first and the conditional scope rule follows immediately. Every clause carries information the agent needs.

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?

For a destructive two-parameter tool with no output schema, the definition covers the recurring-event case but leaves gaps: what `id` refers to, whether deletion is permanent, and the default behavior when `scope` is omitted for a recurring event (the schema does not mark it required, creating a contradiction with "for recurring events pass scope").

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 50%: `scope` is fully documented in the schema and the description largely restates it (instance = one occurrence, series = all), which is mildly helpful but not additive. The `id` parameter has no schema description and is never mentioned in the description, so the agent must infer what identifier is expected (event ID vs. calendar+event pair).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource ("Delete an event"), which cleanly separates it from the create_event/update_event siblings. It stops short of explicitly contrasting itself with those siblings, but the destructive verb makes the intent unambiguous.

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?

It gives one conditional usage rule — pass `scope` for recurring events — but that is parameter guidance rather than when-to-use-this-tool guidance. There is no statement about when deletion is appropriate versus updating, nor any preconditions such as required permissions or ownership.

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

find_free_timeA
Read-only

Free time windows of at least duration_minutes across all (or selected) calendars. Events marked free/transparent and cancelled events do not block time.

NameRequiredDescriptionDefault
endYesYYYY-MM-DD for all-day, or YYYY-MM-DDTHH:MM (local to the configured timezone unless it has Z/±HH:MM). A date-only end includes that whole day.
startYesYYYY-MM-DD for all-day, or YYYY-MM-DDTHH:MM (local to the configured timezone unless it has Z/±HH:MM)
accountsNo
calendarsNo
working_hoursNoOnly return time inside these hours.
duration_minutesYes

TDQS

A4.1/5.0
Behavior4/5

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

readOnlyHint already tells the agent this is a safe read, and the description adds real behavioral content beyond that: free/transparent events and cancelled events do not block time. Still silent on whether free windows are split per day, whether working_hours defaults apply, and timezone resolution beyond what the schema says.

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, zero filler, with the core capability front-loaded and the blocking rule immediately after. Nothing could be cut without losing information.

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 read-only availability query with well-documented date inputs, the definition covers purpose, the key constraint, and the blocking semantics. No output schema exists, but the natural return (windows of >= duration_minutes) is self-evident from the description. Minor gaps around per-day splitting don't make it incomplete for a 6-param query 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?

At 50% schema coverage, the description must compensate. It explains duration_minutes (minimum window length) and hints at calendars ('all (or selected)'), but the 'accounts' parameter and 'working_hours' object are untouched by the description, leaving two parameters documented only thinly or not at all.

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?

States a specific verb+resource ('Free time windows ... across all (or selected) calendars') with a quantified constraint. Among siblings, which are all event CRUD/listing tools, this is unmistakably the availability-computation tool, so no confusion is possible without opening a schema.

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 parenthetical '(or selected) calendars' and the mention of duration_minutes imply the intended scenario (find a slot of a given length), but there is no explicit when-to-use, no prerequisite statement (e.g. calendars must be connected), and no comparison to list_events/search_events.

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

get_eventB
Read-only

Full details of one event (description, attendees, organizer, recurrence rule).

NameRequiredDescriptionDefault
idYes

TDQS

B3.4/5.0
Behavior3/5

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

readOnlyHint=true already tells the agent this is a safe read, so the description's job is reduced. It usefully discloses the shape of the payload (description, attendees, organizer, recurrence rule) in the absence of an output schema, but says nothing about behavior when the id is unknown or about permissions/visibility limits.

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?

A single front-loaded sentence that leads with the retrieval scope and then enumerates the payload; every clause earns its place and nothing is padded.

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 one-parameter read tool with annotation coverage and no output schema, the description adequately conveys both purpose and return fields. The only real omission is the meaning/format of 'id' and any error or visibility caveat.

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 0% and the sole 'id' parameter is undocumented in both schema and description; it is not stated whether this is an event id, a recurring-instance id, or a calendar-scoped id. Since only one self-evidently named parameter exists, this is a modest gap rather than a severe one.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb and resource ('Full details of one event') and enumerates what detail is returned (description, attendees, organizer, recurrence rule), which distinguishes it from list_events and search_events. It stops short of naming those siblings explicitly, so 4 rather than 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no statement of when to use this tool over search_events or list_events, and no prerequisites (e.g., that the id must come from a prior list/search call). An agent must infer the usage pattern from the single required 'id' parameter.

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

list_calendarsA
Read-only

List every calendar across all configured accounts (Nextcloud, iCloud, Google, …), with ids usable in other tools.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true, so the safety profile is covered. The description adds real value by disclosing the multi-account aggregation scope (Nextcloud, iCloud, Google, …) — something the annotations do not say. It does not address what happens if a backend account is unreachable or credentials are missing, which matters for an aggregating 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?

One sentence, front-loaded with the verb and resource, with the cross-account scope and the downstream-use hint packed in without waste.

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?

There is no output schema, and the description compensates by stating the key return property — calendar ids usable in other tools. It stops short of saying what other fields (name, color, provider) come back, which would fully close the gap.

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 takes zero parameters, so the baseline is 4. The description correctly signals that no arguments are needed to scope the listing.

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?

States a specific verb (List) and resource (every calendar) and adds the scope 'across all configured accounts', with provider examples. The resource noun 'calendar' vs. the sibling tools' 'events' makes the distinction immediately obvious.

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 phrase 'with ids usable in other tools' implies the intended workflow: call this first to obtain calendar ids for the event tools. It gives clear context but names no explicit alternatives or when-not conditions.

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

list_eventsA
Read-only

Events in a time range, merged across all calendars and sorted by start. Recurring events are expanded into occurrences. Defaults to today through the next 7 days.

NameRequiredDescriptionDefault
endNoYYYY-MM-DD for all-day, or YYYY-MM-DDTHH:MM (local to the configured timezone unless it has Z/±HH:MM). A date-only end includes that whole day.
startNoYYYY-MM-DD for all-day, or YYYY-MM-DDTHH:MM (local to the configured timezone unless it has Z/±HH:MM)
accountsNoAccount ids to limit to (default: all).
calendarsNoCalendar ids or names to limit to (default: all).

TDQS

A3.8/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, so the safety profile is covered; the description adds genuinely non-obvious behavior: results are merged across all calendars, sorted by start, and recurring events are expanded into occurrences. It stops short of describing pagination, result limits, or return shape.

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?

Three short sentences, front-loaded with the core scope and behavior, and each sentence contributes distinct information (scope, recurrence expansion, defaults). No 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?

A read-only list tool with full schema coverage and a clear behavioral summary; there is no output schema, and the description doesn't explain result shape or limits, but nothing critical to forming a correct call is missing.

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%, so all four parameters (start, end, accounts, calendars) are already documented with formats and defaults. The description only reinforces the default time window and adds nothing about the accounts/calendars filters, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific resource (events) and scope (time range, merged across all calendars, sorted by start) plus the recurrence-expansion behavior, so an agent knows exactly what it gets back. It does not explicitly contrast itself with the sibling search_events, so it falls short of a 5.

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 stated default window (today through the next 7 days) implies when this is the convenient call, but there is no explicit when-to-use/when-not guidance and no pointer to search_events or find_free_time as alternatives. Usage must be inferred from the sibling names.

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

search_eventsA
Read-only

Find events whose title, location or description contains the query (case-insensitive). Defaults to 90 days back through 365 days ahead.

NameRequiredDescriptionDefault
endNoYYYY-MM-DD for all-day, or YYYY-MM-DDTHH:MM (local to the configured timezone unless it has Z/±HH:MM)
queryYes
startNoYYYY-MM-DD for all-day, or YYYY-MM-DDTHH:MM (local to the configured timezone unless it has Z/±HH:MM)
calendarsNo

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, so the safety profile is covered. The description adds valuable behavior beyond annotations: case-insensitive matching across specific fields and a default date window. It omits result limits/pagination and how the calendars filter interacts with the search.

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 tight sentences with no filler; the search scope is front-loaded and the default range follows immediately.

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 read-only search tool with no output schema, the description gives the essentials: matching semantics and default time bounds. It could be more complete by explaining the calendars filter and any result-size limits, but nothing critical to invocation is missing.

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 50%: start/end are documented, while query and calendars are not. The description compensates well for the central query parameter by explaining which fields are searched and case-insensitivity, and it clarifies the default time range tied to start/end. The calendars array remains unexplained.

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?

States a specific verb and resource ('Find events') and specifies the matching fields (title, location, description) and case-insensitivity. This clearly distinguishes text search from list_events and get_event.

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 clear context for use via the query-based search and the default time window (90 days back to 365 days ahead). It does not explicitly name alternatives such as list_events or state when not to use it, but the purpose implies the right usage.

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

update_eventA

Change an event. Only the fields you pass change; moving start alone keeps the duration. For recurring events pass scope.

NameRequiredDescriptionDefault
idYes
endNoYYYY-MM-DD for all-day, or YYYY-MM-DDTHH:MM (local to the configured timezone unless it has Z/±HH:MM). For all-day events the end date is inclusive.
busyNoWhether the event blocks time (default: true for timed, false for all-day).
rruleNoiCalendar RRULE, e.g. "FREQ=WEEKLY;BYDAY=MO,WE;COUNT=10". null removes recurrence.
scopeNoRequired for recurring events: "instance" = only this occurrence, "series" = every occurrence.
startNoYYYY-MM-DD for all-day, or YYYY-MM-DDTHH:MM (local to the configured timezone unless it has Z/±HH:MM)
titleNo
locationNo
attendeesNoEmail addresses. The server may email invitations.
descriptionNo
alarm_minutesNoReminder N minutes before start; null removes reminders.

TDQS

A4/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does deliver genuinely non-obvious behavior: partial updates, and that moving `start` alone preserves duration rather than shifting the whole event. It omits permissions/error behavior and, more importantly, does not warn that `scope: series` mutates every occurrence of a recurring event — a destructive consequence the agent should know about.

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?

Three short sentences, front-loaded with the core action, then the two constraints that matter most. No filler and nothing repeated from the schema.

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 an 11-parameter mutation tool with no annotations and no output schema, the description covers the two areas most likely to cause wrong calls: duration drift and recurrence scoping. Gaps remain around `id` validity, failure modes, and the blast radius of series updates, preventing a 5.

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 64%, and the description reinforces the two trickiest parameters: `start` (duration preserved when moved alone) and `scope` (required for recurring events). However, the only required parameter `id` is undocumented in both schema and description, and it doesn't clarify edge cases like whether changing `rrule` on a recurring event requires a particular scope.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

"Change an event" is a specific verb plus resource, and the partial-update framing distinguishes it in practice from create_event and delete_event. It never names a sibling explicitly, so differentiation is implied rather than stated.

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?

Clear operating context: patch semantics ("only the fields you pass change") tells the agent to use this rather than delete-and-recreate, and "For recurring events pass `scope`" is a concrete conditional instruction. It stops short of stating exclusions or naming alternatives such as create_event/delete_event for the cases this tool shouldn't handle.

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. 8 tool updatesv0.1.0
    • First observedcreate_event
    • First observeddelete_event
    • First observedfind_free_time
    • First observedget_event
    • First observedlist_calendars
    • First observedlist_events
    • First observedsearch_events
    • First observedupdate_event

TDQS

A4/5.0

Scored across 8 tools

Disambiguation5/5

Each tool maps to a distinct retrieval or mutation strategy: list_events filters by time range, search_events filters by text query, and get_event fetches a single event by id. find_free_time and the create/update/delete trio are unmistakable. No two tools overlap in a way that would cause misselection.

Naming Consistency5/5

All eight tools follow the same snake_case verb_noun pattern (list_, search_, get_, find_, create_, update_, delete_). The verb choice matches the operation type consistently, and the resource noun is always the trailing token.

Tool Count5/5

Eight tools is well within the healthy 3-15 range and every tool earns its place: discovery, three read modes, availability lookup, and full mutation coverage. Nothing feels padded or redundant.

Completeness4/5

Event lifecycle is fully covered (list/search/get/create/update/delete) with sensible recurrence scope and availability handling. Minor gaps remain around attendee interactions — no RSVP/accept-decline tool and calendars themselves can only be listed, not created or modified.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    F
    maintenance
    Enables interaction with any CalDAV-compatible calendar server (Yandex, Google, Nextcloud, iCloud, etc.) to list calendars, create/manage events with reminders and attendees, search events, and handle recurring events through natural language.
    15
    -
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI assistants to connect to calendar servers and manage events and tasks, including listing calendars, querying timeframes, creating, updating, completing, and deleting items through tools.
    3,018 npm
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI assistants to connect to CalDAV servers and manage calendars, events, and tasks through tools for listing, creating, updating, completing, and deleting items.
    3,018 npm
    MIT