mcp-telegram
This server lets an LLM control a Telegram bot via MCP: verify the bot identity and send messages, photos, and documents; the README also mentions retrieving updates and file info.
get_me: return the bot’s identity to verify the token/connection.send_message: send text with optional chat_id, parse_mode (MarkdownV2/HTML/Markdown), silent mode, link preview disable, and reply_to_message_id.send_photo: send a photo via URL, local path, or Telegram file_id, with optional caption and parse_mode.send_document: send a document via URL, local path, or Telegram file_id, with optional caption and parse_mode.Note: the README also lists
get_updatesandget_file, but they are not present in the provided server schema.
Allows sending messages, photos, and documents to Telegram via a bot using the Telegram Bot API.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-telegramsend a Telegram message saying the build passed"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-telegram
An MCP server that lets an LLM send messages, photos and documents to Telegram through a bot, as well as retrieve incoming updates.
Point any MCP-capable client (Claude Desktop, Claude Code, Antigravity, or your own agent) at
this server and the model gains tools: get_me, get_updates, get_file, send_message,
send_photo and send_document. The model decides what to say or process; the server
handles how it communicates with Telegram.
Why the Bot API
This server talks to the Telegram Bot API. That means you create a bot, the bot sends messages, and users receive them.
No phone-number login, no
api_id/api_hash, no session files.The bot can only message chats it already shares with a user (the user must start the bot first) or channels/groups it belongs to.
If you instead need to send messages as your own user account to arbitrary people, that requires the MTProto client API (Telethon/Pyrogram) and account authentication — a deliberately different, heavier tool that is out of scope here.
Related MCP server: Telegram MCP Server
Architecture
Three small layers, each with one responsibility:
src/mcp_telegram/
├── config.py # load & validate settings from the environment (fail-fast)
├── telegram.py # thin async client over the Bot API (httpx, no heavy SDK)
├── server.py # FastMCP server: tool definitions + shared client lifespan
└── __main__.py # entry point (stdio transport)The MCP layer never builds HTTP requests and the HTTP layer never knows about
MCP, so each can be tested and changed on its own. A single httpx.AsyncClient
is created once per server run via the FastMCP lifespan and reused across calls.
Requirements
Python 3.10+
A Telegram bot token from @BotFather
Setup
1. Create the bot and get a token
Open @BotFather in Telegram and send
/newbot.Follow the prompts and copy the token it gives you (looks like
123456789:AA...).
2. Find your chat id
The bot can only message a chat it knows. The simplest path:
Send any message to your new bot in Telegram.
Ask @userinfobot for your numeric id, or call:
curl "https://api.telegram.org/bot<YOUR_TOKEN>/getUpdates"and read
result[].message.chat.idfrom the JSON.
Set that value as TELEGRAM_DEFAULT_CHAT_ID so the model can send without
specifying a chat every time.
3. Install
# with uv (recommended)
uv venv
uv pip install -e .
# or with pip
python -m venv .venv && source .venv/bin/activate
pip install -e .4. Configure
Copy the example env file and fill it in:
cp .env.example .env
# edit .env: set TELEGRAM_BOT_TOKEN (and ideally TELEGRAM_DEFAULT_CHAT_ID)Variable | Required | Default | Description |
| yes | — | Token from @BotFather. |
| no | — | Chat used when a tool call omits |
| no |
| Override the API host (e.g. a local Bot API server). |
| no |
| Per-request timeout in seconds. |
Running
The server speaks MCP over stdio, so you normally don't launch it by hand — your MCP client does. To sanity-check that it starts:
TELEGRAM_BOT_TOKEN=... mcp-telegramIt will wait for an MCP client on stdin. Press Ctrl+C to stop.
Connecting a client
Claude Desktop
Add this to your claude_desktop_config.json
(~/Library/Application Support/Claude/ on macOS,
%APPDATA%\Claude\ on Windows):
{
"mcpServers": {
"telegram": {
"command": "mcp-telegram",
"env": {
"TELEGRAM_BOT_TOKEN": "123456789:AA...",
"TELEGRAM_DEFAULT_CHAT_ID": "123456789"
}
}
}
}If mcp-telegram is not on your PATH, use the venv's absolute path or run it
through uv:
{
"mcpServers": {
"telegram": {
"command": "uv",
"args": ["run", "--directory", "/absolute/path/to/mcp-telegram", "mcp-telegram"],
"env": { "TELEGRAM_BOT_TOKEN": "123456789:AA..." }
}
}
}Claude Code
claude mcp add telegram \
--env TELEGRAM_BOT_TOKEN=123456789:AA... \
--env TELEGRAM_DEFAULT_CHAT_ID=123456789 \
-- mcp-telegramRestart the client after editing its config, then ask the model something like "send me a Telegram message saying the build passed".
Tools
Tool | What it does |
| Return the bot's identity — use it to verify the token. |
| Fetch incoming messages and updates (supports offset & polling). |
| Get file info and download URL for voice/photos/docs. |
| Send a text message (optional Markdown/HTML formatting). |
| Send a photo by URL, local path, or Telegram |
| Send a file by URL, local path, or Telegram |
Every send tool accepts an optional chat_id; when omitted it falls back to
TELEGRAM_DEFAULT_CHAT_ID. parse_mode is optional and defaults to plain text —
only set "MarkdownV2", "HTML" or "Markdown" when you need formatting, and
make sure the payload is escaped for that mode.
Development
uv pip install -e ".[dev]"
pytestTests mock the Telegram HTTP API with respx, so they run offline and never
touch a real bot.
License
MIT — see LICENSE.
Available Tools
4 toolsget_meA
Return the bot's own identity. Use it to verify the token and connection.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Describes the operation as returning identity, implying read-only, non-destructive behavior. No annotations provided, so description carries full burden and meets it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences, front-loaded with purpose, no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Simple tool with no params and an output schema; description covers identity retrieval and use case completely.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Tool has no parameters; schema coverage is 100%. Baseline 4 applies as description adds no param info but none needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the verb 'Return' and resource 'bot's own identity', distinguishing it from send tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use it to verify the token and connection', providing clear context for when to use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_documentA
Send a file/document to a Telegram chat.
Args:
document: An http(s) URL, a local file path, or a Telegram file_id.
chat_id: Target chat; omit to use the server's default chat.
caption: Optional caption shown with the document (max 1024 characters).
parse_mode: Optional caption formatting (see send_message).
disable_notification: Send silently, without a notification sound.
| Name | Required | Description | Default |
|---|---|---|---|
| caption | No | ||
| chat_id | No | ||
| document | Yes | ||
| parse_mode | No | ||
| disable_notification | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It mentions that document can be a URL, file path, or file_id, and notes caption character limit and parse_mode reference. However, it does not disclose destructive hints, authentication needs, rate limits, file size constraints, or behavior on failure. Critical gaps remain for a mutation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a one-line summary followed by a bulleted Args list. It is concise and front-loaded. Minor improvement could be reducing redundancy in parameter names, but it is clear and efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool complexity (5 params, required document) and presence of an output schema, the description covers parameter semantics well but lacks usage guidelines and behavioral transparency. It references send_message for parse_mode but does not provide independent context. Overall adequate but with noticeable gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description fully compensates. Each parameter is explained: document (URL, path, file_id), chat_id (default chat), caption (max 1024), parse_mode (see send_message), disable_notification (silent). This adds essential meaning beyond the schema's type-only definitions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action: 'Send a file/document to a Telegram chat.' This is a specific verb+resource combination. The title and sibling tools (send_message, send_photo) indicate distinct purposes, so the tool is well-differentiated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit guidance on when to use this tool versus alternatives like send_message or send_photo. The description only explains parameters, not the context for choosing this tool. Usage is implied by the purpose, but no when-not or exclusion criteria are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_messageA
Send a text message to a Telegram chat.
Args:
text: Message body (max 4096 characters).
chat_id: Target chat: a numeric id or an @channelusername. Omit to
use the server's default chat.
parse_mode: Optional formatting: "MarkdownV2", "HTML" or "Markdown".
Leave empty to send plain text (safest). When set, the text must be
valid/escaped for that mode or Telegram rejects it.
disable_notification: Send silently, without a notification sound.
disable_web_page_preview: Do not expand link previews.
reply_to_message_id: Make this message a reply to an existing message.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | ||
| chat_id | No | ||
| parse_mode | No | ||
| reply_to_message_id | No | ||
| disable_notification | No | ||
| disable_web_page_preview | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses text length limits, optional chat_id, parse_mode behavior, silent notification, link preview control, and reply-to functionality. It does not cover rate limits, authentication requirements, or detailed error handling, but the disclosure is substantial for a simple send tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a clear main line followed by a bulleted list of arguments. Every sentence provides necessary information, and there is no fluff. It is appropriately sized for the complexity of the tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that an output schema exists (not shown), the description does not need to explain return values. It covers all parameters and their constraints thoroughly. However, it lacks information on idempotency, retries, or error scenarios, which might be relevant for a messaging tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0% description coverage, so the description must add meaning. It fully explains each parameter: text (max length, required), chat_id (numeric or @username, optional), parse_mode (options and validation), and the boolean flags. This adds significant value beyond the schema's type/default information.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Send a text message to a Telegram chat,' which is a specific verb+resource. It distinguishes itself from sibling tools like send_document and send_photo, which handle files and images, respectively.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides usage context, such as omitting chat_id to use the default chat, and explains parse_mode options with a warning about escaping. However, it does not explicitly state when not to use this tool or mention alternatives beyond the sibling names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_photoA
Send a photo to a Telegram chat.
Args:
photo: An http(s) URL, a local file path, or a Telegram file_id.
chat_id: Target chat; omit to use the server's default chat.
caption: Optional caption shown under the photo (max 1024 characters).
parse_mode: Optional caption formatting (see send_message).
disable_notification: Send silently, without a notification sound.
| Name | Required | Description | Default |
|---|---|---|---|
| photo | Yes | ||
| caption | No | ||
| chat_id | No | ||
| parse_mode | No | ||
| disable_notification | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description adds some behavioral context (e.g., silent sending through disable_notification, caption max length). However, it omits other traits like file size limits or required authentication.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and front-loaded with a clear purpose statement. The parameter list is well-organized but could benefit from a slightly more structured format.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the moderate complexity (5 params, 1 required) and the presence of an output schema, the description adequately covers parameter usage and key behaviors, though some behavioral details like error handling are missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but the description provides detailed meanings for all parameters: photo sources (URL, file path, file_id), chat_id default behavior, caption max length, parse_mode reference, and disable_notification effect.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Send a photo to a Telegram chat,' which is a specific verb+resource. It distinguishes from sibling tools like send_document and send_message by focusing on photos.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for sending photos but does not provide explicit guidance on when to use this tool over alternatives, nor does it mention when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
4 tool updates
v0.1.0- First observed
get_me - First observed
send_document - First observed
send_message - First observed
send_photo
TDQS
Each tool has a distinct purpose: get_me verifies bot identity, send_message sends text, send_photo sends images, send_document sends files. No ambiguity.
All tools follow a consistent verb_noun pattern: get_me, send_document, send_message, send_photo, using snake_case throughout.
Four tools is a small but reasonable set for a basic Telegram bot, covering identity and three message types. Could be expanded but not inappropriate.
The tool surface lacks many common Telegram operations like send_audio, send_video, forward_message, delete_message, limiting the bot's capabilities for a full-featured server.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
MCP server exposing the Backtest360 engine API as tools for AI agents.
Remote MCP server for supportsheep: run AI interviews and manage support content for your blog.
MCP server connecting AI agents to 100+ apps (Gmail, Slack, Notion, GitHub) via one-click OAuth.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceAn MCP server that wraps the Telegram Bot API into semantic tools for LLM agents, supporting multi-bot management for sending and receiving messages. It enables agents to send text, photos, and documents, as well as fetch recent updates from multiple configured Telegram bots.-
- FlicenseAqualityDmaintenanceAn MCP server for interacting with Telegram bots and channels using the Telegraf library. It allows AI agents to send messages, manage channels, forward content, and intelligently respond to Telegram conversations.5408-
- AlicenseNot gradedqualityDmaintenanceAn MCP server for sending and receiving Telegram messages via a bot, enabling AI assistants to interact directly through Telegram by sending messages, reading recent messages, and sending photos.24MIT
- AlicenseNot gradedqualityBmaintenanceMCP server that exposes a Telegram bot over stdio transport, enabling LLM agents to discover each other, announce capabilities, and communicate via messages in shared group chats. It provides tools like whoami, announce, list_agents, ping_agent, send_message, list_chats, get_recent_messages, and wait_for_reply.MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Moreti2002/mcp-telegram'
If you have feedback or need assistance with the MCP directory API, please join our Discord server