--channels flag never matches plugin server identifier — channel notifications always skipped

Resolved 💬 1 comment Opened Apr 22, 2026 by plywoodtom Closed May 27, 2026

Summary

The Telegram plugin's inbound message delivery is completely broken. Channel push notifications are silently dropped by the harness due to an identifier-matching bug in the --channels flag implementation. The check_messages polling tool (the only workaround) was removed in plugin v0.0.6, leaving zero working paths for inbound messages.

This affects every --channels value — including the harness's own internal identifier for the server. The comparison itself is broken.

Environment

  • OS: Windows 11 Home 10.0.26200
  • Claude Code: Tested on 2.1.104 and 2.1.117
  • Plugin: telegram@claude-plugins-official v0.0.6
  • Plugin runtime: Bun 1.3.11

The Bug

The harness resolves the Telegram MCP server's internal identifier as plugin:telegram:telegram. When the plugin sends a notifications/claude/channel MCP notification, the harness checks whether this identifier is in the --channels list. This check always fails, even when the exact string plugin:telegram:telegram is passed via --channels.

MCP log proof

Every session since ~April 8 logs this at startup (4ms after connection):

{"debug":"Channel notifications skipped: server plugin:telegram:telegram not in --channels list for this session"}

This appears regardless of what --channels value is passed:

| Invocation | Result |
|---|---|
| claude (no flag) | "not in --channels list" |
| claude --channels plugin:telegram@claude-plugins-official | "not in --channels list" |
| claude --channels plugin:telegram:telegram | "not in --channels list" |
| claude --channels telegram | "not in --channels list" |

The identifier in the error message (plugin:telegram:telegram) is the harness's own internal name for this server. Passing that exact string back via --channels still fails. The comparison itself is broken.

Contrast with working session

The last working session (March 27, 2026) used an older harness version that auto-registered channels:

March 27 (WORKING):
  Line 2: "Successfully connected to undefined server in 227ms"
  Line 4: "Channel notifications registered"

April 8+ (BROKEN):
  Line 2: "Successfully connected (transport: stdio) in 300ms"
  Line 4: "Channel notifications skipped: server plugin:telegram:telegram not in --channels list"

The old harness didn't resolve a server identifier ("undefined server"). It auto-registered channel notifications for any MCP server declaring the experimental: { 'claude/channel': {} } capability. A harness update between March 27 and April 8 introduced the --channels opt-in requirement, but the identifier matching was implemented incorrectly.

Where the Bug Lives

The bug is in the Claude Code harness (compiled binary), in the code path that:

  1. Receives a notifications/claude/channel MCP notification from a connected server
  2. Looks up the server's identifier (resolves to plugin:telegram:telegram)
  3. Checks whether that identifier appears in the parsed --channels CLI argument
  4. This check returns false even when the strings are identical

Possible root causes:

  • The --channels argument may not be parsed at all (the list is always empty)
  • The CLI argument parser may be splitting on : and mangling the value
  • The comparison may use a different normalization than the identifier resolution
  • The --channels feature may be gated behind a flag that silently disables it

The log message "Channel notifications skipped: server {id} not in --channels list for this session" should be searchable in the harness source.

Secondary Issue: check_messages Tool Removed

On April 8, even though push notifications were already broken, inbound messages still worked because the plugin had a check_messages tool that Claude could call via cron to poll for queued messages:

April 8 MCP log:
  Line 4: "Channel notifications skipped" (push broken)
  Line 5: "Calling MCP tool: check_messages" (poll workaround working)
  Line 6: "Tool 'check_messages' completed successfully in 19ms"

Plugin v0.0.6 removed check_messages, leaving only: reply, react, download_attachment, edit_message. With push broken AND poll removed, there is no path for inbound messages.

Recommendation: Re-add check_messages to the official plugin as a fallback for environments where channel notifications don't work.

Timeline

| Date | Harness | Plugin | Push | Poll | Inbound |
|---|---|---|---|---|---|
| March 27 | Old (auto-register) | Pre-0.0.6 | Working | Working | Working |
| April 8 | New (--channels required) | Pre-0.0.6 | Broken | Working | Working (via poll) |
| April 11+ | New | v0.0.6 | Broken | Removed | Dead |
| April 21 | New (2.1.104 + 2.1.117) | v0.0.6 | Broken (all values tried) | Removed | Dead |

What Was Tried (exhaustive)

  1. Plugin reinstall (x2)
  2. Nuclear reset of channel state directory
  3. Claude Code downgrade 2.1.117 to 2.1.104
  4. --channels plugin:telegram@claude-plugins-official
  5. --channels plugin:telegram:telegram (exact match to harness identifier)
  6. --channels plugin:telegram
  7. --channels telegram
  8. Verified plugin connects fine (tools work, outbound replies work)
  9. Verified plugin sends notifications (no error in plugin's catch handler)
  10. Read plugin source — notification code is correct
  11. Compared working vs broken MCP logs — confirmed harness-side regression

Workaround

Patched check_messages back into the local plugin source (server.ts). The plugin bot queues inbound messages in memory, and a CronCreate job calls check_messages every 3 minutes. This restores inbound messaging with a 0-3 minute delay. Fragile — any plugin auto-update overwrites the patch.

Steps to Reproduce

  1. Install: claude plugins install telegram@claude-plugins-official
  2. Configure bot token in ~/.claude/channels/telegram/.env
  3. Pair a Telegram user via /telegram:access
  4. Start: claude --channels plugin:telegram:telegram
  5. Check MCP log — will show "Channel notifications skipped"
  6. Send a message from Telegram — bot receives it (typing indicator shows), but nothing appears in Claude Code

Key Files

  • MCP logs: %LOCALAPPDATA%\claude-cli-nodejs\Cache\C--Users-timeb\mcp-logs-plugin-telegram-telegram\
  • Plugin source: %USERPROFILE%\.claude\plugins\cache\claude-plugins-official\telegram\0.0.6\server.ts
  • Channel state: %USERPROFILE%\.claude\channels\telegram\

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗