Telegram channel for Claude Code — a drop-in enhanced fork of the official telegram plugin that adds two things the stock plugin doesn't have:
The reply tool accepts an optional buttons: string[] parameter. Labels render
as an inline keyboard under the message; when the user taps one, the chosen label
is delivered back to the model as a regular inbound message, the message is edited
to record the choice, and the keyboard is removed so it can't be answered twice.
Great for yes/no confirmations and small multiple-choice questions — one tap instead of typing, especially on mobile.
reply(chat_id, "Send the draft?", buttons: ["Send", "Show me first", "Cancel"])
- Button sets are held in-memory keyed by a short random id (callback data stays under Telegram's 64-byte cap). They expire on plugin restart; taps on expired buttons get a polite "this choice expired" callback answer.
- Authorization mirrors the text-reply path (
allowFrom).
The reply tool's format parameter accepts a third mode: 'rich'. It sends the
text via Bot API 10.1 sendRichMessage, which renders document-grade content from
plain GFM markdown — real tables, headings, nested lists, blockquotes and
inline images (, up to 50 per message) — no escaping required.
reply(chat_id, "| Meal | kcal |\n|---|---:|\n| Lunch | 780 |", format: "rich")
- Works together with
buttons(table + answer buttons under it). - On any API error (e.g. an older Bot API server) it falls back to the plain-text path automatically, so content is never lost.
- Requires an up-to-date Telegram client to render (Desktop 6.9+ / current mobile).
Everything else — pairing, allowlists, access policy, file attachments, reactions, message editing, voice-note handling — is identical to the stock plugin. See ACCESS.md for groups and multi-user setups.
Scope note: the code diff against the upstream plugin is exactly these two features — nothing else is changed. It's a replacement, not an add-on, because Telegram allows only one polling consumer per bot token: button taps arrive on the same connection the channel server owns, so they can't be handled by a separate companion plugin.
- Bun — the MCP server runs on Bun.
Install with
curl -fsSL https://bun.sh/install | bash.
1. Create a bot with @BotFather (/newbot) and copy
the token (123456789:AAH...).
2. Install the plugin (inside a claude session):
/plugin marketplace add anthropics/claude-plugins-community
/plugin install telegram-plus@claude-community
/reload-plugins
Or straight from this repo:
/plugin install github:snjrusmn/claude-telegram-plus
3. Give the server the token:
/telegram-plus:configure 123456789:AAH...
4. Relaunch with the channel flag (exit the session and start a new one):
claude --channels plugin:telegram-plus@claude-community5. Pair. DM your bot on Telegram — it replies with a 6-character pairing code:
/telegram-plus:access pair <code>
Your next DM reaches the assistant.
Migrating from the stock telegram plugin? State (token, allowlist) lives in
~/.claude/channels/telegram/and is shared, so pairing carries over — just swap the plugin name in your--channelsflag. Don't run both plugins in the same session.
Apache-2.0. Based on the official telegram plugin by Anthropic
(see NOTICE); button and rich-message additions by
Sanjar Usman.