omni-notify-mcp 1.3.6 → 1.3.7

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.
Files changed (2) hide show
  1. package/dist/ui/server.js +57 -16
  2. package/package.json +1 -1
package/dist/ui/server.js CHANGED
@@ -165,9 +165,8 @@ function ntfyFanout(topic, message, title, priority, tags) {
165
165
  }
166
166
  }
167
167
  }
168
- // SSE subscribe — ntfy app connects here
169
- app.get("/ntfy/:topic/sse", (req, res) => {
170
- const { topic } = req.params;
168
+ function handleNtfySse(req, res) {
169
+ const topic = req.params.topic;
171
170
  res.setHeader("Content-Type", "text/event-stream");
172
171
  res.setHeader("Cache-Control", "no-cache");
173
172
  res.setHeader("Connection", "keep-alive");
@@ -184,14 +183,10 @@ app.get("/ntfy/:topic/sse", (req, res) => {
184
183
  catch {
185
184
  clearInterval(keepalive);
186
185
  } }, 30_000);
187
- req.on("close", () => {
188
- clearInterval(keepalive);
189
- ntfySubscribers.get(topic)?.delete(sub);
190
- });
191
- });
192
- // Also support ntfy's JSON stream endpoint
193
- app.get("/ntfy/:topic/json", (req, res) => {
194
- const { topic } = req.params;
186
+ req.on("close", () => { clearInterval(keepalive); ntfySubscribers.get(topic)?.delete(sub); });
187
+ }
188
+ function handleNtfyJson(req, res) {
189
+ const topic = req.params.topic;
195
190
  res.setHeader("Content-Type", "application/x-ndjson");
196
191
  res.setHeader("Cache-Control", "no-cache");
197
192
  res.setHeader("Connection", "keep-alive");
@@ -208,12 +203,58 @@ app.get("/ntfy/:topic/json", (req, res) => {
208
203
  clearInterval(keepalive);
209
204
  }
210
205
  }, 30_000);
211
- req.on("close", () => {
212
- clearInterval(keepalive);
213
- ntfySubscribers.get(topic)?.delete(sub);
214
- });
206
+ req.on("close", () => { clearInterval(keepalive); ntfySubscribers.get(topic)?.delete(sub); });
207
+ }
208
+ // ntfy app hits /:topic/sse or /:topic/json (no /ntfy/ prefix)
209
+ app.get("/:topic/sse", (req, res) => {
210
+ if (["api", "auth", "mcp", "assets", "ntfy"].includes(req.params.topic)) {
211
+ res.status(404).end();
212
+ return;
213
+ }
214
+ handleNtfySse(req, res);
215
215
  });
216
- // Publish endpoint ntfy protocol POST
216
+ app.get("/:topic/json", (req, res) => {
217
+ if (["api", "auth", "mcp", "assets", "ntfy"].includes(req.params.topic)) {
218
+ res.status(404).end();
219
+ return;
220
+ }
221
+ handleNtfyJson(req, res);
222
+ });
223
+ // Also with /ntfy/ prefix for internal use
224
+ app.get("/ntfy/:topic/sse", (req, res) => handleNtfySse(req, res));
225
+ app.get("/ntfy/:topic/json", (req, res) => handleNtfyJson(req, res));
226
+ // Publish endpoint — ntfy protocol POST (with and without /ntfy/ prefix)
227
+ app.put("/:topic", express.text({ type: "*/*" }), (req, res, next) => {
228
+ if (["api", "auth", "mcp", "assets", "ntfy"].includes(req.params.topic)) {
229
+ next();
230
+ return;
231
+ }
232
+ handleNtfyPublish(req, res);
233
+ });
234
+ app.post("/:topic", express.text({ type: "*/*" }), (req, res, next) => {
235
+ if (["api", "auth", "mcp", "assets", "ntfy"].includes(req.params.topic)) {
236
+ next();
237
+ return;
238
+ }
239
+ handleNtfyPublish(req, res);
240
+ });
241
+ app.get("/:topic/subscribers", (req, res) => {
242
+ if (["api", "auth", "mcp", "assets", "ntfy"].includes(req.params.topic)) {
243
+ res.status(404).end();
244
+ return;
245
+ }
246
+ const count = ntfySubscribers.get(req.params.topic)?.size ?? 0;
247
+ res.json({ topic: req.params.topic, subscribers: count });
248
+ });
249
+ function handleNtfyPublish(req, res) {
250
+ const topic = req.params.topic;
251
+ const message = typeof req.body === "string" ? req.body : "";
252
+ const title = decodeURIComponent((req.headers["title"] || req.headers["x-title"] || "Claude Notify"));
253
+ const priority = parseInt((req.headers["priority"] || req.headers["x-priority"] || "3")) || 3;
254
+ const tags = (req.headers["tags"] || req.headers["x-tags"] || "");
255
+ ntfyFanout(topic, message, title, priority, tags);
256
+ res.json({ id: String(Date.now()), time: Math.floor(Date.now() / 1000), event: "message", topic, title, message, priority });
257
+ }
217
258
  app.put("/ntfy/:topic", express.text({ type: "*/*" }), (req, res) => {
218
259
  const { topic } = req.params;
219
260
  const message = typeof req.body === "string" ? req.body : "";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omni-notify-mcp",
3
- "version": "1.3.6",
3
+ "version": "1.3.7",
4
4
  "description": "An MCP server that lets AI agents (Claude, Cursor, etc.) reach you on any channel — desktop, Telegram, SMS, email — with two-way ask/reply, real-time inbox push, Do Not Disturb, idle gating, multi-session routing, and a one-page web UI for setup. Zero config code; configure once, agents call notify/ask.",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",