CalDAV MCP Server
README.md
# CalDAV MCP Server
MCP (Model Context Protocol) server for interacting with CalDAV calendars. Provides full CRUD operations on calendar events plus free/busy and availability-finding tools.
Supports **Nextcloud**, **Radicale**, **Fastmail**, **iCloud**, **Baikal**, **Zimbra**, **SOGo**, and any RFC 4791-compliant CalDAV server.
## Quick Start
```bash
# Install
cd caldav-mcp-server
pip install -e .
# Configure
export CALDAV_URL="https://your-server.com/remote.php/dav/"
export CALDAV_USERNAME="your-username"
export CALDAV_PASSWORD="your-password"
# Run
caldav-mcp-server
# or: python -m caldav_mcp_server.main
```
## Claude Code Integration
Add to `~/.claude.json` in the `mcpServers` section:
```json
{
"mcpServers": {
"caldav": {
"command": "python",
"args": ["-m", "caldav_mcp_server.main"],
"cwd": "/Users/jiangwu/claude/caldav-mcp-server/src",
"env": {
"CALDAV_URL": "https://your-server.com/remote.php/dav/",
"CALDAV_USERNAME": "your-username",
"CALDAV_PASSWORD": "your-password",
"CALDAV_FEATURES": "nextcloud"
}
}
}
}
```
## Environment Variables
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `CALDAV_URL` | Yes | — | Full CalDAV server URL |
| `CALDAV_USERNAME` | Yes | — | Login username |
| `CALDAV_PASSWORD` | Yes | — | Password or app-specific token |
| `CALDAV_FEATURES` | No | — | Server compatibility profile |
| `CALDAV_SSL_VERIFY_CERT` | No | `true` | Set to `false` for self-signed certs, or path to CA bundle |
| `CALDAV_TIMEOUT` | No | `30` | HTTP request timeout in seconds |
## Tools
| Tool | Description |
|------|-------------|
| `calendar_list_calendars` | List all calendars on the server with names, URLs, and supported component types |
| `calendar_search_events` | Search events by date range with optional text filtering |
| `calendar_get_event` | Get full details of a single event by UID (summary, times, description, location, attendees, recurrence) |
| `calendar_create_event` | Create a new event with optional recurrence rules, attendees, and reminders |
| `calendar_update_event` | Update fields on an existing event (only specified fields are changed) |
| `calendar_delete_event` | Permanently delete an event by UID |
| `calendar_get_freebusy` | Get busy time slots in a date range (falls back to event search if server doesn't support free/busy) |
| `calendar_find_available_slots` | Find free time slots for scheduling, with optional working hours/days constraints |
### Time Format
All times use ISO 8601 format: `2026-01-15T09:00:00` or `2026-01-15T09:00:00+02:00`. Times without a timezone offset are treated as UTC.
### Recurrence Rules
The `rrule` parameter accepts RFC 5545 recurrence rule strings:
- `FREQ=WEEKLY;BYDAY=MO,WE,FR` — every Monday, Wednesday, Friday
- `FREQ=MONTHLY;BYMONTHDAY=15` — 15th of every month
- `FREQ=DAILY;COUNT=10` — every day for 10 occurrences
## Server Compatibility
Set `CALDAV_FEATURES` to one of these profiles to enable server-specific workarounds:
| Profile | Servers |
|---------|---------|
| `nextcloud` | Nextcloud |
| `radicale` | Radicale |
| `baikal` | Baikal |
| `fastmail` | Fastmail |
| `icloud` | Apple iCloud |
| `google` | Google Calendar |
| `zimbra` | Zimbra |
| `sogo` | SOGo |
| `posteo` | Posteo |
| `ox` | Open-Xchange / mailbox.org |
| `synology` | Synology Calendar |
### iCloud Setup
1. Generate an app-specific password at [appleid.apple.com](https://appleid.apple.com)
2. Set `CALDAV_URL=https://caldav.icloud.com`
3. Set `CALDAV_USERNAME` to your Apple ID email
4. Set `CALDAV_PASSWORD` to the generated app-specific password
5. Set `CALDAV_FEATURES=icloud`
**iCloud limitations**: no recurring event expansion, no todos, no free/busy, no calendar creation.
### Local Testing with Radicale
```bash
pip install radicale
radicale --storage-type filesystem --filesystem-folder /tmp/radicale
# Server runs at http://localhost:5232
# No auth by default — leave CALDAV_USERNAME and CALDAV_PASSWORD empty
```
## Project Structure
```
caldav-mcp-server/
├── pyproject.toml
├── README.md
├── src/
│ └── caldav_mcp_server/
│ ├── __init__.py
│ ├── main.py # FastMCP entry point + 8 tools
│ ├── auth.py # Client factory + calendar resolution
│ ├── config.py # Pydantic settings from env vars
│ ├── errors.py # Error mapping + decorator
│ └── formatters.py # Markdown + JSON output formatters
└── tests/
└── __init__.py
```
## License
MIT
TDQS
A4.2/5.0
Scored across 8 tools
Disambiguation5/5
Each tool targets a distinct action (create, delete, get, update, search, list calendars, find slots, get free/busy). No overlap; even the two availability tools are complementary.
Naming Consistency5/5
All tools follow the pattern `calendar_verb_noun` with consistent snake_case. Very predictable and clear.
Tool Count5/5
With 8 tools, the surface is well-scoped for a CalDAV server: covers calendar discovery, CRUD, search, and availability checks. Not too many or too few.
Completeness4/5
Event management is fully covered (CRUD + search + availability). However, missing tools for VTODO and VJOURNAL, despite `calendar_list_calendars` reporting them as supported component types.
Maintenance
ActivityStale
ResponsivenessNo issues