caldav-mcp
โจ 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 server URL>",
"CALDAV_USERNAME": "<CalDAV username>",
"CALDAV_PASSWORD": "<CalDAV password>"
}
}
}
}
Development
Quick Start
Run the MCP server in development mode with auto-reload:
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:
- Compile:
- Run:
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