Skip to content
Conduit

mcp server

dav-mcp

Simple MCP for CalDAV and CardDAV

subconscious-labs/dav-mcpcommunitylistedunreviewed

Set up

Runs on your computer. Pick your agent and operating system.

This project does not publish an install method we can turn into a config. Follow the README instead.

README

synced Oct 29, 2026

dav-mcp

An MCP server for CalDAV and CardDAV. Exposes calendar and contact management as tools callable by LLM clients (Claude Desktop, Cursor, etc.).

Transport: stdio. No HTTP server, no daemon — the client spawns the process and communicates over stdin/stdout per the MCP spec.

Requirements

  • Go 1.22+
  • A CalDAV / CardDAV server (Nextcloud, Radicale, iCloud, Fastmail, …)

Build

make          # tidy deps + build → bin/dav-mcp
make test     # run tests with race detector + coverage
make check    # fmt + vet + test

Configuration

Single account

Set three environment variables and the server auto-connects on the first tool call — no explicit dav_connect needed.

VariableRequiredDescription
DAV_URLyesBase URL of the DAV server
DAV_USERNAMEyesUsername for Basic Auth
DAV_PASSWORDyesPassword for Basic Auth
DAV_DEBUGnoSet to 1 for verbose HTTP logging

Multiple accounts (DAV_ACCOUNTS)

Set DAV_ACCOUNTS to a JSON array of account objects. When present, it takes priority over DAV_URL / DAV_USERNAME / DAV_PASSWORD.

export DAV_ACCOUNTS='[
  {"name": "personal", "url": "https://cloud.example.com",  "username": "alice", "password": "s3cr3t"},
  {"name": "work",     "url": "https://dav.corp.example",   "username": "alice@corp", "password": "w0rkp@ss"}
]'
FieldRequiredDescription
namenoAccount label used in tool calls; defaults to account1, account2, …
urlyesBase URL of the DAV server
usernamenoUsername for Basic Auth
passwordnoPassword for Basic Auth

All accounts are connected in parallel at startup. Pass "account": "work" to any tool to target a specific account. Omitting account selects the first configured account.

MCP Client Setup

Single account — Claude Desktop (claude_desktop_config.json)

{
  "mcpServers": {
    "dav": {
      "command": "/path/to/bin/dav-mcp",
      "env": {
        "DAV_URL": "https://dav.example.com",
        "DAV_USERNAME": "alice",
        "DAV_PASSWORD": "secret"
      }
    }
  }
}

Multiple accounts — Claude Desktop

{
  "mcpServers": {
    "dav": {
      "command": "/path/to/bin/dav-mcp",
      "env": {
        "DAV_ACCOUNTS": "[{\"name\":\"personal\",\"url\":\"https://cloud.example.com\",\"username\":\"alice\",\"password\":\"s3cr3t\"},{\"name\":\"work\",\"url\":\"https://dav.corp.example\",\"username\":\"alice@corp\",\"password\":\"w0rkp@ss\"}]"
      }
    }
  }
}

Cursor (~/.cursor/mcp.json)

{
  "mcpServers": {
    "dav": {
      "command": "/path/to/bin/dav-mcp",
      "env": {
        "DAV_ACCOUNTS": "[{\"name\":\"personal\",\"url\":\"https://cloud.example.com\",\"username\":\"alice\",\"password\":\"s3cr3t\"},{\"name\":\"work\",\"url\":\"https://dav.corp.example\",\"username\":\"alice@corp\",\"password\":\"w0rkp@ss\"}]"
      }
    }
  }
}

Tools

Every tool accepts an optional "account" parameter to target a specific configured account. When omitted, the first (primary) account is used.

Session

ToolDescription
dav_connectConnect to a CalDAV/CardDAV server and discover calendars and address books
dav_reconnectReconnect one or all accounts from environment config

Calendar (CalDAV)

ToolDescription
calendar_calendar_listList all discovered calendar collections
calendar_event_listList events in a time range
calendar_event_createCreate a new event
calendar_event_create_recurringCreate a recurring event (RFC 5545 rrule, e.g. FREQ=WEEKLY;BYDAY=MO,WE)
calendar_event_updateUpdate an existing event by UID (only supplied fields are changed)
calendar_event_deleteDelete an event by UID

Tasks (CalDAV — VTODO)

ToolDescription
calendar_todo_listList VTODO items; optionally filter by status (NEEDS-ACTION, IN-PROCESS, COMPLETED, CANCELLED)
calendar_todo_getGet a single todo by UID
calendar_todo_createCreate a new todo (summary, due, priority, status)
calendar_todo_updateUpdate an existing todo by UID (only supplied fields are changed)
calendar_todo_deleteDelete a todo by UID

Journal (CalDAV — VJOURNAL)

ToolDescription
calendar_journal_listList VJOURNAL entries; optionally filter by status (DRAFT, FINAL, CANCELLED)
calendar_journal_getGet a single journal entry by UID
calendar_journal_createCreate a new journal entry (summary, description, date, status)
calendar_journal_updateUpdate an existing journal entry by UID (only supplied fields are changed)
calendar_journal_deleteDelete a journal entry by UID

Contacts (CardDAV)

ToolDescription
contacts_listList all contacts in an address book
contacts_getGet a single contact by UID
contacts_searchSearch contacts by name, email, phone, or org
contacts_createCreate a new contact (vCard 4.0)
contacts_updateUpdate an existing contact (only supplied fields are changed)
contacts_deleteDelete a contact by UID

Server Capabilities

During connection, dav-mcp queries supported-calendar-component-set for each calendar collection. Tools that require a component type the server does not advertise return an explanatory message instead of attempting the operation:

VTODO is not supported by this CalDAV server.

Debugging

Enable verbose HTTP logging to stderr:

DAV_DEBUG=1 DAV_URL=https://dav.example.com DAV_USERNAME=alice DAV_PASSWORD=secret ./bin/dav-mcp

Project Layout

cmd/dav-mcp/      entry point
internal/
  config/         env-based configuration (DAV_URL / DAV_ACCOUNTS)
  dav/            WebDAV HTTP client (Propfind, Report, Put, Delete) + session store
  ical/           iCalendar builder and parser (VEVENT, VTODO, VJOURNAL)
  mcp/            MCP protocol (stdio transport, JSON-RPC 2.0)
  tools/          tool handlers (calendar, tasks, journal, contacts)
  vcard/          vCard 4.0 builder and parser

License

MIT

↑↓ navigate openesc close