Skip to main content
Glama
SarjuThakkar

Skylight MCP server

by SarjuThakkar

Skylight MCP server

Позволяет кольцу Pebble Index добавлять события в семейный календарь Skylight голосом. Облачный агент Pebble является MCP-клиентом; этот сервер выполняет HTTP-работу с неофициальным API Skylight. Pebble никогда не общается со Skylight напрямую, и Skylight не видит ваш аккаунт Pebble.

Единственный доступный инструмент — create_event (только запись — Pebble не нужно читать календарь обратно, а отказ от list_events сделал поверхность инструментов однозначной). Он умеет автоматически назначать тег профиля члена семьи по умолчанию и понимает "me"/"myself" как этого человека, а любого другого члена — по имени.

Транспорт: Streamable HTTP. Аутентификация: статический bearer-токен в заголовке Authorization (Pebble не поддерживает процедуры входа через OAuth для пользовательских MCP-серверов, только фиксированный заголовок).

Можно ли переиспользовать это для чужой связки Pebble + Skylight?

Да — в коде нет ничего, что было бы привязано к конкретному человеку. Каждое значение, специфичное для аккаунта (логин Skylight, frame id, часовой пояс, какой член семьи является основным по умолчанию, bearer-токен), берётся из переменной окружения, а имена членов семьи сопоставляются на лету с вашими категориями Skylight, а не захардкожены. Любой, у кого есть собственный аккаунт Skylight, Pebble Index и место для размещения небольшого Python HTTP-сервиса, может запустить свою копию. См. Развёртывание ниже — это несколько команд CLI, а не ручное редактирование кода.

Related MCP server: Google Calendar AutoAuth MCP Server

Переменные окружения

Переменная

Обязательная

Описание

SKYLIGHT_EMAIL

да

Ваш email для входа в app.ourskylight.com.

SKYLIGHT_PASSWORD

да

Ваш пароль для входа в app.ourskylight.com.

SKYLIGHT_FRAME_ID

да

Число из app.ourskylight.com/calendar/<id> после входа в систему.

MCP_BEARER_TOKEN

да

Статический токен, который Pebble отправляет как Authorization: Bearer <token>. Сгенерируйте с помощью openssl rand -hex 32.

SKYLIGHT_TIMEZONE

нет

IANA-часовой пояс, в котором интерпретируются наивные времена событий. По умолчанию — America/Chicago. Это же значение docstring инструмента сообщает агенту Pebble, так что синхронизация поддерживается автоматически.

SKYLIGHT_DEFAULT_MEMBER

нет

Имя профиля члена семьи Skylight (должно совпадать с названием категории в вашем календаре). Используется, когда who опущен, и именно к нему приводятся "me"/"myself"/"i". Оставьте пустым, чтобы не назначать тег по умолчанию.

PORT

нет

Устанавливается автоматически Railway/большинством хостингов. Локально по умолчанию — 8000.

Локальная настройка

python3 -m venv .venv && source .venv/bin/activate   # needs Python 3.10+
pip install -r requirements.txt

cp .env.example .env   # then fill in real values
export $(grep -v '^#' .env | xargs)   # or use your own env loader
export MCP_BEARER_TOKEN=$(openssl rand -hex 32)

python skylight_mcp_server.py

Сервер слушает http://0.0.0.0:8000 (или $PORT, если задан), MCP-эндпоинт — на /mcp, проверка здоровья — на /healthz (без аутентификации).

Тестирование с помощью MCP Inspector

npx @modelcontextprotocol/inspector

В интерфейсе Inspector:

  1. Транспорт: Streamable HTTP

  2. URL: http://localhost:8000/mcp

  3. В разделе аутентификации добавьте заголовок Authorization: Bearer <your MCP_BEARER_TOKEN>

  4. Подключитесь, затем вызовите create_event с тестовым названием и проверьте, что событие появилось в нужном профиле в приложении Skylight.

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

Вариант A: вспомогательный скрипт deploy.sh

export SKYLIGHT_EMAIL=you@example.com
export SKYLIGHT_PASSWORD=...
export SKYLIGHT_FRAME_ID=1234567
export MCP_BEARER_TOKEN=$(openssl rand -hex 32)
# optional:
export SKYLIGHT_TIMEZONE=America/Chicago
export SKYLIGHT_DEFAULT_MEMBER=YourName

./deploy.sh

Он устанавливает Railway CLI, если тот отсутствует, предлагает вам войти в систему (OAuth в браузере — эту часть нельзя автоматизировать скриптом), при первом запуске создаёт проект, задаёт все переменные окружения, выполняет деплой и выводит публичный URL. Повторно запускайте его после любого изменения skylight_mcp_server.py, чтобы выложить новую сборку, — ссылка на проект хранится в ~/.railway/config.json с привязкой к этому каталогу, а не в репозитории, поэтому в git не попадает ничего специфичного для Railway.

Вариант B: вручную

railway login                                  # browser OAuth
railway init --name skylight-mcp               # first time only
railway variable set SKYLIGHT_EMAIL=you@example.com --service skylight-mcp --skip-deploys
railway variable set SKYLIGHT_PASSWORD=... --service skylight-mcp --skip-deploys
railway variable set SKYLIGHT_FRAME_ID=1234567 --service skylight-mcp --skip-deploys
railway variable set MCP_BEARER_TOKEN=$(openssl rand -hex 32) --service skylight-mcp
railway up -c -y --service skylight-mcp        # builds the Dockerfile, deploys
railway domain --service skylight-mcp          # public HTTPS URL, real cert

Повторный деплой позже (вами после изменения кода или кем угодно, кто уже один раз выполнил настройку) — это просто:

railway up -c -y --service skylight-mcp

На этом весь рассказ о повторном деплое — никакого конфигурационного файла, кроме Dockerfile, который уже есть в репозитории, и никакого CI-пайплайна. railway logs --service skylight-mcp показывает живые логи, что полезно, поскольку аргументы create_event логируются при каждом вызове (см. Устранение неполадок).

Укажите в конфигурации MCP-клиента Pebble адрес https://<your-railway-domain>/mcp и bearer-токен из настройки.

Настройка приложения Pebble

В настройках MCP-сервера приложения Pebble:

  • Название: любое, но без пробелов и специальных символов — см. Устранение неполадок. Подойдут и SkylightCalendar, и skylight-calendar.

  • URL: https://<your-railway-domain>/mcp

  • Транспорт: Streamable (в выпадающем списке буквально написано "SSE/Streamable" — выбирайте Streamable, а не SSE)

  • Authorization: Bearer <your MCP_BEARER_TOKEN> — полная строка, включая префикс Bearer

Пользовательские MCP-инструменты работают только в режиме записи Pebble по двойному щелчку (одинарный щелчок использует собственные встроенные действия Pebble). Убедитесь, что этот сервер назначен той группе песочницы, которую использует ваш двойной щелчок.

Как работает тегирование членов семьи

Члены семьи вообще не настраиваются в этом сервере — create_event вызывает GET /frames/{id}/categories в вашем реальном аккаунте Skylight (кэшируется в памяти процесса) и сопоставляет аргумент who с этими названиями без учёта регистра. "me"/"myself"/"i" приводятся к SKYLIGHT_DEFAULT_MEMBER. Если точное совпадение не найдено, используется нечёткое сопоставление (difflib) по тем же названиям, поскольку распознавание речи Pebble может искажать менее распространённые имена (например, "Metree" или "May Tree" в обоих случаях всё равно сводятся к "Maitree" — проверено вживую). Имена, которым так и не нашлось соответствия, не блокируют событие — оно создаётся без тега профиля, и подтверждение об этом сообщает, так что ошибка распознавания становится заметной, а не молча неправильной.

Примеры фраз для проверки

Каждая фраза задействует отдельную часть инструмента — после того как вы произнесёте одну из них (двойной щелчок по кольцу), проверьте в Skylight дату/время, целодневное ли это событие или с временем, и какие профили получили тег(и):

  • "Add a dentist appointment tomorrow at 2pm." Событие с временем; по умолчанию привязывается к профилю SKYLIGHT_DEFAULT_MEMBER, без места.

  • "Block off next Monday as a vacation day." Время не названо → создаётся целодневное событие (автоматически определяется по голой дате — чтобы это сработало, не нужно говорить "all day").

  • "Add a trip to Chicago from the 2nd to the 3rd of September." Многодневное целодневное событие — охватывает оба дня включительно.

  • "Add Maitree's haircut next Tuesday at 10am." Явный who — тегирует профиль этого человека вместо профиля по умолчанию.

  • "Add family movie night Friday at 7pm for Maitree and me." Тегирование нескольких людей — событие будет привязано к обоим.

  • "Add a dentist appointment at Dr. Smith's office next Wednesday at 3pm." Проверяет, что поле location захватывается.

Что проверено, а что предполагается

API Skylight неофициальный и восстановленный методами обратной разработки. Поток аутентификации и формы полезной нагрузки этого сервера были протестированы вживую на реальном аккаунте 2026-08-26/27 (точные шаги входа см. в docstring модуля skylight_mcp_server.py). Примечательные находки, противоречащие первоначальным предположениям, взятым из захвата OpenAPI за декабрь 2025 года:

  • Старый вход через POST /api/sessions (email/пароль → Basic auth) выведен из эксплуатации — теперь он возвращает 401 "This version of Skylight is no longer supported." Живой поток представляет собой 4-шаговый обмен кода авторизации OAuth2 (для успеха этого потока PKCE не требуется, хотя вариант с PKCE тоже встречается в дикой природе).

  • skylight-api-version: 2026-05-01 обязателен при каждом API-вызове.

  • date_max в GET .../calendar_events — это исключающая верхняя граница.

  • ends_at целодневных событий также исключающий — однодневному целодневному событию нужен ends_at в полночь следующего дня (или, что эквивалентно, равный starts_at — это тоже работает), а для интервала в N дней ends_at должен быть с запасом на один день после последнего включённого дня. create_event обрабатывает этот сдвиг внутренне, так что его собственный аргумент end остаётся включающим для вызывающих.

  • Члены семьи тегируются через category_ids (массив) в полезной нагрузке создания; идентификаторы категорий берутся из GET .../categories и кэшируются на процесс.

Если Skylight снова изменит свой API, это самые вероятные места поломки: _login() (шаги OAuth) и форма полезной нагрузки calendar_events в create_event.

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

Pebble пишет "invalid tool call, action failed", и в календаре ничего не появляется. Сначала проверьте railway logs --service skylight-mcp — каждый вызов create_event логирует свои сырые аргументы, а ошибки API Skylight тоже перехватываются и логируются. Проект уже сталкивался с двумя вещами:

  • В имени MCP-сервера есть пробел или специальный символ в конфигурации приложения Pebble. Подтверждено на форуме Pebble: пробел в поле Name сервера заставляет агента собирать неправильное составное имя инструмента, и вызов молча никогда не достигает сервера (в логах вы увидите ListToolsRequest, но не CallToolRequest). Переименуйте сервер, используя только буквенно-цифровые символы и дефисы.

  • Необязательные аргументы инструмента, объявленные как nullable (str | None). Некоторые строгие валидаторы вызова функций отвергают JSON-схему с anyOf: [string, null] ещё до отправки запроса. Этот сервер вместо этого использует обычные str = "" (пустая строка = "not provided"), чтобы специально избежать этого.

Дата/время не распарсилась. create_event перехватывает это и возвращает описательную строку ошибки (видимую там, где Pebble показывает результаты инструмента) вместо падения, называя именно то, что не удалось распарсить.

Событие попало не в то время (например, в 2 часа ночи). Почти наверняка это путаница между наивным временем и UTC. Обработка наивного времени в create_event всегда предполагает SKYLIGHT_TIMEZONE, никогда не UTC — если вы видите такое, проверьте, не отправил ли Pebble по ошибке голое UTC-время (посмотрите в логах сырой аргумент start).

Проверка работы проверки bearer-токена

# No token -> 401
curl -i https://<your-railway-domain>/healthz    # should be 200, no auth needed
curl -i https://<your-railway-domain>/mcp         # should be 401

# With token -> reaches the MCP layer
curl -i https://<your-railway-domain>/mcp \
  -H "Authorization: Bearer <your MCP_BEARER_TOKEN>" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2026-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"0"}}}'

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

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

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Transforms macOS calendar management into a conversational experience using natural language, allowing users to create, manage, and update calendar events seamlessly through an MCP-compatible client.
    327
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to manage Google Calendar through natural language interactions with features like creating, updating, and deleting events, searching calendars, and supporting natural language date/time inputs.
    27
    2
    MIT
  • F
    license
    Not graded
    quality
    F
    maintenance
    Enables programmatic management of Google Calendar events through natural language interactions, supporting creation, reading, updating, and deletion of events with features for recurring events, attendees, and reminders.
    2

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/SarjuThakkar/skylight-mcp-pebble'

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