[FEATURE] Telegram plugin: add parse_mode support for MarkdownV2 formatting
Problem
The Telegram plugin's reply and edit_message tools send messages without a parse_mode parameter, so Telegram treats all outbound messages as plain text. Any formatting syntax (*bold*, _italic_, ` code `) renders as literal characters instead of being parsed.
Screenshot — raw markdown symbols visible to the user:
Messages show **bold**, _italic_, ` code ` as literal text instead of formatted output.
Proposed Solution
Add an optional parse_mode parameter to both reply and edit_message tools, defaulting to MarkdownV2.
Changes to server.ts
1. Tool schema — add parse_mode to reply and edit_message:
parse_mode: {
type: 'string',
enum: ['MarkdownV2', 'HTML', 'plain'],
description: 'Telegram parse mode. Default: MarkdownV2. Use "plain" to send without formatting.',
},
2. reply handler — extract and pass parse_mode to sendMessage:
const rawParseMode = (args.parse_mode as string | undefined) ?? 'MarkdownV2'
const parseMode = rawParseMode === 'plain' ? undefined : rawParseMode as 'MarkdownV2' | 'HTML'
// In the sendMessage call:
const sent = await bot.api.sendMessage(chat_id, chunks[i], {
...(parseMode ? { parse_mode: parseMode } : {}),
...(shouldReplyTo ? { reply_parameters: { message_id: reply_to } } : {}),
})
3. edit_message handler — same treatment for editMessageText:
const editParseMode = ((args.parse_mode as string | undefined) ?? 'MarkdownV2')
const editParseModeOpt = editParseMode === 'plain' ? undefined : editParseMode as 'MarkdownV2' | 'HTML'
const edited = await bot.api.editMessageText(
args.chat_id as string,
Number(args.message_id),
args.text as string,
editParseModeOpt ? { parse_mode: editParseModeOpt } : undefined,
)
4. MCP instructions — add MarkdownV2 formatting guide:
Messages use Telegram MarkdownV2 by default. Formatting: *bold*, _italic_, `code`, ```pre```,
~strikethrough~, __underline__, ||spoiler||, [link](url). IMPORTANT: In MarkdownV2, these
characters MUST be escaped with \ when used literally (not as formatting):
_ * [ ] ( ) ~ ` > # + - = | { } . !
Use parse_mode "plain" if escaping is too complex for a given message.
Why This Matters
- Telegram's Bot API supports rich formatting but it must be explicitly opted into via
parse_mode - Without it, Claude's formatted responses show raw syntax to users, which looks broken
- The
plainfallback ensures messages with complex content (lots of special chars) can still be sent reliably - grammy already supports the parameter — it just needs to be passed through
Tested
Applied locally and confirmed working with MarkdownV2 bold, italic, code, strikethrough, and underline rendering correctly in Telegram DMs.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗