simple-notify-mcp
Provides text-to-speech capabilities using ElevenLabs via the FAL provider.
Provides text-to-speech capabilities using OpenAI's TTS models (e.g., gpt-4o-mini-tts).
Enables sending notifications, photos, and reading incoming messages via a Telegram bot.
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., "@simple-notify-mcpsay 'build complete'"
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.
simple-notify-mcp
Model Context Protocol (MCP) server for Codex and Claude Code with text-to-speech (TTS) and Telegram notifications.
Tools
simple_notify_status: always available; returns capabilities, missing config, and setup-web availability/running state.simple_notify_setup_web_start: available when--enable-setup-webis set; starts the local setup web UI on demand and returns the current tokenized URL.simple_notify_setup_web_stop: available when--enable-setup-webis set; stops the local setup web UI when no longer needed.tts_say: text-only input; async by default, uses configured provider (openai,fal-minimax,fal-elevenlabs) with macOSsayfallback.telegram_notify: available when Telegram bot token + chat id are configured; supportsparse_mode(plain,markdown,html) and returnshasUnreadIncomingfrom a non-advancing unread peek.telegram_send_photo: available when Telegram bot token + chat id are configured; sends local image files (jpg,jpeg,png,webp,gif,bmp) with optional caption andparse_mode.telegram_read_incoming: available when Telegram bot token + chat id are configured; reads incoming updates for configured chat.telegram_read_media: available when Telegram bot token + chat id are configured; reads image updates and can return MCP image content blocks.
Telegram formatting quick examples:
telegram_notify({ "text": "**Build done**. [Diff](https://example.com)", "parse_mode": "markdown" })telegram_send_photo({ "filePath": "/tmp/plan.png", "caption": "<b>Plan snapshot</b>", "parse_mode": "html" })Markdown mode supports a safe subset:
**bold**,*italic*,_italic_,~~strike~~,`code`,[text](https://url), and#headings.HTML mode is validated and allows only Telegram-safe tags; links must be
https://orhttp://.If Markdown entity parsing fails on Telegram side, the server retries once with plain text for reliability.
Telegram limits are enforced before send (message: 4096 chars, caption: 1024 chars).
Related MCP server: Rime MCP
Install (npx)
1) Recommended: agent-managed setup web
Use this if you want easy reconfiguration anytime without keeping an HTTP port open all the time.
codex mcp remove simple-notify
codex mcp add simple-notify -- \
npx -y simple-notify-mcp@latest \
--enable-setup-webAsk your agent (Codex / Claude Code / another agent) to run simple_notify_status, call simple_notify_setup_web_start if needed, and then send you setupWeb.url.
2) Minimal runtime: no setup web
Use this if config is already done and you do not want the setup server running.
codex mcp remove simple-notify
codex mcp add simple-notify -- npx -y simple-notify-mcp@latestIf you need to change provider/keys later, switch back to mode 1.
Optional: pass API keys via env when adding:
codex mcp add simple-notify -- \
--env OPENAI_API_KEY="$OPENAI_API_KEY" \
--env FAL_KEY="$FAL_KEY" \
-- npx -y simple-notify-mcp@latest \
--enable-setup-web \
--setup-port 21420Optional legacy behavior:
add
--setup-web-autostartif you explicitly want the setup web server to bind during MCP startup
Install (Claude Code)
1) Recommended: agent-managed setup web
Use this if you want easy reconfiguration anytime without keeping an HTTP port open all the time.
claude mcp remove simple-notify
claude mcp add --transport stdio simple-notify -- \
npx -y simple-notify-mcp@latest \
--enable-setup-webAsk Claude Code to run simple_notify_status, call simple_notify_setup_web_start if needed, and then share setupWeb.url.
2) Minimal runtime: no setup web
Use this if config is already done and you do not want the setup server running.
claude mcp remove simple-notify
claude mcp add --transport stdio simple-notify -- npx -y simple-notify-mcp@latestIf you need to change provider/keys later, switch back to mode 1.
Optional: pass API keys via env when adding:
claude mcp add --transport stdio \
--env OPENAI_API_KEY="$OPENAI_API_KEY" \
--env FAL_KEY="$FAL_KEY" \
simple-notify -- \
npx -y simple-notify-mcp@latest \
--enable-setup-webOptional legacy behavior:
add
--setup-web-autostartif you explicitly want the setup web server to bind during MCP startup
How To Use
Think of simple-notify-mcp as your "agent communication layer":
voice message when work is done (
tts_say)Telegram ping when work is done or while work is in progress (
telegram_notify)optional Telegram inbox reads (
telegram_read_incoming,telegram_read_media)
Typical flow
Start with setup web enabled (recommended mode above). This exposes setup-web start/stop tools, but does not open a local port yet.
Ask your agent for setup link:
"Run
simple_notify_status. If setup web is not running, callsimple_notify_setup_web_startand send mesetupWeb.url."
Open the link, set keys/provider/chat id, then click Save. In some clients, you may need to restart the agent process after adding keys so all tools become available.
When you are done configuring, ask your agent to call
simple_notify_setup_web_stop.After that, ask your agent to always:
speak on completion
send Telegram on completion
send Telegram updates during long tasks
What to ask your agent (examples)
Setup:
"Please configure simple-notify and give me the setup link."
Completion behavior:
"When you finish a task, call TTS and Telegram notify."
Long task behavior:
"If task is long, notify me on progress milestones and before escalation requests."
Read incoming Telegram:
"If notify result says unread incoming, read it and continue."
TTS/Notification style tips (easy and practical)
You can tune:
language (EN/RU/etc)
tone (calm/energetic/formal/casual)
emotion (neutral/cheerful/serious)
slang level
pacing
Examples:
EN calm:
Task complete. Build passed. I left a short summary.
EN upbeat:
Done. All checks are green.
RU neutral:
Готово. Проверки прошли успешно.
RU casual:
Запилил фичу, всё пашет, тесты зеленые.
Copy-Paste For AGENTS.md / CLAUDE.md
The easiest way to tune agent behavior is to add explicit tool-usage instructions to your agent config. You can copy-paste this block and adjust it as needed:
If user uses simple-notify-mcp:
1) Setup flow
- Call simple_notify_status.
- If setupWeb.enabled=true and setupWeb.running=false, call simple_notify_setup_web_start.
- If setupWeb.running=true, return setupWeb.url to user.
- When setup is finished or user asks to close it, call simple_notify_setup_web_stop.
- If setup web is disabled, tell user to run MCP with --enable-setup-web.
2) Completion flow
- On task completion, call tts_say with a short completion message.
- Then call telegram_notify with a short completion summary.
- If telegram_notify returns hasUnreadIncoming=true, optionally call telegram_read_incoming.
3) Long-task flow
- For long tasks, send milestone progress via telegram_notify.
- Send a notify before asking user for escalation/approval.
- Keep updates useful (no spam).
4) Safety
- Never include secrets/tokens in TTS or Telegram messages.Configuration Schema
Config file path (default):
$XDG_CONFIG_HOME/simple-notify-mcp/config.jsonor
~/.config/simple-notify-mcp/config.json
Env key precedence:
OPENAI_API_KEYoverrideskeys.openai.apiKeyFAL_KEY/FAL_API_KEYoverridekeys.fal.apiKey
{
"tts": {
"provider": "openai",
"params": {
"openai": {
"model": "gpt-4o-mini-tts",
"voice": "alloy",
"speed": 1,
"responseFormat": "mp3",
"instructions": "Speak calmly and clearly."
},
"falMinimax": {
"voiceId": "Wise_Woman",
"speed": 1,
"vol": 1,
"pitch": 0,
"emotion": "neutral",
"englishNormalization": false,
"languageBoost": "auto",
"outputFormat": "url",
"audioFormat": "mp3",
"audioSampleRate": 32000,
"audioChannel": 1,
"audioBitrate": 128000,
"normalizationEnabled": true,
"normalizationTargetLoudness": -18,
"normalizationTargetRange": 8,
"normalizationTargetPeak": -0.5,
"voiceModifyPitch": 0,
"voiceModifyIntensity": 0,
"voiceModifyTimbre": 0,
"pronunciationToneList": [
"燕少飞/(yan4)(shao3)(fei1)"
]
},
"falElevenlabs": {
"voice": "Rachel",
"stability": 0.5,
"similarityBoost": 0.75,
"style": 0,
"speed": 1,
"timestamps": false,
"languageCode": "en",
"applyTextNormalization": "auto"
}
}
},
"telegram": {
"chatId": "123456789"
},
"keys": {
"openai": {
"apiKey": "sk-..."
},
"fal": {
"apiKey": "fal_..."
},
"telegram": {
"botToken": "123:ABC"
}
},
"misc": {
"ttsAsyncByDefault": true
}
}MiniMax voices available in setup UI:
Wise_Woman,Friendly_Person,Inspirational_girl,Deep_Voice_Man,Calm_Woman,Casual_Guy,Lively_Girl,Patient_Man,Young_Knight,Determined_Man,Lovely_Girl,Decent_Boy,Imposing_Manner,Elegant_Man,Abbess,Sweet_Girl_2,Exuberant_Girl
Setup Web UI Flags (disabled by default)
Flags:
--enable-setup-web(default off)--setup-web-autostart(default off; optional legacy eager-start behavior)--setup-host(default127.0.0.1; non-loopback values are clamped to127.0.0.1)--setup-port(default21420)--setup-token(optional; if omitted, generated per run)
Behavior:
--enable-setup-webexposes the on-demand setup-web tools but does not bind a port by itselfsimple_notify_setup_web_startstarts the local setup server only when the agent needs itsimple_notify_setup_web_stopcloses the local setup server when you are done--setup-web-autostartrestores eager startup if you explicitly want the previous behaviorlocal bind only
if
--setup-portis occupied, server uses the next free local portsetup URL includes the current run token query parameter
if
--setup-tokenis omitted, each fresh start generates a new tokenuse
simple_notify_statusto discover whether setup web is running, plussetupWeb.urlandmissingConfig
Tool Contracts
simple_notify_status
Input:
{}simple_notify_setup_web_start
Input:
{}Output notes:
starts setup web only when
--enable-setup-webis setreturns current setup-web state, including
setupWeb.urlif already running, returns the existing URL without rebinding
simple_notify_setup_web_stop
Input:
{}Output notes:
safe to call repeatedly
returns
wasRunning=falsewhen setup web was already stopped
tts_say
Input:
{ "text": "Job done" }Output notes:
default mode is async (
misc.ttsAsyncByDefault=true), so tool returns immediately after queuing speechset
misc.ttsAsyncByDefault=falsein setup web Misc tab for blocking/sync behavior
telegram_notify
Input:
{ "text": "Job done" }Output notes:
returns
{ "accepted": true }by defaultadds
hasUnreadIncoming: trueonly when unread messages are detectedperforms a non-advancing unread peek (
limit=6) before returning
telegram_read_incoming
Input:
{
"limit": 20,
"timeoutSeconds": 0,
"advanceCursor": true
}Output notes:
reads updates filtered to configured
telegram.chatIdtracks cursor in memory for the current server run
set
advanceCursor=falseto peek without moving cursor
telegram_read_media
Input:
{
"limit": 20,
"timeoutSeconds": 0,
"advanceCursor": true,
"includeData": true,
"maxImages": 1,
"maxBytesPerImage": 8000000
}Output notes:
only image media is returned (text-only updates are ignored)
when
includeData=true, tool can return MCPimagecontent blocks (base64 + mime type)large files are skipped based on
maxBytesPerImagemedia cursor is tracked in memory for current server run
Self-test
npm run self-test -- --text "Task complete. Build passed and your results are ready."Disable one side:
npm run self-test -- --no-tts
npm run self-test -- --no-telegramNotes
tts_sayis text-only; provider/model/voice/etc are server config.tts_sayruns async by default; switch in setup webMisctab if you need sync mode.OpenAI and FAL network errors fall back to macOS
saywhen available.OpenAI
responseFormat=pcmis not directly playable by this local player path.Runtime config is reloaded from disk before tool calls, so manual config edits are picked up without restarting the MCP process.
Available Tools
2 toolssimple_notify_statusSimple Notify statusA
Read runtime status: setup-web availability and running state, missing config, active provider, async mode, and Telegram cursor state.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite no annotations, the description clearly indicates a read-only operation ('Read runtime status') and enumerates the specific status items returned. It does not disclose error behavior but is sufficient for a simple read tool.
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?
A single sentence that front-loads the core purpose ('Read runtime status') and then lists specifics. No wasted words.
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?
For a tool with no parameters, no output schema, and a distinctly different sibling, the description fully covers what the tool does and what it returns.
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?
The input schema has no parameters (0 param, 100% coverage). The description adds context by listing the status fields, providing value beyond the schema.
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?
The description starts with 'Read runtime status', clearly stating the action and resource. It lists specific status fields (setup-web availability, running state, etc.), distinguishing it from the sibling tool 'tts_say'.
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 is provided on when to use this tool vs. the sibling 'tts_say'. The description assumes the agent understands from context, but no explicit direction is given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tts_saySpeak textA
Speak a short message using configured provider; async by default and playback is queued (no overlap). Falls back to system TTS when needed.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description covers async behavior, queued playback, no overlap, and fallback to system TTS, adding meaningful context beyond the schema.
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?
Two sentences, front-loaded with purpose, every word earns its place. No unnecessary information.
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?
For a simple 1-param tool with no output schema or annotations, the description covers key behaviors. Lacks info on response or error handling but sufficient for typical use.
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?
The single parameter 'text' is self-explanatory, and 'short message' adds slight context but no additional constraints or format details beyond the schema.
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?
The description clearly states the tool speaks text using a configured provider, distinguishing it from the sibling tool 'simple_notify_status' which is for visual 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?
Implied usage for short messages, async, and queued playback is described, but no explicit when-not-to-use or alternatives beyond the sibling.
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.1.12- First observed
simple_notify_status - First observed
tts_say
TDQS
The two tools serve entirely different purposes: one provides runtime status information, the other performs speech output. There is no overlap or ambiguity in their functionality.
Both tools use underscored names, but one follows a noun-based pattern ('simple_notify_status') while the other uses a verb (‘tts_say’). The prefixes also differ, making the naming pattern inconsistent.
With only 2 tools, the server feels thin for a 'notification' domain. While the tools cover basic status display and text-to-speech, more tools (e.g., configuration, provider management) would be expected.
The tool set covers status checking and speech output, but lacks tools for configuring providers, managing queues, or handling errors. The domain is narrowly scoped, so the gaps are notable but not severe.
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
Telegram bridge for your MCP-compatible agent. Bidirectional, no LLM in our stack.
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
Share one project context across ChatGPT, Claude, Telegram and any MCP client.
AI voice generation: text-to-speech and voice cloning from any MCP client.
Related MCP Servers
- AlicenseDqualityCmaintenanceProvides text-to-speech capabilities through the Model Context Protocol, allowing applications to easily integrate speech synthesis with customizable voices, adjustable speech speed, and cross-platform audio playback support.110MIT
- AlicenseAqualityDmaintenanceA Model Context Protocol server that enables AI models to generate and play high-quality text-to-speech audio through your device's native audio system using Rime's voice synthesis API.18127-
- FlicenseNot gradedqualityDmaintenanceExposes a text-to-speech announcement tool for the CastleCall home PA system on Raspberry Pi. It enables users to broadcast voice messages using local Piper or cloud-based ElevenLabs providers through the Model Context Protocol.-
- AlicenseNot gradedqualityDmaintenanceEnables LLMs to send notifications and receive responses via Telegram.364MIT
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/pintar-team/simple-notify-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server