Receive push notifications on your Mac from any source — servers, IoT devices, home automation, CI pipelines, or custom scripts. No account required, works with the public ntfy.sh service or your own self-hosted server.
ntfy-macos is a native macOS client that subscribes to ntfy topics and delivers rich notifications with SF Symbols, images, and interactive buttons. Trigger shell scripts automatically when messages arrive.
- Native macOS Notifications: Rich notifications with SF Symbols and local images
- Multi-Server Support: Connect to multiple ntfy servers simultaneously
- Emoji Tags: Automatic conversion of ntfy tags to emojis in notification titles
- Interactive Actions: Add custom buttons to notifications that execute scripts or open URLs
- Automatic Script Execution: Run shell scripts automatically when messages arrive
- Silent Notifications: Receive messages without displaying notification banners
- Secure Authentication: Store tokens securely in macOS Keychain
- Robust Reconnection: Handles network interruptions and sleep/wake gracefully
- Priority Mapping: Maps ntfy priority levels to macOS interruption levels (critical, time-sensitive)
- Menu Bar App: Runs in the menu bar with quick access to config and reload
- Live Config Reload: Configuration changes are detected and applied automatically
- Click to Open: Click notifications to open in browser (configurable per topic)
- Automatic Permission Request: Prompts for notification permission on first launch
# Add the tap
brew tap laurentftech/ntfy-macos
# Install
brew install ntfy-macos# Clone the repository
git clone https://github.com/laurentftech/ntfy-macos.git
cd ntfy-macos
# Build the app bundle
./build-app.sh
# Install
sudo cp -r .build/release/ntfy-macos.app /Applications/# Update via Homebrew
brew update && brew upgrade ntfy-macos
# Restart the service to apply the update
brew services restart ntfy-macosNote: Homebrew installation requires Xcode (not just Command Line Tools) because the app is built from source.
- Initialize Configuration
ntfy-macos initThis creates a sample configuration at ~/.config/ntfy-macos/config.yml.
- Edit Configuration
Edit the configuration file to add your servers and topics:
servers:
- url: https://ntfy.sh
topics:
- name: alerts
icon_symbol: bell.fill
actions:
- title: Acknowledge
type: script
path: /usr/local/bin/ack-alert.sh
- url: https://your-private-server.com
token: tk_yourtoken
topics:
- name: deployments
icon_path: /Users/you/icons/deploy.png- (Optional) Store Authentication Token in Keychain
ntfy-macos auth add https://ntfy.sh tk_yourtoken- Start the Service
# Using Homebrew services (recommended - auto-restarts on crash)
brew services start ntfy-macos
# Or run directly
ntfy-macos serveOn first launch, the app will automatically request notification permission.
The app runs in the menu bar with options to:
- Edit Config: Open config file in your default editor
- Show Config in Finder: Reveal config directory
- Reload Config: Apply configuration changes
- View Logs: Open log files (with automatic rotation)
- About: Credits and links
- Quit: Stop the service
- (Optional) Add to Launchpad
sudo ln -sf /usr/local/opt/ntfy-macos/ntfy-macos.app /Applications/The configuration file is located at ~/.config/ntfy-macos/config.yml:
servers:
# Public ntfy.sh server
- url: https://ntfy.sh
# token: tk_optional # Can also use Keychain
topics:
- name: alerts
icon_symbol: bell.fill
actions:
- title: Acknowledge
type: script
path: /usr/local/bin/ack-alert.sh
- title: Open Dashboard
type: view
url: "https://dashboard.example.com"
- name: deployments
icon_path: /Users/you/icons/deploy.png
auto_run_script: /usr/local/bin/deploy-handler.sh
# Private server
- url: https://your-private-server.com
token: tk_yourtoken
topics:
- name: monitoring
icon_symbol: server.rack
silent: true
auto_run_script: /usr/local/bin/monitor-handler.shurl(required): Server URL (e.g.,https://ntfy.sh)token(optional): Authentication token (can also be stored in Keychain)topics(required): List of topics to subscribe to
name(required): Topic name to subscribe toicon_symbol(optional): SF Symbol name (e.g.,bell.fill,server.rack)icon_path(optional): Absolute path to local image file (.png, .jpg)auto_run_script(optional): Script to execute automatically when message arrivessilent(optional): Iftrue, skip notification banner (useful for background automation)click_url(optional): Control what happens when clicking the notification:- Not set or
true: Opens{server_url}/{topic}in browser false: Disables click action"https://...": Opens custom URL
- Not set or
actions(optional): List of interactive buttons
title(required): Button labeltype(required):scriptorviewpath(required for script): Absolute path to script fileurl(required for view): URL to open when clicked
Note: Config-defined actions override any actions sent with the ntfy message. This lets you define your own local scripts/URLs that always appear, regardless of what the message sender specified. Message actions are only used when no config actions are defined for the topic.
Start the notification service:
ntfy-macos serveManage authentication tokens in Keychain:
# Add a token
ntfy-macos auth add <server-url> <token>
# List all stored tokens
ntfy-macos auth list
# Remove a token
ntfy-macos auth remove <server-url>Keychain tokens take priority over tokens in the YAML configuration.
Send a test notification (and request permissions):
ntfy-macos test-notify --topic <NAME>Create a sample configuration file:
ntfy-macos initDisplay help information:
ntfy-macos helpScripts receive the message body as the first argument ($1):
#!/bin/bash
MESSAGE="$1"
echo "Received: $MESSAGE"
# Your automation logic hereScripts are executed with an enhanced PATH:
/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
This ensures Homebrew-installed tools are available.
chmod +x /path/to/your/script.shScripts are only executed if explicitly configured in your local config.yml file. ntfy-macos will never execute arbitrary code from incoming messages.
Best practices:
- Only configure scripts that you trust and have reviewed
- Use absolute paths to scripts (e.g.,
/usr/local/bin/myscript.sh) - For public topics, avoid
auto_run_script— use interactive action buttons instead, so you can review notifications before triggering scripts - Keep your configuration file secure (
chmod 600 ~/.config/ntfy-macos/config.yml) - For sensitive automation, use a self-hosted ntfy server with authentication
ntfy priority levels map to macOS interruption levels:
- Priority 5 → Critical (bypasses Focus modes)
- Priority 4 → Time Sensitive (prominently displayed)
- Priority 1-3 → Active (normal notifications)
You can use any SF Symbol name for icons. Common examples:
bell.fill- Bell iconserver.rack- Server iconexclamationmark.triangle.fill- Warning iconcheckmark.circle.fill- Success iconenvelope.fill- Mail icongear- Settings icon
Browse all symbols using the SF Symbols app (free from Apple).
ntfy supports emoji shortcodes in the Tags field. When you send a message with tags like warning or fire, ntfy-macos automatically converts them to emojis and prepends them to the notification title.
Example using curl:
curl -H "Tags: warning,fire" -H "Title: Alert" -d "Server is down" https://ntfy.sh/mytopicThis displays as:
Common tags: warning (fire (🔥), +1 (👍), skull (💀), bell (🔔), rocket (🚀), check (✅), etc.
-
Check notification permissions:
- System Settings → Notifications → ntfy-macos
- Ensure notifications are enabled
-
Test notifications:
ntfy-macos test-notify --topic test
- Verify server URL in configuration
- Check authentication token
- Review logs:
# View logs (same location for manual and brew services) cat ~/.local/share/ntfy-macos/logs/ntfy-macos.log # Or follow in real-time tail -f ~/.local/share/ntfy-macos/logs/ntfy-macos.log
-
Verify script is executable:
chmod +x /path/to/script.sh
-
Test script manually:
/bin/sh /path/to/script.sh "test message" -
Check script output in service logs
servers:
# Public ntfy.sh
- url: https://ntfy.sh
topics:
- name: public-alerts
icon_symbol: bell.fill
# Self-hosted server
- url: https://ntfy.mycompany.com
token: tk_secret
topics:
- name: deployments
icon_symbol: arrow.up.circle.fill
actions:
- title: View Status
type: view
url: "https://ci.mycompany.com"
- title: Rollback
type: script
path: /usr/local/bin/rollback.shservers:
- url: https://ntfy.home.local
topics:
- name: homeassistant
icon_path: /Users/you/icons/ha.png
actions:
- title: Open Home Assistant
type: view
url: "homeassistant://"servers:
- url: https://ntfy.sh
topics:
- name: background-jobs
silent: true
auto_run_script: /usr/local/bin/process-job.shservers:
- url: https://ntfy.sh
topics:
- name: yt-dlp-releases
icon_symbol: arrow.down.circle.fill
click_url: https://github.com/yt-dlp/yt-dlp/releases
auto_run_script: /usr/local/bin/update-yt-dlp.sh- Swift 6: Modern Swift with strict concurrency
- URLSession: Native streaming JSON support
- UserNotifications: Rich macOS notifications
- Security Framework: Keychain integration
- Yams: YAML parsing
- Foundation & AppKit: Core macOS frameworks
Contributions are welcome! Please open issues or pull requests on GitHub.
MIT License
This project is a third-party client for ntfy, created by Philipp C. Heckel. ntfy is a simple, open-source pub-sub notification service that makes it easy to send push notifications to your devices.
- ntfy - Simple pub-sub notification service by Philipp C. Heckel
- ntfy-android - Official Android app
- ntfy-ios - Official iOS app
For bugs and feature requests, please open an issue on GitHub.
