ntfy-mcp-server
Send, manage, and replay ntfy push notifications via MCP.
The record the registry holds
There is no address to call. This one is a package you install and run yourself, wherever your assistant runs.
{
"server": {
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
"name": "io.github.cyanheads/ntfy-mcp-server",
"description": "Send, manage, and replay ntfy push notifications via MCP.",
"repository": {
"url": "https://github.com/cyanheads/ntfy-mcp-server",
"source": "github"
},
"version": "2.3.2",
"packages": [
{
"registryType": "npm",
"registryBaseUrl": "https://registry.npmjs.org",
"identifier": "ntfy-mcp-server",
"version": "2.3.2",
"runtimeHint": "bun",
"transport": {
"type": "stdio"
},
"packageArguments": [
{
"value": "run",
"type": "positional"
},
{
"value": "start:stdio",
"type": "positional"
}
],
"environmentVariables": [
{
"description": "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. Takes precedence over the single-server NTFY_BASE_URL / NTFY_AUTH_* shorthand.",
"format": "string",
"name": "NTFY_SERVERS"
},
{
"description": "Single-server shorthand — base URL of the ntfy server (no trailing slash). Used when NTFY_SERVERS is unset.",
"format": "string",
"default": "https://ntfy.sh",
"name": "NTFY_BASE_URL"
},
{
"description": "Topic used when a tool call omits `topic`. Treat the topic name as a secret — anyone who knows it can publish or subscribe.",
"format": "string",
"name": "NTFY_DEFAULT_TOPIC"
},
{
"description": "Bearer access token (`tk_…`) for the single-server shorthand. Mutually exclusive with NTFY_AUTH_USERNAME / NTFY_AUTH_PASSWORD.",
"format": "string",
"name": "NTFY_AUTH_TOKEN"
},
{
"description": "Basic-auth username for the single-server shorthand — must be set together with NTFY_AUTH_PASSWORD.",
"format": "string",
"name": "NTFY_AUTH_USERNAME"
},
{
"description": "Basic-auth password for the single-server shorthand — must be set together with NTFY_AUTH_USERNAME.",
"format": "string",
"name": "NTFY_AUTH_PASSWORD"
},
{
"description": "Per-request HTTP timeout in milliseconds.",
"format": "string",
"default": "15000",
"name": "NTFY_REQUEST_TIMEOUT_MS"
},
{
"description": "Max retry attempts for transient upstream failures (5xx, network, 429).",
"format": "string",
"default": "3",
"name": "NTFY_MAX_RETRIES"
},
{
"description": "When 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.",
"format": "string",
"default": "false",
"name": "NTFY_BLOCK_PRIVATE_HOSTS"
},
{
"description": "Sets the minimum log level for output (e.g., 'debug', 'info', 'warn').",
"format": "string",
"default": "info",
"name": "MCP_LOG_LEVEL"
},
{
"description": "Directory for file-based logs (Node only; ignored on Workers).",
"format": "string",
"default": "./logs",
"name": "LOGS_DIR"
},
{
"description": "Enable OpenTelemetry instrumentation (spans, metrics, completion logs).",
"format": "string",
"default": "false",
"name": "OTEL_ENABLED"
}
]
},
{
"registryType": "npm",
"registryBaseUrl": "https://registry.npmjs.org",
"identifier": "ntfy-mcp-server",
"version": "2.3.2",
"runtimeHint": "bun",
"transport": {
"type": "streamable-http",
"url": "http://127.0.0.1:3010/mcp"
},
"packageArguments": [
{
"value": "run",
"type": "positional"
},
{
"value": "start:http",
"type": "positional"
}
],
"environmentVariables": [
{
"description": "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. Takes precedence over the single-server NTFY_BASE_URL / NTFY_AUTH_* shorthand.",
"format": "string",
"name": "NTFY_SERVERS"
},
{
"description": "Single-server shorthand — base URL of the ntfy server (no trailing slash). Used when NTFY_SERVERS is unset.",
"format": "string",
"default": "https://ntfy.sh",
"name": "NTFY_BASE_URL"
},
{
"description": "Topic used when a tool call omits `topic`. Treat the topic name as a secret — anyone who knows it can publish or subscribe.",
"format": "string",
"name": "NTFY_DEFAULT_TOPIC"
},
{
"description": "Bearer access token (`tk_…`) for the single-server shorthand. Mutually exclusive with NTFY_AUTH_USERNAME / NTFY_AUTH_PASSWORD.",
"format": "string",
"name": "NTFY_AUTH_TOKEN"
},
{
"description": "Basic-auth username for the single-server shorthand — must be set together with NTFY_AUTH_PASSWORD.",
"format": "string",
"name": "NTFY_AUTH_USERNAME"
},
{
"description": "Basic-auth password for the single-server shorthand — must be set together with NTFY_AUTH_USERNAME.",
"format": "string",
"name": "NTFY_AUTH_PASSWORD"
},
{
"description": "Per-request HTTP timeout in milliseconds.",
"format": "string",
"default": "15000",
"name": "NTFY_REQUEST_TIMEOUT_MS"
},
{
"description": "Max retry attempts for transient upstream failures (5xx, network, 429).",
"format": "string",
"default": "3",
"name": "NTFY_MAX_RETRIES"
},
{
"description": "When 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.",
"format": "string",
"default": "false",
"name": "NTFY_BLOCK_PRIVATE_HOSTS"
},
{
"description": "HTTP session model: 'auto', 'stateful', or 'stateless'. 'auto' resolves to 'stateful'. Keep it stateful — 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.",
"format": "string",
"default": "auto",
"name": "MCP_SESSION_MODE"
},
{
"description": "The hostname for the HTTP server.",
"format": "string",
"default": "127.0.0.1",
"name": "MCP_HTTP_HOST"
},
{
"description": "The port to run the HTTP server on.",
"format": "string",
"default": "3010",
"name": "MCP_HTTP_PORT"
},
{
"description": "The endpoint path for the MCP server.",
"format": "string",
"default": "/mcp",
"name": "MCP_HTTP_ENDPOINT_PATH"
},
{
"description": "Authentication mode to use: 'none', 'jwt', or 'oauth'.",
"format": "string",
"default": "none",
"name": "MCP_AUTH_MODE"
},
{
"description": "Sets the minimum log level for output (e.g., 'debug', 'info', 'warn').",
"format": "string",
"default": "info",
"name": "MCP_LOG_LEVEL"
},
{
"description": "Directory for file-based logs (Node only; ignored on Workers).",
"format": "string",
"default": "./logs",
"name": "LOGS_DIR"
},
{
"description": "Enable OpenTelemetry instrumentation (spans, metrics, completion logs).",
"format": "string",
"default": "false",
"name": "OTEL_ENABLED"
}
]
}
]
},
"_meta": {
"io.modelcontextprotocol.registry/official": {
"status": "active",
"statusChangedAt": "2026-08-22T19:39:24.403276Z",
"publishedAt": "2026-08-22T19:39:24.403276Z",
"updatedAt": "2026-08-22T19:39:24.403276Z",
"isLatest": true
}
}
}
Draft an Agent Plugin from this
An MCP server is raw capability: some tools, wired to something. An Agent Plugin is the packaging that says what job it does, what it leaves behind and where it stops. The prompt below carries this record and asks for the packaging; your own assistant writes it, and nothing here is sent anywhere.
MCP server
These are the publisher's own words, filed by them with the official MCP registry and mirrored here. This catalog did not read them from the publisher and has not run, called or installed anything.
The publisher's own address
https://github.com/cyanheads/ntfy-mcp-server
The address the publisher put in their registry record, printed as they wrote it. Nobody here has opened it.