mcp-caldav
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-caldavwhat's on my calendar and Room A today?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-caldav
A small, read-only CalDAV MCP server that exposes an explicit set of CalDAV calendars to an agent.
The project is designed for CalDAV installations where collection URLs are already known, for example:
https://caldav.example.test/calendars/calendar-user/personal/
https://caldav.example.test/calendars/team/shared/
https://caldav.example.test/calendars/rooms/room-123/It performs no autodiscovery.
Principles
read-only by design: no MCP write tools and no mutation business methods;
calendar URLs are explicitly declared in YAML;
credentials are referenced through environment variables and never stored in YAML;
an allowlist of URL prefixes bounds network destinations;
HTTPS is required by default and TLS validation is enabled;
requests run concurrently across calendars, but are serialized per calendar;
CalDAV searches and returned result sets are bounded;
event content is explicitly marked as untrusted;
long descriptions and control characters are sanitized before reaching the LLM;
logs go exclusively to stderr, which is compatible with MCP stdio transport.
The code is new. Its general organization is informed by patterns found in existing calendar MCP servers, particularly explicitly configured multi-calendar setups, without reusing their implementation.
Related MCP server: calendar-mcp
Installation
Requirements: Python 3.12+ and uv.
cp config.example.yaml config.yaml
cp .env.example .env
# Load your secrets using your usual process.
export CALDAV_USERNAME="calendar-user"
export CALDAV_PASSWORD="..."
export MCP_CALDAV_CONFIG="$PWD/config.yaml"
uv sync
uv run mcp-caldavThe server uses stdio, the natural transport for OpenCode, OMP, Claude
Desktop, and other local MCP hosts.
Configuration
Minimal example:
version: 1
settings:
timezone: Europe/Paris
allowed_url_prefixes:
- "https://caldav.example.test/calendars/"
credentials:
example:
username_env: CALDAV_USERNAME
password_env: CALDAV_PASSWORD
auth_type: basic
calendars:
- name: me
label: "My calendar"
url: "https://caldav.example.test/calendars/calendar-user/personal/"
credentials: example
- name: room-a
label: "Room A"
url: "https://caldav.example.test/calendars/rooms/room-123/"
credentials: examplename is the stable identifier used by the LLM. label is the human-readable
name. url must always be the exact CalDAV collection URL.
Network security
allowed_url_prefixes is strongly recommended. Matching compares the scheme,
host, port, and normalized path; it does not use a naïve startswith() check.
URLs containing a username, password, query string, or fragment are rejected.
require_https: true is the default. Disable it only in an isolated development
environment.
Credentials
Each profile contains the names of environment variables:
credentials:
example:
username_env: CALDAV_USERNAME
password_env: CALDAV_PASSWORD
auth_type: basicPasswords are never serialized in MCP responses or written to logs.
MCP tools
The server exposes exactly three tools:
list_calendars
Returns the explicitly configured calendars.
list_events
Parameters:
calendars: optional list of names; empty means all calendars;start,end: ISO 8601; empty means today in the configured time zone;query: optional local text filter for title, location, description, and organizer;limit: maximum number of returned results;include_description: defaults tofalseto limit exposed context.
Recurrences are requested with expand=True over a closed time range.
get_event
Retrieves an event by calendar and uid.
For a recurring event, list_events is the most reliable view for retrieving a
specific occurrence in a time window.
OpenCode / OMP configuration
Generic example:
{
"mcp": {
"caldav": {
"command": "uv",
"args": [
"--directory",
"/path/to/mcp-caldav",
"run",
"mcp-caldav"
],
"env": {
"MCP_CALDAV_CONFIG": "/path/to/mcp-caldav/config.yaml",
"CALDAV_USERNAME": "calendar-user",
"CALDAV_PASSWORD": "..."
}
}
}
}Adjust the exact syntax for your chosen MCP client.
Development
uv sync --group dev
make test
uv run ruff check .Releases
Run make release from a clean branch to run the test suite, update
CHANGELOG.md, create an annotated release tag, and push the release commit
and tag to origin in one atomic publication.
Tags use the current date (YYYYMMDD). When a tag for that date already
exists locally or on origin, the command chooses the next available suffix,
such as YYYYMMDD-1. Changelog entries are generated from commit subjects
since the preceding dated release tag.
The default remote is origin. To publish to a different configured remote,
set RELEASE_REMOTE, for example RELEASE_REMOTE=upstream make release.
For the MCP Inspector:
uv run --with "mcp[cli]" mcp dev src/mcp_caldav/server.pyTrust boundary
Calendar data is external input. An appointment's title, description, or location can contain text hostile to an LLM.
The server therefore returns:
{
"content_is_untrusted": true
}and bounds and sanitizes text. This reduces the attack surface but is not a complete defense against prompt injection.
The real protection is structural:
no MCP write tools;
no write business functions and an HTTP guard for DAV methods;
no arbitrary URL supplied by the model;
ideally, a dedicated CalDAV account with read-only ACLs on the server.
Point 4 remains the strongest barrier.
This server cannot be deployed
Maintenance
Related MCP Connectors
Read-only access to a Lumin project's logs, metrics, uptime checks, alerts and infrastructure.
Read-only Search Console analytics, URL inspection, indexing diagnostics, and sitemaps.
Read-only access to Genie accounts, transactions, investments, and financial summaries.
Read-only senior-care exit routes, duplicate-referral deadlines, and templates; no PII or sending.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol server that provides read-only access to the Google Calendar API v3. It enables users to list calendars, search for events, check free/busy availability, and retrieve calendar settings.MIT
- AlicenseNot gradedqualityCmaintenanceProvides read-only access to calendar events from iCal feeds, enabling agents to query schedules, search events, and check availability via natural language.AGPL 3.0
- AlicenseNot gradedqualityCmaintenanceThis MCP server enables Claude to read and manage self-hosted CalDAV calendars (SOGo, Nextcloud, Radicale, etc.) with strict safety guardrails: read-only by default, optional writes only when explicitly enabled, no permanent deletes, and no event invitations.MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI clients to remotely read and edit a single iCloud Calendar account, including events, availability, and invitations, without requiring an Apple device to stay online.18 npmMIT