npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@akito.sakuraba/notify-mcp

v0.1.0

Published

Cross-platform desktop notification MCP server (macOS / Windows / Linux). Replaces per-host hook setup for Claude Code / Claude Desktop.

Readme

notify-mcp

npm version CI License: MIT Node

🇯🇵 日本語の README は README.ja.md にあります。

Cross-platform desktop notification MCP server. One install, three OSes, five clients.

notify-mcp is a small Model Context Protocol server that exposes three tools — notify, list_sounds, play_sound — so any MCP client (Claude Code, Claude Desktop, Cursor, OpenAI Codex CLI, Google Antigravity, …) can pop a desktop notification on macOS, Windows, or Linux without per-host hook configuration.

  • Single npm package, runs over MCP stdio.
  • No native dependencies. Pure Node, uses each OS's built-in notifier:
    • macOSosascript (display notification)
    • Windows → PowerShell + WinRT ToastNotificationManager
    • Linuxnotify-send (libnotify)
  • Sound support: built-in OS system sounds, or any absolute .wav / .aiff path.
  • Built-in installer (notify-mcp install <client>) writes the right config block into each client — no more hand-editing JSON / TOML on every machine.
  • Security-conscious: argv-only subprocess invocation, env-var passthrough for untrusted strings, input sanitization, length caps, file-size cap.

Install

The package is intended to be run via npx so users do not have to install it globally.

# one-shot (recommended)
npx -y @akito.sakuraba/notify-mcp

# or install globally
pnpm add -g @akito.sakuraba/notify-mcp
npm  i  -g @akito.sakuraba/notify-mcp

One-command client setup

Instead of hand-editing each client's config, use the bundled installer:

# Install into a specific client (creates the config if missing, merges if existing).
npx -y @akito.sakuraba/notify-mcp install claude-code
npx -y @akito.sakuraba/notify-mcp install claude-desktop
npx -y @akito.sakuraba/notify-mcp install cursor
npx -y @akito.sakuraba/notify-mcp install codex
npx -y @akito.sakuraba/notify-mcp install antigravity

# Install into every supported client at once.
npx -y @akito.sakuraba/notify-mcp install --all

# Preview without writing.
npx -y @akito.sakuraba/notify-mcp install --all --dry-run

# Use a different server key inside mcpServers / mcp_servers.
npx -y @akito.sakuraba/notify-mcp install cursor --name desktop-notify

# Show every config path the installer would touch, and whether it exists.
npx -y @akito.sakuraba/notify-mcp list-clients

# Remove the entry later.
npx -y @akito.sakuraba/notify-mcp uninstall claude-code

The installer:

  1. Reads the existing config (JSON for Claude Code / Claude Desktop / Cursor / Antigravity, TOML for Codex).
  2. Backs it up to <path>.bak-YYYYMMDD-HHmmss before overwriting.
  3. Merges (or creates) the notify entry under mcpServers (or mcp_servers for Codex).
  4. Leaves every other field of your config untouched.

If a config file is malformed, the installer still writes a backup, then rewrites a clean file containing your notify entry.

Where each client stores its config

| Client | Path | Format | |---|---|---| | Claude Code (CLI) | ~/.claude.json | JSON | | Claude Desktop (macOS) | ~/Library/Application Support/Claude/claude_desktop_config.json | JSON | | Claude Desktop (Windows) | %APPDATA%\Claude\claude_desktop_config.json | JSON | | Claude Desktop (Linux, unofficial) | ~/.config/Claude/claude_desktop_config.json | JSON | | Cursor | ~/.cursor/mcp.json | JSON | | OpenAI Codex CLI | ~/.codex/config.toml (table [mcp_servers.<name>]) | TOML | | Google Antigravity | ~/.gemini/antigravity/mcp_config.json | JSON |

If you prefer to edit by hand, all five clients accept the same shape:

// JSON clients (claude-code, claude-desktop, cursor, antigravity)
{
  "mcpServers": {
    "notify": {
      "command": "npx",
      "args": ["-y", "@akito.sakuraba/notify-mcp"]
    }
  }
}
# OpenAI Codex CLI (~/.codex/config.toml)
[mcp_servers.notify]
command = "npx"
args = ["-y", "@akito.sakuraba/notify-mcp"]

After editing, restart the client. The tools notify, list_sounds, and play_sound will appear.


Tools

notify

Send a desktop notification.

| Field | Type | Required | Notes | |---|---|---|---| | title | string (1–256) | yes | Notification title shown to the user. | | message | string (1–4096) | yes | Notification body. | | urgency | "low" \| "normal" \| "critical" | no | Linux notify-send only. Ignored elsewhere. | | sound | string (1–1024) | no | "system:NAME" (see list_sounds) or an absolute file path. |

Returns:

{
  "delivered": true,
  "platform": "darwin",
  "method": "osascript",
  "sound": { "played": true, "method": "afplay" }
}

list_sounds

Return the platform's built-in system-sound names. Example output on macOS:

{
  "platform": "darwin",
  "sounds": ["Basso", "Blow", "Bottle", "Frog", "Funk", "Glass", "Hero",
             "Morse", "Ping", "Pop", "Purr", "Sosumi", "Submarine", "Tink"]
}
  • Windows: Beep, Asterisk, Exclamation, Hand, Question
  • Linux: a small libcanberra set (bell, message, complete, alarm, dialog-warning)

play_sound

Play a sound without sending a notification.

| Field | Type | Required | |---|---|---| | sound | string (1–1024): "system:NAME" or absolute path | yes |

Custom sound files

Absolute paths only. The file must exist, be a regular file, and be ≤ 10 MB. macOS uses afplay, Windows uses System.Media.SoundPlayer, Linux tries paplay then aplay.


Security

  • All subprocesses are spawned with execFile / spawnno shell, so argv values are never interpreted by /bin/sh / cmd.exe.
  • Windows PowerShell scripts are fixed-literal strings. Untrusted values are passed through environment variables, not interpolated.
  • macOS AppleScript values are escaped per AppleScript string-literal rules (\\\, "\").
  • Windows WinRT toast XML is escaped per XML rules (& < > " ').
  • Control characters (except TAB / LF / CR) are stripped from title and message.
  • Length caps: title 256, message 4096, sound spec 1024.
  • Sound file: absolute path required, size capped at 10 MB.
  • Notification subprocess timeout: 5 s. Sound subprocess timeout: 10 s.
  • The installer backs up every existing config before overwriting it.

Platform-specific notes

macOS

  • First-time display notification triggers a one-time permission grant for "Script Editor". After that, banners just work.
  • Sound files: .aiff, .wav, .mp3, etc. — anything afplay accepts.

Windows

  • Requires PowerShell 5.1+ (ships with Windows 10/11). No third-party PowerShell module needed.
  • Toast notifications appear in the Action Center.
  • Some Windows policies suppress toast for non-AppUserModelID processes; using npx -y @akito.sakuraba/notify-mcp is the simplest robust default.

Linux (Ubuntu / etc.)

  • Requires libnotify-bin (provides notify-send). Install: sudo apt install libnotify-bin.
  • For built-in system sounds: libcanberra-gtk-module / canberra-gtk-play.
  • For file sounds: pulseaudio-utils (paplay) or alsa-utils (aplay).

Development

pnpm install
pnpm typecheck    # tsc --noEmit
pnpm test         # vitest run (64 cases)
pnpm build        # tsc → dist/
pnpm smoke        # spawn dist/index.js and run a real notification flow

Repository layout

src/
  index.ts       # bin entrypoint (CLI + stdio transport)
  cli.ts         # argv parser, install/uninstall/list-clients/help/version
  install.ts     # client registry, JSON+TOML merge, backups
  server.ts      # MCP server + tool registrations
  notifier.ts    # cross-platform notification dispatcher
  sound.ts       # cross-platform sound player
  sanitize.ts    # input sanitization + per-platform escapes
  platform.ts    # OS detection
  errors.ts      # typed error helpers
test/
  *.test.ts      # vitest specs (sanitize / sound / notifier / server / cli / install)
scripts/
  smoke.mjs      # end-to-end smoke runner

License

MIT — see LICENSE.