# caldav-mcp [Health: Active]

**Category:** 💻 Developer Tools  
**Repository:** https://github.com/dominik1001/caldav-mcp  
**GitHub Stars:** 99  
**Views:** 0  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/caldav-mcp

## Description
CalDAV calendar operations (list, create, update, delete events) as MCP tools.

## Claude Desktop Quick Installation
Install path detected from listing signals. Uses `npx` (confidence: high):

```json
"mcpServers": {
  "caldav-mcp": {
    "command": "npx",
    "args": ["caldav-mcp"]
  }
}
```

## Documentation & README

# caldav-mcp

<div align="center">

🗓️ A CalDAV Model Context Protocol (MCP) server to expose calendar operations as tools for AI assistants.

[![Release](https://github.com/dominik1001/caldav-mcp/actions/workflows/release.yml/badge.svg)](https://github.com/dominik1001/caldav-mcp/actions/workflows/release.yml)
[![npm version](https://badge.fury.io/js/caldav-mcp.svg)](https://www.npmjs.com/package/caldav-mcp)
[![MIT License](https://img.shields.io/badge/License-MIT-green.svg)](https://choosealicense.com/licenses/mit/)
[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)
[![MCP Compatible](https://img.shields.io/badge/MCP-Compatible-purple.svg)](https://modelcontextprotocol.io)
[![semantic-release: angular](https://img.shields.io/badge/semantic--release-angular-e10079?logo=semantic-release)](https://github.com/semantic-release/semantic-release)

</div>

## ✨ 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:
```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

<!-- TOOLS:START - generated by scripts/gen-tool-docs.ts -->
### 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
<!-- TOOLS:END -->

## License

MIT

