mcp-os-notifications
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-os-notificationsrun the backup script and notify me when finished"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-os-notifications
An MCP server that lets LLM agents dispatch native OS notifications when a task finishes. If you tell your agent, "do this and notify me when done", it will.
Works with Claude Code, Claude Desktop, OpenCode, or any other MCP client.
What it does
Exposes a single MCP tool:
dispatch_os_notification.Detects when you ask to be notified (
"notify me when done","ping me when finished", etc.).Sends a native desktop notification once the agent finishes its work.
Task tokens: reuse a token to update an existing notification instead of spamming new ones. Great for progress updates.
Mobile bridge: optionally push to
ntfy.sh, Telegram, or Pushover when you are away from your desk.Quiet hours: suppress non-critical desktop notifications during configured hours; critical ones still come through.
Cross-platform: Linux (DBus/FreeDesktop notifications), macOS, Windows.
Related MCP server: MCP Discord Agent Communication
How it works
The MCP server runs locally as a
stdiosubprocess of your agent.Project-level agent instructions (
.claude/CLAUDE.md,skills/notify-when-done.md) teach the agent when to call the tool.When the work is done, the agent calls
dispatch_os_notification(title, message).The server uses the native notification backend on your OS to show the toast/banner.
Requirements
Python 3.10+
uv (recommended for development) or
pipA notification daemon on Linux (e.g.,
mako,dunst, GNOME/KDE built-in)
Install on a new machine
Option A: clone + uv (recommended for development)
git clone https://github.com/ekomac/mcp-os-notifications.git
cd mcp-os-notifications
uv sync
uv run mcp-os-notificationsOption B: clone + pip
git clone https://github.com/ekomac/mcp-os-notifications.git
cd mcp-os-notifications
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
mcp-os-notificationsOption C: install from GitHub without cloning
python3 -m pip install git+https://github.com/ekomac/mcp-os-notifications.git
mcp-os-notificationsNote: If you install from PyPI in the future (once published), the command is simply
pip install mcp-os-notifications.
Verify the server starts
The server runs over stdio and waits for MCP messages. Press Ctrl+C to stop.
# If using uv in the repo
uv run mcp-os-notifications
# If installed globally with pip
mcp-os-notificationsAdd to Claude Code
Claude Code reads .mcp.json at project scope or ~/.claude.json at user scope.
Project scope (recommended per repo)
If you open this repository directly in Claude Code, the bundled .mcp.json already
registers the server. Just ask:
Build a quick Python script that prints the current time and notify me when done.To use it in a different project while keeping the source in this repo, copy the
snippet below into that project's .mcp.json and replace /ABSOLUTE/PATH/TO/mcp-os-notifications:
{
"mcpServers": {
"os-notifications": {
"type": "stdio",
"command": "uv",
"args": [
"--directory",
"/ABSOLUTE/PATH/TO/mcp-os-notifications",
"run",
"mcp-os-notifications"
]
}
}
}User scope (global for all projects)
If you installed globally with pip or uv tool, add the command directly:
claude mcp add --transport stdio os-notifications mcp-os-notificationsOr if you keep the cloned repo:
claude mcp add --transport stdio os-notifications uv --directory /ABSOLUTE/PATH/TO/mcp-os-notifications run mcp-os-notificationsCheck that it loaded
claude mcp listYou should see os-notifications with the dispatch_os_notification and notify_user
tools.
Add to Claude Desktop
Add the server to claude_desktop_config.json:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%AppData%\Claude\claude_desktop_config.jsonLinux:
~/.config/Claude/claude_desktop_config.json(or$XDG_CONFIG_HOME/Claude/claude_desktop_config.json)
If installed globally with pip:
{
"mcpServers": {
"os-notifications": {
"command": "mcp-os-notifications"
}
}
}If using the cloned repo with uv:
{
"mcpServers": {
"os-notifications": {
"command": "uv",
"args": [
"--directory",
"/ABSOLUTE/PATH/TO/mcp-os-notifications",
"run",
"mcp-os-notifications"
]
}
}
}Add to OpenCode
OpenCode supports MCP servers via stdio. Add this to your OpenCode MCP configuration:
{
"mcpServers": {
"os-notifications": {
"command": "mcp-os-notifications"
}
}
}If you run from the cloned repo instead:
{
"mcpServers": {
"os-notifications": {
"command": "uv",
"args": [
"--directory",
"/ABSOLUTE/PATH/TO/mcp-os-notifications",
"run",
"mcp-os-notifications"
]
}
}
}Then copy the skill reference so OpenCode knows when to use the tool:
mkdir -p ~/.config/opencode/skills/notify-when-done
cp skills/notify-when-done.md ~/.config/opencode/skills/notify-when-done/SKILL.mdOther MCP clients
Any client that supports stdio MCP servers can use one of these commands:
# Installed globally
mcp-os-notifications
# From the cloned repo with uv
uv --directory /ABSOLUTE/PATH/TO/mcp-os-notifications run mcp-os-notifications
# From the cloned repo with pip venv
.venv/bin/mcp-os-notificationsTool schema
The server exposes two identical tools; notify_user is a convenience alias for
dispatch_os_notification.
dispatch_os_notification
Parameter | Type | Required | Default | Description |
| string | yes | — | Short notification title |
| string | yes | — | Notification body |
| string | no |
|
|
| boolean | no |
| Play an audible alert |
| integer | no |
| Auto-dismiss after N seconds; |
| string | no |
| Stable id; reusing it replaces the previous notification |
| boolean | no |
| Also push to configured mobile backends |
Example tool calls
Simple completion notification
{
"title": "Build finished",
"message": "All 42 tests passed.",
"urgency": "normal",
"sound": true
}Progress updates with a token
{
"title": "Syncing files...",
"message": "25 of 100 files processed",
"token": "file-sync-job"
}Then later with the same token:
{
"title": "Sync complete",
"message": "All 100 files uploaded",
"token": "file-sync-job"
}Critical + mobile push
{
"title": "Build failed",
"message": "Production deployment failed on the test stage.",
"urgency": "critical",
"mobile": true
}Mobile bridge
The server can push notifications to mobile/remote backends alongside the desktop toast. This is useful when you are away from the computer. Configure one or more backends via environment variables.
ntfy.sh
export MCP_OS_NOTIFICATIONS_NTFY_URL="https://ntfy.sh/my-secret-topic"You can also use a self-hosted ntfy instance:
export MCP_OS_NOTIFICATIONS_NTFY_URL="https://ntfy.example.com/alerts"Telegram
export MCP_OS_NOTIFICATIONS_TELEGRAM_BOT_TOKEN="123456:ABC..."
export MCP_OS_NOTIFICATIONS_TELEGRAM_CHAT_ID="123456789"Pushover
export MCP_OS_NOTIFICATIONS_PUSHOVER_USER_KEY="uQiRz..."
export MCP_OS_NOTIFICATIONS_PUSHOVER_APP_TOKEN="azGDO..."Usage
Once a backend is configured, set mobile: true in the tool call. The server will
notify every configured backend in parallel.
Passing environment variables to the server
Mobile and quiet-hours settings are read from the environment of the MCP server process. How you set them depends on the client:
Claude Code: environment variables are inherited from the shell where you launched
claude, or you can set them in the.mcp.jsonenvblock:{ "mcpServers": { "os-notifications": { "type": "stdio", "command": "mcp-os-notifications", "env": { "MCP_OS_NOTIFICATIONS_NTFY_URL": "https://ntfy.sh/my-topic" } } } }Claude Desktop: use the
envblock inclaude_desktop_config.json:{ "mcpServers": { "os-notifications": { "command": "mcp-os-notifications", "env": { "MCP_OS_NOTIFICATIONS_NTFY_URL": "https://ntfy.sh/my-topic" } } } }OpenCode / other clients: set the variables in the shell before launching the client, or use the client's equivalent MCP environment settings.
Quiet hours
Suppress non-critical desktop notifications during a configured time window. Critical notifications still come through.
export MCP_OS_NOTIFICATIONS_QUIET_START="22:00"
export MCP_OS_NOTIFICATIONS_QUIET_END="07:00"The window can span midnight (e.g., 22:00 to 07:00). Mobile pushes are not affected by quiet hours.
See Passing environment variables to the server above for how to expose these variables to the MCP server process.
Project structure
.
├── src/mcp_os_notifications/
│ ├── server.py # MCP server and tools
│ ├── mobile.py # Mobile/remote notification backends
│ └── quiet_hours.py # Do-not-disturb logic
├── skills/notify-when-done.md # Generic agent skill reference
├── .claude/CLAUDE.md # Claude Code project instructions
├── .mcp.json # Project-scoped Claude Code MCP config
├── .github/workflows/ci.yml # GitHub Actions CI
├── Makefile # Common dev commands
├── pyproject.toml
├── README.md
└── LICENSEDevelopment
A Makefile is provided for convenience:
make install # uv sync
make test # uv run pytest
make lint # uv run ruff check .
make run # uv run mcp-os-notifications
make clean # remove caches, venv, build artifactsCI runs on GitHub Actions for Python 3.10–3.14.
Troubleshooting
Linux: "DBUS_SESSION_BUS_ADDRESS not set"
The server tries to auto-detect the session bus, but if that fails, make sure your
notification daemon is running (e.g., mako, dunst, swaync). You can also set:
export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$(id - u)/bus"No notification appears
Check that your OS has a notification service enabled.
Try running the server directly with verbose logging:
MCP_OS_NOTIFICATIONS_LOG_LEVEL=DEBUG uv run mcp-os-notificationsCheck your agent's tool call output for the
successflag.
Publishing / adding to the MCP ecosystem
There is no "Anthropic marketplace" for MCP servers, but there are official and community registries:
Registry | How to submit |
Official registry. Use | |
Anthropic-reviewed connectors. Submit via the directory form for remote servers or desktop extensions. | |
Third-party MCP registry/marketplace. | |
Indexes the official MCP Registry automatically. |
modelcontextprotocol/servers no longer accepts third-party listings.
Prior art
This is not the first MCP notification server. Similar projects exist, e.g.:
This repo focuses on:
A clean, minimal Python implementation using
desktop-notifier.Ready-to-use agent skill references for Claude Code and OpenCode.
A project-scoped
.mcp.jsonso Claude Code works out of the box.Task tokens to replace notifications instead of spamming.
Mobile bridge to ntfy.sh, Telegram, and Pushover.
Quiet hours to respect do-not-disturb time windows.
License
MIT — see LICENSE.
Available Tools
2 toolsdispatch_os_notificationA
Dispatch a native OS notification.
Use this tool whenever the user asks to be notified, for example:
"notify me when done"
"ping me when finished"
"let me know when you're done"
"send me a notification when complete"
Args: title: Short title for the notification (e.g. "Task finished"). message: Body text explaining what happened (e.g. "Your download is ready"). urgency: Notification priority: "low", "normal" (default), or "critical". sound: Whether to play an audible alert alongside the notification. timeout: Number of seconds before the notification auto-dismisses. -1 means use the OS default. token: Optional stable identifier for this notification. Reusing the same token replaces the previous notification instead of creating a new one. mobile: Also send to configured mobile backends (ntfy.sh, Telegram, Pushover).
Returns: A dictionary with the scheduled notification id, success flag, and details of any mobile dispatch attempts.
| Name | Required | Description | Default |
|---|---|---|---|
| sound | No | ||
| title | Yes | ||
| token | No | ||
| mobile | No | ||
| message | Yes | ||
| timeout | No | ||
| urgency | No | normal |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. Explains behavior: token replacement, mobile dispatch, return value. Could mention permission needs, but overall adequate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with intro, usage examples, Args bullet list, and Returns. No fluff; every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 7 params (2 required), no annotations, and presence of output schema, the description covers parameters, return value, and use cases comprehensively.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but the description includes a detailed Args section explaining each parameter (title, message, urgency, sound, timeout, token, mobile) with context and defaults, fully compensating.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Starts with 'Dispatch a native OS notification' – a specific verb and resource. Clearly distinguishes from sibling 'notify_user' by providing usage examples for OS notifications.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use: 'whenever the user asks to be notified' with concrete examples. Does not explicitly mention when not to use, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notify_userC
Alias for dispatch_os_notification. Send a native OS notification.
| Name | Required | Description | Default |
|---|---|---|---|
| sound | No | ||
| title | Yes | ||
| token | No | ||
| mobile | No | ||
| message | Yes | ||
| timeout | No | ||
| urgency | No | normal |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided; description lacks side effects, permissions, or behavioral details beyond the basic action of sending a notification.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Extremely brief but under-specifies the tool; given 7 parameters and no annotations, more detail is needed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Incomplete for a tool with 7 parameters and no annotations; lacks usage context, prerequisites, and output implications.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% and description adds no explanation for parameters like sound, token, mobile, timeout, urgency, which are not self-evident.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it sends a native OS notification, but fails to differentiate from sibling tool dispatch_os_notification, explicitly calling itself an alias.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool vs the sibling; implies they are interchangeable but provides no criteria for selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
2 tool updates
v0.2.0- First observed
dispatch_os_notification - First observed
notify_user
TDQS
The two tools are actually the same; notify_user is explicitly an alias for dispatch_os_notification. This creates complete overlap and makes it impossible for an agent to distinguish between them.
Both tool names follow a verb_noun pattern (dispatch_os_notification, notify_user), so the naming convention is consistent. However, the presence of a duplicate alias reduces the overall pattern's clarity.
With only 2 tools (one of which is a duplicate), the count is minimal but still reasonable for a focused notification dispatch server. It is not excessive, but could be consolidated into a single tool.
The server covers the core functionality of dispatching OS notifications with configurable options (urgency, sound, timeout, mobile). However, it lacks any management or querying capabilities, which could be considered a minor gap.
Maintenance
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
Push notifications for AI agents - send instant iPhone notifications from any MCP client.
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
MCP server connecting AI agents to 100+ apps (Gmail, Slack, Notion, GitHub) via one-click OAuth.
- DazbenchOAuthapp.dazbench
Task management your AI agents can actually run. One line becomes a context-ready task over MCP.
Related MCP Servers
- AlicenseBqualityFmaintenanceA Model Context Protocol service that sends desktop notifications and alert sounds when AI agent tasks are completed, integrating with various LLM clients like Claude Desktop and Cursor.154MIT
- AlicenseNot gradedqualityDmaintenanceAn MCP server that enables AI agents to send notifications and request user input via Discord during long-running tasks. It allows users to remotely interact with their AI assistants and provide feedback through the Discord messaging platform.262MIT
- AlicenseAqualityDmaintenanceMCP server that lets Claude Desktop or another MCP client trigger macOS sound and visual notifications through a task_status tool.116MIT
- AlicenseNot gradedqualityCmaintenanceA lightweight MCP server that enables sending native desktop notifications with action buttons and text replies, compatible with any MCP client.161MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/ekomac/mcp-os-notifications'
If you have feedback or need assistance with the MCP directory API, please join our Discord server