telegram-channel-mcp-server
MCP server (stdio) for publishing and managing posts in a Telegram channel via the Bot API.Lets an agent (Claude Code, Claude Desktop, etc.) post text, photos, videos, albums, documents,voice messages, video notes, polls/quizzes and paid content, and edit/delete/pin posts.
Installation
npm install
npm run build
Configuration
| Variable | Required | Description |
|---|---|---|
TELEGRAM_BOT_TOKEN |
yes | Bot token from @BotFather. The bot must be a channel admin with the "Post messages" permission (and the matching rights for editing/deleting). |
TELEGRAM_CHAT_ID |
no | Default channel: -100… or @username. Every tool accepts a chat_id that overrides the default. |
Claude Code
claude mcp add telegram-channel -e TELEGRAM_BOT_TOKEN=123:ABC -e TELEGRAM_CHAT_ID=-1001234567890 -- node /abs/path/telegram-channel-mcp/dist/index.js
Claude Desktop (claude_desktop_config.json)
{
"mcpServers": {
"telegram-channel": {
"command": "node",
"args": ["/abs/path/telegram-channel-mcp/dist/index.js"],
"env": { "TELEGRAM_BOT_TOKEN": "123:ABC", "TELEGRAM_CHAT_ID": "-1001234567890" }
}
}
}
Tools
| Tool | What it does |
|---|---|
telegram_send_message |
Text with HTML/MarkdownV2, link preview control, buttons |
telegram_send_photo / _video / _animation / _document / _audio / _voice / _video_note |
A single media item with caption, spoiler, buttons |
telegram_send_media_group |
Album of 2-10 items as one post |
telegram_send_paid_media |
Paid post for Telegram Stars |
telegram_send_poll / telegram_stop_poll |
Poll or quiz / close it and get the results |
telegram_edit_message |
Change text, caption, media, buttons |
telegram_delete_messages |
Delete up to 100 posts |
telegram_pin_message / telegram_unpin_message |
Pin / unpin |
telegram_copy_message |
Copy or forward a post from another chat |
telegram_set_reaction |
React on behalf of the channel |
telegram_get_chat |
Channel info and subscriber count (read-only) |
Media in every tool is given as a string: a public http(s) URL, an absolute path to a local file (the server uploads it), or a Telegram file_id (returned in the send result, so you can reuse a file without uploading it again).
Buttons are an array of rows: [[{ "text": "Website", "url": "https://…", "style": "primary" }], [{ "text": "Copy", "copy_text": "PROMO" }]]. Exactly one of url / callback_data / copy_text; style: primary | success | danger.
Bot API limitations handled by the server
- Albums and video notes cannot carry buttons - send them in a separate message.
- In an album
show_caption_above_mediaapplies to all items at once. - Paid content works in channels only, 1-10 000 stars.
- Polls in channels are always anonymous.
- Limits: text 4096 chars, caption 1024, file 50 MB on upload / 20 MB via URL.
Development
npm run dev # run from sources
npm run smoke -- /path/to/img.png # e2e check against a real channel (creates and deletes test posts)
npx @modelcontextprotocol/inspector node dist/index.js
Layout: src/telegram.ts - API client and media resolution, src/schemas.ts - shared zod schemas,src/format.ts - response formatting, src/tools/* - tools grouped by domain, src/index.ts - entry point.