# caldav-mcp
🗓️ A CalDAV Model Context Protocol (MCP) server to expose calendar operations as tools for AI assistants.
[](https://github.com/dominik1001/caldav-mcp/actions/workflows/release.yml)
[](https://www.npmjs.com/package/caldav-mcp)
[](https://choosealicense.com/licenses/mit/)
[](https://github.com/prettier/prettier)
[](https://modelcontextprotocol.io)
[](https://github.com/semantic-release/semantic-release)
## ✨ Features
- Connect to CalDAV servers
- List calendars
- List calendar events within a specific timeframe
- Create calendar events
- Update calendar events
- Delete calendar events by UID
## Setup
```
{
"mcpServers": {
...,
"calendar": {
"command": "npx",
"args": [
"caldav-mcp"
],
"env": {
"CALDAV_BASE_URL": "",
"CALDAV_USERNAME": "",
"CALDAV_PASSWORD": ""
}
}
}
}
```
## Development
### Quick Start
Run the MCP server in development mode with auto-reload:
```bash
npm run dev
```
This will run the TypeScript code directly with watch mode and automatically load environment variables from `.env`.
### Manual Build
Alternatively, you can compile TypeScript to JavaScript and run it:
1. Compile:
```bash
npx tsc
```
2. Run:
```bash
node dist/index.js
```
## Available Tools
### list-calendars
List all calendars returning both name and URL
Parameters: none
Returns:
- List of all available calendars
### list-events
List all events between start and end date in the calendar specified by its URL
Parameters:
- `start`: string — Start date (ISO 8601)
- `end`: string — End date (ISO 8601)
- `calendarUrl`: string
Returns:
- A list of events that fall within the given timeframe, each containing `uid`, `summary`, `start`, `end`, and optionally `description` and `location`
### create-event
Creates an event in the calendar specified by its URL. For all-day events, set `wholeDay` to true. For a single-day all-day event, use `start` and `end` datetimes on the same calendar date; they do not need to be identical timestamps.
Parameters:
- `summary`: string
- `start`: string — Start datetime (ISO 8601)
- `end`: string — End datetime (ISO 8601)
- `wholeDay`: boolean (optional) — Create as a whole-day event
- `calendarUrl`: string
- `description`: string (optional)
- `location`: string (optional)
- `recurrenceRule`: object (optional)
- `freq`: enum (`DAILY` | `WEEKLY` | `MONTHLY` | `YEARLY`) (optional)
- `interval`: number (optional)
- `count`: number (optional)
- `until`: string (optional)
- `byday`: array of string (optional)
- `bymonthday`: array of number (optional)
- `bymonth`: array of number (optional)
Returns:
- The unique ID of the created event
### update-event
Updates an existing event in the calendar specified by its URL. Only provided fields are changed. For a one-day full-day event, set `wholeDay` to true and set `start` and `end` to the same calendar day.
Parameters:
- `uid`: string — Unique identifier of the event to update (obtained from list-events)
- `calendarUrl`: string
- `summary`: string (optional)
- `start`: string (optional)
- `end`: string (optional)
- `wholeDay`: boolean (optional) — Update whether this is a whole-day event
- `description`: string (optional)
- `location`: string (optional)
- `recurrenceRule`: object (optional)
- `freq`: enum (`DAILY` | `WEEKLY` | `MONTHLY` | `YEARLY`) (optional)
- `interval`: number (optional)
- `count`: number (optional)
- `until`: string (optional)
- `byday`: array of string (optional)
- `bymonthday`: array of number (optional)
- `bymonth`: array of number (optional)
Returns:
- The unique ID of the updated event
### delete-event
Deletes an event in the calendar specified by its URL
Parameters:
- `uid`: string — Unique identifier of the event to delete (obtained from list-events)
- `calendarUrl`: string
Returns:
- Confirmation message when the event is successfully deleted
### list-todos
List tasks (VTODOs) in the calendar specified by its URL. By default returns only open tasks (NEEDS-ACTION and IN-PROCESS), sorted by manual order then due date. Use `status` to include completed (`COMPLETED`) or all (`ALL`) tasks, and `limit`/`offset` to page through long lists.
Parameters:
- `calendarUrl`: string
- `status`: enum (`OPEN` | `ALL` | `NEEDS-ACTION` | `COMPLETED` | `IN-PROCESS` | `CANCELLED`) (optional) — Filter by status. `OPEN` (default) = NEEDS-ACTION + IN-PROCESS; `ALL` = everything; or an exact status (NEEDS-ACTION, COMPLETED, IN-PROCESS, CANCELLED).
- `due_before`: string (optional) — Only tasks with a due date at or before this (ISO 8601). Undated tasks are excluded when a due window is set.
- `due_after`: string (optional) — Only tasks with a due date at or after this (ISO 8601). Undated tasks are excluded when a due window is set.
- `limit`: number (optional) — Max tasks to return (default 50, max 500)
- `offset`: number (optional) — Tasks to skip (default 0)
Returns:
- An object `{ todos, total, limit, offset }` where `total` is the count before pagination. Each todo has `uid`, `summary`, `status`, and optionally `due`, `start`, `completed`, `description`, `location`.
### create-todo
Creates a task (VTODO) in the calendar specified by its URL. Only `summary` is required; a task may have no dates. Use `due` for a deadline and `start` for when work should begin.
Parameters:
- `summary`: string
- `calendarUrl`: string
- `due`: string (optional) — Due datetime (ISO 8601)
- `start`: string (optional) — Start datetime (ISO 8601)
- `description`: string (optional)
- `location`: string (optional)
- `status`: enum (`NEEDS-ACTION` | `COMPLETED` | `IN-PROCESS` | `CANCELLED`) (optional) — Defaults to NEEDS-ACTION when omitted
Returns:
- The unique ID of the created todo
### update-todo
Updates an existing task (VTODO) in the calendar specified by its URL. Only provided fields are changed. To mark a task done, prefer the `complete-todo` tool.
Parameters:
- `uid`: string — Unique identifier of the todo to update (from list-todos)
- `calendarUrl`: string
- `summary`: string (optional)
- `due`: string (optional)
- `start`: string (optional)
- `description`: string (optional)
- `location`: string (optional)
- `status`: enum (`NEEDS-ACTION` | `COMPLETED` | `IN-PROCESS` | `CANCELLED`) (optional)
Returns:
- The unique ID of the updated todo
### complete-todo
Marks a task (VTODO) as done. Sets its status to COMPLETED and records the completion time.
Parameters:
- `uid`: string — Unique identifier of the todo to complete (from list-todos)
- `calendarUrl`: string
Returns:
- The unique ID of the completed todo
### delete-todo
Deletes a task (VTODO) in the calendar specified by its URL
Parameters:
- `uid`: string — Unique identifier of the todo to delete (from list-todos)
- `calendarUrl`: string
Returns:
- Confirmation message when the todo is successfully deleted
## License
MIT