[BUG] Telegram channel plugin tools disappear mid-session — Tool not found
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?
Hi guys! I think I hit a host-side bug while trying to wire up the official Telegram channel plugin — sharing the details below in case it helps with triage.
Motivation
Trying to connect the official Telegram channel plugin so that I can send and receive Telegram messages from a Claude Code session. The plugin does work — pairing succeeds, the bot polls Telegram, the assistant replies in the chat — but it regularly stops working mid-session and has to be brought back with /reload-plugins (or, when that doesn't help, a full Claude Code restart). The time from a fresh start (or the previous /reload-plugins) to the next failure is suspiciously often close to 5 minutes, which roughly matches the default Anthropic prompt-cache breakpoint TTL.
The full round-trip — and where it breaks
Pairing (via /telegram:configure + /telegram:access) succeeds and the full round-trip works correctly for the first few minutes:
- I send a message in Telegram.
- The bot receives it via long-poll
getUpdatesand pushes it to Claude Code as an MCPnotifications/claude/channel. - The host wakes up and sends an Anthropic API request with my message as a new user turn.
- The model responds with
tool_use → mcp__plugin_telegram_telegram__reply. - The host dispatches that call to the bot; the bot calls Telegram
sendMessage; the reply lands in my chat.
After a few minutes step 5 breaks: the model still wants to call reply, but the host responds with Error: Tool mcp__plugin_telegram_telegram__reply not found. From the chat side it looks like the assistant simply went silent — whatever the model decides to do with that error in its next turn (fall back to plain text in the local Claude Code terminal, retry, or pivot to other tools), nothing reaches Telegram, because the only outbound path back to Telegram (reply) is gone. The Telegram bot process is still alive (continues writing heartbeats every ~2 s to %USERPROFILE%\.claude\channels\telegram\logs\telegram_bot_*.log); no crash, no shutdown, no stdin: end on the plugin side.
Where the failure actually sits
The in-session Claude Code assistant helped narrow this down and explicitly recommended that I file this issue. Its conclusion was that the failure is not at the telegram plugin level — it is one level up, on the Claude Code host side. After a few minutes the host silently deregisters all 4 telegram tools (reply, react, edit_message, download_attachment) from its in-session registry. The only --debug evidence is a numeric flip Dynamic tool loading: 1/46 → 0/42. There is no disconnect / shutdown / transport closed / respawn / new Starting connection line in --debug to explain the drop. The 4 tools are never re-registered automatically for the rest of the session; recovery requires /reload-plugins or a full Claude Code restart.
Misleading diagnostic
claude mcp list still reports the server as ✓ Connected after the drop — because that command spawns a fresh health-check subprocess that completes its initialize handshake successfully and exits, blind to the live session's broken registry.
What Should Happen?
A claude/channel-capable stdio MCP server, once successfully connected at session start, should keep its tools available in the host's in-session registry for as long as the underlying transport is healthy. Concretely:
- Tools must not silently disappear mid-session. A long-lived interactive session that started with
Dynamic tool loading: 1/46 deferred tools includedshould not flip to0/42without anything in--debugexplaining why.
- If the host has a legitimate reason to re-pull tool definitions (e.g. prompt-cache window rotation, plugin update, transport reset), that re-pull should be automatic and atomic — old tools stay registered until the new tool set is in place — so live
tool_usecalls keep succeeding. If for any reason the new tool set is empty/missing, the host should retry rather than leave the registry in a permanently broken state.
- Equal treatment for channel-capable and non-capable stdio MCP servers.
playwright(noclaude/channel) survives more than an hour in the same session under the same--debug mcpinvocation;plugin:telegram:telegram(declaresclaude/channel) dies in 4–6 minutes. Whatever code path treats the two servers differently has a bug.
- Observable lifecycle in
--debug. Any deregistration / re-registration / refresh of MCP tool definitions should produce explicit log lines. Today the only diagnostic is aDynamic tool loadingnumeric counter — accidental and easy to miss. Lines along these would have made this bug trivial to localize:
MCP server "X": cache TTL expired, refreshing tool definitionsMCP server "X": tools deregistered (count=4, reason=…)MCP server "X": tools re-registered (count=4)MCP server "X": failed to re-register tools after refresh: <error>
- Honest
claude mcp list. Today the command spawns its own short-lived health-check subprocess and reports ✓ Connected even when the live interactive session has lost the server's tools. The diagnostic should reflect (or at least surface) the live session's actual registry state, otherwise it actively misleads users into thinking the plugin is fine.
Claude Code itself recommended that I open this issue — the investigation above was done in-session by the assistant.
Error Messages/Logs
## Error cascade: tool deregistration without explanation
**From:** `C:\Users\user\.claude\claude_debug_2.log` (Repro #2, session started ~16:28)
**Session startup (16:27–16:28:01):** Normal state. `[DEBUG] Dynamic tool loading: 1/**46** deferred tools included` appears consistently across multiple turns
for ~3–4 minutes. No warnings, no errors. Telegram plugin tools are available and registered.
**First error (16:28:04.518Z):** Three identical errors fire in rapid succession (.518Z, .519Z, .521Z):
[ERROR] Error: Error: Tool mcp__plugin_telegram_telegram__reply not found
2026-05-08T17:12:15.518Z [ERROR] Error: Error: Tool mcp__plugin_telegram_telegram__reply not found
at uT7 (B:/~BUN/root/src/entrypoints/cli.js:3067:36101)
at x5 (B:/~BUN/root/src/entrypoints/cli.js:519:21148)
at gY (B:/~BUN/root/src/entrypoints/cli.js:519:39925)
at dC (B:/~BUN/root/src/entrypoints/cli.js:519:50741)
at TNH (B:/~BUN/root/src/entrypoints/cli.js:519:87806)
at VL6 (B:/~BUN/root/src/entrypoints/cli.js:519:86759)
at VNH (B:/~BUN/root/src/entrypoints/cli.js:519:86578)
at zoH (B:/~BUN/root/src/entrypoints/cli.js:519:82897)
at _8 (B:/~BUN/root/src/entrypoints/cli.js:519:6558)
at VH (B:/~BUN/root/src/entrypoints/cli.js:519:5012)
**Silent deregistration (16:28:07.384Z):** Exactly 3 seconds later, the tool pool shrinks:
[DEBUG] Dynamic tool loading: 0/42 deferred tools included (was **1/46** immediately before)
**Four telegram tools deleted from registry:**
- `mcp__plugin_telegram_telegram__reply`
- `mcp__plugin_telegram_telegram__react`
- `mcp__plugin_telegram_telegram__edit_message`
- `mcp__plugin_telegram_telegram__download_attachment`
No lifecycle logs explain the removal — no deregistration events, no plugin reload, no cache rotation marker.
**Aftermath (16:28:07.384Z onwards):** A cascade of WARN lines (repeated for the duration of the session):
[WARN] Filtering out tool_reference for unavailable tool: mcp__plugin_telegram_telegram__reply
[WARN] Filtering out tool_reference for unavailable tool: mcp__plugin_telegram_telegram__react
[WARN] Filtering out tool_reference for unavailable tool: mcp__plugin_telegram_telegram__edit_message
[WARN] Filtering out tool_reference for unavailable tool: mcp__plugin_telegram_telegram__download_attachment
Steps to Reproduce
- Install and enable the official Telegram channel plugin:
``text``
claude plugins install telegram@claude-plugins-official
- In Claude Code, pair the plugin with a Telegram chat:
/telegram:configure— paste your Telegram bot token, review access policy./telegram:access— approve the chat that should be allowed to reach the assistant./plugin enable telegram— enable plugin
- Start a debug session bound to the Telegram channel:
``text``
claude --channels plugin:telegram@claude-plugins-official --dangerously-skip-permissions --debug "mcp,api" --debug-file %USERPROFILE%\.claude\claude_debug.log
- From your Telegram chat, send a message (e.g.
hi).
- Expected: the assistant replies in the Telegram chat.
- Observed: the assistant replies in the Telegram chat. ✅
- Wait. Either keep the session moderately active with a few more Telegram exchanges, or idle.
- With light Telegram-tool activity: failure typically lands within ~4–6 minutes of the last successful
reply. - With idle / no Telegram tool use: same failure can arrive much later (observed up to ~21–26 min in earlier sessions before this report) — cadence is variable, not a fixed timer.
- Send another Telegram message.
- Expected: the assistant replies in the Telegram chat.
- Observed: nothing arrives in Telegram. In
claude_debug.logyou'll see:
``text`
[ERROR] Error: Error: Tool mcp__plugin_telegram_telegram__reply not found
[DEBUG] Dynamic tool loading: 0/42 deferred tools included (was 1/46 immediately before)
[WARN] Filtering out tool_reference for unavailable tool: mcp__plugin_telegram_telegram__reply
reply
Between the last successful and the error: **no** disconnect / shutdown / transport closed / respawn / new Starting connection` line.
- Confirm the misleading diagnostic:
``text`
claude mcp list
plugin:telegram:telegram ✓ Connected` because that command spawns its own health-check subprocess.
Output still shows
- Check the plugin process is still alive on disk:
``text``
dir %USERPROFILE%\.claude\channels\telegram\logs\telegram_bot_*.log
Heartbeats keep being written every ~2 s. The plugin itself didn't die. (I added such heartbeat for the debug localy)
- Recovery: run
/reload-plugins. Tools come back;Dynamic tool loadingflips back to1/46. Then the cycle repeats — another drop is expected within a few minutes.
- If
/reload-pluginsdoes not recover the tools, fully exit and restart Claude Code.
Note on cross-platform reproduction: I have only reproduced this on Windows. Confirmation on macOS / Linux would help bound the bug.
Claude Model
Not sure / Multiple models
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.133
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
Windows Terminal
Additional Information
Hypotheses
Main hypothesis (cache rotation)
The host drops MCP tool definitions when the cached prefix that contains them rotates (~5 min default Anthropic prompt-cache breakpoint TTL), and then fails to re-register them specifically for claude/channel-capable stdio plugins. The playwright differential supports this — same session, same stdio transport, no claude/channel capability, unaffected for 1+ hour while telegram dies in minutes.
Alternative hypotheses (the same data is consistent with any of these)
With only host-side --debug logs and no view into Claude Code internals, I cannot distinguish between mechanisms; the cache-TTL link is correlation-only. Plausible alternatives:
claude/channel-specific timer / watchdog. The host runs a separate lifecycle for channel-capable MCP servers and disables them on its own timer, not tied to prompt cache at all. The ~5 min match would then be coincidence (or just the value of that timer).- Periodic cleanup task that only iterates channel-capable servers. A scheduled task in the host (memory cleanup, GC, registry compaction, anything similar) walks
claude/channel-registered MCP servers and incorrectly removes their tools. - Registration race in the channel-notifications subsystem.
Channel notifications registeredfor the telegram server fires more than once at start (e.g.14:49:47.467Zand again at14:49:56.583Zinclaude_debug.log). Some later re-registration may be overwriting / clearing the tool entries instead of merging.
What I can confirm regardless of mechanism: the cadence is in the minutes range, and playwright (same session, same stdio transport, no claude/channel capability) is unaffected — which narrows the bug to channel-capable stdio MCP servers.
Plugin & runtime versions
- Plugin:
telegram@claude-plugins-official0.0.6 (stdio MCP, declaresclaude/channel) - Bun runtime (used to launch the plugin's MCP server, per
claude mcp list):1.3.13(frombun --version) - Other MCP server in session:
playwright(stdio, noclaude/channel) — unaffected
Exact launch command
claude --channels plugin:telegram@claude-plugins-official --debug "mcp,api" --debug-file C:\Users\user\.claude\claude_debug_2.log
P.S.
Claude Code itself recommended that I open this issue — the investigation above was done in-session by the assistant: it correlated claude_debug_2.log with the plugin-side bot logs, spotted the playwright differential, and concluded the failure is on the Claude Code host side rather than inside the telegram plugin. Any ideas? Happy to grab more debug data, run additional repros across builds / platforms, or test patches if it helps narrow this down.
Has anyone kept this plugin running for a couple of days without a drop? What's the setup?
This issue has 8 comments on GitHub. Read the full discussion on GitHub ↗