Fast MCP Telegram
Summary: Fast MCP Telegram is an MCP/HTTP gateway that lets AI agents read, search, send, and manage Telegram messages, chats, and media via 8 consolidated tools, with optional direct MTProto access.
Read & search messages:
search_messages_globally(across all chats) andget_messages(per-chat browse/search/by-IDs/replies).Send messages:
send_message(text, files, formatting, replies) andsend_message_to_phone(to phone numbers, with temporary contact handling).Edit messages:
edit_message(text only, own messages).Discover chats:
find_chats(by name/username/phone, filters, folders) andget_chat_info(profile, members, forum topics).Direct Telegram API:
invoke_mtprotofor any raw method (with safety guardrails).Multi-tenant, multi-account: one server supports many users, each with isolated Telegram sessions.
Authentication: QR code or phone/bot token login; web setup UI.
File handling: attachments via URLs, local paths, or data URIs (base64).
Advanced features: voice transcription (Premium), global search, folder filtering, replies to forum topics/channel posts, S3 session storage.
Provides tools to interact with Telegram, including sending messages, searching chats, retrieving messages, and direct access to the Telegram API via MTProto bridge.
Telegram MCP Server — Model Context Protocol (MCP) gateway for Telegram. 8 context-efficient tools, multi-tenant, MTProto bridge.
Try the Demo
Scan the QR code from Telegram mobile (Settings → Devices → Scan QR) — no phone typing, no OTP, no 2FA. Or enter your phone number as fallback.
Copy your Bearer token from the success page
Then choose your path:
MCP Client (AI assistants)
From the setup page, download the
mcp.jsonfileAdd the server to your AI client and ask: "send hello to my saved messages in telegram"
Direct API (curl)
Run the command below (replace TOKEN with yours):
curl -X POST "https://tg-mcp.l1979.ru/mtproto-api/messages.SendMessage" \
-H "Authorization: Bearer TOKEN" \
-H "Content-Type: application/json" \
-d '{"params": {"peer": "me", "message": "Hello!"}}'
Related MCP server: mcp-telegram
How It Works
This server sits between your AI agent and Telegram's API:
Your agent → MCP/HTTP → this server → MTProto → TelegramWhat it does: Authenticates you with Telegram (QR or phone/bot token), exposes 8 AI-friendly tools instead of 80+ micro-APIs, and bridges raw MTProto for power users. Multi-tenant — one server, many users, isolated sessions.
Features
Feature | Description |
:building_construction: Dual Transport | Stdio for local MCP clients, HTTP for remote deploys ( |
:closed_lock_with_key: Multi-User Authentication | Shared |
:dart: AI-Optimized | 8 consolidated tools vs 80+ micro-tools — context-efficient design, LLM-friendly API, MCP ToolAnnotations |
:globe_with_meridians: HTTP-MTProto Bridge | Direct curl access to any Telegram API method with entity resolution and safety guardrails |
:shield: Session ACL | Opt-in per-principal limits on |
:tv: QR & Web Setup | Scan QR from Telegram mobile for instant auth (no phone/OTP/2FA) or use phone/code/2FA fallback — live at |
:label: One Agent, Multiple Accounts | Optional |
:rocket: MTProto Proxy Support | Connect via MTProto proxy with automatic Fake TLS (EE prefix) and standard proxy detection |
:card_file_box: Unified Session Management | Single configuration system for setup and server; per-token session files on shared multi-user hosts |
:cloud: S3 Session Storage | Store sessions in S3-compatible object storage for ephemeral hosted deployments (Smithery, Fly.io, Railway) |
:mag_right: Intelligent Search | Global & per-chat message search with multi-query support and intelligent deduplication |
:mag: Unified Message API | Single |
:speech_balloon: Universal Replies | Get replies from channel posts, forum topics, or any message with one parameter |
:busts_in_silhouette: Smart Contact Discovery | Search users, groups, channels with uniform entity schemas, forum detection, profile enrichment |
:file_folder: Folder Filtering | Filter chats by dialog folder (archived, custom folders) with integer ID or name matching |
:envelope: Advanced Messaging | Send, edit, reply, post to forum topics, formatting, file attachments, and phone number messaging |
:paperclip: Secure File Handling | Rich media sharing with SSRF protection, size limits, album support, optional HTTP attachment streaming |
:outbox_tray: Inline File Uploads | Data: URI (base64) file uploads in |
:microphone: Voice Transcription | Automatic speech-to-text for Premium accounts with parallel processing and polling |
:zap: High Performance | Async operations, parallel queries, and memory-conscious batching |
:shield: Production Reliability | Auto-reconnect, configurable logging, comprehensive error handling |
Quick Start
1. Install and authenticate
Quickest path (remote server): Open /setup → scan QR → copy token (see Try the Demo).
CLI path (local stdio): Run fast-mcp-telegram-setup once to create a Telegram session — then fast-mcp-telegram serves it:
uvx --from fast-mcp-telegram fast-mcp-telegram-setup \
--api-id="your_api_id" \
--api-hash="your_api_hash" \
--phone-number="+123456789"Bot token alternative (no phone, no OTP):
Set BOT_API_TOKEN instead of --phone-number. See Installation Guide.
2. Configure MCP Client
stdio mode (local): Add to your MCP client config (e.g. claude_desktop_config.json) — stdio (standard input/output) is the default transport for local MCP clients:
{
"mcpServers": {
"telegram": {
"command": "uvx",
"args": ["fast-mcp-telegram"],
"env": {
"API_ID": "your_api_id",
"API_HASH": "your_api_hash"
}
}
}
}http-auth mode (remote): Add to your MCP client config (e.g. claude_desktop_config.json):
{
"mcpServers": {
"telegram": {
"url": "https://tg-mcp.l1979.ru/mcp",
"headers": {
"Authorization": "Bearer YOUR_TOKEN"
}
}
}
}Get your token by scanning the QR code on the setup page or see Installation Guide for deploying your own server.
3. Start Using
{"tool": "search_messages_globally", "params": {"query": "hello", "limit": 5}}
{"tool": "get_messages", "params": {"chat_id": "me", "limit": 10}}
{"tool": "send_message", "params": {"chat_id": "me", "message": "Hello!"}}Deploy to Remote Server
Deploy your own MCP server on a VDS — see Installation Guide for step-by-step instructions.
Available Tools
Tool | Purpose | Key Features |
| Search across all chats | Multi-term queries, date filtering, chat type filtering |
| Unified message retrieval | Search/browse, read by IDs, get replies (posts/topics/messages), date filtering in all modes |
| Send new message | File attachments (URLs/local/data URIs), classic formatting (markdown/html), |
| Edit existing message | Classic or |
| Find users/groups/channels | Multi-term search, contact discovery, folder filtering, username/phone lookup |
| Get detailed profile info | Member counts, bio/about, online status, forum topics, common groups, enriched data |
| Message phone numbers | Auto-contact management, optional cleanup, file support (URLs/data URIs), |
| Direct Telegram API (power user) | Raw MTProto methods, entity resolution, PII/credential fields dropped by default ( |
See Tools Reference for detailed documentation with examples.
Documentation
Installation Guide - Local setup and remote server deployment
Tools Reference - Complete tools documentation
MTProto Bridge - Direct API access via curl
Contributing - Guidelines for contributors
Security - Security features and best practices
Telemetry
Anonymous tool telemetry since v0.30.1 — heartbeat every 6h, no credentials or message content collected. Opt out with DO_NOT_TRACK=1. See ADR 0005.
Auth flow telemetry since v0.38.0 — atomic events during setup (phone, QR, bot token, reauthorize). Buffered flush on flow completion. See ADR 0008.
License
MIT License - see LICENSE
mcp-name: io.github.leshchenko1979/fast-mcp-telegram
Available Tools
8 toolsedit_messageEdit messageADestructiveIdempotentInspect
Replace the text of an existing message in a Telegram chat. Only works on messages sent by the authenticated account. Cannot edit media or other message attributes — text only. parse_mode: classic markdown/html/auto or rich (Rich Message; dialect auto-detected). Success: dict with message_id, date, chat, text, status='edited', and edit_date (rich messages also set rich=true and rich_format). Error: dict with ok=false and error string (e.g. message not found or not editable). Use edit_message to update a previously sent message; use send_message to create new ones. Full documentation: https://github.com/leshchenko1979/fast-mcp-telegram/blob/main/docs/Tools-Reference.md
| Name | Required | Description | Default |
|---|---|---|---|
| chat_id | Yes | Target chat: numeric id (e.g. -100…), username without @, or 'me' for Saved Messages. | |
| message | Yes | Message text. When sending files, used as caption. | |
| message_id | Yes | Message id in this chat to edit (from get_messages or Telegram). | |
| parse_mode | No | 'markdown'/'html'/'auto': classic entity formatting (auto detects). 'rich': Telegram Rich Message document; dialect auto-detected (known HTML tags outside code → rich HTML, else rich markdown). Default is 'auto'. parse_mode='rich' cannot be combined with files. | auto |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | No | |
| chat | No | |
| code | No | |
| date | No | |
| rich | No | |
| text | No | |
| error | No | |
| action | No | |
| params | No | |
| sender | No | |
| status | No | |
| topic_id | No | |
| edit_date | No | |
| exception | No | |
| operation | No | |
| error_code | No | |
| message_id | No | |
| rich_format | No | |
| reply_markup | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide destructiveHint, idempotentHint, and openWorldHint, but the description adds rich behavioral context: the restriction to the authenticated account's messages, text-only limitation, explicit success/error dict shapes (including status='edited' and edit_date), and parse_mode side effects (rich messages setting rich=true). No contradiction with annotations.
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 front-loaded with the core purpose, followed by constraints, return format, and usage guidance. Every sentence adds value and the structure is logical, despite the length. No fluff or redundancy.
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?
The description is complete for a mutation tool: it covers purpose, constraints, success/error formats, usage alternatives, and links to full documentation. The schema covers parameter syntax, and annotations cover safety hints. Nothing essential is 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 100%, so the schema already documents all parameters fully. The description does not add new meaning beyond the schema; it merely restates parse_mode behavior already covered. Thus the baseline 3 applies.
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 opens with 'Replace the text of an existing message in a Telegram chat,' a specific verb+resource+action. It clearly distinguishes from siblings by stating 'Use edit_message to update a previously sent message; use send_message to create new ones.'
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 explicitly names the alternative tool (send_message) for creating messages. It also provides when-not-to-use constraints: 'Only works on messages sent by the authenticated account' and 'Cannot edit media or other message attributes — text only.'
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_chatsFind chatsARead-onlyIdempotentInspect
Find users/groups/channels by name, username, or phone. Comma-separated usernames are searched in parallel and results are merged round-robin. Global search (query required) searches all Telegram; with min_date, max_date, or filter, search uses dialog list or a named filter; include_peers filters use last-activity from GetPeerDialogs; flag-based filters use dialog list dates. Success: dict with key chats (list of chat objects). Full documentation: https://github.com/leshchenko1979/fast-mcp-telegram/blob/main/docs/Tools-Reference.md
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum chats to return (recommended 50 or less). | |
| query | No | Name, username (no @), phone (+country…), or comma-separated usernames for batch lookup. Example: 'alice,bob,charlie'. Required for global search unless you use min_date/max_date or folder alone. | |
| folder | No | Telegram folder name (case-insensitive exact match after normalization). In Telegram's UI these are called folders; internally they are "dialog filters" — saved filter presets that group chats by custom criteria (pinned, unread, business, etc.). See Filters-vs-Folders.md for the technical distinction. | |
| public | No | If true, prefer chats with a public username; if false, without. Does not apply to private DMs. Omit to skip this filter. | |
| max_date | No | Inclusive maximum date filter (ISO 8601 date or datetime). Omit for no upper bound. | |
| min_date | No | Inclusive minimum date filter (ISO 8601 date or datetime). Omit for no lower bound. | |
| chat_type | No | Comma-separated chat kinds: private, bot, group, channel. Case-insensitive; extra spaces allowed. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | No | |
| code | No | |
| chats | No | |
| error | No | |
| action | No | |
| params | No | |
| exception | No | |
| operation | No | |
| error_code | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish read-only, open-world, and idempotent behavior. The description adds valuable context beyond that, such as parallel search in comma-separated usernames and round-robin result merging, plus mode-dependent behavior. No contradictions with annotations.
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 dense and technically complex, mixing multiple modes and filter behaviors into long sentences. It is front-loaded with the purpose but the second sentence is overloaded with semicolon-separated conditions, making it harder to parse quickly. It could be restructured into clearer segments.
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 output schema and annotations, the description is largely complete: it covers the success return shape ('dict with key chats'), explains parameter modes, and points to full documentation. However, it references 'include_peers filters' and 'flag-based filters' that do not correspond to any schema parameters, which may confuse users.
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 coverage is 100%, so the baseline is 3. The description adds meaning by explaining that certain parameters (min_date, max_date) switch the search mode from global to dialog list, and that query is required only for global search, enriching the schema's per-parameter descriptions.
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 opens with a specific verb and resource: 'Find users/groups/channels by name, username, or phone.' This clearly states the tool's function and differentiates it from sibling tools like search_messages_globally (messages) and get_chat_info (individual chat details).
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 explains when to use global search versus dialog list filtering based on parameters (e.g., 'Global search (query required)... with min_date, max_date, or filter...'), providing clear context for selecting search modes. It does not explicitly name alternatives, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_chat_infoGet chat infoARead-onlyIdempotentInspect
Load profile and metadata for one user, bot, group, or channel. Success: info dict; forum chats may include topics up to topics_limit; user targets may include common_chats up to common_chats_limit. Full documentation: https://github.com/leshchenko1979/fast-mcp-telegram/blob/main/docs/Tools-Reference.md
| Name | Required | Description | Default |
|---|---|---|---|
| chat_id | Yes | Target chat: numeric id (e.g. -100…), username without @, or 'me' for Saved Messages. | |
| topics_limit | No | Max forum topics to list when the chat is a forum. | |
| common_chats_limit | No | Max common groups to list for user targets. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | |
| ok | No | |
| code | No | |
| error | No | |
| phone | No | |
| title | No | |
| action | No | |
| is_bot | No | |
| params | No | |
| topics | No | |
| is_user | No | |
| is_forum | No | |
| is_group | No | |
| username | No | |
| exception | No | |
| last_name | No | |
| operation | No | |
| error_code | No | |
| first_name | No | |
| is_channel | No | |
| common_chats | No | |
| topics_has_more | No | |
| participants_count | No | |
| common_chats_has_more | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, and idempotentHint, so the safety profile is covered. The description adds some return-shape and conditional field context (topics, common_chats), but this largely repeats information in the schema and output schema. No additional behavior such as error cases or rate limits is disclosed.
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 compact and front-loaded: the core purpose appears first, conditional behavior follows, and a documentation link is tucked at the end. It loses one point for slight redundancy with the schema descriptions, but there is no filler or ambiguity.
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, all parameters are fully described in the schema, and annotations cover the read-only/idempotent nature, the description is largely complete for invocation. The only notable omission is explicit routing guidance against sibling tools, but that is already assessed under usage guidelines.
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 100%, with each parameter already well documented and defaults provided. The description adds no new parameter-level meaning beyond restating that topics_limit and common_chats_limit bound optional result fields, so the baseline of 3 is appropriate.
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 states a specific verb ('Load') and a precise resource ('profile and metadata for one user, bot, group, or channel'). This clearly scopes the tool and distinguishes it from message-oriented or search-oriented siblings. The target-kind enumeration adds immediate practical clarity.
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 when to use the tool—when you need info about a single chat entity—but it gives no explicit when-not-to-use guidance or alternatives. It does not mention sibling tools like find_chats or get_messages, so an agent must infer the decision boundary.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_messagesGet messages in chatARead-onlyIdempotentInspect
Read or search messages in one chat: browse latest, search text, fetch by ids, or load replies to a message (comments, forum topics, threads). Use from_user to filter by sender (server-side, per-chat only). Use context to include neighboring messages and reply chains around each result. Use include_replies to fetch up to 5 direct replies per result. Do not combine message_ids with query or reply_to_id. Success: messages, has_more, optional total_count and discussion fields. Full documentation: https://github.com/leshchenko1979/fast-mcp-telegram/blob/main/docs/Tools-Reference.md
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum messages to return (recommended 50 or less). | |
| query | No | Search within this chat only; comma-separated terms. Omit to browse latest or use message_ids / reply_to_id modes. | |
| chat_id | Yes | Target chat: numeric id (e.g. -100…), username without @, or 'me' for Saved Messages. | |
| context | No | Number of surrounding messages to include as context for each search result. 0 = disabled (default). 1-10 = include N messages before and N after each result. Also fetches the message being replied to and top replies (if include_replies=true). Requires chat_id. Disabled when result count exceeds cost-based caps. | |
| max_date | No | Inclusive maximum date filter (ISO 8601 date or datetime). Omit for no upper bound. | |
| min_date | No | Inclusive minimum date filter (ISO 8601 date or datetime). Omit for no lower bound. | |
| from_user | No | Only return messages from this sender. Not a display-name or contact-name search — bare strings resolve like chat_id via get_entity (usernames are case-insensitive and may match an unrelated channel). Prefer @username, phone (+…), or numeric user id. Also accepts 'me', 'self', t.me URL, -100 prefixed id. Uses Telegram's native from_id server-side filter (per-chat search only). | |
| message_ids | No | Exact message ids to fetch. Mutually exclusive with query and reply_to_id. | |
| reply_to_id | No | Anchor message id: channel post id, forum topic_id from get_chat_info, or a message id for direct replies. Use with thread_scope. | |
| thread_scope | No | Only with reply_to_id. auto: full forum topic (topic_id) or channel comment thread via getReplies; else direct replies. full: nested branch under a message id (forum in-topic uses search window, not whole topic); supergroup threads use search top_msg_id. direct: immediate replies only. | auto |
| include_replies | No | If true, fetch up to 5 direct replies per search result and attach as replies. Each result costs one API call (not batchable). Default: false. | |
| auto_expand_batches | No | Extra search batches to run when filters narrow results. Higher values may return more matches at the cost of latency. | |
| include_total_count | No | If true, response may include total_count where supported (per-chat search; ignored for global search). |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | No | |
| code | No | |
| error | No | |
| action | No | |
| params | No | |
| _warning | No | |
| has_more | No | |
| messages | No | |
| exception | No | |
| operation | No | |
| error_code | No | |
| total_count | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint and idempotentHint annotations, the description discloses meaningful behavioral traits: include_replies 'costs one API call (not batchable),' context is 'Disabled when result count exceeds cost-based caps,' and the server-side per-chat filter for from_user. These details inform the agent about side effects and limitations without contradicting annotations.
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 compact yet information-dense, front-loading the core action in the first sentence and then detailing key usage points and constraints. It avoids fluff and ends with a documentation link, earning each sentence's place.
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?
For a tool with 13 parameters, an output schema, and read-only annotations, the description provides a comprehensive overview: it lists all major modes, notes cost-related behavior, states success response fields, and links to full documentation. This is sufficient for an agent to select and invoke the tool correctly without needing to infer critical details.
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 schema descriptions already cover all 13 parameters with 100% coverage, including the mutual exclusivity of message_ids and the per-chat nature of from_user. The description's parameter-related guidance, such as 'Use context to include neighboring messages,' largely repeats what the schema already states, adding minimal semantic value beyond the structured fields.
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 tool reads or searches messages within one chat, enumerating four distinct modes: browse latest, search text, fetch by ids, and load replies. The phrase 'in one chat' explicitly distinguishes it from the sibling tool search_messages_globally, establishing scope and resource.
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 clear usage context, such as 'Use from_user to filter by sender (server-side, per-chat only)' and 'Do not combine message_ids with query or reply_to_id,' which set expectations for parameter combinations. However, it does not explicitly mention when to prefer the global search sibling or exclude this tool for cross-chat searches, so it stops short of full when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
invoke_mtprotoInvoke MTProtoADestructiveInspect
Low-level Telegram API (MTProto) invoke for methods not wrapped by other tools. Dangerous methods require allow_dangerous=true. Success: API result dict or normalized error. PII and credential-shaped fields (phone, access_hash) are dropped from a successful result by default; pass include_sensitive=true for the raw payload. A bare message id needs a chat binding: requests with no peer field (messages.GetMessages, messages.DeleteMessages) are refused, because a bare id resolves against an arbitrary dialog. Use channels.GetMessages or messages.GetHistory, which carry the binding. messages.GetHistory cannot address a forum topic (no thread_id/top_msg_id in the schema, and channels.GetHistory does not exist) -- use messages.Search with top_msg_id, or the high-level get_messages with reply_to_id. Full documentation: https://github.com/leshchenko1979/fast-mcp-telegram/blob/main/docs/Tools-Reference.md
| Name | Required | Description | Default |
|---|---|---|---|
| resolve | No | If true, resolve string/int peer-like fields to TL Input* entities before invoke. | |
| params_json | Yes | JSON object string of TL parameters as in Telegram API docs; nested TL uses "_": "typeName" discriminator. | |
| allow_dangerous | No | If false, destructive methods (e.g. deletes) are blocked. Set true only when intended. | |
| method_full_name | Yes | Telegram API method, e.g. "messages.GetHistory" or "users.GetFullUser" (normalization applied). | |
| include_sensitive | No | If true, return the raw result including PII and credential-shaped fields (phone, access_hash). Default false drops them. |
Output Schema
| Name | Required | Description |
|---|---|---|
| _ | No | |
| id | No | |
| ok | No | |
| code | No | |
| date | No | |
| chats | No | |
| error | No | |
| users | No | |
| action | No | |
| params | No | |
| result | No | |
| messages | No | |
| exception | No | |
| operation | No | |
| error_code | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations that only indicate openWorldHint and destructiveHint, the description discloses concrete behavior: dangerous methods are blocked unless allow_dangerous=true, PII/credential-shaped fields are stripped by default, include_sensitive=true returns the raw payload, bare message id requests without a peer field are refused, and messages.GetHistory cannot address forum topics. No contradiction with annotations.
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 front-loaded with purpose, then safety, result semantics, and edge-case constraints. Each sentence contributes distinct information, and the documentation link provides an exit for deeper details without bloating the text.
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?
For a broad low-level invoke tool, the description covers safety gating, sensitive-data filtering, peer-binding requirements, a difficult forum-topic edge case, and points to full documentation. Since an output schema exists, the response shape does not need to be re-explained.
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 coverage is 100%, so baseline is 3. Description adds operational meaning for params_json through the chat-binding rule and forum-topic caveat, and reinforces include_sensitive behavior by naming phone and access_hash. This is modest but genuine added value over the schema.
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?
Description says 'Low-level Telegram API (MTProto) invoke for methods not wrapped by other tools,' naming the verb, resource, and scope. It also differentiates itself from the higher-level sibling tools by explicitly framing itself as the fallback for unwrapped methods.
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?
States clearly to use it for methods not wrapped by other tools. It gives explicit routing guidance: use channels.GetMessages or messages.GetHistory with the chat binding, and messages.Search or get_messages for forum topics. It also explains when allow_dangerous=true is required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_messages_globallySearch messages globallyARead-onlyIdempotentInspect
Search all Telegram chats at once (not scoped to one chat). Comma-separated query terms; optional filters by date, chat kind, and public username. Success: message list and metadata dict. Global search ignores include_total_count. Full documentation: https://github.com/leshchenko1979/fast-mcp-telegram/blob/main/docs/Tools-Reference.md
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum messages to return (recommended 50 or less). | |
| query | Yes | Search terms, comma-separated for multiple terms (OR-style global search). Required. | |
| public | No | If true, prefer chats with a public username; if false, without. Does not apply to private DMs. Omit to skip this filter. | |
| max_date | No | Inclusive maximum date filter (ISO 8601 date or datetime). Omit for no upper bound. | |
| min_date | No | Inclusive minimum date filter (ISO 8601 date or datetime). Omit for no lower bound. | |
| chat_type | No | Comma-separated chat kinds: private, bot, group, channel. Case-insensitive; extra spaces allowed. | |
| auto_expand_batches | No | Extra search batches to run when filters narrow results. Higher values may return more matches at the cost of latency. | |
| include_total_count | No | If true, response may include total_count where supported (per-chat search; ignored for global search). |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | No | |
| code | No | |
| error | No | |
| action | No | |
| params | No | |
| _warning | No | |
| has_more | No | |
| messages | No | |
| exception | No | |
| operation | No | |
| error_code | No | |
| total_count | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses a non-obvious behavior (global search ignores include_total_count) and states the success return shape ('message list and metadata dict'). This adds context beyond the readOnly/idempotent annotations. No contradictions exist with the annotations.
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?
Three concise sentences front-load the core purpose, followed by key search behavior and a documentation link. Every sentence earns its place with no redundancy or fluff.
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 8-parameter schema with full descriptions, the description covers global scope, return format, and a behavioral caveat, plus a documentation link for deeper reference. It's sufficiently complete for an agent to select and invoke the tool correctly without needing additional information.
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 coverage is 100% with rich parameter descriptions, so the baseline is 3. The description restates query semantics ('Comma-separated query terms') and summarizes filter options, but doesn't add significant new parameter details beyond what the schema already provides. The include_total_count caveat is a small extra.
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 ('Search all Telegram chats at once') and resource (messages across all chats). The parenthetical 'not scoped to one chat' explicitly differentiates it from sibling tools like get_messages, giving it a distinct and unambiguous purpose.
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?
It implies use when needing cross-chat search by stating 'Search all Telegram chats at once' and contrasting with scoped search. It also provides a specific behavioral caveat ('Global search ignores include_total_count'). However, it doesn't explicitly name alternative tools for single-chat search, so the guidance is clear but not fully explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_messageSend messageADestructiveInspect
Send text and optional file attachments to a Telegram chat. Supports reply-to (including forum topics and channel discussion groups), parse_mode: classic markdown/html/auto (entities) or rich (Rich Message document; dialect auto-detected). parse_mode=rich cannot be combined with files. File attachments as http(s) URLs, local paths, or data: URIs. When files are provided, the message text becomes a caption. For channel posts with reply_to_id, automatically posts in the linked discussion group. Success: dict with message_id, date, chat, text, status='sent', and sender info (rich messages also set rich=true and rich_format). Error: dict with ok=false and error string. Use send_message to create new messages; use edit_message to modify existing ones. Use send_message_to_phone when targeting a phone number instead of a chat_id. Full documentation: https://github.com/leshchenko1979/fast-mcp-telegram/blob/main/docs/Tools-Reference.md
| Name | Required | Description | Default |
|---|---|---|---|
| files | No | List of attachment URLs, local paths, or data URIs (one or more strings). data: URIs (data:<mime>;base64,<payload>) work in all server modes; local paths work in stdio mode only. | |
| chat_id | Yes | Target chat: numeric id (e.g. -100…), username without @, or 'me' for Saved Messages. | |
| message | Yes | Message text. When sending files, used as caption. | |
| parse_mode | No | 'markdown'/'html'/'auto': classic entity formatting (auto detects). 'rich': Telegram Rich Message document; dialect auto-detected (known HTML tags outside code → rich HTML, else rich markdown). Default is 'auto'. parse_mode='rich' cannot be combined with files. | auto |
| reply_to_id | No | Telegram message id to reply to. For forums, topic root id; for channel posts, post id (may create a comment). Omit for a new top-level message. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | No | |
| chat | No | |
| code | No | |
| date | No | |
| rich | No | |
| text | No | |
| error | No | |
| action | No | |
| params | No | |
| sender | No | |
| status | No | |
| topic_id | No | |
| edit_date | No | |
| exception | No | |
| operation | No | |
| error_code | No | |
| message_id | No | |
| rich_format | No | |
| reply_markup | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide openWorldHint and destructiveHint, but the description goes further by disclosing specific behaviors: parse_mode dialects auto-detected, file attachments treated as captions, automatic posting in linked discussion groups for channel replies, and detailed success/error dict structures. This adds substantial context beyond the annotations and aligns with destructiveHint.
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?
Every sentence earns its place: it covers purpose, parameter nuances, file behavior, channel posting, return values, and alternatives in a compact paragraph. The optional documentation link is a minor extra that doesn't detract.
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?
The description is fully complete for a 5-parameter tool with complex interactions: it explains parse_mode variants, reply_to scenarios, file handling, and success/error formats. The output schema exists, but the description redundantly specifies return fields (message_id, date, chat, etc.) and also covers edge cases like rich messages.
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 coverage is 100% with descriptive parameter docs, so baseline is 3. The description adds value by explaining interactions between parameters (e.g., files make message a caption, parse_mode=rich cannot combine with files) and the return payload structure, though much is redundant with schema descriptions.
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 text and optional file attachments to a Telegram chat' with a specific verb and resource. It explicitly distinguishes from sibling tools by mentioning alternatives like edit_message and send_message_to_phone, and includes detailed context about reply-to behavior and channel discussion groups.
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 offers explicit when-to-use guidance: 'Use send_message to create new messages; use edit_message to modify existing ones' and 'Use send_message_to_phone when targeting a phone number instead of a chat_id.' It also clarifies constraints like parse_mode=rich not combinable with files and channel post behavior.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_message_to_phoneSend message to phoneADestructiveInspect
Send to a phone number: may create a temporary contact, then send text or files. Supports parse_mode: classic markdown/html/auto or rich (Rich Message; dialect auto-detected). parse_mode=rich cannot be combined with files. Success: send result plus contact_was_new / contact_removed when applicable. Full documentation: https://github.com/leshchenko1979/fast-mcp-telegram/blob/main/docs/Tools-Reference.md
| Name | Required | Description | Default |
|---|---|---|---|
| files | No | List of attachment URLs, local paths, or data URIs (one or more strings). data: URIs (data:<mime>;base64,<payload>) work in all server modes; local paths work in stdio mode only. | |
| message | Yes | Message text. When sending files, used as caption. | |
| last_name | No | Last name when creating a temporary contact. | Name |
| first_name | No | First name when creating a temporary contact. | Contact |
| parse_mode | No | 'markdown'/'html'/'auto': classic entity formatting (auto detects). 'rich': Telegram Rich Message document; dialect auto-detected (known HTML tags outside code → rich HTML, else rich markdown). Default is 'auto'. parse_mode='rich' cannot be combined with files. | auto |
| phone_number | Yes | E.164 phone number with country code, e.g. +1234567890 (must be on Telegram). | |
| remove_if_new | No | If true, delete the contact after send when it was created only for this send. | |
| reply_to_msg_id | No | Reply to this message id in the target chat after resolve. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | No | |
| chat | No | |
| code | No | |
| date | No | |
| rich | No | |
| text | No | |
| error | No | |
| action | No | |
| params | No | |
| sender | No | |
| status | No | |
| topic_id | No | |
| edit_date | No | |
| exception | No | |
| operation | No | |
| error_code | No | |
| message_id | No | |
| rich_format | No | |
| phone_number | No | |
| reply_markup | No | |
| contact_removed | No | |
| contact_was_new | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, and the description adds valuable context about temporary contact lifecycle ('may create a temporary contact', 'contact_was_new / contact_removed') and the rich mode restriction. This goes beyond the annotation without contradicting 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?
The description is two sentences plus a documentation link. It front-loads the primary purpose, includes the most important caveat, and mentions success output fields in a compact way. No fluff or repetition.
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's complexity (8 parameters, output schema, annotations), the description covers the core purpose, temporary contact behavior, rich mode limitation, and result fields. It doesn't explain prerequisites like 'phone must be on Telegram', but that is in the schema. A documentation link further fills gaps. Sufficiently complete.
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 schema covers 100% of parameters with detailed descriptions, so the baseline is 3. The description's note that 'parse_mode=rich cannot be combined with files' is helpful but is also present in the schema's parse_mode description. No additional parameter semantics provided beyond schema.
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 opens with 'Send to a phone number', clearly stating the action and specific resource. It also mentions the temporary contact creation and text/file sending, which distinguishes it from sibling tools like send_message that likely operate on existing chats.
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?
It clearly implies the use case (when you have a phone number) by starting with 'Send to a phone number'. It does not explicitly mention alternatives or exclusions, but the phone-number focus is clear enough to guide tool selection. Lacks an explicit 'use send_message instead when you have a chat ID' style note, so not a 5.
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.
7 tool updates
v0.45.0- Changed
edit_message4 fields changed- changed
Input schema / properties / parse_mode / descriptionPrevious value: -"'markdown', 'html', or 'auto' (detect from content). Default is 'auto'."New value: +"'markdown'/'html'/'auto': classic entity formatting (auto detects). 'rich': Telegram Rich Message document; dialect auto-detected (known HTML tags outside code → rich HTML, else rich markdown). Default is 'auto'. parse_mode='rich' cannot be combined with files." - changed
Input schema / properties / parse_mode / enumPrevious value: -[ - "markdown", - "html", - "auto" -]New value: +[ + "markdown", + "html", + "auto", + "rich" +] - added
Output schema / properties / richAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / rich_formatAdded value: +{ + "type": "string" +}
- Changed
find_chats1 field changed- changed
Input schema / properties / query / descriptionPrevious value: -"Name, username (no @), phone (+country…), or comma-separated multi-queries. Required for global search unless you use min_date/max_date or folder alone."New value: +"Name, username (no @), phone (+country…), or comma-separated usernames for batch lookup. Example: 'alice,bob,charlie'. Required for global search unless you use min_date/max_date or folder alone."
- Changed
get_chat_info3 fields changed- added
Input schema / properties / common_chats_limitAdded value: +{ + "default": 10, + "description": "Max common groups to list for user targets.", + "type": "integer" +} - added
Output schema / properties / common_chatsAdded value: +{ + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / common_chats_has_moreAdded value: +{ + "type": "boolean" +}
- Changed
get_messages3 fields changed- added
Input schema / properties / contextAdded value: +{ + "default": 0, + "description": "Number of surrounding messages to include as context for each search result. 0 = disabled (default). 1-10 = include N messages before and N after each result. Also fetches the message being replied to and top replies (if include_replies=true). Requires chat_id. Disabled when result count exceeds cost-based caps.", + "maximum": 10, + "minimum": 0, + "type": "integer" +} - added
Input schema / properties / from_userAdded value: +{ + "default": null, + "description": "Only return messages from this sender. Not a display-name or contact-name search — bare strings resolve like chat_id via get_entity (usernames are case-insensitive and may match an unrelated channel). Prefer @username, phone (+…), or numeric user id. Also accepts 'me', 'self', t.me URL, -100 prefixed id. Uses Telegram's native from_id server-side filter (per-chat search only).", + "type": "string" +} - added
Input schema / properties / include_repliesAdded value: +{ + "default": false, + "description": "If true, fetch up to 5 direct replies per search result and attach as replies. Each result costs one API call (not batchable). Default: false.", + "type": "boolean" +}
- Changed
invoke_mtproto3 fields changed- added
Input schema / properties / include_sensitiveAdded value: +{ + "default": false, + "description": "If true, return the raw result including PII and credential-shaped fields (phone, access_hash). Default false drops them.", + "type": "boolean" +} - removed
Output schema / properties / result / additionalPropertiesRemoved value: -true - removed
Output schema / properties / result / typeRemoved value: -"object"
- Changed
send_message4 fields changed- changed
Input schema / properties / parse_mode / descriptionPrevious value: -"'markdown', 'html', or 'auto' (detect from content). Default is 'auto'."New value: +"'markdown'/'html'/'auto': classic entity formatting (auto detects). 'rich': Telegram Rich Message document; dialect auto-detected (known HTML tags outside code → rich HTML, else rich markdown). Default is 'auto'. parse_mode='rich' cannot be combined with files." - changed
Input schema / properties / parse_mode / enumPrevious value: -[ - "markdown", - "html", - "auto" -]New value: +[ + "markdown", + "html", + "auto", + "rich" +] - added
Output schema / properties / richAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / rich_formatAdded value: +{ + "type": "string" +}
- Changed
send_message_to_phone4 fields changed- changed
Input schema / properties / parse_mode / descriptionPrevious value: -"'markdown', 'html', or 'auto' (detect from content). Default is 'auto'."New value: +"'markdown'/'html'/'auto': classic entity formatting (auto detects). 'rich': Telegram Rich Message document; dialect auto-detected (known HTML tags outside code → rich HTML, else rich markdown). Default is 'auto'. parse_mode='rich' cannot be combined with files." - changed
Input schema / properties / parse_mode / enumPrevious value: -[ - "markdown", - "html", - "auto" -]New value: +[ + "markdown", + "html", + "auto", + "rich" +] - added
Output schema / properties / richAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / rich_formatAdded value: +{ + "type": "string" +}
1 tool update
v0.37.0- Added
search_messages_globally
1 tool update
- Removed
search_messages_globally
8 tool updates
v0.36.0- Changed
edit_message3 fields changed- removed
Output schema / additionalPropertiesRemoved value: -true - added
Output schema / descriptionAdded value: +"Return type for ``send_message`` and ``edit_message``." - added
Output schema / propertiesAdded value: +{ + "action": { + "type": "string" + }, + "chat": { + "additionalProperties": true, + "type": "object" + }, + "code": { + "type": "integer" + }, + "date": { + "type": "string" + }, + "edit_date": { + "type": "string" + }, + "error": { + "type": "string" + }, + "error_code": { + "type": "string" + }, + "exception": { + "additionalProperties": true, + "type": "object" + }, + "message_id": { + "type": "integer" + }, + "ok": { + "type": "boolean" + }, + "operation": { + "type": "string" + }, + "params": { + "additionalProperties": true, + "type": "object" + }, + "reply_markup": { + "additionalProperties": true, + "type": "object" + }, + "sender": { + "additionalProperties": true, + "type": "object" + }, + "status": { + "type": "string" + }, + "text": { + "type": "string" + }, + "topic_id": { + "type": "integer" + } +}
- Changed
find_chats3 fields changed- removed
Output schema / additionalPropertiesRemoved value: -true - added
Output schema / descriptionAdded value: +"Return type for ``find_chats``." - added
Output schema / propertiesAdded value: +{ + "action": { + "type": "string" + }, + "chats": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" + }, + "code": { + "type": "integer" + }, + "error": { + "type": "string" + }, + "error_code": { + "type": "string" + }, + "exception": { + "additionalProperties": true, + "type": "object" + }, + "ok": { + "type": "boolean" + }, + "operation": { + "type": "string" + }, + "params": { + "additionalProperties": true, + "type": "object" + } +}
- Changed
get_chat_info3 fields changed- removed
Output schema / additionalPropertiesRemoved value: -true - added
Output schema / descriptionAdded value: +"Return type for ``get_chat_info``." - added
Output schema / propertiesAdded value: +{ + "action": { + "type": "string" + }, + "code": { + "type": "integer" + }, + "error": { + "type": "string" + }, + "error_code": { + "type": "string" + }, + "exception": { + "additionalProperties": true, + "type": "object" + }, + "first_name": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "is_bot": { + "type": "boolean" + }, + "is_channel": { + "type": "boolean" + }, + "is_forum": { + "type": "boolean" + }, + "is_group": { + "type": "boolean" + }, + "is_user": { + "type": "boolean" + }, + "last_name": { + "type": "string" + }, + "ok": { + "type": "boolean" + }, + "operation": { + "type": "string" + }, + "params": { + "additionalProperties": true, + "type": "object" + }, + "participants_count": { + "type": "integer" + }, + "phone": { + "type": "string" + }, + "title": { + "type": "string" + }, + "topics": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" + }, + "topics_has_more": { + "type": "boolean" + }, + "username": { + "type": "string" + } +}
- Changed
get_messages3 fields changed- removed
Output schema / additionalPropertiesRemoved value: -true - added
Output schema / descriptionAdded value: +"Return type for ``search_messages_globally`` and ``get_messages``." - added
Output schema / propertiesAdded value: +{ + "_warning": { + "type": "string" + }, + "action": { + "type": "string" + }, + "code": { + "type": "integer" + }, + "error": { + "type": "string" + }, + "error_code": { + "type": "string" + }, + "exception": { + "additionalProperties": true, + "type": "object" + }, + "has_more": { + "type": "boolean" + }, + "messages": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" + }, + "ok": { + "type": "boolean" + }, + "operation": { + "type": "string" + }, + "params": { + "additionalProperties": true, + "type": "object" + }, + "total_count": { + "type": "integer" + } +}
- Changed
invoke_mtproto3 fields changed- removed
Output schema / additionalPropertiesRemoved value: -true - added
Output schema / descriptionAdded value: +"Return type for ``invoke_mtproto``.\n\nThe success payload is a JSON-safe dict whose shape depends on the\nTelegram API method invoked. Common top-level fields are listed here;\neverything else passes through as-is." - added
Output schema / propertiesAdded value: +{ + "_": { + "type": "string" + }, + "action": { + "type": "string" + }, + "chats": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" + }, + "code": { + "type": "integer" + }, + "date": { + "type": "integer" + }, + "error": { + "type": "string" + }, + "error_code": { + "type": "string" + }, + "exception": { + "additionalProperties": true, + "type": "object" + }, + "id": { + "type": "integer" + }, + "messages": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" + }, + "ok": { + "type": "boolean" + }, + "operation": { + "type": "string" + }, + "params": { + "additionalProperties": true, + "type": "object" + }, + "result": { + "additionalProperties": true, + "type": "object" + }, + "users": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" + } +}
- Changed
search_messages_globally3 fields changed- removed
Output schema / additionalPropertiesRemoved value: -true - added
Output schema / descriptionAdded value: +"Return type for ``search_messages_globally`` and ``get_messages``." - added
Output schema / propertiesAdded value: +{ + "_warning": { + "type": "string" + }, + "action": { + "type": "string" + }, + "code": { + "type": "integer" + }, + "error": { + "type": "string" + }, + "error_code": { + "type": "string" + }, + "exception": { + "additionalProperties": true, + "type": "object" + }, + "has_more": { + "type": "boolean" + }, + "messages": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" + }, + "ok": { + "type": "boolean" + }, + "operation": { + "type": "string" + }, + "params": { + "additionalProperties": true, + "type": "object" + }, + "total_count": { + "type": "integer" + } +}
- Changed
send_message3 fields changed- removed
Output schema / additionalPropertiesRemoved value: -true - added
Output schema / descriptionAdded value: +"Return type for ``send_message`` and ``edit_message``." - added
Output schema / propertiesAdded value: +{ + "action": { + "type": "string" + }, + "chat": { + "additionalProperties": true, + "type": "object" + }, + "code": { + "type": "integer" + }, + "date": { + "type": "string" + }, + "edit_date": { + "type": "string" + }, + "error": { + "type": "string" + }, + "error_code": { + "type": "string" + }, + "exception": { + "additionalProperties": true, + "type": "object" + }, + "message_id": { + "type": "integer" + }, + "ok": { + "type": "boolean" + }, + "operation": { + "type": "string" + }, + "params": { + "additionalProperties": true, + "type": "object" + }, + "reply_markup": { + "additionalProperties": true, + "type": "object" + }, + "sender": { + "additionalProperties": true, + "type": "object" + }, + "status": { + "type": "string" + }, + "text": { + "type": "string" + }, + "topic_id": { + "type": "integer" + } +}
- Changed
send_message_to_phone3 fields changed- removed
Output schema / additionalPropertiesRemoved value: -true - added
Output schema / descriptionAdded value: +"Return type for ``send_message_to_phone``." - added
Output schema / propertiesAdded value: +{ + "action": { + "type": "string" + }, + "chat": { + "additionalProperties": true, + "type": "object" + }, + "code": { + "type": "integer" + }, + "contact_removed": { + "type": "boolean" + }, + "contact_was_new": { + "type": "boolean" + }, + "date": { + "type": "string" + }, + "edit_date": { + "type": "string" + }, + "error": { + "type": "string" + }, + "error_code": { + "type": "string" + }, + "exception": { + "additionalProperties": true, + "type": "object" + }, + "message_id": { + "type": "integer" + }, + "ok": { + "type": "boolean" + }, + "operation": { + "type": "string" + }, + "params": { + "additionalProperties": true, + "type": "object" + }, + "phone_number": { + "type": "string" + }, + "reply_markup": { + "additionalProperties": true, + "type": "object" + }, + "sender": { + "additionalProperties": true, + "type": "object" + }, + "status": { + "type": "string" + }, + "text": { + "type": "string" + }, + "topic_id": { + "type": "integer" + } +}
2 tool updates
v0.29.0- Changed
send_message1 field changed- changed
Input schema / properties / files / descriptionPrevious value: -"List of attachment URLs or local paths (one or more strings). Local paths work in stdio mode only."New value: +"List of attachment URLs, local paths, or data URIs (one or more strings). data: URIs (data:<mime>;base64,<payload>) work in all server modes; local paths work in stdio mode only."
- Changed
send_message_to_phone1 field changed- changed
Input schema / properties / files / descriptionPrevious value: -"List of attachment URLs or local paths (one or more strings). Local paths work in stdio mode only."New value: +"List of attachment URLs, local paths, or data URIs (one or more strings). data: URIs (data:<mime>;base64,<payload>) work in all server modes; local paths work in stdio mode only."
8 tool updates
v0.21.0- First observed
edit_message - First observed
find_chats - First observed
get_chat_info - First observed
get_messages - First observed
invoke_mtproto - First observed
search_messages_globally - First observed
send_message - First observed
send_message_to_phone
TDQS
Scored across 8 tools
The tools are mostly distinct: get_messages vs search_messages_globally are clearly scoped (per-chat vs global), and send_message vs send_message_to_phone differ by target. However, get_messages and search_messages_globally could be confused when query terms are used, and find_chats vs get_chat_info have overlapping 'lookup' purposes. The descriptions help, but the boundaries between some retrieval tools are not entirely crisp.
Most tools follow a verb_noun pattern: get_messages, send_message, edit_message, find_chats, get_chat_info. The naming is clear and consistent for the read/write operations. However, there are two outliers: 'invoke_mtproto' uses a different style (verb_infrastructure) and 'send_message_to_phone' has a prepositional suffix that breaks the simple pattern, but overall the conventions are recognizable and predictable.
With 8 tools, the server is well within the ideal range (3-15). Each tool serves a distinct purpose: messaging (send/edit), retrieval (get/search), chat discovery (find/get), and low-level API access. It feels neither too thin nor too heavy, though a couple more specialized tools (e.g., for managing chat members or deleting messages) could be added, but the count is appropriate for a messaging-focused server.
The server covers the core messaging lifecycle: send, edit, read, and search. It also handles chat discovery and metadata retrieval. However, there is a noticeable gap: there is no delete_message tool (though invoke_mtproto could be used for it with danger flags). Also, the server lacks tools for managing chats (e.g., create group, add members) or handling message reactions, but those are not essential for basic messaging workflows. The low-level invoke_mtproto fills some gaps, so coverage is good overall.
Maintenance
Related MCP Connectors
Telegram bridge for your MCP-compatible agent. Bidirectional, no LLM in our stack.
Unified messaging MCP server: WhatsApp, Instagram, Telegram, SMS, Messenger & email support inbox
MCP server for Gainium — manage trading bots, deals, and balances via AI assistants
FastMCP server for posting formatted content to X (Twitter) — Tollbooth-monetized, DPYC-native
Related MCP Servers
- AlicenseNot gradedqualityFmaintenanceProduction-grade MCP server for Telegram with dual-mode Bot API and MTProto. 6 composite tools covering messages, chats, media, contacts management with 3-tier token optimization.11Apache 2.0
- AlicenseNot gradedqualityDmaintenanceMCP server that connects AI assistants to your real Telegram account via User API (MTProto). Features default-deny ACL with per-chat permissions, message search, file sending, forwarding, media downloads, and rate limiting.3MIT
- AlicenseNot gradedqualityBmaintenanceTelegram MTProto-based MCP server with 19 tools for reading, searching, sending, forwarding, and summarizing messagesMIT
- AlicenseNot gradedqualityDmaintenancePrivacy-first Telegram MCP server enabling maintainers to triage chats, inspect context, search messages, draft replies, and send authorized messages locally without a cloud relay.557 npm1MIT