Skip to main content
Glama

ntfy-notify

CI License: MIT Python 3.10+

A tiny Model Context Protocol (MCP) server that lets Claude / Cowork push notifications to your phone via ntfy. Point a scheduled task at it and the results land on your lock screen instead of waiting in a log somewhere.

Why I built this: I run a scheduled daily job-search inbox sweep, and I wanted the summary on my phone the moment it finishes instead of having to go check on it. ntfy is a dead-simple pub/sub-over-HTTP service, so the whole thing is one HTTP POST behind an MCP tool.

What it does

Exposes two MCP tools over stdio:

Tool

Purpose

send_notification(message, title="", priority="default", tags="", click_url="")

Send any push notification to your configured ntfy topic.

send_job_alert(summary)

Convenience wrapper: title "Job sweep", high priority, briefcase tag.

priority accepts min / low / default / high / urgent (or "1".."5"). tags is a comma-separated list of emoji shortcodes, e.g. tada,computer. click_url opens when you tap the notification.

Related MCP server: ntfy-mcp

How ntfy works (30-second version)

ntfy is pub/sub over HTTP. You pick a topic — any string — and subscribe to it in the phone app. Anyone who knows the topic name can publish to it with a single HTTP POST, and it shows up on every subscribed device. There's no account or auth for public topics, which means the topic name is the only secret, so make it long and random.

How it works

There's no daemon and no always-on process. A stdio MCP server is launched by the client (Claude/Cowork) as a child process when a session starts, speaks JSON-RPC over stdin/stdout, stays idle until a tool is called, and is shut down when the session ends.

Claude / Cowork session
        │  (launches as subprocess, JSON-RPC over stdio)
        ▼
   server.py  ──►  @mcp.tool() functions
        │              send_notification / send_job_alert
        │  builds one HTTP POST:
        │    body    = message text
        │    headers = Title / Priority / Tags / Click / Authorization
        ▼
   https://ntfy.sh/<NTFY_TOPIC>
        │  (pub/sub fan-out)
        ▼
   ntfy app on your phone

Key design points:

  • The topic is read from the environment, never hardcoded (_config()). Since the topic name is the only secret in ntfy, this is what makes the repo safe to be public — and it fails loudly with a clear error if NTFY_TOPIC is unset.

  • @mcp.tool() turns a plain function into a tool. The function name, type hints, and docstring become the schema and description that Claude reads to decide when and how to call it.

  • ntfy has no JSON payload. The message is the raw request body; everything else (title, priority, tags, click URL, auth token) rides along as HTTP headers.

  • Every call returns an OK: / FAILED: status string so the model knows whether the push actually went out. Network errors and non-2xx responses are caught and reported rather than raised.

Development

Run the test suite (pure logic + header construction, no network calls):

pip install -e ".[dev]"
pytest

1. Install the ntfy app and pick a topic

  1. Install ntfy on your phone:

  2. Generate a long, random topic name so nobody else can guess it:

    openssl rand -hex 16
  3. In the app, tap + and subscribe to that exact string.

2. Install the server

Requires Python 3.10+.

git clone https://github.com/Gardner-Programs/ntfy-notify.git
cd ntfy-notify
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt

3. Configure environment variables

Copy the example and fill it in:

cp .env.example .env

Variable

Required

Default

Notes

NTFY_TOPIC

yes

Your long, random topic. Never hardcoded.

NTFY_BASE_URL

no

https://ntfy.sh

Set to your own host if self-hosting.

NTFY_TOKEN

no

Bearer token for protected / self-hosted topics.

The server reads these from the process environment. The MCP config below sets them directly, so a .env file is only needed for the curl test / manual runs.

4. Register the server with Cowork / Claude

Add an entry to your MCP client config. For Claude Desktop (claude_desktop_config.json) or Cowork, point it at the cloned repo:

{
  "mcpServers": {
    "ntfy-notify": {
      "command": "python",
      "args": ["/absolute/path/to/ntfy-notify/server.py"],
      "env": {
        "NTFY_TOPIC": "your-long-random-topic",
        "NTFY_BASE_URL": "https://ntfy.sh",
        "NTFY_TOKEN": ""
      }
    }
  }
}

For Claude Code, the equivalent one-liner:

claude mcp add ntfy-notify \
  --env NTFY_TOPIC=your-long-random-topic \
  -- python /absolute/path/to/ntfy-notify/server.py

If you installed into a virtualenv, use that interpreter's absolute path (e.g. /absolute/path/to/ntfy-notify/.venv/bin/python) as the command.

Restart the client and the send_notification / send_job_alert tools will appear.

5. Verify with curl

You don't need this server to test ntfy itself — confirm your topic works first:

curl \
  -H "Title: Hello from ntfy" \
  -H "Priority: high" \
  -H "Tags: tada" \
  -d "It works!" \
  https://ntfy.sh/your-long-random-topic

With a token (protected / self-hosted):

curl \
  -H "Authorization: Bearer tk_yourtoken" \
  -d "It works!" \
  https://ntfy.example.com/your-long-random-topic

You should get a push on your phone within a second or two.

Integration: daily job-inbox-sweep

Once the server is registered, update the scheduled daily-job-inbox-sweep task so its final step calls the tool with the run's summary, e.g.:

At the end of the run, call send_job_alert with a one-paragraph summary of what was found (new postings, replies, anything needing action).

send_job_alert already sets a sensible title and high priority, so a single call with the summary text is all the task needs.

License

MIT — see LICENSE.

Available Tools

2 tools
send_job_alertA

Send a job-search inbox-sweep summary with sensible defaults.

Thin wrapper around send_notification: title "Job sweep", high priority, a briefcase tag. Intended for the daily job-inbox-sweep task.

Args: summary: The summary text to push to your phone.

Returns: A status string starting with "OK:" on success or "FAILED:" on error.

ParametersJSON Schema
NameRequiredDescriptionDefault
summaryYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description fully discloses behavior: it is a thin wrapper with fixed defaults (title 'Job sweep', high priority, briefcase tag), and it specifies the return format (status string starting with 'OK:' or 'FAILED:'). No hidden behaviors or contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is very concise, uses bullet-like Args/Returns sections, and front-loads the purpose. Every sentence adds value with no fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple tool with one parameter and an output schema (which it describes), the description covers purpose, usage, behavior, parameter meaning, and return format. No gaps given the tool's simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 0% description coverage, but the description adds 'summary: The summary text to push to your phone.' While this is basic, it provides meaning beyond the parameter name and type. Could include constraints like max length, but the meaning is clear.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool sends a 'job-search inbox-sweep summary with sensible defaults', identifies it as a thin wrapper around send_notification, and specifies the defaults. This distinguishes it from the sibling tool and leaves no ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says 'Intended for the daily job-inbox-sweep task', providing clear context. It identifies the parent tool (send_notification) but does not explicitly state when not to use it. The guidance is adequate but lacks explicit alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

send_notificationA

Send a push notification to the configured ntfy topic (your phone).

Args: message: The notification body text. title: Optional bold title shown above the message. priority: One of min, low, default, high, urgent (or "1".."5"). Anything unrecognized falls back to "default". tags: Comma-separated emoji shortcodes, e.g. "tada,computer". click_url: Optional URL opened when the notification is tapped.

Returns: A status string starting with "OK:" on success or "FAILED:" on error.

ParametersJSON Schema
NameRequiredDescriptionDefault
tagsNo
titleNo
messageYes
priorityNodefault
click_urlNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description bears full responsibility. It only states that a notification is sent and returns a status string. Missing details: whether the tool blocks, rate limits, side effects, or what happens if the ntfy topic is unreachable.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise: one sentence for purpose, then bullet-like Args and Returns. No wasted words. Front-loaded with the main action.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the presence of an output schema (implied by context) and 5 parameters, the description covers parameter semantics and return status well. It lacks prerequisites (ntfy configuration) and error handling details, but overall is sufficient for a straightforward notification tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, but the description compensates fully by explaining every parameter's meaning. For 'priority' it enumerates valid values and fallback. 'tags' is described as 'emoji shortcodes'. 'click_url' and 'title' are defined. This adds high value beyond the schema's bare names.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description opens with 'Send a push notification to the configured ntfy topic (your phone).' The verb 'Send' and resource 'push notification' with a specific target (ntfy topic) clearly define the action. This distinguishes it from 'send_job_alert' which likely targets a different channel.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided about when to use this tool versus the sibling 'send_job_alert'. There is no mention of prerequisites (e.g., ntfy must be configured) or scenarios where alternatives should be considered.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

TDQS

A4.2/5.0
Disambiguation5/5

The two tools have clear, distinct purposes: send_notification for general push notifications and send_job_alert as a specialized wrapper for job search alerts. No overlap or ambiguity.

Naming Consistency5/5

Both tool names follow a consistent verb_noun pattern (send_job_alert, send_notification), making them predictable and intuitive.

Tool Count4/5

With 2 tools, the set is minimal but well-justified: a general notification tool and a convenience wrapper for a common use case. A few more specific wrappers could be added, but current count is appropriate for the server's focused purpose.

Completeness5/5

The server's purpose is to send push notifications, and it provides both a general-purpose tool and a task-specific shortcut. There are no obvious gaps for the intended functionality.

Maintenance

ActivityStale
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
    B
    quality
    D
    maintenance
    Enables AI agents to send push notifications to your phone through ntfy, with built-in security controls to prevent data exfiltration. It exposes a single tool notify_user for notifying when tasks complete or need attention.
    1
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables sending push notifications via ntfy with a single tool, allowing Claude agents to send notifications directly without shell access.
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    MCP server for sending notifications to ntfy.sh or self-hosted ntfy instances.
    19
    MIT
  • A
    license
    B
    quality
    D
    maintenance
    A lightweight MCP server for sending push notifications via ntfy.sh, supporting customizable titles, priorities, tags, and action buttons.
    1
    10
    6
    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/Gardner-Programs/ntfy-notify'

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