Skip to main content
Glama
yandex-calendar-mcp
by architawr

Яндекс Календарь для MCP

Локальный MCP-сервер для работы с Яндекс Календарём из Codex, Claude Code и других MCP-клиентов. Работает через stdio: клиент сам запускает процесс, открытого сетевого порта нет.

Базовая версия 0.1.0. Чтение доступно сразу после настройки аккаунта. Запись включается отдельно для выбранных календарей. Проект не является официальным продуктом Яндекса.

Возможности

Инструмент

Назначение

list_calendars

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

list_events

События за период, включая повторения и исключения

prepare_event_change

Предпросмотр создания, изменения или удаления без записи в Яндекс

apply_event_change

Применение подготовленного изменения; требует отдельного разрешения клиента

Поддерживаются часовые пояса, события на весь день, RRULE, EXDATE и переносы RECURRENCE-ID при чтении. Ответ содержит UID, доступность free/busy и признак усечения.

Ограничения: ответы на приглашения (RSVP), отправка приглашений, изменение повторяющихся событий и операции с задачами VTODO пока отсутствуют. Изменять можно только одиночные события без участников; организатором может быть сам владелец аккаунта. Внешние приглашения можно читать, но нельзя принимать/отклонять или редактировать.

Related MCP server: yandex-calendar-plugin

Установка

Нужны Python 3.11+, uv и системное хранилище секретов. Рабочий сценарий проверен на macOS с Keychain. Для Linux нужен Secret Service/libsecret; Linux проверяется в CI без реального аккаунта. Windows пока не проверен, shell-скрипт запуска рассчитан на macOS/Linux.

git clone https://github.com/architawr/yandex-calendar-mcp.git
cd yandex-calendar-mcp
uv sync --locked
./scripts/run.sh credentials

Команда credentials запросит полный адрес почты и пароль приложения типа «Календарь / CalDAV», созданный в Яндекс ID. Основной пароль аккаунта не нужен.

Пароль сохраняется в системном хранилище под именем local.yandex-calendar-mcp. При недоступном скрытом вводе или системном хранилище команда прекращает работу: перехода на открытое хранение нет. Повторный запуск обновляет пароль.

В config.local.json сохраняются только несекретные настройки аккаунта. Этот файл и резервные копии исключены из Git и публикуемых пакетов. Не добавляйте их в Git принудительно.

Установка как пакета (без запуска из репозитория)

Для повседневного использования удобнее установленный пакет, а не рабочая копия: сервер не зависит от .venv и текущей ветки. Исполняемый файл называется yandex-calendar-mcp.

Через uvx, без клонирования. Конфиг передаётся переменной YANDEX_CALENDAR_CONFIG (см. ниже), потому что по умолчанию сервер ищет config.local.json в текущей папке, а при запуске клиентом она заранее неизвестна.

mkdir -p ~/.config/yandex-calendar-mcp
export YANDEX_CALENDAR_CONFIG=~/.config/yandex-calendar-mcp/config.json
uvx --from git+https://github.com/architawr/yandex-calendar-mcp yandex-calendar-mcp credentials

Запуск сервера клиентом: uvx --from git+https://github.com/architawr/yandex-calendar-mcp yandex-calendar-mcp serve. Для воспроизводимости закрепите версию: git+https://github.com/architawr/yandex-calendar-mcp@<тег или коммит>. Регистрация в клиенте с переменной окружения, например для Claude Code:

claude mcp add --scope user --transport stdio \
  --env YANDEX_CALENDAR_CONFIG="$HOME/.config/yandex-calendar-mcp/config.json" \
  yandex-calendar -- uvx --from git+https://github.com/architawr/yandex-calendar-mcp yandex-calendar-mcp serve

Из локальной сборки. Собранный .whl ставится как инструмент uv; исполняемый файл появляется в ~/.local/bin/:

uv build
uv tool install --force dist/*.whl
yandex-calendar-mcp --help

В регистрации клиента укажите команду yandex-calendar-mcp (или абсолютный путь к ~/.local/bin/yandex-calendar-mcp) с аргументом serve и переменной YANDEX_CALENDAR_CONFIG.

Где лежит конфиг

Файл настроек (формат — config.example.json) читается по пути из YANDEX_CALENDAR_CONFIG, а без неё — из config.local.json в текущей папке. Для установленного пакета держите его вне репозитория, в каталоге данных пользователя, и ограничьте права:

ОС

Рекомендуемое место

macOS

~/Library/Application Support/YandexCalendarMCP/config.json

Linux

~/.config/yandex-calendar-mcp/config.json

mkdir -p ~/.config/yandex-calendar-mcp && chmod 700 ~/.config/yandex-calendar-mcp
chmod 600 ~/.config/yandex-calendar-mcp/config.json

Каталог для файла нужно создать заранее: credentials сам его не создаёт. Рядом с конфигом сервер сохраняет .calendar-trash (см. «Как работает запись»). Пароль в конфиг не попадает, он хранится в системном хранилище секретов.

Обновление

После изменения кода или выхода новой версии:

git pull
uv build
uv tool install --force dist/*.whl

Затем перезапустите MCP-клиент или сессию: уже запущенный процесс продолжает работать со старой версией. Конфиг и пароль в хранилище при обновлении не меняются. Для uvx обновление запрашивается так: uvx --refresh --from git+https://github.com/architawr/yandex-calendar-mcp yandex-calendar-mcp --help; закреплённую на тег версию меняйте в команде регистрации.

Подключение к Codex

Из корня проекта:

codex mcp add yandex-calendar -- "$PWD/scripts/run.sh"

Конфигурация хранится в ~/.codex/config.toml. Для начала ограничьте список инструментов чтением; пример — codex-mcp-readonly.example.toml. Замените пример абсолютного пути на путь к своему проекту.

Для записи добавьте prepare_event_change и apply_event_change в enabled_tools той же регистрации и задайте:

[mcp_servers.yandex-calendar.tools.apply_event_change]
approval_mode = "prompt"

Полный пример — codex-mcp-write.example.toml. Не создавайте две одинаковые таблицы TOML. При запуске Codex из BB на том же Mac используется пользовательская конфигурация Codex; на другом хосте потребуются собственная установка и хранилище секретов.

Подключение к Claude Code

claude mcp add --scope user --transport stdio yandex-calendar -- "$PWD/scripts/run.sh"
claude mcp get yandex-calendar

Регистрация уровня пользователя доступна в разных проектах. В ~/.claude/settings.json добавьте правило к существующему permissions.ask:

{
  "permissions": {
    "ask": ["mcp__yandex-calendar__apply_event_change"]
  }
}

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

Если сервер установлен как пакет (см. «Установка как пакета»), вместо "$PWD/scripts/run.sh" в обеих регистрациях укажите yandex-calendar-mcp serve и передайте YANDEX_CALENDAR_CONFIG.

После установки или изменения настроек перезапустите MCP/сессию клиента. Шаблон для других клиентов — mcp.example.json.

Настройки

Смотрите config.example.json:

  • username — полный адрес аккаунта;

  • timezone — часовой пояс IANA, например Europe/Podgorica;

  • allowed_calendars — список разрешённых для чтения URL; пустой массив разрешает чтение всех доступных календарей;

  • allowed_write_calendars — список календарей для записи; пустой массив или отсутствие поля запрещает запись;

  • calendar_profiles — необязательные описания и доступность по умолчанию для конкретных URL.

Сначала вызовите list_calendars, затем скопируйте выбранные calendar_id в настройки. Права самого аккаунта Яндекса продолжают действовать. Не публикуйте реальные URL своих календарей.

Переменные переопределения: YANDEX_CALENDAR_CONFIG (путь к JSON), YANDEX_CALENDAR_USERNAME, YANDEX_CALENDAR_TIMEZONE, YANDEX_CALENDAR_ALLOWLIST (JSON-массив для чтения). Пароль через окружение не передаётся.

Профиль календаря имеет поля description и default_availability (free или busy). Описание показывается агенту в list_calendars.

Например, можно разделить задачи:

  • Soft — гибкие дела без конкретного времени. Предпочтительны события на весь день; новые события получают TRANSP:TRANSPARENT и оставляют время свободным.

  • Hard — задачи с точными началом и окончанием. Новые события получают TRANSP:OPAQUE и резервируют время.

  • Обычные встречи и личные планы можно держать в отдельных календарях.

Soft здесь реализован событиями VEVENT без времени, не объектами VTODO. Названия календарей произвольные: поведение задаёт профиль URL. Существующие события автоматически не меняются; обновление сохраняет их доступность. Итоговое отображение занятости также зависит от календарного клиента.

Чтение событий

list_events(calendar_id, start, end, limit=100) принимает даты YYYY-MM-DD или временные метки ISO 8601 с явным смещением. Конец периода не включается. Даты без времени означают полночь в настроенном часовом поясе.

Период — до 92 суток, limit — от 1 до 500. Если truncated=true, сузьте период, прежде чем делать выводы о свободном времени.

Повторения раскрываются в отдельном процессе с таймаутом 10 секунд; на Linux дополнительно ограничена память процесса. Слишком плотные правила отклоняются до раскрытия, посекундные и поминутные повторения не поддерживаются. Оценка сложности консервативна: некоторые допустимые сложные правила также могут быть отклонены. Это ограничение ресурсов, не ОС-песочница и не гарантия жёсткого лимита памяти на всех платформах.

При ошибке запроса или раскрытия повторений сервер возвращает ошибку, а не частичное расписание под видом полного.

Как работает запись

  1. Агент вызывает prepare_event_change с operation: create, update или delete.

  2. Сервер возвращает календарь, UID, данные до/после и одноразовый change_id на пять минут. Изменений в Яндексе ещё нет.

  3. Пользователь подтверждает конкретное изменение в MCP-клиенте.

  4. Агент вызывает отдельно разрешаемый apply_event_change.

changes принимает только summary, start, end, description, location. Создание требует названия и обеих границ времени; изменение/удаление — UID. Новые временные метки записываются в UTC, чтение возвращает настроенный часовой пояс.

Создание использует If-None-Match: *; изменение/удаление — If-Match с сильным ETag. Конфликт не перезаписывается автоматически. После операции результат перечитывается.

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

Перед изменением/удалением исходный ICS сохраняется в .calendar-trash рядом с локальным конфигом. На Unix каталог имеет права 0700, файл — 0600. Автоматической очистки и инструмента восстановления пока нет; резервная копия не гарантирует откат. Содержимое копий приватно.

Границы безопасности

  • Только stdio, без HTTP-сервера и входящих сетевых портов.

  • Исходящие запросы только к https://caldav.yandex.ru:443; TLS проверяется, редиректы и proxy-переменные окружения отключены.

  • Чтение использует PROPFIND/REPORT/GET; применение изменений — PUT/DELETE только в выбранных календарях.

  • XML разбирается через defusedxml; ответы ограничены 8 MiB, сетевые операции имеют таймауты.

  • Пароль находится в системном хранилище, не в исходниках, аргументах запуска или конфиге MCP.

  • Пароль CalDAV потенциально разрешает запись шире, чем наш список календарей. Ограничение обеспечивает код сервера, а не отдельный read-only пароль Яндекса.

  • Локальный процесс и зависимости работают с правами пользователя. MCP не защищает от скомпрометированного Mac или произвольного кода агента с доступом к тому же аккаунту ОС.

  • Подтверждение обеспечивает клиент. readOnlyHint, destructiveHint, requires_user_approval и наличие change_id сами по себе не доказывают согласие человека.

  • Названия и описания событий — недоверенные данные, а не инструкции агенту. При чтении сведения о встречах передаются модели выбранного клиента.

Подробнее: SECURITY.md. Независимый аудит не проводился; абсолютная безопасность не заявляется.

Проверки и разработка

uv sync --locked
uv run --locked pytest -q
uv build

Тесты не используют реальный аккаунт и Keychain: проверяют сетевые ограничения, повторения, часовые пояса, конфликты, одноразовые изменения и MCP stdio. Живой цикл создания, изменения, удаления и перечитывания одиночных событий проверен на Яндексе с macOS. Тестовые события после проверки удалены.

Инструкции для изменений: CONTRIBUTING.md. Лицензия: MIT.

Документация протоколов и клиентов

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Unofficial local MCP plugin for interacting with Yandex Calendar from Codex. Enables calendar listing, event CRUD, and Telemost meeting creation via CalDAV.
    Apache 2.0
  • A
    license
    Not graded
    quality
    D
    maintenance
    This MCP server enables Claude to read and manage self-hosted CalDAV calendars (SOGo, Nextcloud, Radicale, etc.) with strict safety guardrails: read-only by default, optional writes only when explicitly enabled, no permanent deletes, and no event invitations.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables remote MCP clients such as ChatGPT to read and search calendars, fetch events, and perform controlled writes to Apple iCloud calendars through CalDAV, with OAuth and server-enforced write policies.
    MIT