Skip to main content
Glama

ntfy-cf

ntfy-cf — это приватное подмножество API ntfy, реализованное нативно для Workers. Развёрнутый Worker называется ntfy-kyeshimizu.

Архитектура

Публичный NtfyWorker проверяет темы, маршруты, размеры запросов и токен Authorization: Bearer .... Каждая тема сопоставляется с одним SQLite Durable Object (Topic) через getByName(topic). Объект хранит не более 100 сообщений в течение не более 7 дней, обслуживает запросы на опрос и рассылает новые сообщения спящим WebSocket-соединениям.

HTTP API требует bearer-токен для публикации, опроса и подписки через WebSocket. Сервисная привязка Worker вызывает типизированный RPC publish() на NtfyWorker; этот приватный путь не требует HTTP-токена.

Агенты могут использовать тот же сервис через аутентифицированную конечную точку Streamable HTTP MCP по адресу /mcp. Она предоставляет методы publish_notification и get_notifications.

Темы должны соответствовать [A-Za-z0-9._-]+ и быть не длиннее 128 символов. Тела HTTP-запросов и RPC-уведомления ограничены 64 KiB. Публикуемые сообщения используют JSON-объекты в стиле ntfy с полями event, id, time, topic, message и необязательными метаданными, такими как title, tags, priority, click, actions, attach, filename, email, call и icon.

Related MCP server: mcp-gotify

Локальная разработка

Создайте локальный файл .dev.vars (он игнорируется Wrangler):

PUBLISH_TOKEN=replace-with-a-local-random-token

Запустите Worker:

npm install
npm run types
npx wrangler dev

Используйте то же значение из .dev.vars в примерах ниже. Не включайте .dev.vars в коммиты и не помещайте токен в исходный код, историю команд или документацию.

HTTP API

Задайте переменную оболочки, указав токен, который вы создали локально или сохранили в менеджере секретов:

export NTFY_TOKEN='replace-with-the-token-from-your-local-environment'
export NTFY_URL='http://localhost:8787'

Опубликуйте обычный текст с совместимыми с ntfy заголовками:

curl -sS -X POST "$NTFY_URL/alerts" \
  -H "Authorization: Bearer $NTFY_TOKEN" \
  -H 'Title: Build finished' \
  -H 'Tags: white_check_mark,ci' \
  -H 'Priority: 4' \
  --data-raw 'release 42 is ready'

Опубликуйте JSON-метаданные:

curl -sS -X POST "$NTFY_URL/alerts" \
  -H "Authorization: Bearer $NTFY_TOKEN" \
  -H 'Content-Type: application/json' \
  --data '{"message":"Deploy finished","title":"Production","priority":3,"tags":["deploy"]}'

Получите ограниченную историю темы в виде JSON, разделённого переводами строк. since=all (или отсутствие since) возвращает сохранённую историю; метка времени Unix возвращает более поздние сообщения; существующий идентификатор сообщения возвращает сообщения после этого идентификатора.

curl -sS "$NTFY_URL/alerts/json?poll=1&since=all" \
  -H "Authorization: Bearer $NTFY_TOKEN"

Проверьте готовность:

curl -i "$NTFY_URL/healthz"

Конечная точка WebSocket — /<topic>/ws. Рукопожатие через curl полезно для смоук-проверки, но curl не является WebSocket-клиентом и не будет удобно обрабатывать последующие кадры:

curl --http1.1 -i -N "$NTFY_URL/alerts/ws" \
  -H "Authorization: Bearer $NTFY_TOKEN" \
  -H 'Connection: Upgrade' \
  -H 'Upgrade: websocket' \
  -H 'Sec-WebSocket-Version: 13' \
  -H 'Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==' \
  --max-time 5

Для живой подписки используйте WebSocket-клиент, например websocat, и адрес ws://localhost:8787/alerts/ws с заголовком Authorization. Первый кадр — событие open; последующие публикации приходят как события message.

Bearer-токен

Токен — это единый секрет Worker, а не учётные данные пользователя/аккаунта ntfy. Настройте его после аутентификации Wrangler:

npx wrangler secret put PUBLISH_TOKEN --name ntfy-kyeshimizu

Вставляйте токен только по запросу Wrangler. Команда не должна попадать в журналы CI или в коммитимые файлы. Запросы без точно совпадающего настроенного bearer-токена получают 401 Unauthorized.

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

Сохранённая в репозитории конфигурация Wrangler уже называет сервис ntfy-kyeshimizu, включает Workers Observability и объявляет миграцию SQLite Durable Object Topic. Разверните с помощью:

npx wrangler deploy
npx wrangler secret put PUBLISH_TOKEN --name ntfy-kyeshimizu

Используйте развёрнутый HTTPS-URL как NTFY_URL и wss:// вместо ws:// для смоук-проверки WebSocket. Никогда не выводите и не коммитьте секрет.

Сервисные привязки и типизированный RPC

В wrangler.jsonc потребляющего Worker-а привяжите именованную точку входа RPC:

{
  "services": [
    {
      "binding": "NTFY",
      "service": "ntfy-kyeshimizu",
      "entrypoint": "NtfyWorker"
    }
  ]
}

Сгенерируйте типы привязок потребляющего Worker-а с помощью Wrangler, включив конфигурацию Worker-а-издателя и конфигурацию этого Worker-а, если это отдельные проекты:

npx wrangler types -c wrangler.jsonc

Сгенерированный Env.NTFY типизируется на основе экспортируемой точки входа NtfyWorker. Вызывайте его без HTTP-учётных данных:

const notification = await env.NTFY.publish("alerts", {
  message: "Published from another Worker",
  title: "Internal job",
  tags: ["worker"],
  priority: 3,
});

Полную точку входа издателя см. в examples/worker-publisher.ts. Сервисные привязки — это приватные вызовы между Worker-ами; не передавайте объект привязки в данные непроверенных запросов.

Плагин OpenCode, MCP и навык агента

Репозиторий включает локальный для проекта плагин OpenCode, конфигурацию MCP и навык:

  • .opencode/plugins/ntfy-cf.js автоматически отправляет уведомления о жизненном цикле.

  • opencode.jsonc подключается к развёрнутой конечной точке /mcp.

  • .opencode/skills/ntfy-cf/SKILL.md обучает агентов, когда и как уведомлять.

Задайте токен перед запуском OpenCode из этого репозитория:

export NTFY_CF_TOKEN='replace-with-your-worker-secret'
export NTFY_CF_TOPIC='agent-status'
opencode2

OpenCode автоматически обнаруживает плагин, навык ntfy-cf и MCP-сервер ntfy. Плагин отправляет уведомления, когда корневая сессия завершается, сталкивается с ошибкой или запрашивает разрешение. События завершения дочерних сессий и ошибок подавляются. Задайте NTFY_CF_URL, чтобы переопределить URL развёрнутого Worker-а. Сбои доставки логируются и никогда не прерывают сессию OpenCode. Плагин рассчитан на V2 API событий OpenCode; предварительные сборки, которые ещё не предоставляют ctx.event.subscribe(), загружают плагин, но отключают автоматические события.

MCP использует аутентификацию через заголовок, а не OAuth, и поддерживает запросы JSON-RPC без состояния по Streamable HTTP. Не коммитьте токен в конфигурацию OpenCode.

Другие MCP-клиенты могут подключаться к:

https://ntfy-kyeshimizu.kyeshimizu.workers.dev/mcp

Отправляйте Authorization: Bearer <token> в каждом запросе. Конечная точка реализует MCP-методы initialize, ping, tools/list и tools/call; у неё нет зависимости от MCP-фреймворка времени выполнения, и она не включает Zod.

Проверка и эксплуатация

Запустите локальный автоматический набор смоук-тестов и проверку типов:

npm test
npm run typecheck

Для смоук-теста развёрнутого сервиса проверьте /healthz, опубликуйте сообщение в одноразовую тему, получите её историю с since=all и выполните рукопожатие WebSocket. Убедитесь, что запрос с отсутствующим или неверным bearer-токеном возвращает 401, а недопустимый маршрут — 404.

Workers Observability включена в wrangler.jsonc с полным head-сэмплированием. Используйте панель управления Cloudflare или журналы Wrangler для просмотра структурированных событий, таких как publish и websocket_error. История Durable Object ограничена и не заменяет журнал аудита или архивное хранилище.

Ограничения совместимости

Это не готовая замена вышестоящему Go-серверу. v1 не реализует:

  • Веб-приложение вышестоящего сервера, учётные записи пользователей, списки контроля доступа или управление темами.

  • Android FCM, пересылку iOS/APNs, UnifiedPush или другие способы мобильной доставки.

  • SSE, бесконечную потоковую передачу по HTTP или подписки через long-polling.

  • Вложения/загрузку файлов, хранение вложений, доставку электронной почты, голосовые вызовы или интеграцию с R2.

  • Запланированную или отложенную доставку. Поле delay отклоняется.

  • Функции вышестоящего сервера, не перечисленные в этом README, включая полные API аутентификации и администрирования.

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

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    A Model Context Protocol server enabling AI systems to send real-time notifications to phones, desktops, and other devices through the ntfy publish/subscribe service.
    379 npm
    23
    Apache 2.0
  • A
    license
    B
    quality
    D
    maintenance
    MCP server for sending Gotify push notifications to your devices.
    1
    MIT
  • A
    license
    C
    quality
    D
    maintenance
    MCP server for sending notifications to ntfy.sh or self-hosted ntfy instances.
    2
    11 npm
    MIT