caldav-mcp
Allows managing iCloud calendars via CalDAV, including creating, reading, updating, and deleting events as well as handling attendees.
Provides read/write access to Nextcloud calendars via CalDAV, enabling event creation, retrieval, updating, deletion, search, and attendee management.
Provides read/write access to ownCloud calendars via CalDAV, enabling event creation, retrieval, updating, deletion, search, and attendee management.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
caldav-mcp
Give AI assistants full read/write access to any CalDAV calendar.
A self-hosted MCP bridge between AI assistants and CalDAV servers. Connect Claude, Cursor, VS Code, and others to Nextcloud, Radicale, Baikal, and any RFC 4791 server through a single Docker container.
What problem does it solve
Bridges any MCP-compatible AI client (Claude, Cursor, VS Code, Codex, …) to any RFC 4791 CalDAV server (Nextcloud, Radicale, Baikal, …) so the assistant can read and write your calendar directly.
Ask your assistant:
"What's on my calendar tomorrow?" —
caldav_get_today_events"Create a meeting next Tuesday at 14:00." —
caldav_create_event"Move this event to my personal calendar." —
caldav_move_event"When am I free next week?" —
caldav_get_freebusy
Related MCP server: calendar-mcp
What it does NOT do
No stdio transport — Streamable HTTP only. To use stdio, modify
server.pyto callmcp.run()instead ofmcp.run_http_async().Not a CalDAV server — you need an existing CalDAV server (Nextcloud, Radicale, Baikal, etc.).
No iTIP/imip scheduling — attendees are stored on events, but no email invitations or scheduling messages are sent.
Client-side search —
caldav_search_eventsfetches all events and filters locally. Works well for small-to-medium calendars; may be slow on very large ones.Non-atomic move —
caldav_move_eventcopies the event then deletes the original. A failure after copy leaves a duplicate (the safer failure mode).No hot-reload — config changes require a server restart. The store is frozen into an immutable singleton at startup.
Self-hosted only — not a SaaS. You run and operate the server yourself.
Quick start
docker-compose
services:
caldav-mcp:
image: ghcr.io/gelse/caldav-mcp:latest
ports:
- "8600:8080"
environment:
CALDAV_URL: https://cloud.example.com/remote.php/dav/calendars/user/
CALDAV_USERNAME: user
CALDAV_PASSWORD: app-password
CALDAV_MCP_API_KEY: your-secret-token
TZ: Europe/Viennadocker compose up -dNote:
CALDAV_URL,CALDAV_USERNAME, andCALDAV_PASSWORDare optional. When set,X-Caldav-*request headers are ignored (environment mode). When omitted, sendX-Caldav-Url,X-Caldav-Username, andX-Caldav-Passwordheaders per request (header mode).
Verify
curl -s http://localhost:8600/mcp \
-H "Authorization: Bearer your-secret-token" \
-H "X-Caldav-Url: https://cloud.example.com/remote.php/dav/calendars/user/" \
-H "X-Caldav-Username: user" \
-H "X-Caldav-Password: app-password" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1"}}}'MCP client config
{
"mcpServers": {
"caldav": {
"type": "http",
"url": "http://localhost:8600/mcp",
"headers": {
"Authorization": "Bearer YOUR_API_KEY",
"X-Caldav-Url": "https://cloud.example.com/remote.php/dav/calendars/user/",
"X-Caldav-Username": "user",
"X-Caldav-Password": "app-password"
}
}
}
}Client-specific config files (Claude Desktop, Claude Code, Cursor, VS Code, OpenCode, OpenWebUI): see docs/clients.md.
Why this over other MCP calendar servers
Self-hosted — no data leaves your network. No third-party SaaS.
Stateless single container — no database, no sidecars. Optional SQLite store for pro mode.
Any RFC 4791 server — Radicale CI-integration-tested, Nextcloud used in development. Baikal, ownCloud, iCloud, Fastmail are protocol-compatible.
Multi-account without restarts — credentials travel per-request in HTTP headers.
Pro mode — optional SQLite store with per-user keys, fan-out reads across multiple remotes. See
docs/pro-mode.md.Security built in — optional API key auth, per-IP rate limiting, structured audit logging, read-only mode.
Why Docker (not npx)
caldav-mcp is Python-based (not Node), so npx is not an option. Docker means:
No local Python, venv, or dependency management — the pre-built image has everything pinned.
Pinned dependencies — the image is built once in CI with fully pinned requirements, identical on every host.
One container shared by your entire homelab or team, serving multiple AI clients.
The 14 tools
Queries (7) — read-only
Tool | Description |
List all available calendars | |
Get events in a date range | |
Get events for today | |
Get events for the next 7 days | |
Get a specific event by UID | |
Find events by text | |
Get free/busy information |
Mutations (4) — write
Tool | Description |
Create a new event | |
Partially update an existing event | |
Delete an event | |
Move an event between calendars |
Attendees (3)
Tool | Description |
Add an attendee to an event | |
Remove an attendee from an event | |
List attendees of an event |
Full API docs: docs/api.md.
Authentication & security
API key auth — optional
CALDAV_MCP_API_KEYwith constant-time comparison. Pro mode uses PBKDF2-HMAC-SHA256 DB-stored keys.Rate limiting — per-IP sliding window (default: 10 failures / 60 s), configurable via
CALDAV_MCP_RATE_LIMIT_MAX_FAILURESandCALDAV_MCP_RATE_LIMIT_WINDOW_SECONDS.Audit logging — all auth attempts and tool operations logged. Set
CALDAV_MCP_LOG_FORMAT=jsonfor structured output.Read-only mode —
CALDAV_MCP_READ_ONLY=truehides all write tools, leaving only the 8 read-only tools visible.
Configuration essentials
Most users only need these:
Variable | Description |
| CalDAV server URL (set = env mode; unset = header mode) |
| CalDAV username (env mode) |
| CalDAV password (env mode) |
| API key for endpoint auth (optional) |
| IANA timezone for today/week boundaries (default: UTC) |
|
|
Credential modes: environment variables (env mode), per-request X-Caldav-* headers (header mode), or SQLite store (pro mode). No per-field mixing — all three credentials come from the same source. Full reference: docs/configuration.md.
Pro mode (DB_CONFIG_ENABLED=true): loads users and configs from a SQLite store at startup. Supports per-user keys, fan-out reads across multiple remotes, and dotted-path writes. Requires CALDAV_MCP_DB_PATH and CALDAV_MCP_CONFIG_SECRET. Config changes require a restart. Details: docs/pro-mode.md, docs/cli.md.
Documentation
Document | Contents |
API reference — auth headers, addressing, aggregated results | |
MCP client configuration (Claude Desktop, Cursor, VS Code, …) | |
Config store CLI ( | |
Full env var reference, TLS, reverse proxy, deployment | |
Pro mode — SQLite store, fan-out, per-user auth | |
Architecture and design decisions | |
Development setup, code style, architecture rules |
Known gaps & planned features
Client-side search does not scale to very large calendars.
caldav_move_eventis non-atomic (copy + delete; duplicate on failure).Config changes require a server restart — no hot-reload yet.
No stdio transport — Streamable HTTP only.
Version
0.1.0— pre-1.0, API may change between releases.X-Caldav-Username/X-Caldav-Passwordpassthrough mode reserved for future use.Future: hot-reload, pro-mode enhancements (see
ideas/).
FAQ
I get ERROR:[auth] unauthorized — Set CALDAV_MCP_API_KEY and include
Authorization: Bearer <token> (or X-Api-Key) in every request. When
CALDAV_MCP_API_KEY is unset the endpoint is open, but never expose it
to the internet without auth.
Calendar not found — Calendar names are case-sensitive. Run
caldav_list_calendars to see the exact names your server reports.
Events show wrong time — Set the TZ environment variable to your IANA
timezone (e.g. Europe/Vienna). Without it, today/week boundaries default
to UTC.
SSL certificate errors — For self-signed certs, either import the CA into
the system trust store or set CALDAV_MCP_CALDAV_VERIFY_SSL=false for
testing.
Can I use stdio? — Not out of the box. The server uses Streamable HTTP
transport. To add stdio support, modify server.py to call
mcp.run() instead of mcp.run_http_async().
Contributing
See docs/contributing.md.
License
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
This server cannot be deployed
Maintenance
Related MCP Connectors
Hosted Google Calendar MCP server for AI agents. No self-hosting or Google Cloud setup.
MCP server connecting AI agents to 100+ apps (Gmail, Slack, Notion, GitHub) via one-click OAuth.
A MCP server that works with Google Calendar to manage event listing, reading, and updates.
Calendar API for AI agents: events, availability, Google/Microsoft setup, scheduling, and iCal.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceAn MCP server that exposes CalDAV calendar operations as tools for AI assistants. It enables users to connect to CalDAV servers to create and list calendar events within specific timeframes.511 npm111MIT
- AlicenseNot gradedqualityDmaintenanceProvider-agnostic CalDAV calendar MCP server that connects any CalDAV calendar to AI assistants, enabling calendar operations like listing, creating, updating, and deleting events.35 PyPIAGPL 3.0
- AlicenseNot gradedqualityDmaintenanceA comprehensive MCP server that provides AI assistants with natural language access to Apple Calendar, enabling reading, searching, creating, and managing calendar events.3MIT
- FlicenseNot gradedqualityBmaintenanceMCP server for Radicale/CalDAV servers, enabling AI agents to manage calendars and task lists by listing, creating, and deleting events and reminders.-