linagora

mcp-twake-dav

Community linagora
Updated

MCP server for Twake.ai Calendar and contacts: give any AI assistant secure access to your sovereign CalDAV calendars and CardDAV address books

mcp-twake-dav

npm versionCILicense: AGPL-3.0Node.js >= 20

Give your AI assistant secure access to Twake Calendar and your contacts, in the Twake.ai Digital Workplace.

Twake Calendar

What is it?

mcp-twake-dav is a Model Context Protocol (MCP) server. MCP is the open standard that lets AI assistants (Claude Desktop, Claude Code, Hermes Agent, Cursor, VS Code and many others) use external tools. This server exposes your calendars and address books to the assistant as 20 tools: agenda, availability, events, reminders, invitations and contacts.

It speaks the open standards CalDAV (RFC 4791), CardDAV (RFC 6352) and CalDAV scheduling (RFC 6638). It is built for Twake Calendar and works with other SabreDAV-compatible servers (Nextcloud, SOGo, DAViCal, ownCloud…).

Part of Twake.ai

Twake.ai is the truly open source and sovereign Digital Workplace developed by LINAGORA: Twake Mail, Twake Calendar, Twake Drive, Twake Chat and Twake Visio with a single account, hosted in France or on your own infrastructure.

Three open source MCP servers connect AI assistants to the whole workplace:

MCP server Twake.ai service Protocol
mcp-twake-mail Twake Mail JMAP
mcp-twake-dav (this project) Twake Calendar and contacts CalDAV / CardDAV
mcp-twake-drive Twake Drive cozy-stack API

Used together, they let one assistant prepare a meeting from the invitation, the related email thread and the documents in the drive, without your data leaving your servers.

What it brings

  • Your day at a glance: "What's on my agenda today? Where is my 3 pm meeting?"
  • Finding a slot: "When am I free for one hour with Marie next week?"
  • Scheduling in natural language: "Book a project review on Tuesday at 10 with Pierre and Marie" (dates like "next Monday" or "in two weeks" are understood).
  • Reminders and invitations: add or remove reminders, list pending invitations and answer them.
  • Contacts: find an email address or a phone number, create and update contact cards.
  • Sovereignty: the server runs next to your assistant and talks directly to your calendar server. Pair it with a self-hosted or European AI model to keep the whole chain under your control.

Features

20 MCP tools

Category Tools
Calendar, read get_next_event, get_todays_schedule, get_events_in_range, search_events, check_availability, list_calendars
Calendar, write create_event (with attendees and recurrence), update_event, delete_event ⚠️, add_alarm, remove_alarm
Invitations list_invitations, respond_to_invitation ⚠️
Contacts, read search_contacts, get_contact_details, list_contacts, list_addressbooks
Contacts, write create_contact, update_contact, delete_contact ⚠️

⚠️ = deletes data or makes the server notify other people. Every tool carries MCP annotations (readOnlyHint, destructiveHint, openWorldHint) so clients can ask for confirmation.

Highlights

  • Attendees and organizer: create_event invites attendees, with the organizer taken from DAV_ORGANIZER_EMAIL / DAV_ORGANIZER_NAME; the server sends the invitations.
  • Recurring events: RRULE expansion with safety limits, single-occurrence edits and deletions, and an opt-out (DAV_RECURRING_WRITES=false) for cautious deployments.
  • Reliable updates: events are found by UID with a server-side query; updates use parse-modify-serialize, so alarms, attendees and X- properties are preserved.
  • Status display: cancelled and tentative events, attendee participation status.
  • Five authentication methods: Basic, Bearer, OpenPaaS ESNToken, token command (short-lived tokens refreshed before every call) and an external credentials file.
  • Reverse proxy support: DAV_HREF_PREFIX for servers published under a path prefix that their responses omit (Twake Calendar / OpenPaaS).
  • CTag-based caching, retries with backoff, natural-language dates (chrono-node), HTTPS enforced.

Requirements

  • Node.js >= 20
  • A CalDAV / CardDAV server: Twake Calendar, Nextcloud, SOGo, DAViCal, ownCloud… (HTTPS required, except localhost)
  • An MCP client: Claude Desktop, Claude Code, Hermes Agent, Cursor, VS Code, or any MCP-compatible assistant

Installation

Interactive setup (recommended):

npx mcp-twake-dav setup

The wizard asks for your server URL and credentials, tests the connection, lists your calendars and address books, lets you pick the defaults, and can write the Claude Desktop configuration for you.

Global install:

npm install -g mcp-twake-dav

From source:

git clone https://github.com/linagora/mcp-twake-dav.git
cd mcp-twake-dav
npm install
npm run build          # then run: node build/index.js

Configuration

The server is configured through environment variables, usually set in your MCP client configuration.

Authentication

Method Variables
Basic (default) DAV_URL, DAV_USERNAME, DAV_PASSWORD
Bearer DAV_URL, DAV_AUTH_METHOD=bearer, DAV_TOKEN
ESNToken (OpenPaaS) DAV_URL, DAV_AUTH_METHOD=esntoken, DAV_TOKEN
Token command DAV_URL, DAV_AUTH_METHOD=command, DAV_TOKEN_COMMAND
  • With token command, the server runs DAV_TOKEN_COMMAND to get an access token, either raw on stdout or as JSON {"access_token": "...", "expires_at": <epoch seconds>}, and refreshes it before every call. A single broker you control can then own the OIDC grant for several tools.
  • DAV_CREDENTIALS_FILE points to a file holding DAV_USERNAME=…, DAV_PASSWORD=… or DAV_TOKEN=… lines, so secrets stay out of the MCP client configuration.

Other options

Variable Description Default
DAV_DEFAULT_CALENDAR Calendar used when the assistant does not name one ("all" in a tool call still searches every calendar) all calendars
DAV_DEFAULT_ADDRESSBOOK Address book used by default all address books
DAV_ORGANIZER_EMAIL / DAV_ORGANIZER_NAME Organizer written in events that have attendees none
DAV_RECURRING_WRITES false = update_event / delete_event refuse recurring series and occurrences true
DAV_HREF_PREFIX Path prefix stripped by a reverse proxy, e.g. /dav for Twake Calendar / OpenPaaS none
USER_TIMEZONE IANA time zone used to display and interpret dates, e.g. Europe/Paris system time zone
LOG_LEVEL fatal, error, warn, info, debug, trace info

Twake Calendar

Twake Calendar publishes its SabreDAV endpoint under /dav/ and accepts OIDC Bearer tokens:

DAV_URL=https://calendar.example.com/dav/
DAV_HREF_PREFIX=/dav
DAV_AUTH_METHOD=command
DAV_TOKEN_COMMAND="/usr/local/bin/my-token-broker token"
[email protected]
DAV_DEFAULT_CALENDAR="Jane Doe"

Without DAV_HREF_PREFIX, discovery fails with cannot find homeUrl or calendars come back empty.

Use it with your assistant

Claude Desktop

Edit claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Linux: ~/.config/Claude/, Windows: %APPDATA%\Claude\), then restart Claude Desktop:

{
  "mcpServers": {
    "twake-dav": {
      "command": "npx",
      "args": ["-y", "mcp-twake-dav"],
      "env": {
        "DAV_URL": "https://dav.example.com",
        "DAV_USERNAME": "[email protected]",
        "DAV_PASSWORD": "your-password",
        "DAV_DEFAULT_CALENDAR": "My Calendar",
        "DAV_DEFAULT_ADDRESSBOOK": "My Contacts",
        "USER_TIMEZONE": "Europe/Paris"
      }
    }
  }
}

Claude Code

claude mcp add twake-dav --scope user \
  -e DAV_URL=https://dav.example.com \
  -e [email protected] \
  -e DAV_CREDENTIALS_FILE=~/.config/mcp-twake-dav/credentials \
  -- npx -y mcp-twake-dav

Hermes Agent

mcp_servers:
  twake_dav:
    command: npx
    args: ["-y", "mcp-twake-dav"]
    env:
      DAV_URL: https://calendar.example.com/dav/
      DAV_HREF_PREFIX: /dav
      DAV_AUTH_METHOD: command
      DAV_TOKEN_COMMAND: /usr/local/bin/my-token-broker token
      DAV_ORGANIZER_EMAIL: [email protected]
      DAV_RECURRING_WRITES: "false"

Other MCP clients

Any client that can launch a stdio MCP server works: command npx, arguments -y mcp-twake-dav, and the environment variables above.

Recommended safe configuration

Creating, moving or deleting an event with attendees makes the server email them in your name, and contact deletion is final (CardDAV has no trash). For an assistant that acts on its own:

  • ask it to confirm the recap (title, date, place, attendees) before create_event, update_event or delete_event;
  • set DAV_RECURRING_WRITES=false and edit recurring series in Twake Calendar;
  • filter out respond_to_invitation (and delete_contact if not needed) in your MCP client, for example with Hermes Agent:
    tools:
      exclude: [respond_to_invitation, delete_contact]

Event descriptions and contact notes may be written by third parties (prompt injection). See SECURITY.md.

Usage examples

  • "What's my next meeting, and where is it?"
  • "Show my schedule for this week."
  • "Am I free tomorrow afternoon? Find me a 45-minute slot."
  • "Create a meeting with Pierre on Thursday at 2 pm and invite him."
  • "Add a 15-minute reminder to my dentist appointment."
  • "Do I have pending invitations?"
  • "What's Marie's email address? Update her phone number."

Troubleshooting

Symptom Fix
Configuration validation failed Set the variables required by your DAV_AUTH_METHOD (see Authentication).
401 Unauthorized Check the credentials; with a token, check that it is valid and not expired.
URL must use HTTPS Use https:// (HTTP is only accepted for localhost / 127.0.0.1).
cannot find homeUrl / empty calendars The server sits behind a path prefix: set DAV_HREF_PREFIX (e.g. /dav).
Event not found on update or delete Pass the calendar name, or calendar: "all".
No calendars or address books Check the account's permissions in the server's web interface.
Tools missing in the client Restart the client after editing its configuration; check that npx is in the PATH.

Run with LOG_LEVEL=debug for details (logs go to stderr).

Architecture

MCP client ⇄ stdio (JSON-RPC) ⇄ mcp-twake-dav ⇄ HTTPS (CalDAV / CardDAV) ⇄ Twake Calendar / any DAV server

Layers: Zod configuration with HTTPS enforcement, Pino logger on stderr, tsdav clients with pluggable authentication and href-prefix rewriting, retry and CTag cache, calendar and address book services, ical.js transformers (iCalendar, vCard, RRULE, time zones), and the MCP tools.

Development

npm install
npm run build    # compile TypeScript
npm test         # Vitest suite, no real server needed
npm run dev      # watch mode
node scripts/check-command-auth.mjs   # token-command refresh against a mock CalDAV server

Contributing

Contributions are welcome: read CONTRIBUTING.md and our Code of Conduct. Please report vulnerabilities privately as described in SECURITY.md. Release notes are in CHANGELOG.md.

License

Licensed under the GNU Affero General Public License v3.0 (AGPL-3.0).

Copyright © 2026 LINAGORA

About

mcp-twake-dav is developed by LINAGORA, French open source software publisher, as part of Twake.ai. For support, hosting or integration of Twake.ai and its AI connectors, contact LINAGORA at https://linagora.com.

MCP Server · Populars

MCP Server · New

    FROWNINGdev

    ORM Lens

    ER diagrams, N+1 detection, schema drift & migration-risk linting for Django and SQLAlchemy (Alembic) — VS Code, CLI and MCP server. Static analysis: no database, no app boot. Free & MIT. Formerly django-orm-lens.

    Community FROWNINGdev
    M-Pineapple

    Dev Project Coordinator

    Local desk for AI agents: track coding and non-coding projects as JSON, with Analytics and Kanban views. MCP server, Mac-first, Docker for Linux.

    Community M-Pineapple
    gimp-mcp

    GIMP MCP

    GIMP MCP server

    Community gimp-mcp
    PrismorSec

    Prismor

    Self-hosted runtime control plane for AI agents. Observe or HITL approve or Block rogue tool calls before it executes: secret leaks, prompt injection, supply chain etc in a local dashboard. Agent agnostic (Claude, codex, langchain etc.)

    Community PrismorSec
    grafana-cold-storage

    Loki MCP Server

    An MCP ( Model Context Protocol ) Server for Grafana Loki