gcalc-mcp: безопасный MCP-сервер, который даёт вашему ИИ-ассистенту доступ к Google Calendar
← Назад в блог

gcalc-mcp: безопасный MCP-сервер, который даёт вашему ИИ-ассистенту доступ к Google Calendar

Опубликовано
5 мин чтения
--- просмотров
gcalc-mcp — Google Calendar через Model Context Protocol

Каждый раз, когда я хотел, чтобы мой ИИ-ассистент реально что-то сделал с моим календарём — а не просто поговорил о нём — я упирался в одну и ту же стену. Танцы с OAuth, клиентские библиотеки API, обновление токенов, жонглирование scope'ами. Слишком много сантехники, прежде чем прочитаешь хотя бы одно событие. Поэтому я написал gcalc-mcp: небольшой сервер Model Context Protocol на Go, который оборачивает проверенный временем gcalcli и открывает Google Calendar как аккуратный набор MCP-инструментов через stdio.

Цель была простой. Позволить ИИ трогать ваш календарь — это обычно бардак. gcalc-mcp существует, чтобы сделать это скучным и безопасным.

Почему обернуть CLI, а не вызывать API напрямую

Соблазн при написании MCP-сервера — тянуться прямо к Google Calendar API. Я сознательно этого не сделал. gcalcli уже решил самые сложные части — OAuth2, хранение токенов, работу с часовыми поясами — много лет назад, и миллионы cron-задач доверяют ему. Переиспользование означает, что сервер сам не вызывает никакие Google API и не хранит credentials. Вы один раз запускаете gcalcli init, и сервер наследует эту сессию.

Весь дизайн сводится к нескольким проблемам и решениям, которые я выбрал для каждой из них:

ПроблемаКак её решает gcalc-mcp
Подключить LLM к Google Calendar — это кошмар сантехники.Переиспользует уже готовый OAuth gcalcli. Запустите gcalcli init один раз; сервер наследует сессию. Credentials не хранятся.
Вы не хотите, чтобы модель выполняла произвольные shell-команды.Раннер принимает жёстко заданный allowlist субкоманд. Ввод модели передаётся только как значения флагов — никогда как токены команды. Неизвестные субкоманды отклоняются до exec.
Вывод CLI рассчитан на людей, а не на машины.Принудительно использует --json там, где это поддерживается, и добавляет --nocolor --lineart ascii везде остальном — для чистого, детерминированного текста.
Один неверный вызов может уничтожить весь календарь.Удаление закрыто явным confirm: true. Без него инструмент отказывается работать и объясняет почему — никаких случайных сносов.
Интерактивные запросы вешают stdio-сервер.Флоу, управляемые TTY (init, edit, remind), намеренно не выставлены наружу. Каждый инструмент неинтерактивен.
Даты — это раздражает.Естественный язык проходит напрямую: today, tomorrow 3pm, next monday, 2026-06-21.

Набор инструментов

Сервер поставляется с 12 инструментами, разделёнными между чтением и записью. Всё деструктивное — опционально.

ИнструментЧто делает
gcal_auth_statusПодтверждает настройку прежде всего остального.
gcal_list_calendarsВыводит список календарей на аккаунте.
gcal_agendaПредставление повестки дня за диапазон дат.
gcal_searchИщет события по тексту.
gcal_calwНедельная сетка календаря.
gcal_calmМесячная сетка календаря.
gcal_updatesНедавно изменённые события.
gcal_conflictsНаходит пересекающиеся события.
gcal_quick_addБыстро добавляет событие из фразы на естественном языке.
gcal_add_eventДобавляет подробное событие (название / когда / где / длительность / участники).
gcal_importИмпортирует ICS/vCal из пути к файлу или сырого содержимого.
gcal_deleteДеструктивный — удаляет все подходящие события. Требует confirm: true.

Совет: сначала вызовите gcal_auth_status, чтобы убедиться, что сессия активна, прежде чем делать что-либо ещё.

Настройка

Предварительные требования

Вам нужен один раз аутентифицированный gcalcli. Сервер опирается на эту сессию.

pipx install gcalcli   # or: brew install gcalcli
gcalcli init           # one-time OAuth2 browser flow

Сборка и установка

Сервер — это единый бинарник на Go (Go 1.23+).

make build          # -> bin/gcalc-mcp
make install        # -> /usr/local/bin/gcalc-mcp (sudo)

Подключение к вашему MCP-клиенту

Добавьте запись stdio-сервера в MCP-конфиг вашего клиента — Claude Desktop, Claude Code или что угодно ещё, что говорит на MCP:

{
  "mcpServers": {
    "gcalc": {
      "type": "stdio",
      "command": "/usr/local/bin/gcalc-mcp"
    }
  }
}

Чтобы указать нестандартную директорию конфигурации gcalcli, задайте GCALCLI_CONFIG в окружении сервера. Вот и всё — перезапустите клиент, и ваш ассистент сможет читать и создавать события.

Безопасность как часть дизайна

Это та часть, которая волновала меня больше всего. Дать языковой модели shell — классическая дыра для инъекций, поэтому раннер никогда не позволяет выводу модели стать командой. Субкоманды берутся из фиксированного allowlist; ввод пользователя и модели привязывается только к значениям флагов или позиционным аргументам, а неизвестные субкоманды отклоняются до того, как что-либо выполнится.

Удаление заслуживает отдельного упоминания. gcal_delete удаляет все подходящие события, поэтому отказывается работать без confirm: true и объясняет почему. Модель должна намеренно запросить уничтожение — она не может наткнуться на него случайно. В сочетании с тем, что интерактивные команды вообще не выставлены наружу, режимы отказа получаются узкими и предсказуемыми.

Почему я считаю этот паттерн важным

Большинство MCP-серверов, которые я вижу, либо переизобретают всю поверхность API, либо отдают модели голый shell. Средний путь — обернуть зрелый CLI, заставить его выдавать машиночитаемый вывод и поставить тонкий allowlist между моделью и системой — даёт полезную интеграцию за пару сотен строк, не унаследовав новую поверхность атаки. gcalcli делает всю тяжёлую работу; gcalc-mcp просто учит его говорить на MCP, безопасно.

Проект под лицензией MIT и открыт на GitHub: github.com/artschekoff/gcalc-mcp. Issues, идеи и пул-реквесты приветствуются — и если вы пишете свои собственные MCP-серверы вокруг существующих CLI, буду рад сравнить заметки.

Открыт для работы по контракту

Я доступен для работы по контракту. Если у вас есть интересная идея проекта — запишитесь на звонок через Calendly.

Записаться на 30-минутный звонок