ntfy-mcp-server 1.0.4 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +409 -0
- package/Dockerfile +98 -0
- package/README.md +167 -393
- package/changelog/1.0.x/1.0.0.md +13 -0
- package/changelog/1.0.x/1.0.1.md +11 -0
- package/changelog/1.0.x/1.0.2.md +12 -0
- package/changelog/1.0.x/1.0.3.md +17 -0
- package/changelog/1.0.x/1.0.4.md +12 -0
- package/changelog/1.0.x/1.0.6.md +22 -0
- package/changelog/2.0.x/2.0.0.md +57 -0
- package/changelog/template.md +93 -0
- package/dist/config/server-config.d.ts +41 -0
- package/dist/config/server-config.d.ts.map +1 -0
- package/dist/config/server-config.js +189 -0
- package/dist/config/server-config.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -104
- package/dist/index.js.map +1 -0
- package/dist/mcp-server/resources/definitions/ntfy-topic.resource.d.ts +12 -0
- package/dist/mcp-server/resources/definitions/ntfy-topic.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/ntfy-topic.resource.js +58 -0
- package/dist/mcp-server/resources/definitions/ntfy-topic.resource.js.map +1 -0
- package/dist/mcp-server/tools/definitions/ntfy-fetch-messages.tool.d.ts +101 -0
- package/dist/mcp-server/tools/definitions/ntfy-fetch-messages.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/ntfy-fetch-messages.tool.js +408 -0
- package/dist/mcp-server/tools/definitions/ntfy-fetch-messages.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/ntfy-manage-message.tool.d.ts +44 -0
- package/dist/mcp-server/tools/definitions/ntfy-manage-message.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/ntfy-manage-message.tool.js +133 -0
- package/dist/mcp-server/tools/definitions/ntfy-manage-message.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/ntfy-publish-message.tool.d.ts +125 -0
- package/dist/mcp-server/tools/definitions/ntfy-publish-message.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/ntfy-publish-message.tool.js +411 -0
- package/dist/mcp-server/tools/definitions/ntfy-publish-message.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/ntfy-search-emoji-tags.tool.d.ts +20 -0
- package/dist/mcp-server/tools/definitions/ntfy-search-emoji-tags.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/ntfy-search-emoji-tags.tool.js +69 -0
- package/dist/mcp-server/tools/definitions/ntfy-search-emoji-tags.tool.js.map +1 -0
- package/dist/services/emoji-tags/data.generated.d.ts +8 -0
- package/dist/services/emoji-tags/data.generated.d.ts.map +1 -0
- package/dist/services/emoji-tags/data.generated.js +1821 -0
- package/dist/services/emoji-tags/data.generated.js.map +1 -0
- package/dist/services/emoji-tags/emoji-tag-service.d.ts +28 -0
- package/dist/services/emoji-tags/emoji-tag-service.d.ts.map +1 -0
- package/dist/services/emoji-tags/emoji-tag-service.js +50 -0
- package/dist/services/emoji-tags/emoji-tag-service.js.map +1 -0
- package/dist/services/ntfy/error-classifier.d.ts +31 -0
- package/dist/services/ntfy/error-classifier.d.ts.map +1 -0
- package/dist/services/ntfy/error-classifier.js +65 -0
- package/dist/services/ntfy/error-classifier.js.map +1 -0
- package/dist/services/ntfy/ntfy-service.d.ts +42 -0
- package/dist/services/ntfy/ntfy-service.d.ts.map +1 -0
- package/dist/services/ntfy/ntfy-service.js +213 -0
- package/dist/services/ntfy/ntfy-service.js.map +1 -0
- package/dist/services/ntfy/types.d.ts +108 -138
- package/dist/services/ntfy/types.d.ts.map +1 -0
- package/dist/services/ntfy/types.js +6 -1
- package/dist/services/ntfy/types.js.map +1 -0
- package/package.json +76 -38
- package/server.json +224 -0
- package/dist/config/index.d.ts +0 -23
- package/dist/config/index.js +0 -111
- package/dist/mcp-server/resources/ntfyResource/getNtfyTopic.d.ts +0 -2
- package/dist/mcp-server/resources/ntfyResource/getNtfyTopic.js +0 -133
- package/dist/mcp-server/resources/ntfyResource/index.d.ts +0 -12
- package/dist/mcp-server/resources/ntfyResource/index.js +0 -77
- package/dist/mcp-server/resources/ntfyResource/types.d.ts +0 -59
- package/dist/mcp-server/resources/ntfyResource/types.js +0 -8
- package/dist/mcp-server/server.d.ts +0 -40
- package/dist/mcp-server/server.js +0 -299
- package/dist/mcp-server/tools/ntfyTool/index.d.ts +0 -11
- package/dist/mcp-server/tools/ntfyTool/index.js +0 -124
- package/dist/mcp-server/tools/ntfyTool/ntfyMessage.d.ts +0 -9
- package/dist/mcp-server/tools/ntfyTool/ntfyMessage.js +0 -307
- package/dist/mcp-server/tools/ntfyTool/types.d.ts +0 -252
- package/dist/mcp-server/tools/ntfyTool/types.js +0 -144
- package/dist/mcp-server/utils/registrationHelper.d.ts +0 -48
- package/dist/mcp-server/utils/registrationHelper.js +0 -63
- package/dist/services/ntfy/constants.d.ts +0 -37
- package/dist/services/ntfy/constants.js +0 -37
- package/dist/services/ntfy/errors.d.ts +0 -79
- package/dist/services/ntfy/errors.js +0 -134
- package/dist/services/ntfy/index.d.ts +0 -33
- package/dist/services/ntfy/index.js +0 -56
- package/dist/services/ntfy/publisher.d.ts +0 -66
- package/dist/services/ntfy/publisher.js +0 -229
- package/dist/services/ntfy/subscriber.d.ts +0 -81
- package/dist/services/ntfy/subscriber.js +0 -502
- package/dist/services/ntfy/utils.d.ts +0 -85
- package/dist/services/ntfy/utils.js +0 -410
- package/dist/types-global/errors.d.ts +0 -35
- package/dist/types-global/errors.js +0 -39
- package/dist/types-global/mcp.d.ts +0 -30
- package/dist/types-global/mcp.js +0 -25
- package/dist/types-global/tool.d.ts +0 -44
- package/dist/types-global/tool.js +0 -30
- package/dist/utils/errorHandler.d.ts +0 -98
- package/dist/utils/errorHandler.js +0 -271
- package/dist/utils/idGenerator.d.ts +0 -94
- package/dist/utils/idGenerator.js +0 -149
- package/dist/utils/index.d.ts +0 -13
- package/dist/utils/index.js +0 -16
- package/dist/utils/logger.d.ts +0 -38
- package/dist/utils/logger.js +0 -141
- package/dist/utils/rateLimiter.d.ts +0 -115
- package/dist/utils/rateLimiter.js +0 -180
- package/dist/utils/requestContext.d.ts +0 -68
- package/dist/utils/requestContext.js +0 -91
- package/dist/utils/sanitization.d.ts +0 -224
- package/dist/utils/sanitization.js +0 -367
- package/dist/utils/security.d.ts +0 -26
- package/dist/utils/security.js +0 -27
package/README.md
CHANGED
|
@@ -1,484 +1,258 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
[](https://github.com/cyanheads/ntfy-mcp-server)
|
|
8
|
-
[](https://github.com/cyanheads/ntfy-mcp-server)
|
|
9
|
-
|
|
10
|
-
An MCP (Model Context Protocol) server designed to interact with the [ntfy](https://ntfy.sh/) push notification service. It enables LLMs and AI agents to send notifications to your devices with extensive customization options.
|
|
11
|
-
|
|
12
|
-
## Table of Contents
|
|
13
|
-
|
|
14
|
-
- [Overview](#overview)
|
|
15
|
-
- [Features](#features)
|
|
16
|
-
- [Quick Start](#quick-start)
|
|
17
|
-
- [Installation](#installation)
|
|
18
|
-
- [Configuration](#configuration)
|
|
19
|
-
- [Project Structure](#project-structure)
|
|
20
|
-
- [Tools](#tools)
|
|
21
|
-
- [Resources](#resources)
|
|
22
|
-
- [Use Cases](#use-cases)
|
|
23
|
-
- [Available Scripts](#available-scripts)
|
|
24
|
-
- [Contributing](#contributing)
|
|
25
|
-
- [License](#license)
|
|
26
|
-
|
|
27
|
-
## Overview
|
|
28
|
-
|
|
29
|
-
This server implements the Model Context Protocol (MCP), enabling standardized communication between LLMs and external systems. Specifically, it provides an interface to the ntfy push notification service.
|
|
30
|
-
|
|
31
|
-
[Ntfy](https://ntfy.sh/) is a simple HTTP-based pub-sub notification service that allows you to send notifications to your phone or desktop via simple HTTP requests. With this MCP server, LLM agents like Claude can send notifications to you through ntfy without needing direct HTTP access.
|
|
32
|
-
|
|
33
|
-
```
|
|
34
|
-
┌───────────┐ ┌───────────┐ ┌───────────┐ ┌─────────┐
|
|
35
|
-
│ LLM Agent │ ────▶│ Ntfy MCP │ ────▶│ Ntfy │ ────▶│ Your │
|
|
36
|
-
│ (Claude) │ │ Server │ │ Service │ │ Devices │
|
|
37
|
-
└───────────┘ └───────────┘ └───────────┘ └─────────┘
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## Features
|
|
41
|
-
|
|
42
|
-
- **MCP Server Implementation:** Built using the `@modelcontextprotocol/sdk` for seamless integration with LLM agents.
|
|
43
|
-
- **Ntfy Integration:** Provides a tool (`send_ntfy`) to send notifications with support for:
|
|
44
|
-
- Message prioritization (1-5 levels)
|
|
45
|
-
- Emoji tags
|
|
46
|
-
- Clickable actions and buttons
|
|
47
|
-
- File attachments
|
|
48
|
-
- Delayed delivery
|
|
49
|
-
- Markdown formatting
|
|
50
|
-
- **Resource Exposure:** Exposes the configured default ntfy topic as an MCP resource.
|
|
51
|
-
- **TypeScript:** Modern, type-safe codebase with comprehensive type definitions.
|
|
52
|
-
- **Structured Logging:** Uses `winston` and `winston-daily-rotate-file` for detailed and rotatable logs.
|
|
53
|
-
- **Configuration Management:** Uses `dotenv` for easy environment-based configuration.
|
|
54
|
-
- **Utility Scripts:** Includes scripts for cleaning build artifacts and generating directory structure documentation.
|
|
55
|
-
- **Error Handling & Security:** Implements robust error handling, input sanitization (`sanitize-html`), and security filters (`xss-filters`).
|
|
56
|
-
|
|
57
|
-
## Quick Start
|
|
1
|
+
<div align="center">
|
|
2
|
+
<h1>ntfy-mcp-server</h1>
|
|
3
|
+
<p><b>Send, manage, and replay ntfy push notifications via MCP. STDIO or Streamable HTTP.</b>
|
|
4
|
+
<div>4 Tools • 1 Resource</div>
|
|
5
|
+
</p>
|
|
6
|
+
</div>
|
|
58
7
|
|
|
59
|
-
|
|
8
|
+
<div align="center">
|
|
60
9
|
|
|
61
|
-
|
|
62
|
-
- npm or yarn
|
|
63
|
-
- An MCP-compatible client (Claude Desktop, Cline, etc.)
|
|
10
|
+
[](https://www.npmjs.com/package/ntfy-mcp-server) [](./CHANGELOG.md) [](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) [](https://modelcontextprotocol.io/)
|
|
64
11
|
|
|
65
|
-
|
|
12
|
+
[](./LICENSE) [](https://www.typescriptlang.org/) [](https://bun.sh/)
|
|
66
13
|
|
|
67
|
-
|
|
68
|
-
# Option 1: Install via npm
|
|
69
|
-
npm install -g ntfy-mcp-server
|
|
14
|
+
</div>
|
|
70
15
|
|
|
71
|
-
|
|
72
|
-
git clone https://github.com/cyanheads/ntfy-mcp-server.git
|
|
73
|
-
cd ntfy-mcp-server
|
|
74
|
-
npm install
|
|
75
|
-
npm run build
|
|
16
|
+
---
|
|
76
17
|
|
|
77
|
-
|
|
78
|
-
cp .env.example .env
|
|
79
|
-
# Edit .env to set NTFY_DEFAULT_TOPIC
|
|
18
|
+
## Tools
|
|
80
19
|
|
|
81
|
-
|
|
82
|
-
npm start
|
|
83
|
-
```
|
|
20
|
+
Four tools covering the ntfy publish/subscribe surface — message lifecycle (publish, manage, fetch) plus an emoji-tag lookup that feeds the publish tool's `tags` field:
|
|
84
21
|
|
|
85
|
-
|
|
22
|
+
| Tool Name | Description |
|
|
23
|
+
|:----------|:------------|
|
|
24
|
+
| `ntfy_publish_message` | Send or update a push notification on an ntfy topic. |
|
|
25
|
+
| `ntfy_manage_message` | Clear or delete a previously-sent notification by `sequence_id`. |
|
|
26
|
+
| `ntfy_fetch_messages` | Poll cached messages from one or more topics with optional filters. |
|
|
27
|
+
| `ntfy_search_emoji_tags` | Look up ntfy emoji tag short codes for use in `tags`. |
|
|
86
28
|
|
|
87
|
-
|
|
29
|
+
---
|
|
88
30
|
|
|
89
|
-
|
|
31
|
+
### `ntfy_publish_message`
|
|
90
32
|
|
|
91
|
-
|
|
33
|
+
Send or update a push notification on an ntfy topic. Topics are created on first publish — treat the topic name as a secret because anyone who knows it can publish or subscribe.
|
|
92
34
|
|
|
93
|
-
1
|
|
35
|
+
- Full publish-parameter coverage — `title`, `priority` (1–5), `tags`, `click`, `attach`, `icon`, `filename`, `markdown`, `delay`, `email`, `call`, `cache`, `firebase`
|
|
36
|
+
- Up to three discriminated action buttons (`view`, `broadcast`, `http`, `copy`) per message
|
|
37
|
+
- Update or replace previously-sent messages by passing the original `sequence_id`
|
|
38
|
+
- Per-call `base_url` override that forwards credentials only when the override matches a registered server (`NTFY_BASE_URL` or an `NTFY_SERVERS` entry); otherwise the request goes out unauthenticated, so credentials never leak to alternate hosts
|
|
94
39
|
|
|
95
|
-
|
|
96
|
-
npm install -g ntfy-mcp-server
|
|
97
|
-
```
|
|
40
|
+
---
|
|
98
41
|
|
|
99
|
-
|
|
42
|
+
### `ntfy_manage_message`
|
|
100
43
|
|
|
101
|
-
|
|
44
|
+
Clear (mark read & dismiss) or delete a previously-sent ntfy notification by `sequence_id`. Append-only — the original message stays in cache, and a `message_clear` / `message_delete` event is emitted to subscribers. Idempotent.
|
|
102
45
|
|
|
103
|
-
|
|
104
|
-
npm install ntfy-mcp-server
|
|
105
|
-
```
|
|
46
|
+
---
|
|
106
47
|
|
|
107
|
-
|
|
48
|
+
### `ntfy_fetch_messages`
|
|
108
49
|
|
|
109
|
-
|
|
50
|
+
Poll cached messages from one or more topics with optional filters. Returns a snapshot, not a live stream — use it to confirm delivery, replay missed alerts, or audit topic activity.
|
|
110
51
|
|
|
111
|
-
|
|
52
|
+
- Comma-separated multi-topic queries (e.g. `alerts,backups,phil_alerts`)
|
|
53
|
+
- Filter by `since` (duration / timestamp / message ID / `all` / `latest`), `priority`, `tags`, `id`, `title`, `message`, scheduled-only
|
|
54
|
+
- Default window `10m`, default limit 20 messages per response, hard cap 100
|
|
55
|
+
- Long bodies truncated to ~500 chars with `messageTruncated` reporting the dropped count
|
|
112
56
|
|
|
113
|
-
|
|
114
|
-
git clone https://github.com/cyanheads/ntfy-mcp-server.git
|
|
115
|
-
cd ntfy-mcp-server
|
|
116
|
-
```
|
|
57
|
+
---
|
|
117
58
|
|
|
118
|
-
|
|
59
|
+
### `ntfy_search_emoji_tags`
|
|
119
60
|
|
|
120
|
-
|
|
121
|
-
npm install
|
|
122
|
-
```
|
|
61
|
+
Substring search over the bundled ntfy emoji-tag reference. Returns the `tag` strings ready to plug into `ntfy_publish_message`'s `tags` field. Without a query, returns the first slice of the full reference.
|
|
123
62
|
|
|
124
|
-
|
|
125
|
-
```bash
|
|
126
|
-
npm run build
|
|
127
|
-
```
|
|
63
|
+
## Resources and prompts
|
|
128
64
|
|
|
129
|
-
|
|
65
|
+
| Type | Name | Description |
|
|
66
|
+
|:---|:---|:---|
|
|
67
|
+
| Resource | `ntfy://{topic}` | Snapshot of a topic — last 20 messages from the past 1 hour, plus the topic's browser URL. |
|
|
130
68
|
|
|
131
|
-
|
|
69
|
+
`ntfy_fetch_messages` covers the same topic data with custom windows and filters when the resource's fixed defaults aren't enough.
|
|
132
70
|
|
|
133
|
-
|
|
71
|
+
## Features
|
|
134
72
|
|
|
135
|
-
|
|
136
|
-
# Ntfy Configuration
|
|
137
|
-
NTFY_BASE_URL=https://ntfy.sh # Optional: Base URL of your ntfy instance
|
|
138
|
-
NTFY_DEFAULT_TOPIC=your_default_topic # Optional: Default topic if none specified in requests
|
|
73
|
+
Built on [`@cyanheads/mcp-ts-core`](https://www.npmjs.com/package/@cyanheads/mcp-ts-core):
|
|
139
74
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
75
|
+
- Declarative tool and resource definitions — single file per primitive, framework handles registration and validation
|
|
76
|
+
- Typed error contracts via `ctx.fail(reason, …)` plus framework error factories (`forbidden`, `notFound`, `validationError`, …)
|
|
77
|
+
- Pluggable auth: `none`, `jwt`, `oauth`
|
|
78
|
+
- Swappable storage backends: `in-memory`, `filesystem`, `Supabase`, `Cloudflare KV/R2/D1`
|
|
79
|
+
- Structured logging with optional OpenTelemetry tracing
|
|
80
|
+
- STDIO and Streamable HTTP transports
|
|
144
81
|
|
|
145
|
-
|
|
82
|
+
ntfy-specific:
|
|
146
83
|
|
|
147
|
-
|
|
84
|
+
- Wraps ntfy's HTTP API with retry-aware client (`withRetry` + per-request timeout)
|
|
85
|
+
- Per-server scoped auth — credentials are bound to each registered base URL (`NTFY_BASE_URL` or per-entry under `NTFY_SERVERS`); per-call `base_url` overrides forward auth only when the override matches a registered server, and go out unauthenticated otherwise
|
|
86
|
+
- Bundled emoji-tag reference, regenerated from upstream `docs/ntfy/emojis.md` via `scripts/build-emoji-tags.ts`
|
|
87
|
+
- Mutually-exclusive auth modes (bearer token *or* basic auth) validated at config-load time
|
|
148
88
|
|
|
149
|
-
|
|
89
|
+
## Getting started
|
|
150
90
|
|
|
151
|
-
|
|
91
|
+
Add the following to your MCP client configuration file. Public ntfy.sh works out of the box without an account; for protected topics, generate an access token at <https://ntfy.sh/account>.
|
|
152
92
|
|
|
153
93
|
```json
|
|
154
94
|
{
|
|
155
95
|
"mcpServers": {
|
|
156
96
|
"ntfy": {
|
|
157
|
-
"
|
|
97
|
+
"type": "stdio",
|
|
98
|
+
"command": "bunx",
|
|
99
|
+
"args": ["ntfy-mcp-server@latest"],
|
|
158
100
|
"env": {
|
|
159
|
-
"
|
|
160
|
-
"
|
|
161
|
-
"
|
|
162
|
-
"NODE_ENV": "production"
|
|
101
|
+
"MCP_TRANSPORT_TYPE": "stdio",
|
|
102
|
+
"MCP_LOG_LEVEL": "info",
|
|
103
|
+
"NTFY_DEFAULT_TOPIC": "your-topic-name"
|
|
163
104
|
}
|
|
164
105
|
}
|
|
165
106
|
}
|
|
166
107
|
}
|
|
167
108
|
```
|
|
168
109
|
|
|
169
|
-
|
|
110
|
+
Or with Docker:
|
|
170
111
|
|
|
171
112
|
```json
|
|
172
113
|
{
|
|
173
114
|
"mcpServers": {
|
|
174
115
|
"ntfy": {
|
|
175
|
-
"
|
|
176
|
-
"
|
|
177
|
-
"
|
|
178
|
-
"
|
|
179
|
-
"
|
|
180
|
-
"
|
|
181
|
-
"
|
|
182
|
-
|
|
116
|
+
"type": "stdio",
|
|
117
|
+
"command": "docker",
|
|
118
|
+
"args": [
|
|
119
|
+
"run", "-i", "--rm",
|
|
120
|
+
"-e", "MCP_TRANSPORT_TYPE=stdio",
|
|
121
|
+
"-e", "NTFY_DEFAULT_TOPIC=your-topic-name",
|
|
122
|
+
"ghcr.io/cyanheads/ntfy-mcp-server:latest"
|
|
123
|
+
]
|
|
183
124
|
}
|
|
184
125
|
}
|
|
185
126
|
}
|
|
186
127
|
```
|
|
187
128
|
|
|
188
|
-
|
|
129
|
+
For Streamable HTTP, set the transport and start the server:
|
|
189
130
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
```json
|
|
195
|
-
{
|
|
196
|
-
"mcpServers": {
|
|
197
|
-
"ntfy": {
|
|
198
|
-
"command": "ntfy-mcp-server",
|
|
199
|
-
"env": {
|
|
200
|
-
"NTFY_BASE_URL": "https://ntfy.sh",
|
|
201
|
-
"NTFY_DEFAULT_TOPIC": "your_default_topic",
|
|
202
|
-
"LOG_LEVEL": "info",
|
|
203
|
-
"NODE_ENV": "production"
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
}
|
|
131
|
+
```sh
|
|
132
|
+
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 NTFY_DEFAULT_TOPIC=your-topic bun run start:http
|
|
133
|
+
# Server listens at http://127.0.0.1:3010/mcp
|
|
208
134
|
```
|
|
209
135
|
|
|
210
|
-
|
|
136
|
+
### Prerequisites
|
|
211
137
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
"mcpServers": {
|
|
215
|
-
"ntfy": {
|
|
216
|
-
"command": "node",
|
|
217
|
-
"args": ["/path/to/ntfy-mcp-server/dist/index.js"],
|
|
218
|
-
"env": {
|
|
219
|
-
"NTFY_BASE_URL": "https://ntfy.sh",
|
|
220
|
-
"NTFY_DEFAULT_TOPIC": "your_default_topic",
|
|
221
|
-
"LOG_LEVEL": "info",
|
|
222
|
-
"NODE_ENV": "production"
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
_For source installation, replace `/path/to/ntfy-mcp-server/dist/index.js` with the actual absolute path to the built server file._
|
|
230
|
-
_Adjust `env` variables as needed for your setup._
|
|
231
|
-
|
|
232
|
-
### Ntfy Setup
|
|
138
|
+
- [Bun v1.3.11](https://bun.sh/) or higher (or Node.js v24+).
|
|
139
|
+
- A topic name on an ntfy server. Public `ntfy.sh` requires no account; self-hosted instances and protected topics may need a bearer token or basic-auth credentials.
|
|
233
140
|
|
|
234
|
-
|
|
235
|
-
2. **Subscribe to your topic** in the app
|
|
236
|
-
3. **Use the same topic** in your MCP server configuration
|
|
141
|
+
### Installation
|
|
237
142
|
|
|
238
|
-
|
|
143
|
+
1. **Clone the repository:**
|
|
239
144
|
|
|
145
|
+
```sh
|
|
146
|
+
git clone https://github.com/cyanheads/ntfy-mcp-server.git
|
|
240
147
|
```
|
|
241
|
-
.
|
|
242
|
-
├── .env.example # Example environment variables
|
|
243
|
-
├── .gitignore # Git ignore patterns
|
|
244
|
-
├── LICENSE # Project license (Apache-2.0)
|
|
245
|
-
├── package.json # Project metadata and dependencies
|
|
246
|
-
├── tsconfig.json # TypeScript compiler configuration
|
|
247
|
-
├── docs/
|
|
248
|
-
│ └── tree.md # Auto-generated directory structure
|
|
249
|
-
├── logs/ # Runtime logs (created automatically)
|
|
250
|
-
├── scripts/ # Utility scripts
|
|
251
|
-
│ ├── clean.ts # Cleans build artifacts and logs
|
|
252
|
-
│ └── tree.ts # Generates the docs/tree.md file
|
|
253
|
-
└── src/ # Source code
|
|
254
|
-
├── index.ts # Main server entry point
|
|
255
|
-
├── config/ # Configuration loading
|
|
256
|
-
├── mcp-server/ # MCP server logic, tools, and resources
|
|
257
|
-
│ ├── resources/ # MCP resource implementations
|
|
258
|
-
│ ├── tools/ # MCP tool implementations
|
|
259
|
-
│ └── utils/ # MCP-specific utilities
|
|
260
|
-
├── services/ # External service integrations (ntfy)
|
|
261
|
-
├── types-global/ # Global type definitions
|
|
262
|
-
└── utils/ # General utility functions
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
## Tools
|
|
266
148
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
Sends a notification message via the ntfy service.
|
|
270
|
-
|
|
271
|
-
#### Key Arguments:
|
|
272
|
-
|
|
273
|
-
| Parameter | Type | Required | Description |
|
|
274
|
-
| ------------ | -------- | -------- | ---------------------------------------------------------------------------- |
|
|
275
|
-
| `topic` | string | Yes | The ntfy topic to publish to. |
|
|
276
|
-
| `message` | string | Yes | The main content of the notification (max 4096 bytes). |
|
|
277
|
-
| `title` | string | No | Notification title (max 250 bytes). |
|
|
278
|
-
| `tags` | string[] | No | Emojis or keywords for categorization (e.g., `["warning", "robot"]`). Max 5. |
|
|
279
|
-
| `priority` | integer | No | Message priority: 1=min, 2=low, 3=default, 4=high, 5=max. |
|
|
280
|
-
| `click` | string | No | URL to open when the notification is clicked. |
|
|
281
|
-
| `actions` | array | No | Action buttons (view, http, broadcast). Max 3. |
|
|
282
|
-
| `attachment` | object | No | URL and name of an attachment. |
|
|
283
|
-
| `email` | string | No | Email address to forward the notification to. |
|
|
284
|
-
| `delay` | string | No | Delay delivery (e.g., `30m`, `1h`, `tomorrow`). |
|
|
285
|
-
| `cache` | string | No | Cache duration (e.g., `10m`, `1h`, `1d`). |
|
|
286
|
-
| `firebase` | string | No | Firebase Cloud Messaging (FCM) topic to forward to. |
|
|
287
|
-
| `id` | string | No | Unique ID for the message. |
|
|
288
|
-
| `expires` | string | No | Message expiration (e.g., `10m`, `1h`, `1d`). |
|
|
289
|
-
| `markdown` | boolean | No | Set to `true` to enable markdown formatting in the message. |
|
|
290
|
-
| `baseUrl` | string | No | Override the default ntfy server URL for this request. |
|
|
291
|
-
|
|
292
|
-
#### Example Usage:
|
|
293
|
-
|
|
294
|
-
```javascript
|
|
295
|
-
// Basic notification
|
|
296
|
-
{
|
|
297
|
-
"topic": "alerts",
|
|
298
|
-
"message": "The task has completed successfully."
|
|
299
|
-
}
|
|
149
|
+
2. **Navigate into the directory:**
|
|
300
150
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
"topic": "alerts",
|
|
304
|
-
"title": "System Alert",
|
|
305
|
-
"message": "CPU usage has exceeded 90% for 5 minutes.",
|
|
306
|
-
"tags": ["warning", "computer"],
|
|
307
|
-
"priority": 4,
|
|
308
|
-
"click": "https://server-dashboard.example.com",
|
|
309
|
-
"actions": [
|
|
310
|
-
{
|
|
311
|
-
"id": "view",
|
|
312
|
-
"label": "View Details",
|
|
313
|
-
"action": "view",
|
|
314
|
-
"url": "https://server-dashboard.example.com/cpu"
|
|
315
|
-
},
|
|
316
|
-
{
|
|
317
|
-
"id": "restart",
|
|
318
|
-
"label": "Restart Service",
|
|
319
|
-
"action": "http",
|
|
320
|
-
"url": "https://api.example.com/restart-service",
|
|
321
|
-
"method": "POST",
|
|
322
|
-
"headers": {
|
|
323
|
-
"Authorization": "Bearer token123"
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
],
|
|
327
|
-
"markdown": true
|
|
328
|
-
}
|
|
151
|
+
```sh
|
|
152
|
+
cd ntfy-mcp-server
|
|
329
153
|
```
|
|
330
154
|
|
|
331
|
-
|
|
155
|
+
3. **Install dependencies:**
|
|
332
156
|
|
|
333
|
-
```
|
|
334
|
-
|
|
335
|
-
"success": true,
|
|
336
|
-
"id": "5ZFY362156Sa",
|
|
337
|
-
"topic": "ATLAS",
|
|
338
|
-
"time": 1743064235,
|
|
339
|
-
"expires": 1743496235,
|
|
340
|
-
"message": "This is a test message from the README verification process",
|
|
341
|
-
"title": "README Testing"
|
|
342
|
-
}
|
|
157
|
+
```sh
|
|
158
|
+
bun install
|
|
343
159
|
```
|
|
344
160
|
|
|
345
|
-
|
|
161
|
+
4. **Configure environment:**
|
|
346
162
|
|
|
347
|
-
|
|
163
|
+
```sh
|
|
164
|
+
cp .env.example .env
|
|
165
|
+
# edit .env and set NTFY_DEFAULT_TOPIC (and auth, if needed)
|
|
166
|
+
```
|
|
348
167
|
|
|
349
|
-
|
|
168
|
+
## Configuration
|
|
350
169
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
170
|
+
| Variable | Description | Default |
|
|
171
|
+
|:---------|:------------|:--------|
|
|
172
|
+
| `NTFY_SERVERS` | JSON 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. Use this when you need more than one authenticated server in a single process; it takes precedence over the single-server vars below. | — |
|
|
173
|
+
| `NTFY_BASE_URL` | Single-server shorthand — base URL of the ntfy server (no trailing slash). Used when `NTFY_SERVERS` is unset. | `https://ntfy.sh` |
|
|
174
|
+
| `NTFY_DEFAULT_TOPIC` | Topic used when a tool call omits `topic`. | — |
|
|
175
|
+
| `NTFY_AUTH_TOKEN` | Bearer access token (`tk_…`) for the single-server shorthand. Mutually exclusive with `NTFY_AUTH_USERNAME` / `NTFY_AUTH_PASSWORD`. | — |
|
|
176
|
+
| `NTFY_AUTH_USERNAME` | Basic-auth username for the single-server shorthand — required together with `NTFY_AUTH_PASSWORD`. | — |
|
|
177
|
+
| `NTFY_AUTH_PASSWORD` | Basic-auth password for the single-server shorthand — required together with `NTFY_AUTH_USERNAME`. | — |
|
|
178
|
+
| `NTFY_REQUEST_TIMEOUT_MS` | Per-request HTTP timeout in milliseconds. | `15000` |
|
|
179
|
+
| `NTFY_MAX_RETRIES` | Max retry attempts for transient upstream failures (5xx, network, 429). | `3` |
|
|
180
|
+
| `MCP_TRANSPORT_TYPE` | Transport: `stdio` or `http`. | `stdio` |
|
|
181
|
+
| `MCP_SESSION_MODE` | HTTP session model: `stateless`, `stateful`, or `auto`. | `auto` |
|
|
182
|
+
| `MCP_HTTP_HOST` | HTTP host. | `127.0.0.1` |
|
|
183
|
+
| `MCP_HTTP_PORT` | HTTP port. | `3010` |
|
|
184
|
+
| `MCP_HTTP_ENDPOINT_PATH` | HTTP endpoint path. | `/mcp` |
|
|
185
|
+
| `MCP_AUTH_MODE` | Auth mode: `none`, `jwt`, or `oauth`. | `none` |
|
|
186
|
+
| `MCP_LOG_LEVEL` | Log level (RFC 5424). | `info` |
|
|
187
|
+
| `LOGS_DIR` | Directory for file-based logs (Node only; ignored on Workers). | `./logs` |
|
|
188
|
+
| `OTEL_ENABLED` | Enable [OpenTelemetry instrumentation](https://github.com/cyanheads/mcp-ts-core/tree/main/docs/telemetry) (spans, metrics, completion logs). | `false` |
|
|
189
|
+
|
|
190
|
+
See [`.env.example`](./.env.example) for the full list of optional overrides.
|
|
191
|
+
|
|
192
|
+
## Running the server
|
|
193
|
+
|
|
194
|
+
### Local development
|
|
195
|
+
|
|
196
|
+
- **Build and run:**
|
|
197
|
+
|
|
198
|
+
```sh
|
|
199
|
+
# One-time build
|
|
200
|
+
bun run rebuild
|
|
201
|
+
|
|
202
|
+
# Run the built server
|
|
203
|
+
bun run start:stdio
|
|
204
|
+
# or
|
|
205
|
+
bun run start:http
|
|
362
206
|
```
|
|
363
207
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
#### `ntfy://{topic}`
|
|
208
|
+
- **Run checks and tests:**
|
|
367
209
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
```json
|
|
373
|
-
{
|
|
374
|
-
"topic": "ATLAS",
|
|
375
|
-
"timestamp": "2025-03-27T08:30:30.038Z",
|
|
376
|
-
"requestUri": "ntfy://ATLAS",
|
|
377
|
-
"requestId": "31baf1df-278f-4fdb-860d-019f156a72b0"
|
|
378
|
-
}
|
|
210
|
+
```sh
|
|
211
|
+
bun run devcheck # Lint, format, typecheck, security, changelog sync
|
|
212
|
+
bun run test # Vitest test suite
|
|
213
|
+
bun run lint:mcp # Validate MCP definitions against spec
|
|
379
214
|
```
|
|
380
215
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
1. **Long-running Task Notifications** - Get notified when tasks like database backups, code generation, or data processing complete.
|
|
384
|
-
2. **Scheduled Reminders** - Set delayed notifications for future events or reminders.
|
|
385
|
-
3. **Alert Systems** - Set up critical alerts for monitoring systems or important events.
|
|
386
|
-
4. **Mobile Notifications from LLMs** - Allow LLMs to send notifications directly to your phone.
|
|
387
|
-
5. **Multi-step Process Updates** - Receive updates as different stages of a complex process complete.
|
|
388
|
-
|
|
389
|
-
### Usage Examples
|
|
216
|
+
### Docker
|
|
390
217
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
<use_mcp_tool>
|
|
395
|
-
<server_name>ntfy-mcp-server</server_name>
|
|
396
|
-
<tool_name>send_ntfy</tool_name>
|
|
397
|
-
<arguments>
|
|
398
|
-
{
|
|
399
|
-
"topic": "updates",
|
|
400
|
-
"title": "Task Completed",
|
|
401
|
-
"message": "Your requested data analysis has finished",
|
|
402
|
-
"tags": ["check"]
|
|
403
|
-
}
|
|
404
|
-
</arguments>
|
|
405
|
-
</use_mcp_tool>
|
|
218
|
+
```sh
|
|
219
|
+
docker build -t ntfy-mcp-server .
|
|
220
|
+
docker run --rm -e NTFY_DEFAULT_TOPIC=your-topic -p 3010:3010 ntfy-mcp-server
|
|
406
221
|
```
|
|
407
222
|
|
|
408
|
-
|
|
223
|
+
The Dockerfile defaults to HTTP transport, stateless session mode, and logs to `/var/log/ntfy-mcp-server`. OpenTelemetry peer dependencies are installed by default — build with `--build-arg OTEL_ENABLED=false` to omit them.
|
|
409
224
|
|
|
410
|
-
|
|
411
|
-
<use_mcp_tool>
|
|
412
|
-
<server_name>ntfy-mcp-server</server_name>
|
|
413
|
-
<tool_name>send_ntfy</tool_name>
|
|
414
|
-
<arguments>
|
|
415
|
-
{
|
|
416
|
-
"topic": "alerts",
|
|
417
|
-
"title": "Critical Error Detected",
|
|
418
|
-
"message": "The application has encountered a critical error.\n\n**Error Code**: E123\n\n**Details**: Database connection failed",
|
|
419
|
-
"tags": ["warning", "skull"],
|
|
420
|
-
"priority": 5,
|
|
421
|
-
"actions": [
|
|
422
|
-
{
|
|
423
|
-
"id": "view",
|
|
424
|
-
"label": "View Logs",
|
|
425
|
-
"action": "view",
|
|
426
|
-
"url": "https://logs.example.com"
|
|
427
|
-
},
|
|
428
|
-
{
|
|
429
|
-
"id": "restart",
|
|
430
|
-
"label": "Restart Service",
|
|
431
|
-
"action": "http",
|
|
432
|
-
"url": "https://api.example.com/restart",
|
|
433
|
-
"method": "POST"
|
|
434
|
-
}
|
|
435
|
-
],
|
|
436
|
-
"markdown": true
|
|
437
|
-
}
|
|
438
|
-
</arguments>
|
|
439
|
-
</use_mcp_tool>
|
|
440
|
-
```
|
|
225
|
+
## Project structure
|
|
441
226
|
|
|
442
|
-
|
|
227
|
+
| Directory | Purpose |
|
|
228
|
+
|:----------|:--------|
|
|
229
|
+
| `src/index.ts` | `createApp()` entry point — registers tools and resources, initializes services. |
|
|
230
|
+
| `src/config` | Server-specific environment variable parsing (`NTFY_*`) with Zod. |
|
|
231
|
+
| `src/mcp-server/tools` | Tool definitions (`*.tool.ts`). |
|
|
232
|
+
| `src/mcp-server/resources` | Resource definitions (`*.resource.ts`). |
|
|
233
|
+
| `src/services/ntfy` | ntfy HTTP client, types, and error classifier. |
|
|
234
|
+
| `src/services/emoji-tags` | Bundled emoji short-code reference and lookup service. |
|
|
235
|
+
| `docs/ntfy` | Mirrored upstream ntfy API docs (pinned commit in `SOURCES.md`). |
|
|
236
|
+
| `tests/` | Unit and integration tests mirroring `src/`. |
|
|
443
237
|
|
|
444
|
-
|
|
445
|
-
- `npm run clean`: Removes the `dist/` directory and cleans the contents of the `logs/` directory.
|
|
446
|
-
- `npm run rebuild`: Runs `clean` and then `build`.
|
|
447
|
-
- `npm run tree`: Generates a directory tree representation in `docs/tree.md`.
|
|
448
|
-
- `npm start`: Runs the compiled server from the `dist/` directory using Node.js.
|
|
449
|
-
- `npm run watch`: Tails the combined log file (`logs/combined.log`) for real-time monitoring.
|
|
238
|
+
## Development guide
|
|
450
239
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
Contributions are welcome! Please feel free to submit pull requests or open issues to improve the project.
|
|
240
|
+
See [`CLAUDE.md`](./CLAUDE.md) for development guidelines and architectural rules. The short version:
|
|
454
241
|
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
5. Create a new Pull Request.
|
|
242
|
+
- Handlers throw, framework catches — no `try/catch` in tool logic
|
|
243
|
+
- Use `ctx.log` for request-scoped logging, `ctx.state` for tenant-scoped storage
|
|
244
|
+
- Wrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields
|
|
245
|
+
- Per-tool `errors[]` contracts stay inline — repetition is intended for locality
|
|
460
246
|
|
|
461
|
-
|
|
247
|
+
## Contributing
|
|
462
248
|
|
|
463
|
-
|
|
249
|
+
Issues and pull requests are welcome. Run checks and tests before submitting:
|
|
464
250
|
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
251
|
+
```sh
|
|
252
|
+
bun run devcheck
|
|
253
|
+
bun run test
|
|
254
|
+
```
|
|
469
255
|
|
|
470
256
|
## License
|
|
471
257
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
## Acknowledgements
|
|
475
|
-
|
|
476
|
-
- [ntfy.sh](https://ntfy.sh/) for providing the notification service
|
|
477
|
-
- [Model Context Protocol](https://modelcontextprotocol.io/) for enabling LLM-to-tool connections
|
|
478
|
-
- All contributors and users of this project
|
|
479
|
-
|
|
480
|
-
---
|
|
481
|
-
|
|
482
|
-
<div align="center">
|
|
483
|
-
Built with the Model Context Protocol
|
|
484
|
-
</div>
|
|
258
|
+
Apache-2.0 — see [LICENSE](LICENSE) for details.
|