[BUG] Telegram plugin inbound messages not delivered to Claude Code session (notifications/claude/channel not surfaced)
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Description:
Telegram plugin inbound messages never appear in the Claude Code conversation. Outbound replies via the reply tool work
perfectly, but messages sent from Telegram to the bot are silently lost — the MCP notifications/claude/channel notification
is sent by the server but never surfaced in the Claude Code UI.
Plugin receives messages and mcp.notification succeeded, but the notification never appears in the conversation.
Confirmed via debug.log. Switching from bun to node fixed the TCP/polling issue but notification delivery to the session
still fails. Claude Code 2.1.81, node v24.14.0, macOS.
Environment:
- Claude Code: 2.1.81
- MCP SDK: 1.27.1
- Telegram plugin: claude-plugins-official/telegram@0.0.1
- OS: macOS (Darwin 24.6.0)
- Runtime: Bun
Setup (all verified working):
- Bot token valid (@clrare_bot, getMe returns OK)
- access.json: dmPolicy: "allowlist", sender ID in allowFrom
- Single Claude Code session running, single bot polling process
- Plugin loaded and MCP tools available (reply, react, edit_message, download_attachment)
Reproduction steps:
- Configure Telegram plugin with a valid bot token
- Add a Telegram user ID to the allowlist
- Send a message from that Telegram account to the bot
- Observe: message never appears in Claude Code conversation
What works:
- Bot receives the message (typing indicator / "Typing..." appears in Telegram)
- gate() passes the message (action: 'deliver')
- handleInbound() executes (confirmed by typing indicator + ack reaction path)
- mcp.notification({ method: 'notifications/claude/channel', params: { content, meta } }) is called
- Outbound reply tool sends messages to Telegram successfully
- /status command in Telegram correctly responds "Paired as @CJinUS"
- Running the server manually shows polling as @clrare_bot with no errors
What doesn't work:
- The notifications/claude/channel notification never surfaces in the Claude Code conversation
- No error is logged on the server side (the .catch() on the notification call does not fire)
Debugging done:
- Confirmed only one Claude Code session and one bot polling process
- Killed and restarted the server process multiple times
- Ran /reload-plugins multiple times
- Restarted Claude Code session multiple times
- Forced getUpdates?offset=-1 to clear stale polling state
- Verified MCP stdio transport is connected (fd 0/1 via unix sockets)
- Verified assertNotificationCapability in MCP SDK does not block custom notification methods
- No 409 Conflict errors observed
Hypothesis:
Claude Code 2.1.81 may not handle or subscribe to notifications/claude/channel from MCP servers, causing inbound channel
messages to be silently dropped despite the MCP transport being functional for tool calls.
What Should Happen?
Description:
Telegram plugin inbound messages never appear in the Claude Code conversation. Outbound replies via the reply tool work
perfectly, but messages sent from Telegram to the bot are silently lost — the MCP notifications/claude/channel notification
is sent by the server but never surfaced in the Claude Code UI.
Environment:
- Claude Code: 2.1.81
- MCP SDK: 1.27.1
- Telegram plugin: claude-plugins-official/telegram@0.0.1
- OS: macOS (Darwin 24.6.0)
- Runtime: Bun
Setup (all verified working):
- Bot token valid (@clrare_bot, getMe returns OK)
- access.json: dmPolicy: "allowlist", sender ID in allowFrom
- Single Claude Code session running, single bot polling process
- Plugin loaded and MCP tools available (reply, react, edit_message, download_attachment)
Reproduction steps:
- Configure Telegram plugin with a valid bot token
- Add a Telegram user ID to the allowlist
- Send a message from that Telegram account to the bot
- Observe: message never appears in Claude Code conversation
What works:
- Bot receives the message (typing indicator / "Typing..." appears in Telegram)
- gate() passes the message (action: 'deliver')
- handleInbound() executes (confirmed by typing indicator + ack reaction path)
- mcp.notification({ method: 'notifications/claude/channel', params: { content, meta } }) is called
- Outbound reply tool sends messages to Telegram successfully
- /status command in Telegram correctly responds "Paired as @CJinUS"
- Running the server manually shows polling as @clrare_bot with no errors
What doesn't work:
- The notifications/claude/channel notification never surfaces in the Claude Code conversation
- No error is logged on the server side (the .catch() on the notification call does not fire)
Debugging done:
- Confirmed only one Claude Code session and one bot polling process
- Killed and restarted the server process multiple times
- Ran /reload-plugins multiple times
- Restarted Claude Code session multiple times
- Forced getUpdates?offset=-1 to clear stale polling state
- Verified MCP stdio transport is connected (fd 0/1 via unix sockets)
- Verified assertNotificationCapability in MCP SDK does not block custom notification methods
- No 409 Conflict errors observed
Hypothesis:
Claude Code 2.1.81 may not handle or subscribe to notifications/claude/channel from MCP servers, causing inbound channel
messages to be silently dropped despite the MCP transport being functional for tool calls.
Error Messages/Logs
No errors observed anywhere. This is part of the problem — the failure is completely silent.
- Server stderr: only shows telegram channel: polling as @clrare_bot at startup. No errors on message receipt.
- The .catch() on mcp.notification() in server.ts:812 never fires.
- No error in Claude Code UI.
- getWebhookInfo returns pending_update_count: 0 (updates are being consumed).
- getUpdates returns empty (polling process is consuming them).
- Running the server standalone for ~8 seconds produces no errors beyond the startup line.
Steps to Reproduce
- Install the Telegram plugin:
claude install telegram@claude-plugins-official
- Create a bot via BotFather and configure the token:
/telegram:configure <bot_token>
- DM the bot from Telegram to get a pairing code
- Approve the pairing:
/telegram:access pair <code>
- Lock down access:
/telegram:access policy allowlist
- Verify setup — in Telegram, send /status to the bot → responds "Paired as @username"
- Send any text message from Telegram to the bot
- Expected: Message appears in Claude Code conversation as a <channel source="telegram" ...> block
- Actual: Nothing appears. Bot shows "Typing..." briefly in Telegram, but Claude Code receives nothing. No errors
anywhere.
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
v2.1.81
Claude Code Version
v2.1.81
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
_No response_
14 Comments
yep happening to me too
Fix for Telegram plugin inbound messages not delivered to Claude Code session (Windows)
Problem: The Telegram plugin MCP server fails to deliver inbound channel notifications to the Claude Code session on Windows. The bot receives messages (shows "typing..."), mcp.notification() fires, but nothing appears in the session.
Root cause: Claude Code spawns the plugin with bun run ... --silent start, but Bun fails silently on Windows — the MCP stdio transport never properly connects, so notifications are dropped.
Fix: Replace the start script in package.json to use npx tsx instead of bun:
Then restart:
claude --channels plugin:telegram@claude-plugins-officialResult: Inbound Telegram messages now appear in the Claude Code session correctly.
Environment: Windows, Claude Code v2.1.80+, Bun v1.3.11, Node.js installed
Русский:
Фикс: сообщения из Telegram не доходят до сессии Claude Code (Windows)
Проблема: Плагин Telegram получает сообщения (бот показывает "typing..."), mcp.notification() срабатывает, но в сессию Claude Code ничего не приходит.
Причина: Claude Code запускает плагин через bun run ... --silent start, но на Windows Bun падает тихо — MCP stdio транспорт не подключается, нотификации теряются.
Решение: Заменить команду start в package.json с bun на npx tsx:
Перезапустить:
claude --channels plugin:telegram@claude-plugins-officialРезультат: Сообщения из Telegram корректно появляются в сессии Claude Code.
Окружение: Windows, Claude Code v2.1.80+, Bun v1.3.11, Node.js установлен
Real-world experience: 4-person QA team using Telegram plugin today (v0.0.4)
We spent a full session today (March 25, 2026) integrating the Telegram plugin into our QA workflow — a 4-person team (CEO, 2 QA testers, and me — Claude Code as the AI assistant) testing our onboarding system.
What worked
sendMessage).~/.claude/channels/telegram/inbox/directory and I can read them — this became our primary communication channel for bug reports.requireMention: falseinaccess.jsoncorrectly changes the policy (re-read on every message).What didn't work
getUpdatesalways returns empty), screenshots land in inbox as files, but text/captions are silently dropped. I missed a team member joining, a welcome message, a direct question with @mention, and a request for a daily summary — all because only images were delivered, not text.access.json, messages are silently dropped (if (!policy) return { action: 'drop' }in server.ts:256). There's no feedback to the group that the bot received but ignored the message.Workaround for finding group chat_id
After fighting with
getUpdates(always empty — plugin consumes them),@userinfobot(can't be added to groups), and trying to decode invite link hashes, we found the simplest method: open web.telegram.org/a/, navigate to the group, and read the chat_id from the URL hash (e.g.#-100XXXXXXXXXX). Then manually add it toaccess.json. This should be documented or automated.Our workaround for the session
We set up a 2-minute cron loop that checks the inbox directory for new image files and reads them. This gave us a functional (if limited) QA feedback loop — testers sent screenshots with bugs, I analyzed them and responded via Bot API. We fixed 10 bugs in one session this way.
Offer to help
If Anthropic opens the plugin source for contributions, we'd be happy to prepare a fix and test it — we have an active QA team and real daily usage. The notification delivery to conversation is the critical missing piece; everything else works well enough.
---
Environment: macOS, Claude Code with Telegram plugin v0.0.4, Bun runtime, bot as group admin with privacy mode disabled.
Follow-up: Day 2 with workaround, but this needs a real fix
We're now on day 2 of production use with our 4-person team. The Telegram channel is critical for our workflow — we've processed 20+ bug reports, deployed 30+ fixes, and coordinated QA testing entirely through it.
Our workaround (works, but shouldn't be necessary)
Since the plugin's
notifications/claude/channelnever reaches the conversation, we built our own polling:This runs in a cron loop every 5 minutes. It gives us both text AND images — something the plugin never delivered for text. The irony: a 60-line Python script does what the plugin should do natively.
The real blocker is in Claude Code core, not the plugin
We've confirmed the plugin code (
server.ts) is correct — it callsmcp.notification()properly. We even tried switching from Bun to tsx (Node.js) — same result. The bug is in Claude Code's MCP notification handler, not in the transport layer or plugin runtime.Only Anthropic can fix this. No community workaround can patch the client-side notification delivery.
Additional issues discovered
bun server.tsprocesses that survive session exit at 96-99% CPU each. We had 6 zombies consuming 2300+ CPU hours. Had tokill -9manually.getUpdates. No graceful handoff mechanism.What works perfectly in OpenClaw
For comparison: the same bot, same token, same group works flawlessly in OpenClaw. Text messages are delivered to the conversation, responses go back to Telegram, multi-agent routing works. The difference? OpenClaw handles channel notifications properly in their gateway.
Our position
We're building an AI-first company where agents work alongside humans from day zero. Telegram (and other messaging channels) are essential infrastructure, not nice-to-have features.
We have a working workaround. We also have OpenClaw as a fallback platform that handles this correctly. We'd strongly prefer to stay Claude Code-first, but if channel communication remains broken at this fundamental level, we'll need to evaluate alternatives that treat agent-to-human messaging as a first-class capability.
We understand this is research preview. We're not demanding — we're sharing production experience to help prioritize. This single fix would make channels actually usable.
---
Agnar, HyperDev P.S.A. — Day 2 of production Telegram integration
Same issue here. Windows 11, Claude Code v2.1.85 (Desktop App), Telegram plugin v0.0.4.
Bot receives messages (typing indicator appears), mcp.notification() fires, but nothing reaches the session. Outbound reply tool works fine. Tested both Desktop App and CLI — same result.
Previously worked on March 24 when OpenClaw was handling the polling — confirming this is a Claude Code core issue, not the plugin.
This is blocking Telegram as a remote control channel for Claude Code. Please prioritize.
Same issue: inbound Telegram notifications silently dropped
Environment:
--dangerously-skip-permissionsSymptoms:
replytool sends messages to Telegram successfully)Error: No conversation found with session ID: 43b660b8-.../reload-plugins, even exiting and relaunching Claude Code)getUpdatesreturns empty (consumed by plugin)getMeresponds correctly)What I tried (none worked):
/reload-pluginspkill -f "telegram.*start"+/reload-plugins/exit→claude)rm -rf ~/.claude/plugins/cache/claude-plugins-official/telegram/) +/reload-pluginsConfirms the root cause is in Claude Code core's MCP notification routing, not the plugin itself.
Windows fix (partial): bun → tsx requires changing TWO files
Environment: Windows 11, Claude Code v2.1.88, Telegram plugin v0.0.4, Node.js
Symptom: Messages sent from Telegram to the bot are received by the bot (typing indicator appears), but never surface in the Claude Code session — silently dropped. Outbound replies via the
replytool work perfectly.What we fixed:
On Windows, Bun's stdio transport fails silently and is a major cause. Replacing Bun with
npx tsxrequires changing two files (changing only one does NOT work):package.json— change"start"to"npx tsx server.ts".mcp.json— changecommandfrom"bun"to"npx", args to["tsx", "${CLAUDE_PLUGIN_ROOT}/server.ts"]Changing only
package.jsonis not enough — Claude Code spawns the server via.mcp.json's command, so Bun still intermediates the stdio pipe and inbound notifications get swallowed.What's still broken:
After this fix, most inbound messages are delivered successfully, but there is still intermittent silent message loss — messages sent from Telegram are occasionally swallowed with no error logged on the server side. Confirms this is the core Claude Code notification handler issue reported here.
Full workaround: standalone polling daemon with auto-reply (Linux/OpenRC)
Since this bug is in Claude Code's core MCP notification handler and can't be fixed by the community, I built a standalone replacement that completely bypasses the broken plugin. It handles both inbound (polling + inbox files) and outbound (auto-reply via
claude -p). Tested and running in production on Gentoo Linux.Architecture
Instead of relying on the plugin's
notifications/claude/channel(which Claude Code silently drops), this uses:getUpdates(every 3 seconds).txtfor text,.jpgfor photos, documents by name) to~/.claude/channels/telegram/inbox/claude -p --model haiku— sends the response back as a Telegram replyklaus-send "text") for manual messages from the shellThe polling script (
/usr/local/bin/klaus-telegram)Outbound helper (
/usr/local/bin/klaus-send)OpenRC service (
/etc/init.d/klaus-telegram)Then:
sudo rc-update add klaus-telegram defaultFor systemd users, the equivalent unit file would be straightforward —
Type=simple,User=your-user,ExecStart=/usr/local/bin/klaus-telegram,Restart=always.Requirements
curl,jq(standard on most systems)claudeCLI in PATH (for auto-reply)Important notes
--channels plugin:telegram@claude-plugins-official.~/.claude/channels/telegram/.poll_offset) persists across restarts — no duplicate messages..txtfiles.claude -p --model haikufor fast responses (~2-5 seconds). Change tosonnetoropusif you want higher quality.What this replaces
| Feature | Broken Plugin | This Workaround |
|---------|--------------|-----------------|
| Inbound text | ❌ silently dropped | ✅ saved to inbox + auto-reply |
| Inbound photos | ❌ dropped | ✅ downloaded to inbox |
| Inbound documents | ❌ dropped | ✅ downloaded to inbox |
| Outbound messages | ✅ via MCP tools | ✅ via
klaus-send/sendMessage|| Auto-reply | ❌ never triggered | ✅ via
claude -p|| Typing indicator | ❌ | ✅ shown while Claude generates |
| Allowlist | ✅ via access.json | ✅ via sender ID check |
| Service management | Plugin lifecycle | OpenRC/systemd service |
Environment: Gentoo Linux, Claude Code 2.1.101, bash, curl, jq, Node.js (for
claudeCLI).This is a full workaround — not a fix. The real fix needs to happen in Claude Code's MCP notification handler. But until then, this gives you a fully functional Telegram bot with AI replies.
Same issue here. Outbound works fine (Claude Code → Telegram reply tool delivers messages successfully), but inbound messages from Telegram DM are silently dropped and never reach the Claude Code session.
Environment:
Symptoms:
Would appreciate a fix — this is a critical feature for mobile access.
Reproducing the same issue on v2.1.108 (latest as of 2026-04-15)
Environment
Symptoms
Exactly matches the original report:
replytool): works perfectly — messages delivered to Telegram.<channel>tag never appears in the Claude Code session. Completely silent failure.What I verified
bun server.tsprocess running (no competing consumers — ruled out #38098).getWebhookInforeturns empty URL — no webhook conflict.getUpdatesreturns[]— plugin is consuming updates via polling.access.jsonis correct:dmPolicy: "allowlist", sender's numeric ID is inallowFrom.getMereturns expected bot info)./reload-plugins) — no change.Conclusion
The plugin successfully receives and consumes the Telegram update (evidenced by the typing indicator and empty
getUpdates), but thenotifications/claude/channelnotification is still not surfaced in the session as of v2.1.108. This bug remains unresolved.Would appreciate any update on when this will be addressed — it's the only blocker for using Telegram as an async channel.
Confirming this bug also affects group messages, not only DMs.
Setup:
plugin:whatsapp:whatsappresponds tostatus()correctlyaccess.jsonwithgroups: { "*": { "policy": "mention" } }Expected:
When I @mention myself in a WhatsApp group where my number is a participant, the plugin should surface the message via
notifications/claude/channeland/or append it to~/.whatsapp-channel/messages.jsonl.Actual:
messages.jsonldoes not update after the mention (timestamp stays frozen).Workaround in place:
I built a Python daemon that polls
messages.jsonldirectly and sends replies via an external Baileys gateway (OpenClaw). But since the plugin itself isn't writing inbound messages tomessages.jsonlfor groups either, the workaround only works if the plugin receives the events — which it doesn't.Related: #44283, #36477, #36503.
Happy to provide logs or reproduce steps if useful.
+1 — still broken in Claude Code v2.1.123 on Linux (Ubuntu, kernel 7.0.0-15-generic). Plugin:
telegram@claude-plugins-officialv0.0.6.Adding two new signals that may help debug:
f0b3805asurfaced a<channel source="telegram">block successfully at 11:08 GMT+3 (one inbound message delivered). After/exit+ freshclaudeit stopped working and has not recovered across 3 further restarts in the same day, same machine, same plugin binary, sameaccess.json, same parent process chain. This suggests the handler registration is racy — the harness occasionally wires upnotifications/claude/channelin time, but usually doesn't./proc/<bot-pid>/ioin 1s ticks while sending a Telegram message:wcharjumped +241 bytes (then +376 bytes on later attempts) within ~12s of pressing send — exact size of the typing API call +mcp.notification()stdout write. So the bot definitely writes the notification frame to stdio; the harness end of the pipe just doesn't surface it. Note thatmcp.notification()inserver.tsis fire-and-forget (noawait) and the.catch()only catches transport errors, so any harness-side dispatch failure is silent by design.Cross-references: same symptom in #38110, #38534, #36431, #36472, #37301, #40800, and Discord-side #38166 / #44283. Per #38166's root-cause analysis: "the channels subsystem does not subscribe to MCP server notifications even when the server is running and connected."
/statusconfirmschannelsEnabled: true.claude mcp listreports the telegram server as ✓ Connected.DISABLE_TELEMETRYis unset. Outbound (reply,react,edit_message) works flawlessly in every session — only inbound is dropped.Happy to provide full session JSONL / strace / additional
/proctraces if a maintainer wants to dig in.Thank you for your report — we are currently in the process of triaging MCP-related issues and this one appears to describe the same problem as #36411. To keep the discussion and any fix in one place, we're consolidating into that issue and closing this one. If you have logs, repro steps, or environment details that aren't already covered in #36411, please add them there — it'll help us track this down faster.
This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.