About caldav-mcp
caldav-mcp is an MCP server that exposes CalDAV calendar and task operations to AI assistants. It is for people who want to inspect and manage schedules or to-dos through an MCP client, with tools for creating, updating, and deleting events and tasks.
Key features
- 01Connect to CalDAV servers and list calendars
- 02Query events within a date range
- 03Create, update, and delete events
- 04List and filter paginated tasks
- 05Create, update, complete, and delete tasks
Use cases
- 01Check events for a chosen date range through an AI assistant
- 02Create or edit a calendar meeting
- 03Manage to-dos with due dates
MCP support
The MCP server exposes CalDAV calendar and task tools to MCP clients, including operations for calendars, events, and VTODOs.
Configuration
Local server config is the same for every client. Copy it into your client’s MCP config file.
npx -y caldav-mcpCALDAV_BASE_URLBase URL of the CalDAV server (e.g. https://caldav.example.com)CALDAV_USERNAMEUsername for CalDAV authenticationCALDAV_PASSWORDSecretPassword for CalDAV authenticationLocal servers need a runtime on your machine (e.g. Node.js 18+). Config file locations differ by client; see your client’s docs.
Tools
Local servers expose tools only once running on your machine, and the maintainer has not provided a tool list.
Details
From the project READMEcaldav-mcp
🗓️ A CalDAV Model Context Protocol (MCP) server to expose calendar operations as tools for AI assistants.
✨ 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:
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:
- Compile:
npx tsc
- Run:
node dist/index.js
Available Tools
list-calendars
List all calendars returning both name and absolute URL. Pass a calendar's url unchanged as calendarUrl to the other tools.
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:
calendarUrl: stringend: string — End date (ISO 8601)start: string — Start date (ISO 8601)
Returns:
- A list of events that fall within the given timeframe, each containing
uid,summary,start,end, and optionallydescriptionandlocation
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:
calendarUrl: stringdescription: string (optional)end: string — End datetime (ISO 8601)location: string (optional)recurrenceRule: object (optional)byday: array of string (optional)bymonth: array of number (optional)bymonthday: array of number (optional)count: number (optional)freq: enum (DAILY|WEEKLY|MONTHLY|YEARLY) (optional)interval: number (optional)until: string (optional)
start: string — Start datetime (ISO 8601)summary: stringwholeDay: boolean (optional) — Create as a whole-day event
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:
calendarUrl: stringdescription: string (optional)end: string (optional)location: string (optional)recurrenceRule: object (optional)byday: array of string (optional)bymonth: array of number (optional)bymonthday: array of number (optional)count: number (optional)freq: enum (DAILY|WEEKLY|MONTHLY|YEARLY) (optional)interval: number (optional)until: string (optional)
start: string (optional)summary: string (optional)uid: string — Unique identifier of the event to update (obtained from list-events)wholeDay: boolean (optional) — Update whether this is a whole-day event
Returns:
- The unique ID of the updated event
delete-event
Deletes an event in the calendar specified by its URL
Parameters:
calendarUrl: stringuid: string — Unique identifier of the event to delete (obtained from list-events)
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: stringdue_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.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.limit: number (optional) — Max tasks to return (default 50, max 500)offset: number (optional) — Tasks to skip (default 0)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).
Returns:
- An object
{ todos, total, limit, offset }wheretotalis the count before pagination. Each todo hasuid,summary,status, and optionallydue,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:
calendarUrl: stringdescription: string (optional)due: string (optional) — Due datetime (ISO 8601)location: string (optional)start: string (optional) — Start datetime (ISO 8601)status: enum (NEEDS-ACTION|COMPLETED|IN-PROCESS|CANCELLED) (optional) — Defaults to NEEDS-ACTION when omittedsummary: string
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:
calendarUrl: stringdescription: string (optional)due: string (optional)location: string (optional)start: string (optional)status: enum (NEEDS-ACTION|COMPLETED|IN-PROCESS|CANCELLED) (optional)summary: string (optional)uid: string — Unique identifier of the todo to update (from list-todos)
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:
calendarUrl: stringuid: string — Unique identifier of the todo to complete (from list-todos)
Returns:
- The unique ID of the completed todo
delete-todo
Deletes a task (VTODO) in the calendar specified by its URL
Parameters:
calendarUrl: stringuid: string — Unique identifier of the todo to delete (from list-todos)
Returns:
- Confirmation message when the todo is successfully deleted
License
MIT
Comments
New to MCP?
From what the protocol is to installing your first server, these answers cover most first questions.
An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.