Skip to main content
Glama

caldav-mcp

Дайте вашему ИИ-ассистенту календарь. MCP-сервер, который предоставляет доступ на чтение и запись к любому календарю с поддержкой CalDAV — Nextcloud, Radicale, Baikal, ownCloud, iCloud, Fastmail и другим, — через 14 специализированных инструментов.

Зачем caldav-mcp?

Dockerized

Многоступенчатый образ на базе Alpine, выполнение без привилегий root, встроенный healthcheck. Разворачивайте там, где работает Docker.

Python 3.13

Чистая типизированная кодовая база с валидацией Pydantic. Легко читать и легко расширять.

Один контейнер

Одна команда docker compose up — никаких баз данных, фоновых работников и sidecar-контейнеров.

Без состояния

Между запросами не сохраняется состояние сессии. Учётные данные передаются с каждым запросом в HTTP-заголовках, что позволяет использовать multi-tenant без перезапуска сервера.

Безопасность по умолчанию

Сравнение токенов за постоянное время, ограничение частоты запросов по IP с экспоненциальной задержкой, санитизация входных данных, структурированный аудит журнала, никаких секретов в ответах об ошибках.

Двухуровневая аутентификация

Опциональный API-ключ защищает конечную точку MCP; учётные данные CalDAV подставляются для каждого запроса. Уровни независимы, компонуемы и без неожиданностей.

Related MCP server: mcp-labrat

Где это полезно

  • Управление календарём с помощью ИИ — Позвольте Claude, Codex или любому MCP-клиенту создавать, обновлять, искать и удалять события через естественный язык.

  • Мультитенантный доступ — Отправляйте разные X-Caldav-* заголовки в каждом запросе, чтобы работать с разными учётными записями CalDAV на одном экземпляре сервера.

  • Автоматизация календаря на собственном сервере — Работает с уже существующим Nextcloud, Radicale или Baikal. Без привязки к облаку.

  • Корпоративные и командные развёртывания — Централизованные, не имеющие состояния, контейнеризированные. Размещайте за обратным прокси, масштабируйте горизонтально, изменяйте учётные данные без простоя.

Быстрый старт

# 1. Clone the repo
git clone https://git.gelse.net/werner/caldav-mcp.git && cd caldav-mcp

# 2. Create your .env file
cp .env.example .env
# Edit .env — at minimum set CALDAV_MCP_API_KEY, CALDAV_URL, CALDAV_USERNAME, CALDAV_PASSWORD

# 3. Launch
docker compose up -d

# 4. Verify
curl -s http://localhost:8600/mcp \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "X-Caldav-Url: https://cloud.example.com/remote.php/dav/calendars/user/" \
  -H "X-Caldav-Username: user" \
  -H "X-Caldav-Password: app-password" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1"}}}'

Теперь сервер доступен по адресу http://localhost:8600/mcp (Streamable HTTP).

Инструменты

Сервер предоставляет 14 MCP-инструментов в трёх категориях.

Запросы (только чтение)

Tool

Description

caldav_list_calendars

Список всех доступных календарей

caldav_get_events

Получить события за указанный период дат

caldav_get_today_events

Получить события на сегодня

caldav_get_week_events

Получить события на следующие 7 дней

caldav_get_event_by_uid

Получить конкретное событие по UID (включая участников)

caldav_search_events

Искать события по тексту: в теме, описании, месте и категориях

caldav_get_freebusy

Получить данные о свободном/занятом времени за период

Изменения (запись)

Tool

Description

caldav_create_event

Создать новое событие — поддерживает RRULE, приоритет, категории, участников

caldav_update_event

Частично изменить существующее событие по UID

caldav_delete_event

Удалить событие по UID

caldav_move_event

Переместить событие между календарями

Участники

Tool

Description

caldav_add_attendee

Добавить участника к событию

caldav_remove_attendee

Удалить участника из события

caldav_list_attendees

Список участников события

Развёртывание

Docker

Проект поставляется с многоступенчатым Dockerfile:

  1. Этап сборки — устанавливает Python-зависимости из requirements.txt в чистый префикс.

  2. Этап выполнения — копирование ранее собранные пакеты в минимальный Alpine-образ, работает из-под непривилегированного пользователя app, открывает порт 8080.

docker build -t caldav-mcp:latest .
docker run -p 8600:8080 \
  -e CALDAV_MCP_API_KEY=YOUR_KEY \
  -e CALDAV_URL=https://cloud.example.com/remote.php/dav/calendars/user/ \
  -e CALDAV_USERNAME=user \
  -e CALDAV_PASSWORD=app-password \
  caldav-mcp:latest

Docker Compose

docker-compose.yaml сопоставляет порт хоста 8600 с портом контейнера 8080 и читает переменные окружения из локального файла .env:

services:
  caldav-mcp:
    build: .
    image: caldav-mcp:latest
    restart: unless-stopped
    ports:
      - "8600:8080"
    environment:
      CALDAV_MCP_API_KEY: "${CALDAV_MCP_API_KEY:-}"
      TZ: Europe/Vienna
docker compose up -d

Также для интеграционных тестов доступен docker-compose.test.yaml — он включает CalDAV-сервер Radicale.

TLS / HTTPS

Сервер поддерживает встроенный TLS без обратного прокси. Используйте следующие переменные окружения для включения HTTPS:

CALDAV_MCP_TLS_CERT=/path/to/cert.pem
CALDAV_MCP_TLS_KEY=/path/to/key.pem
CALDAV_MCP_TLS_CA_BUNDLE=/path/to/ca.pem   # optional

Когда TLS включён, сервер слушает HTTPS. Если TLS не настроен, запускайте сервер за обратным прокси (Traefik, Caddy, nginx), который выполняет завершение TLS.

Аутентификация

Два независимых уровня — оба опциональны, но рекомендуются.

Уровень 1: аутентификация конечной точки MCP

Если задан CALDAV_MCP_API_KEY, каждый запрос к конечной точке /mcp должен содержать один из вариантов:

  • Authorization: Bearer <token>

  • X-Api-Key: <token>

Сравнение токена выполняется за постоянное время, чтобы исключить атаки по вспомогательным каналам, связанным со временем. Неудачные попытки отслеживаются по IP-адресу клиента с помощью скользящего окна с экспоненциальной задержкой.

Если CALDAV_MCP_API_KEY не задан, конечная точка открыта — не публикуйте её в публичный интернет без аутентификации.

Уровень 2: учётные данные CalDAV

Учётные данные CalDAV запрашиваются для каждого запроса:

  1. HTTP-заголовки (предпочтительно): X-Caldav-Url, X-Caldav-Username, X-Caldav-Password

  2. Переменные окружения (резервный вариант): CALDAV_URL, CALDAV_USERNAME, CALDAV_PASSWORD

HTTP-заголовки имеют приоритет. Это позволяет организовать multi-tenant использование: разные клиенты могут направлять запросы к разным учётным записям CalDAV без перезапуска сервера.

Конфигурация

Вся конфигурация задаётся через переменные окружения и проверяется при запуске с помощью Pydantic.

Сервер

Variable

Default

Description

CALDAV_MCP_PORT

8080

Порт прослушивания (внутри контейнера)

CALDAV_MCP_PATH

/mcp

Путь к конечной точке Streamable HTTP

CALDAV_MCP_API_KEY

"" (отключён)

Общий секрет для аутентификации конечной точки MCP

TZ

"" (UTC)

Часовой пояс IANA (например, Europe/Vienna) для границ сегодня/недели

CalDAV

Variable

Default

Description

CALDAV_URL

""

URL-адрес CalDAV-сервера (резерв для заголовка X-Caldav-Url)

CALDAV_USERNAME

""

Имя пользователя CalDAV (запас для заголовка X-Caldav-Username)

CALDAV_PASSWORD

""

Пароль CalDAV (запасной вариант для заголовка X-Caldav-Password)

CALDAV_MCP_CALDAV_VERIFY_SSL

true

Проверять TLS-сертификаты при подключениях к CalDAV. Установите false только для тестов с самоподписанными сертификатами.

Ограничение частоты запросов

Variable

Default

Description

CALDAV_MCP_RATE_LIMIT_MAX_FAILURES

10

Максимум Failed попыток аутентификации с одного IP-адреса в рамках скользящего окна

CALDAV_MCP_RATE_LIMIT_WINDOW_SECONDS

60

Длительность скользящего окна в секундах

TLS

Variable

Default

Description

CALDAV_MCP_TLS_CERT

""

Путь к PEM-файлу TLS-сертификата

CALDAV_MCP_TLS_KEY

""

Путь к PEM-файлу приватного ключа TLS

CALDAV_MCP_TLS_CA_BUNDLE

""

Необязательный пакет CA-сертификатов для пользовательских центров сертификации

Логирование

Variable

Default

Description

CALDAV_MCP_LOG_FORMAT

text

Формат журнала аудита: text или json

Безопасность

  • МВСТАВИТЬ сервер за обратным прокси, который завершает TLS, либо включите встроенный TLS.

  • Установите надёжный CALDAV_MCP_API_KEY.

  • Ограничьте доступ на уровне сети/межсетевого экрана доверенными хостами или VPN.

  • Предпочтительно привязывайте сервер к адресу 127.0.0.1, если явно не нужен удалённый доступ.

  • Никогда не помещайте пароли приложений CalDAV в публичную конфигурацию или журналы.

Разработка

Команды

make test           # Run unit tests
make test-integration  # Run integration tests (requires docker-compose.test.yaml)
make test-performance  # Run performance benchmarks
make lint           # Lint with ruff (check + format)
make typecheck      # Type check with mypy
make check          # All checks: lint + typecheck + deps-check + test
make deps-check     # Verify pyproject.toml and requirements.txt are in sync
make build          # Build Docker image

Структура проекта

caldav-mcp/
├── server.py                 # Thin entrypoint, launches FastMCP HTTP server
├── caldav_mcp/               # Core package
│   ├── tools/                # MCP tool handlers
│   │   ├── queries.py        #   Read-only tools (7)
│   │   ├── mutations.py      #   Write tools (4)
│   │   └── attendees.py      #   Attendee management (3)
│   ├── auth.py               # Two-layer auth (API key + CalDAV creds)
│   ├── calendar.py           # CalDAV calendar selection & serialization
│   ├── client_cache.py       # Thread-safe LRU cache for DAVClient
│   ├── config.py             # Env var parsing, header constants
│   ├── config_schema.py      # Pydantic startup validation
│   ├── datetime_utils.py     # Date/time parsing, timezone helpers
│   ├── errors.py             # Typed exceptions, ToolResult dataclass
│   ├── event_builder.py      # Pure iCalendar VEVENT construction
│   ├── sanitizers.py         # Input sanitization, field length limits
│   ├── rate_limit.py         # Sliding-window rate limiter
│   ├── audit.py              # Structured JSON audit logging
│   ├── constants.py          # Shared string constants
│   └── types.py              # CalDAVClient Protocol definition
├── tests/                    # Unit, integration, performance
├── docs/                     # Architecture, API, contributing docs
├── Dockerfile                # Multi-stage Docker build
├── docker-compose.yaml       # Production compose
├── docker-compose.test.yaml  # Test compose with Radicale
├── requirements.txt          # Runtime dependencies (pinned)
├── pyproject.toml            # Dev config and dependencies
└── Makefile                  # Build/test shortcuts

Зависимости

Package

Version

Purpose

fastmcp

3.4.7

Фреймворк MCP-сервера, транспорт Streamable HTTP

calldav

3.2.1

Клиентская библиотека CalDAV

icalendar

7.2.2

Разбор/генерация iCalendar RFC 5545

requests

>=2.28.0

Слой HTTP-транспорта

Устранение неполадок

Симптом

Причина

Исправление

Connection refused

Сервер CalDAV недоступен

Проверьте, что CALDAV_URL указан верно и сервер запущен

SSL: CERTIFICATE_VERIFY_FAILED

Самоподписанный или недействительный TLS-сертификат

Импортируйте CA-сертификат сервера в системное хранилище доверия или используйте действительный сертификат

ERROR:[auth] unauthorized

Отсутствует или неверен API-токен

Установите CALDAV_MCP_API_KEY и укажите Authorization: Bearer <token> в вашем запросе

Missing CalDAV credentials

Отсутствуют заголовки CalDAV или переменные окружения

Укажите заголовки X-Caldav-* или задайте CALDAV_URL/CALDAV_USERNAME/CALDAV_PASSWORD

Calendar 'X' not found

Опечатка или неверное название календаря

Запустите caldav_list_calendars, чтобы увидеть доступные названия — они чувствительны к регистру

События показывают неверное время

Часовой пояс сервера не задан

Установите переменную окружения TZ в ваш часовой пояс IANA (например, Europe/Vienna)

FAQ

В: Можно ли использовать это с несколькими учетными записями CalDAV? О: Да — отправляйте разные заголовки X-Caldav-Url / X-Caldav-Username / X-Caldav-Password для каждого запроса. Кэш клиента привязан к паре (url, username).

В: Какие серверы CalDAV поддерживаются? О: Любой сервер, реализующий стандарт CalDAV: Nextcloud, ownCloud, iCloud, Fastmail, Baikal, Radicale и другие.

В: Передается ли API-токен безопасно? О: Только при использовании HTTPS. Включите встроенный TLS или разместите сервер за TLS-terminating обратным прокси.

В: Как сгенерировать пароль приложения CalDAV? О: Зависит от вашего провайдера. Nextcloud: Настройки → Безопасность → Пароли приложений. iCloud: Используйте пароль, специфичный для приложения, с appleid.apple.com.

В: Можно ли использовать это через stdio вместо HTTP? О: Текущий сервер использует только транспорт Streamable HTTP. Чтобы использовать stdio, измените server.py, вызвав mcp.run() вместо mcp.run_http_async().

Лицензия

MIT

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    An MCP server that enables interaction with CalDAV calendars to manage events and check availability through natural language or voice commands. It provides specific tools for listing, searching, and creating calendar entries using an OpenAI-compatible interface.
  • A
    license
    Not graded
    quality
    F
    maintenance
    Provider-agnostic CalDAV calendar MCP server that connects any CalDAV calendar to AI assistants, enabling calendar operations like listing, creating, updating, and deleting events.
    AGPL 3.0

View all related MCP servers

Related MCP Connectors

  • Hosted Google Calendar MCP server for AI agents. No self-hosting or Google Cloud setup.

  • Calendar API for AI agents: events, availability, Google/Microsoft setup, scheduling, and iCal.

  • A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/gelse/caldav-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server