Skip to main content
Glama

ntfy-cf

ntfy-cf 是 ntfy API 的一个私有、基于 Workers 原生的子集。已部署的 Worker 名为 ntfy-kyeshimizu

架构

公共的 NtfyWorker 负责校验主题、路由、请求大小以及 Authorization: Bearer ... 令牌。每个主题通过 getByName(topic) 映射到一个 SQLite Durable Object(Topic)。该对象最多存储 100 条消息、保留最长 7 天,处理轮询请求,并向休眠中的 WebSocket 广播新消息。

HTTP API 在发布、轮询和 WebSocket 订阅时都需要 bearer 令牌。Worker 服务绑定通过 NtfyWorker 调用类型化的 publish() RPC;该私有路径不需要 HTTP 令牌。

代理可以通过位于 /mcp 的、经过认证的 Streamable HTTP MCP 端点使用同一服务。它暴露了 publish_notificationget_notifications

主题必须匹配 [A-Za-z0-9._-]+ 且长度不超过 128 个字符。HTTP 请求体和 RPC 通知限制为 64 KiB。发布的消息使用 ntfy 风格的 JSON 对象,包含 eventidtimetopicmessage 以及可选元数据,如 titletagspriorityclickactionsattachfilenameemailcallicon

Related MCP server: ntfy-me-mcp

本地开发

创建一个仅限本地的 .dev.vars 文件(Wrangler 会忽略它):

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

启动 Worker:

npm install
npm run types
npx wrangler dev

在下面的示例中使用与 .dev.vars 相同的值。不要提交 .dev.vars,也不要把令牌放在源代码、shell 历史或文档中。

HTTP API

将 shell 变量设置为你在本地创建或存储在密钥管理器中的令牌:

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 时间戳返回之后的消息;已有的消息 ID 返回该 ID 之后的消息。

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

如需实时订阅,请使用 websocat 等 WebSocket 客户端,并使用带 Authorization 请求头的 ws://localhost:8787/alerts/ws。第一帧是 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,并声明了 Topic SQLite Durable Object 迁移。使用以下命令部署:

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

使用已部署的 HTTPS URL 作为 NTFY_URL,并在 WebSocket 冒烟检查中使用 wss:// 而不是 ws://。切勿打印或提交该密钥。

服务绑定与类型化 RPC

在消费方 Worker 的 wrangler.jsonc 中,绑定命名 RPC 入口点:

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

使用 Wrangler 生成消费方 Worker 的绑定类型,当发布方 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 技能和 ntfy MCP 服务器。当根会话结束、遇到错误或请求权限时,插件会发送通知。子会话的完成和错误事件会被抑制。设置 NTFY_CF_URL 可覆盖已部署的 Worker URL。投递失败会被记录日志,且绝不会中断 OpenCode 会话。该插件针对 OpenCode 的 V2 事件 API;尚未暴露 ctx.event.subscribe() 的预览版构建会加载插件,但会禁用自动事件。

MCP 使用请求头认证而非 OAuth,并支持无状态的 Streamable HTTP JSON-RPC 请求。不要将令牌提交到 OpenCode 配置中。

其他 MCP 客户端可以连接到:

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

在每个请求上发送 Authorization: Bearer <token>。该端点实现了 MCP 的 initializepingtools/listtools/call;它没有运行时 MCP 框架依赖,也不捆绑 Zod。

验证与运维

运行本地自动化冒烟测试套件和类型检查:

npm test
npm run typecheck

对于已部署的冒烟测试,请验证 /healthz,向一次性主题发布消息,使用 since=all 轮询,并执行 WebSocket 握手。确认缺少或错误的 bearer 令牌的请求返回 401,无效路由返回 404

wrangler.jsonc 中启用了 Workers Observability,并采用全量头部采样。使用 Cloudflare 仪表板或 Wrangler 日志检查结构化事件,如 publishwebsocket_error。Durable Object 历史是有界的,不能替代审计日志或归档存储。

兼容性限制

这不是上游 Go 服务器的直接替代品。v1 未实现:

  • 上游 Web 应用、用户账户、访问控制列表或主题管理。

  • Android FCM、iOS/APNs 转发、UnifiedPush 或其他移动端投递。

  • SSE、无限 HTTP 流式传输或长轮询订阅。

  • 附件/上传、附件存储、邮件投递、语音通话或 R2 集成。

  • 定时或延迟投递。delay 字段会被拒绝。

  • 本 README 未列出的上游服务器功能,包括完整的认证和管理 API。

该服务仅提供进程内通知历史和实时 WebSocket 投递。元数据字段包含在通知对象中;它们不会激活外部投递提供商。

Maintenance

ActivityMaintained
ResponsivenessSyncing

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
    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.
    1,025
    20
    Apache 2.0
  • A
    license
    A
    quality
    C
    maintenance
    A streamlined MCP server that enables AI assistants to send real-time notifications to your devices through the ntfy service, allowing you to receive alerts when tasks complete or important events occur.
    2
    151
    72
    GPL 3.0
  • A
    license
    B
    quality
    D
    maintenance
    MCP server for sending Gotify push notifications to your devices.
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    MCP server for sending notifications to ntfy.sh or self-hosted ntfy instances.
    19
    MIT

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/kyeshmz/ntfy-cf'

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