ntfy-cf
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_notification 和 get_notifications。
主题必须匹配 [A-Za-z0-9._-]+ 且长度不超过 128 个字符。HTTP 请求体和 RPC 通知限制为 64 KiB。发布的消息使用 ntfy 风格的 JSON 对象,包含 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,也不要把令牌放在源代码、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'
opencode2OpenCode 会自动发现插件、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 的 initialize、ping、tools/list 和 tools/call;它没有运行时 MCP 框架依赖,也不捆绑 Zod。
验证与运维
运行本地自动化冒烟测试套件和类型检查:
npm test
npm run typecheck对于已部署的冒烟测试,请验证 /healthz,向一次性主题发布消息,使用 since=all 轮询,并执行 WebSocket 握手。确认缺少或错误的 bearer 令牌的请求返回 401,无效路由返回 404。
wrangler.jsonc 中启用了 Workers Observability,并采用全量头部采样。使用 Cloudflare 仪表板或 Wrangler 日志检查结构化事件,如 publish 和 websocket_error。Durable Object 历史是有界的,不能替代审计日志或归档存储。
兼容性限制
这不是上游 Go 服务器的直接替代品。v1 未实现:
上游 Web 应用、用户账户、访问控制列表或主题管理。
Android FCM、iOS/APNs 转发、UnifiedPush 或其他移动端投递。
SSE、无限 HTTP 流式传输或长轮询订阅。
附件/上传、附件存储、邮件投递、语音通话或 R2 集成。
定时或延迟投递。
delay字段会被拒绝。本 README 未列出的上游服务器功能,包括完整的认证和管理 API。
该服务仅提供进程内通知历史和实时 WebSocket 投递。元数据字段包含在通知对象中;它们不会激活外部投递提供商。
This server cannot be deployed
Maintenance
Related MCP Connectors
Publish, search, and promote time-sensitive news and messages through a public remote MCP server.
Discover MCP servers and A2A agents; verify, message, post, follow, react, and receive webhooks.
Push notifications with personalized sounds - manage and trigger your vybits via MCP
Push notifications for AI agents - send instant iPhone notifications from any MCP client.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceA Model Context Protocol server enabling AI systems to send real-time notifications to phones, desktops, and other devices through the ntfy publish/subscribe service.610 npm25Apache 2.0
- AlicenseBqualityDmaintenanceMCP server for sending Gotify push notifications to your devices.1MIT
- AlicenseCqualityDmaintenanceMCP server for sending notifications to ntfy.sh or self-hosted ntfy instances.216 npmMIT
- AlicenseAqualityDmaintenanceMCP server for ntfy push notifications. Send and poll notifications from any MCP-compatible client.35 npmMIT