Model Context Protocol (MCP) server for text-to-speech and Telegram notifications in Codex and Claude Code.
Simple Notify MCP provides 8 tools with generally clear purposes and reasonable descriptions. However, there are significant gaps in parameter documentation, missing output schema documentation, and inconsistent schema completeness. Tool naming is action-verb based (notify, speak, status, setup_web_*) which is good. Descriptions are present but vary in quality, some lack operational detail. Parameter schemas are defined using Zod with type constraints and enums where appropriate, but descriptions for individual parameters are sparse in the visible source. No tool annotation hints (readOnlyHint/destructiveHint/idempotentHint) are present. Error handling exists but lacks recovery guidance. The composition is reasonable (each tool has one clear job), but output schemas are not documented for LLM consumption.
Send a short notification message to Telegram.
Send an image from local file path to Telegram; supports optional caption.
Read incoming Telegram updates for configured chat. Advances in-memory cursor by default; set advanceCursor=false to peek.
Read image updates for configured chat; can return MCP image content. Advances in-memory media cursor by default.
Start the local setup web UI when configuration is needed. Returns the current tokenized local URL; if already running, returns the existing URL.
Stop the local setup web UI when it is no longer needed. Safe to call repeatedly.
Speak a short message using configured provider; async by default and playback is queued (no overlap). Falls back to system TTS when needed.
Output schemas not documented. Tools return JSON responses via okResponse() and errorResponse(), but LLMs have no way to know the structure of returned fields (e.g., what does status return?). This forces agents to guess field names.
Parameter descriptions missing for some input fields. The 'speak' tool has minimal description (only 'Text to speak'). The 'status' tool accepts empty object but no explanation of what fields are returned. This violates the pattern that every parameter needs a description.
No tool annotations. The tools lack readOnlyHint, destructiveHint, and idempotentHint attributes. This is critical for tools with side effects: 'notify', 'notify_photo', 'speak', 'setup_web_start', 'setup_web_stop' should be marked as WRITE; 'notify_read' and 'notify_read_media' have state mutations (cursor advancement) that agents need to understand.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-21 | D | 50 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 38 | - | v1 |
Get server status, configuration paths, TTS provider info, job counts, cursor positions, and missing config fields.
Error responses lack recovery guidance. The errorResponse() function returns only the error message as plain text. LLMs receive no indication of whether the error is retryable, user-fixable, or fatal, nor are they offered alternatives or next steps.
notify_read and notify_read_media have dual behavior (can advance or peek at cursor). This is a parameter relationship that must be documented explicitly in descriptions. Currently only the advanceCursor param has a hint; the interaction between state mutations and multi-call sequences is unclear.
Telegram token and chat ID are server-side secrets (environment variables), which is correct, but the status tool exposes configuration paths and missing config fields. This is acceptable for debugging, but the tool description should warn that it reveals configuration state.