关于 Ntfy MCP Server
Ntfy MCP Server 将 ntfy 推送通知管理能力提供给 MCP 客户端,可发送、更新、清除和回看主题消息,并支持 STDIO 与 Streamable HTTP 传输。
主要功能
- 01发布或更新通知
- 02清除或删除已发送通知
- 03获取经过筛选的主题历史
- 04查询表情符号标签代码
- 05支持 STDIO 和 Streamable HTTP
适用场景
- 01在 AI 工作流中发送 ntfy 提醒
- 02查看提醒主题的近期消息
- 03关闭或移除已发送通知
MCP 相关
该服务向 MCP 客户端提供 4 个工具和 `ntfy://{topic}` 资源,并支持 STDIO 与 Streamable HTTP 传输。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y ntfy-mcp-serverNTFY_SERVERSJSON array of `{ baseUrl, authToken? | authUsername?+authPassword? }` entries — one per ntfy server. First entry is the default base. Auth is scoped to the entry's `baseUrl`; per-call `base_url` overrides that match a registered base forward that server's auth. Takes precedence over the single-server NTFY_BASE_URL / NTFY_AUTH_* shorthand.NTFY_BASE_URLSingle-server shorthand — base URL of the ntfy server (no trailing slash). Used when NTFY_SERVERS is unset.NTFY_DEFAULT_TOPICTopic used when a tool call omits `topic`. Treat the topic name as a secret — anyone who knows it can publish or subscribe.NTFY_AUTH_TOKEN密钥Bearer access token (`tk_…`) for the single-server shorthand. Mutually exclusive with NTFY_AUTH_USERNAME / NTFY_AUTH_PASSWORD.NTFY_AUTH_USERNAME密钥Basic-auth username for the single-server shorthand — must be set together with NTFY_AUTH_PASSWORD.NTFY_AUTH_PASSWORD密钥Basic-auth password for the single-server shorthand — must be set together with NTFY_AUTH_USERNAME.NTFY_REQUEST_TIMEOUT_MSPer-attempt HTTP timeout in milliseconds, covering the response body. Each call is also capped at 50 s across all attempts.NTFY_MAX_RETRIESMax retry attempts for transient upstream failures (5xx, network, 429).NTFY_BLOCK_PRIVATE_HOSTSWhen true, a per-call `base_url` override must resolve to a public address and its redirects are not followed. Servers registered under NTFY_SERVERS / NTFY_BASE_URL are exempt. Turn it on where callers you do not control can reach the server.NTFY_ENABLE_EMOJI_TAGSSet to false to disable the ntfy_search_emoji_tags tool: it leaves tools/list, and the server instructions and ntfy_publish_message stop pointing at it.MCP_LOG_LEVELSets the minimum log level for output (e.g., 'debug', 'info', 'warn').LOGS_DIRDirectory for file-based logs (Node only; ignored on Workers).OTEL_ENABLEDEnable OpenTelemetry instrumentation (spans, metrics, completion logs).MCP_TRANSPORT_TYPESelects the HTTP transport.MCP_SESSION_MODEHTTP session model: 'auto', 'stateful', or 'stateless'. This server requires 'stateful' over HTTP — the consent prompt on destructive and outbound calls is a multi-round-trip request that a 2025-era HTTP client can only complete over a live session — so an HTTP start with 'stateless' is refused. 'auto' resolves to 'stateful'; stdio ignores the setting.MCP_HTTP_HOSTThe hostname for the HTTP server.MCP_HTTP_PORTThe port to run the HTTP server on.MCP_HTTP_ENDPOINT_PATHThe endpoint path for the MCP server.MCP_AUTH_MODE密钥Authentication mode to use: 'none', 'jwt', or 'oauth'.MCP_REQUEST_STATE_KEY密钥Recommended for HTTP. Key (>= 32 bytes, the same on every instance) that seals the requestState carrying the consent-record id of a confirmation prompt, bound to the caller for 900 s; a forged, tampered, or expired state is rejected before the handler runs.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
4收录的工具列表 · 更新于 3 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| call | string | 否 | 触发语音呼叫——使用 `+CCNNNNNNNNNN`,或使用 `'yes'` 呼叫已通过身份验证的用户的第一个已验证号码。需要已通过身份验证的 ntfy 账户;ntfy.sh 仅向 Pro 套餐开放此功能。 |
| icon | string | 否 | 显示在消息正文旁的绝对 JPEG/PNG 图标 URL。缓存 24 小时。 |
| tags | array | 否 | 最多 10 个标签。与 ntfy 表情符号短代码匹配的字符串会作为表情符号添加到标题前;其他字符串会显示为标签列表。使用 `ntfy_search_emoji_tags` 查找短代码。 |
| cache | boolean | 否 | 设为 false 可跳过服务端缓存。在线订阅者仍会收到消息,但 `ntfy_fetch_messages` 无法获取该消息。发送时使用 `X-Cache: no`。 |
| click | string | 否 | 点击通知时打开的 URL——例如 http(s)、mailto:、geo:、ntfy:// 等。 |
| delay | string | 否 | 安排稍后发送。支持时长(`30m`、`2h`、`1d`)、Unix 时间戳或自然语言时间(`tomorrow, 10am`、`Tuesday, 7am`)。服务端强制限制为至少 10 秒、最多 3 天。 |
| string | 否 | 转发到电子邮箱——可指定地址(`[email protected]`),或使用 `'yes'` 将邮件发送到已通过身份验证的用户的第一个已验证地址。 | |
| title | string | 否 | 通知标题。默认使用接收设备上的主题 URL。 |
| topic | string | 否 | 目标主题。除非已配置 `NTFY_DEFAULT_TOPIC`,否则必填。请将主题名称视为机密——任何知道名称的人都可以发布或订阅。 |
| attach | string | 否 | 外部附件 URL(绝对 URL)。ntfy 会在接收者设备上获取该文件——请先将文件托管在可访问的位置;不支持上传本地文件。 |
| actions | array | 否 | 最多 3 个操作按钮。由 `action`(`view`、`broadcast`、`http`、`copy`)区分类型。 |
| message | string | 否 | 通知正文,最多 4096 字节(不是字符——带重音字母、CJK 字符和表情符号各占 2–4 字节)。若为空或缺失,服务端会替换为字面值 `triggered`;即使是 ping 式提醒,也请传入实际内容。 |
| base_url | string | 否 | 仅对此次调用覆盖已配置的 `NTFY_BASE_URL`——必须是绝对 `http(s)://` URL。若覆盖值与已配置的基础 URL 不同,则不会转发服务端配置的身份验证凭据。 |
| filename | string | 否 | 覆盖客户端中显示的附件文件名。 |
| firebase | boolean | 否 | 设为 false 可跳过 Firebase Cloud Messaging。除非接收者启用了即时送达,否则 Android 通知最多会延迟 15 分钟。发送时使用 `X-Firebase: no`。 |
| markdown | boolean | 否 | 将消息正文渲染为 Markdown(仅限 Web 应用;移动端会渲染为纯文本)。 |
| priority | integer | 否 | 通知优先级——1=最低,2=低,3=默认,4=高,5=最高/紧急。未指定时,服务器默认为 3。 |
| sequence_id | string | 否 | 更新或替换先前发布的消息,而不是创建新消息。与 `ntfy_manage_message` 使用相同的标识符。1–64 个字符,`[a-zA-Z0-9_-]`。 |
详细介绍
ntfy-mcp-server
通过 MCP 发送、管理和重放 ntfy 推送通知。支持 STDIO 或 Streamable HTTP。
概述
通过 ntfy 向手机或桌面发送推送通知。发布、更新和管理通知,轮询主题的近期历史记录,并查询标签使用的表情符号简码。
工具
| 工具 | 描述 |
|---|---|
ntfy_publish_message | 在 ntfy 主题上发送或更新推送通知。 |
ntfy_manage_message | 根据 sequence_id 清除或删除先前发送的通知。 |
ntfy_fetch_messages | 使用可选筛选条件轮询一个或多个主题的缓存消息。 |
ntfy_search_emoji_tags | 查询 ntfy 表情符号标签简码,以便用于 tags。 |
资源
| 资源 | 描述 |
|---|---|
ntfy://{topic} | 主题快照——过去一小时内的最新 20 条消息,以及该主题的浏览器 URL。 |
当资源固定的默认设置无法满足需求时,ntfy_fetch_messages 可通过自定义时间范围和筛选条件获取相同主题数据。
功能参考
ntfy_publish_message 工具
- 首次发布时会创建主题——请将主题名称视为机密;任何知道名称的人都可以发布或订阅
- 支持
title、priority(1–5)、tags、click、attach、icon、filename、markdown、delay、email、call、cache、firebase,以及最多三个操作按钮(view、broadcast、http、copy);消息正文上限为 4096 字节,正文为空时默认为triggered;传入原始sequence_id可更新已发送的消息 - 使用
email、call或broadcast/http按钮发布时,会要求用户在发送前确认目标 - 单次调用传入的
base_url仅在匹配已注册的服务(NTFY_BASE_URL或NTFY_SERVERS条目)时才会使用凭据;否则请求不进行身份验证
ntfy_manage_message 工具
operation:clear会将通知标记为已读并将其关闭(订阅者会收到message_clear);delete会将其从通知抽屉中移除(订阅者会收到message_delete)- 每次调用都会先要求用户确认主题、
sequence_id和操作;如果用户拒绝,则会以consent_declined失败 - 原始消息会保留在缓存中,重复执行操作是安全的;ntfy.sh 接受未知的
sequence_id,更严格的部署则会返回not_found
ntfy_fetch_messages 工具
- 返回快照,而非实时流;接受逗号分隔的主题(例如
alerts,backups),并支持since(时长/时间戳/消息 ID/all/latest)、priority、tags、id、title、message和仅限计划消息等筛选条件 - 默认时间窗口为
10m,默认限制为 20 条,每次调用最多 100 条;较大的时间窗口会返回最新的limit条消息,并提供totalCount和nextCursor,可将其作为cursor传回 - 消息正文会在约 500 个字符处截断(
messageTruncated会给出省略的字符数);如需获取完整文本,请使用id重新获取 - 如果 ntfy 截断了重放内容,则会设置
upstreamTruncated;如果服务器未返回 ntfy 消息流,则会以upstream_malformed失败
ntfy_search_emoji_tags 工具
- 对标签名称进行不区分大小写的子串匹配;省略
query可按顺序列出参考列表 limit默认为 25,每次调用最多 200 条;使用offset翻页,并参考totalCount- 返回的
tag字符串可直接传入ntfy_publish_message的tags - 默认启用;设置
NTFY_ENABLE_EMOJI_TAGS=false可将其从tools/list中移除
ntfy://{topic} 资源
- 固定快照:过去一小时内的最新 20 条消息,以及该主题的浏览器 URL;格式与
ntfy_fetch_messages相同(包括upstreamTruncated) - 如需自定义时间窗口或筛选条件,请使用
ntfy_fetch_messages
功能
基于 @cyanheads/mcp-ts-core 构建:支持 stdio 和 Streamable HTTP 传输、可插拔身份验证(none/jwt/oauth)、可切换存储(in-memory、filesystem、Supabase、Cloudflare KV/R2/D1),以及支持可选 OpenTelemetry 跟踪的结构化日志记录。
ntfy 特有功能:
- 支持重试的 ntfy 客户端,提供单次尝试超时;每次调用最长为 50 s,可在 MCP 客户端默认的 60 s 超时前完成
- 按服务器进行身份验证:凭据绑定到每个已注册的基础 URL(
NTFY_BASE_URL或NTFY_SERVERS条目);bearer-token 和 basic-auth 模式互斥 - 在 stdio 和 Streamable HTTP 上,执行清除/删除操作,或通过
email、call或broadcast/http按钮发布消息之前,都会要求用户确认 - 可选的 SSRF 防护,用于检查
base_url覆盖项(NTFY_BLOCK_PRIVATE_HOSTS);已注册服务器不受此限制 - 内置 emoji 标签参考列表,通过
scripts/build-emoji-tags.ts从上游docs/ntfy/emojis.md重新生成
适用于 Agent 的输出:
- 发布和管理操作会回显解析后的主题、ID 和时间戳;获取操作也会回显解析后的
since和已应用的筛选条件 - 类型化的
reason代码(consent_declined、forbidden_topic、rate_limited、not_found、payload_too_large等)让调用方可以根据失败类型进行分支处理 - 获取和 emoji 搜索会报告
truncated、totalCount,并通过notice说明下一步操作(将nextCursor作为cursor传入,或递增offset)
开始使用
将以下内容添加到 MCP 客户端配置文件中。无需账户即可直接使用公共 ntfy.sh;对于受保护的主题,请前往 https://ntfy.sh/account 生成访问令牌。
{
"mcpServers": {
"ntfy-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["ntfy-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info",
"NTFY_DEFAULT_TOPIC": "your-topic-name"
}
}
}
}
也可以使用 npx(无需 Bun):
{
"mcpServers": {
"ntfy-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "ntfy-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info",
"NTFY_DEFAULT_TOPIC": "your-topic-name"
}
}
}
}
也可以使用 Docker:
{
"mcpServers": {
"ntfy-mcp-server": {
"type": "stdio",
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT_TYPE=stdio",
"-e", "NTFY_DEFAULT_TOPIC=your-topic-name",
"ghcr.io/cyanheads/ntfy-mcp-server:latest"
]
}
}
}
对于 Streamable HTTP,请设置传输方式并启动服务:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 NTFY_DEFAULT_TOPIC=your-topic bun run start:http
# Server listens at http://127.0.0.1:3010/mcp
先决条件
- Bun v1.4.0 或更高版本(或 Node.js v24+)。
- ntfy 服务器上的主题名称。公共
ntfy.sh无需账户;自托管实例和受保护的主题可能需要 bearer token 或 basic-auth 凭据。
安装
- 克隆仓库:
git clone https://github.com/cyanheads/ntfy-mcp-server.git
- 进入目录:
cd ntfy-mcp-server
- 安装依赖:
bun install
- 配置环境:
cp .env.example .env
# edit .env and set NTFY_DEFAULT_TOPIC (and auth, if needed)
配置
| 变量 | 描述 | 默认值 |
|---|---|---|
NTFY_SERVERS | { baseUrl, authToken? | authUsername?+authPassword? } 条目的 JSON 数组,每个条目对应一个 ntfy 服务;第一个条目为默认服务。优先级高于下面的单服务变量。 | — |
NTFY_BASE_URL | 单服务简写配置——ntfy 服务的基础 URL(末尾不带斜杠)。当未设置 NTFY_SERVERS 时使用。 | https://ntfy.sh |
NTFY_DEFAULT_TOPIC | 工具调用未提供 topic 时使用的主题。 | — |
NTFY_AUTH_TOKEN | 单服务简写配置的 Bearer 访问令牌(tk_…)。不能与 NTFY_AUTH_USERNAME / NTFY_AUTH_PASSWORD 同时使用。 | — |
NTFY_AUTH_USERNAME | 单服务简写配置的基本身份验证用户名——必须与 NTFY_AUTH_PASSWORD 一起设置。 | — |
NTFY_AUTH_PASSWORD | 单服务简写配置的基本身份验证密码——必须与 NTFY_AUTH_USERNAME 一起设置。 | — |
NTFY_REQUEST_TIMEOUT_MS | 每次尝试的 HTTP 超时时间,单位为毫秒。每次调用在所有尝试中的总耗时也限制为 50 s。 | 15000 |
NTFY_MAX_RETRIES | 针对上游临时故障(5xx、网络错误、429)的最大重试次数。 | 3 |
NTFY_BLOCK_PRIVATE_HOSTS | 当值为 true 时,每次调用的 base_url 覆盖值必须解析为公共地址,并且不会跟随重定向。已注册的服务不受此限制。如果不受你控制的调用方可以访问此服务,请启用此选项。 | false |
NTFY_ENABLE_EMOJI_TAGS | 设置为 false 可禁用 ntfy_search_emoji_tags。无法识别的值会导致启动失败。 | true |
MCP_TRANSPORT_TYPE | 传输方式:stdio 或 http。 | stdio |
MCP_SESSION_MODE | HTTP 会话模式:auto、stateful 或 stateless。通过 HTTP 时,此服务要求使用 stateful(auto 会解析为该模式);启动时会拒绝 stateless。在 stdio 模式下忽略此项。 | stateful |
MCP_HTTP_HOST | HTTP 主机。 | 127.0.0.1 |
MCP_HTTP_PORT | HTTP 端口。 | 3010 |
MCP_HTTP_ENDPOINT_PATH | HTTP 端点路径。 | /mcp |
MCP_AUTH_MODE | 身份验证模式:none、jwt 或 oauth。 | none |
MCP_REQUEST_STATE_KEY | HTTP 模式下建议设置。用于对 consent requestState 进行封装、有效期为 900 s 的密钥(≥ 32 字节,例如 openssl rand -base64 32;每个实例必须使用相同的密钥)。无效或过期的状态会被拒绝,并返回 -32602 invalid_request_state。 | — |
STORAGE_PROVIDER_TYPE | consent 记录的存储位置(TTL 为 600 s)。多实例 HTTP 部署需要使用共享存储:filesystem(共享卷)、supabase 或 cloudflare-d1,不能使用 cloudflare-kv。 | in-memory |
MCP_LOG_LEVEL | 日志级别(RFC 5424)。 | info |
LOGS_DIR | 基于文件的日志目录(仅适用于 Node;在 Workers 上忽略)。 | ./logs |
LOG_TOOL_FAILURE_PAYLOADS | 记录每次失败的工具调用参数和结果,按键名进行脱敏,并限制在 LOG_TOOL_FAILURE_PAYLOAD_MAX_BYTES(默认值为 16384)以内。自由格式值中的密钥不会被脱敏。 | false |
OTEL_ENABLED | 启用 OpenTelemetry 插桩(跟踪跨度、指标、完成日志)。 | false |
完整的可选覆盖项列表请参阅 .env.example。
运行服务
本地开发
-
构建并运行:
# One-time build bun run rebuild # Run the built server bun run start:stdio # or bun run start:http -
运行检查和测试:
bun run devcheck # Lint, format, typecheck, security, changelog sync bun run test # Vitest test suite bun run lint:mcp # Validate MCP definitions against spec
Docker
docker build -t ntfy-mcp-server .
docker run --rm -e NTFY_DEFAULT_TOPIC=your-topic -p 3010:3010 ntfy-mcp-server
Dockerfile 默认使用 HTTP 传输、有状态会话模式,并将日志写入 /var/log/ntfy-mcp-server。默认会安装 OpenTelemetry 对等依赖项——构建时添加 --build-arg OTEL_ENABLED=false 可省略这些依赖项。
项目结构
| 目录 | 用途 |
|---|---|
src/index.ts | createApp() 入口 — 注册工具和资源,初始化服务。 |
src/config | 使用 Zod 解析服务专属环境变量(NTFY_*)。 |
src/mcp-server/tools | 工具定义(*.tool.ts)。 |
src/mcp-server/resources | 资源定义(*.resource.ts)。 |
src/services/ntfy | ntfy HTTP 客户端、类型和错误分类器。 |
src/services/emoji-tags | 内置的表情符号短代码参考和查询服务。 |
docs/ntfy | 镜像的上游 ntfy API 文档(固定提交见 SOURCES.md)。 |
tests/ | 与 src/ 结构对应的单元测试和集成测试。 |
开发指南
开发指南和架构规则请参阅 CLAUDE.md。简要说明:
- 处理程序抛出错误,框架捕获错误 — 工具逻辑中不要使用
try/catch - 使用
ctx.log记录请求范围内的日志,使用ctx.state存储租户范围内的数据 - 封装外部 API 调用:校验原始数据 → 规范化为领域类型 → 返回输出模式;绝不伪造缺失字段
- 每个工具的
errors[]契约保持内联 — 有意重复以便就近查看
贡献
欢迎提交问题。提交前请运行检查和测试:
bun run devcheck
bun run test
许可证
Apache-2.0 — 详情请参阅 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。