Sandbox
@dominik1001/caldav-mcp

CalDAV MCP server for calendar tools

caldav-mcp connects an agent to a CalDAV server so it can list calendars, read events, and create, update, or delete events and todos. It works as an MCP server, with tools defined in `src/tools` and wired through the TypeScript server in `src/index.ts`.

99 starsβ€’33 forksβ€’TypeScriptβ€’Updated 10d ago
Who it's for

Builders who want their agent to work with calendars and tasks through CalDAV.

What it delivers

You can let an agent manage calendar events and todos instead of handling them manually.

What it does

List calendars

Returns calendar names and URLs from the connected CalDAV server.

Read events in a date range

Lists events between a start and end date for a chosen calendar URL.

Create, update, and delete events

Lets the agent add events, edit existing ones by UID, and remove them.

List and filter todos

Shows VTODO items with status, due-date filters, and pagination.

Create, update, complete, and delete todos

Supports task creation, edits, completion, and removal in a CalDAV calendar.

MCP setup example

Provides a ready-to-copy MCP server block using `npx caldav-mcp` and CalDAV environment variables.

How to get it

  1. 1Run the MCP server in development mode with auto-reload
    npm run dev

README

caldav-mcp

πŸ—“οΈ A CalDAV Model Context Protocol (MCP) server to expose calendar operations as tools for AI assistants.

Release npm version MIT License code style: prettier MCP Compatible semantic-release: angular

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

  1. Compile:
npx tsc
  1. Run:
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

Files in the repo

Repository payloadβ€’28 top-level entries
  • .agents
  • .claude
  • .github
  • scripts
  • src
  • .env.example
  • .gitignore
  • .mcp.json
  • .npmrc
  • .releaserc.json
  • AGENTS.md
  • biome.json
  • CHANGELOG.md
  • CLAUDE.md
  • CODE_OF_CONDUCT.md
  • commitlint.config.js
  • CONTRIBUTING.md
  • knip.json
  • lefthook.yml
  • LICENSE
  • package-lock.json
  • package.json
  • README.md
  • SECURITY.md
  • server.json
  • skills-lock.json
  • tsconfig.json
  • vitest.config.ts

Discussion (0)

Ask about usage, or say what you built with it

Sign in to join the discussion.

No comments yet. Be the first to say what this is good for.

More connectors

Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface

86k

Universal provider proxy for OpenAI Codex & Claude Code β€” use any LLM (Claude, Gemini, Grok, DeepSeek, Ollama…) with Codex CLI, App, SDK, and Claude Code

14k
noskillish/
bankmcp

BankMCPβ„’: your AI can now read your bank. Self-hosted, read-only MCP server for your own bank accounts via open banking (Enable Banking). Standard MCP; tested with Claude and Ollama.

177

Open-source auth gateway connecting 1400+ SaaS providers to AI agents through SDK, CLI, MCP, HTTP, and OpenAPI.

5.7k

Open-source 3D architectural editor with a local CLI, MCP tools, and practical workflows for humans and AI agents.

23k
cinderline/
northcinder

Open-source MCP server for comparing products and asking the buyer before purchase.

1.2k