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). schedule_date (ISO 8601) reschedules an already-queued message; it does not turn a delivered message into a scheduled one, and the result then carries status='scheduled'. 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 |
| schedule_date | No | ISO 8601 instant at which Telegram should deliver the message, e.g. '2026-10-20T09:00:00Z' or '2026-10-20T12:00:00+03:00'. Must be in the future. On send: queues the message instead of delivering now. On edit: reschedules an already-queued 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 | |
| scheduled | No | |
| error_code | No | |
| message_id | No | |
| draft_saved | No | |
| reply_to_id | No | |
| rich_format | No | |
| reply_markup | No | |
| schedule_date | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructive/idempotent/openWorld, so the bar is lower, and the description still adds real context: text-only constraint, no media edits, ownership requirement, and the non-obvious schedule_date caveat that editing a delivered message cannot make it scheduled. Error modes ('message not found or not editable') are also disclosed. Safety/authorization details are thinner than they could be.
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 purpose and constraints are front-loaded, which is good, but the description is long and spends several clauses describing success/error dict shapes that duplicate an existing output schema. Those return-value sentences and the bare documentation URL add length without new decision-relevant information.
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 5-parameter mutation tool with an output schema and annotations, the description covers purpose, ownership limits, parameter caveats, sibling routing, and failure modes. Nothing an agent needs to call it correctly 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 all five parameters are already documented in the schema, including the parse_mode enum values and schedule_date semantics. The description largely restates that content (rich dialect detection, rescheduling behavior) rather than adding new syntax or constraints, so it meets but does not exceed the baseline.
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 first sentence states a specific verb and resource ('Replace the text of an existing message in a Telegram chat') and immediately scopes it with ownership and text-only limits. It explicitly contrasts with send_message, so an agent can distinguish it from the closest sibling without opening schemas.
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 names the alternative ('use send_message to create new ones') and states when the tool is applicable (messages sent by the authenticated account, text only). It does not spell out a full when-not-to-use matrix (e.g. channel posts, bot messages), but the context is clear.
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. Results are ordered by ascending date-time (oldest first) in every mode, including message_ids and nested context lists; limit selects the newest N. 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?
Annotations already declare readOnlyHint=true, idempotentHint=true, and openWorldHint=true, so the safety/profile is covered. The description adds valuable behavioral detail beyond these: result ordering (ascending date-time in every mode), that limit selects the newest N, and side-effect notes like 'Each result costs one API call' for include_replies. It doesn't cover rate limits or caps for context mode beyond a brief mention, so a 4 is appropriate.
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 action, then proceeds through modes, filters, constraints, and return shape in a logical order. Every sentence earns its place; there is no repetition or filler. The documentation URL is appended without disrupting the flow.
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 13 parameters, a rich schema, and an output schema (which explains return values), the description provides a complete orientation: modes, ordering, mutual exclusions, and success fields. It could mention pagination behavior (has_more when limit is hit) or cost caps for context mode, but it is largely sufficient for correct invocation.
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 some meaning by explaining that from_user is a server-side per-chat filter and that context includes reply chains, but most parameter semantics (date filters, thread_scope enum, auto_expand_batches) are already fully documented in the schema. The description doesn't add significantly beyond what the schema provides.
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?
States a specific verb+resource ('Read or search messages in one chat') and enumerates the distinct modes (browse, search text, fetch by ids, load replies). The description clearly distinguishes it from search_messages_globally by emphasizing 'one chat' and from edit/send siblings. An agent can immediately tell what this tool is for.
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?
Provides explicit when-to-use guidance for each mode (search text, fetch by ids, load replies) and states a critical mutual-exclusion rule ('Do not combine message_ids with query or reply_to_id'). It also names the alternative sibling (search_messages_globally) by contrast in the one-chat scope. This exceeds a typical usage guideline.
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. Results are ordered by ascending date-time (oldest first); limit selects the newest N. 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?
Adds value beyond annotations (which only cover readOnly/idempotent/openWorld): discloses ordering ('ascending date-time, oldest first'), that 'limit selects the newest N', the return shape ('message list and metadata dict'), and the ignored-parameter caveat. Notably omits permission or rate-limit context, so it is strong but not exhaustive.
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?
Front-loads the core purpose and packs scope, filters, ordering, and return shape into compact sentences. Slightly dense but every clause carries information; the doc link is the only marginal element.
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 an 8-parameter global search with a full output schema and rich annotations, the description covers scope, ordering, limit semantics, and the count caveat. Missing only explicit sibling routing ('use X instead when...'), which is a minor gap.
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 parameters are fully documented in the schema; the description only restates query/media filters and the include_total_count caveat. Per the baseline rule, 3 is appropriate when the schema does the heavy lifting.
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?
States a specific verb and resource ('Search all Telegram chats at once') and explicitly disambiguates scope with '(not scoped to one chat)', distinguishing it from chat-scoped siblings like get_messages and find_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?
Implies global scope usage and warns 'Global search ignores include_total_count', but never names an alternative sibling (e.g., when to use get_messages or find_chats instead) or states exclusion conditions. Usage is implied rather than explicitly guided.
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. schedule_date (ISO 8601, must be in the future) queues the message instead of delivering it now, so the result carries status='scheduled' plus scheduled and schedule_date. save_as_draft=true saves the text as the chat's draft instead of sending it (empty message clears the draft; user sessions only, bots cannot; text-only, so no files, no parse_mode='rich', no schedule_date). 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. | |
| save_as_draft | No | If true, save the text as the chat's draft instead of sending it (an empty text clears the existing draft). User sessions only — bot accounts cannot call messages.saveDraft. Cannot be combined with schedule_date, files, or parse_mode='rich'. | |
| schedule_date | No | ISO 8601 instant at which Telegram should deliver the message, e.g. '2026-10-20T09:00:00Z' or '2026-10-20T12:00:00+03:00'. Must be in the future. On send: queues the message instead of delivering now. On edit: reschedules an already-queued 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 | |
| scheduled | No | |
| error_code | No | |
| message_id | No | |
| draft_saved | No | |
| reply_to_id | No | |
| rich_format | No | |
| reply_markup | No | |
| schedule_date | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare title, openWorldHint, and destructiveHint; the description goes well beyond by disclosing caption-vs-text behavior, auto-posting into linked discussion groups, draft-clearing semantics, session limitations (bots cannot save drafts), and the shape of success/error results. These are non-obvious side effects an agent must know before sending.
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?
Dense and front-loaded: core action first, then mode/attachment rules, then scheduling/draft variants, then result shape and sibling routing. Long, but nearly every sentence carries a distinct constraint; only the result-shape sentence is partly redundant with the output schema.
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 7-parameter write tool with rich conditional behavior, the description covers constraints, side effects, session prerequisites, and error shape, leaving nothing essential to inference even though the output schema already exists.
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 cross-parameter constraint knowledge beyond per-field docs – parse_mode='rich' cannot combine with files, save_as_draft excludes schedule_date/files/rich, and text becomes a caption when files are present – which raises it above the baseline.
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?
States a specific verb+resource ('Send text and optional file attachments to a Telegram chat') and immediately names the sibling boundaries: edit_message for modification and send_message_to_phone for phone-number targeting. An agent can distinguish it from all seven siblings without opening a schema.
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?
Explicit routing rules: '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.' It also states when to use schedule_date vs. save_as_draft and their mutual exclusions.
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. schedule_date (ISO 8601, future) queues the message instead of delivering now; save_as_draft=true saves the text as the draft in that chat instead of sending. 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. | |
| save_as_draft | No | If true, save the text as the chat's draft instead of sending it (an empty text clears the existing draft). User sessions only — bot accounts cannot call messages.saveDraft. Cannot be combined with schedule_date, files, or parse_mode='rich'. | |
| schedule_date | No | ISO 8601 instant at which Telegram should deliver the message, e.g. '2026-10-20T09:00:00Z' or '2026-10-20T12:00:00+03:00'. Must be in the future. On send: queues the message instead of delivering now. On edit: reschedules an already-queued message. | |
| 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 | |
| scheduled | No | |
| error_code | No | |
| message_id | No | |
| draft_saved | No | |
| reply_to_id | No | |
| rich_format | No | |
| phone_number | No | |
| reply_markup | No | |
| schedule_date | No | |
| contact_removed | No | |
| contact_was_new | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only flag openWorldHint and destructiveHint, but the description adds substantive side effects: a temporary contact may be created, and contact_was_new/contact_removed may appear in the result, plus the rich-mode and files incompatibility. It stops short of stating auth requirements or failure modes, leaving that to the schema.
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?
Front-loaded with the verb and resource, and every sentence carries a constraint or outcome. It is a dense single paragraph, readable but without breaks, which slightly hurts scannability for a ten-parameter 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?
For a complex ten-parameter mutation tool with a rich schema and an output schema present, the description covers the non-obvious behaviors – contact creation, scheduling, draft saving, and mode conflicts – so an agent can call it correctly. Remaining gaps are minor details already handled by the schema.
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 schema already documents all ten parameters and the baseline would be 3. The description earns a step up by explaining cross-parameter interactions (rich vs classic parse_mode, rich-with-files exclusion, schedule vs draft semantics) and by tying first_name/last_name/remove_if_new to the temporary-contact behavior.
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?
States a specific verb and resource – send to a phone number – with the key mechanism ('may create a temporary contact, then send text or files'). This distinguishes it from the sibling send_message, which targets a chat rather than a phone number, though the description never names the alternative explicitly.
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?
Gives concrete behavioral routing: schedule_date queues instead of delivering now, save_as_draft saves a draft instead of sending, and parse_mode=rich cannot combine with files. These describe when the tool behaves differently, but there is no explicit 'use this vs send_message/find_chats' guidance.
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.
3 tool updates
v0.46.1- Changed
edit_message6 fields changed- added
Input schema / properties / schedule_dateAdded value: +{ + "default": null, + "description": "ISO 8601 instant at which Telegram should deliver the message, e.g. '2026-10-20T09:00:00Z' or '2026-10-20T12:00:00+03:00'. Must be in the future. On send: queues the message instead of delivering now. On edit: reschedules an already-queued message.", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "chat_id", - "message_id", - "message" -]New value: +[ + "chat_id", + "message", + "message_id" +] - added
Output schema / properties / draft_savedAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / reply_to_idAdded value: +{ + "type": "integer" +} - added
Output schema / properties / schedule_dateAdded value: +{ + "type": "string" +} - added
Output schema / properties / scheduledAdded value: +{ + "type": "boolean" +}
- Changed
send_message6 fields changed- added
Input schema / properties / save_as_draftAdded value: +{ + "default": false, + "description": "If true, save the text as the chat's draft instead of sending it (an empty text clears the existing draft). User sessions only — bot accounts cannot call messages.saveDraft. Cannot be combined with schedule_date, files, or parse_mode='rich'.", + "type": "boolean" +} - added
Input schema / properties / schedule_dateAdded value: +{ + "default": null, + "description": "ISO 8601 instant at which Telegram should deliver the message, e.g. '2026-10-20T09:00:00Z' or '2026-10-20T12:00:00+03:00'. Must be in the future. On send: queues the message instead of delivering now. On edit: reschedules an already-queued message.", + "type": "string" +} - added
Output schema / properties / draft_savedAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / reply_to_idAdded value: +{ + "type": "integer" +} - added
Output schema / properties / schedule_dateAdded value: +{ + "type": "string" +} - added
Output schema / properties / scheduledAdded value: +{ + "type": "boolean" +}
- Changed
send_message_to_phone6 fields changed- added
Input schema / properties / save_as_draftAdded value: +{ + "default": false, + "description": "If true, save the text as the chat's draft instead of sending it (an empty text clears the existing draft). User sessions only — bot accounts cannot call messages.saveDraft. Cannot be combined with schedule_date, files, or parse_mode='rich'.", + "type": "boolean" +} - added
Input schema / properties / schedule_dateAdded value: +{ + "default": null, + "description": "ISO 8601 instant at which Telegram should deliver the message, e.g. '2026-10-20T09:00:00Z' or '2026-10-20T12:00:00+03:00'. Must be in the future. On send: queues the message instead of delivering now. On edit: reschedules an already-queued message.", + "type": "string" +} - added
Output schema / properties / draft_savedAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / reply_to_idAdded value: +{ + "type": "integer" +} - added
Output schema / properties / schedule_dateAdded value: +{ + "type": "string" +} - added
Output schema / properties / scheduledAdded value: +{ + "type": "boolean" +}
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
Hosted Telegram MCP server for Claude, ChatGPT and Cursor, with each action switched per account.
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
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceProduction-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.41 npm1MIT