telegram-mcp
Provides tools for interacting with Telegram channels, groups, and private conversations, including retrieving recent messages, searching messages, getting chat information, listing available chats, marking messages as read, checking unread messages, and getting chat status.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@telegram-mcpshow recent messages from @technews"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MCP Telegram Server
A Model Context Protocol (MCP) server that provides tools for interacting with Telegram channels, groups, and private conversations on behalf of a user. This server allows MCP clients to retrieve recent messages, search messages, get chat information, and manage conversations.
Features
Get Recent Messages: Retrieve the most recent messages from channels, groups, or private chats
Get Private Messages: Dedicated tool for reading private conversation messages with enhanced formatting
Search Messages: Search for specific content within channels, groups, or private conversations
Get Chat Info: Retrieve metadata and information about any Telegram chat (channels, groups, private)
Get Available Channels: List all channels and groups that the user has access to
Mark Messages as Read: Mark specific messages or all messages as read in conversations
Check Unread Messages: Find chats with unread messages in private conversations and groups
Get Chat Status: Diagnostic tool to check read status and chat capabilities
User Authentication: Works on behalf of the authenticated user (not bot tokens)
Related MCP server: Telegram Bot MCP Server
Prerequisites
Telegram API Credentials: You need to obtain API credentials from Telegram:
Log in with your phone number
Create a new application to get
api_idandapi_hash
User Session: You need to generate a session string for user authentication (see setup instructions below)
Installation
Install dependencies:
npm installBuild the project:
npm run buildSetup
1. Environment Variables
Create a .env file or set the following environment variables:
export TELEGRAM_API_ID="your_api_id"
export TELEGRAM_API_HASH="your_api_hash"
export TELEGRAM_SESSION="your_session_string"2. Generate Session String
To generate a session string, you can create a simple script:
import { TelegramClient } from "telegram";
import { StringSession } from "telegram/sessions/index.js";
import input from "input";
const apiId = parseInt(process.env.TELEGRAM_API_ID!);
const apiHash = process.env.TELEGRAM_API_HASH!;
const session = new StringSession("");
const client = new TelegramClient(session, apiId, apiHash, {
connectionRetries: 5,
});
(async () => {
await client.start({
phoneNumber: async () => await input.text("Enter your phone number: "),
password: async () => await input.text("Enter your password: "),
phoneCode: async () => await input.text("Enter the code you received: "),
onError: (err) => console.log(err),
});
console.log("Session string:", client.session.save());
console.log("Save this session string as TELEGRAM_SESSION environment variable");
await client.disconnect();
})();Usage
Running the Server
Start the MCP server:
npm startThe server communicates via stdio and can be used with any MCP client.
Available Tools
1. get_recent_messages
Retrieves recent messages from a Telegram channel, group, or private chat.
Parameters:
channel(string, required): Channel username (@channelname), group username, private chat username (@username), phone number (+1234567890), or chat IDlimit(number, optional): Number of messages to retrieve (default: 10, max: 100)sinceMinutes(number, optional): Get messages from the last N minutessinceHours(number, optional): Get messages from the last N hourssinceDate(string, optional): Get messages since this date (ISO format: 2023-12-01T10:00:00Z)
Examples:
Get 20 most recent messages from a channel:
{
"name": "get_recent_messages",
"arguments": {
"channel": "@examplechannel",
"limit": 20
}
}Get messages from a private chat:
{
"name": "get_recent_messages",
"arguments": {
"channel": "@username",
"limit": 15
}
}Get messages from the last 30 minutes:
{
"name": "get_recent_messages",
"arguments": {
"channel": "@examplechannel",
"sinceMinutes": 30
}
}2. get_private_messages
Dedicated tool for retrieving messages from private chat conversations with enhanced formatting.
Parameters:
contact(string, required): Contact identifier: username (@username), phone number (+1234567890), or user IDlimit(number, optional): Number of messages to retrieve (default: 10, max: 100)sinceMinutes(number, optional): Get messages from the last N minutessinceHours(number, optional): Get messages from the last N hourssinceDate(string, optional): Get messages since this date (ISO format: 2023-12-01T10:00:00Z)
Examples:
Get messages from a private chat by username:
{
"name": "get_private_messages",
"arguments": {
"contact": "@username",
"limit": 20
}
}Get messages from a contact by phone number:
{
"name": "get_private_messages",
"arguments": {
"contact": "+1234567890",
"limit": 10
}
}Get recent private messages from the last hour:
{
"name": "get_private_messages",
"arguments": {
"contact": "@username",
"sinceHours": 1
}
}3. get_channel_info
Retrieves information about a Telegram channel, group, or private chat.
Parameters:
channel(string, required): Channel username (@channelname), group username, private chat username (@username), phone number (+1234567890), or chat ID
Examples:
Get channel information:
{
"name": "get_channel_info",
"arguments": {
"channel": "@examplechannel"
}
}Get private chat information:
{
"name": "get_channel_info",
"arguments": {
"channel": "@username"
}
}4. search_messages
Searches for messages containing specific text in a channel, group, or private chat.
Parameters:
channel(string, required): Channel username (@channelname), group username, private chat username (@username), phone number (+1234567890), or chat IDquery(string, required): Search querylimit(number, optional): Number of results (default: 10, max: 100)sinceMinutes(number, optional): Search messages from the last N minutessinceHours(number, optional): Search messages from the last N hourssinceDate(string, optional): Search messages since this date (ISO format: 2023-12-01T10:00:00Z)
Examples:
Search in a channel:
{
"name": "search_messages",
"arguments": {
"channel": "@examplechannel",
"query": "important announcement",
"limit": 15
}
}Search in a private chat:
{
"name": "search_messages",
"arguments": {
"channel": "@username",
"query": "meeting",
"limit": 10
}
}Search messages from the last hour:
{
"name": "search_messages",
"arguments": {
"channel": "@examplechannel",
"query": "update",
"sinceHours": 1
}
}5. get_available_channels
Lists all channels and groups that the user has access to.
Parameters:
limit(number, optional): Number of channels to retrieve (default: 50, max: 200)includeGroups(boolean, optional): Include groups in addition to channels (default: false)
Example:
{
"name": "get_available_channels",
"arguments": {
"limit": 100,
"includeGroups": true
}
}6. mark_messages_read
Mark messages as read in a Telegram chat, group, or private conversation.
Parameters:
channel(string, required): Channel username, group username, private chat username (@username), phone number (+1234567890), or chat IDmessageIds(array of numbers, optional): Specific message IDs to mark as readmaxId(number, optional): Mark all messages up to this message ID as read
Important Note: This feature works with groups, supergroups, and private chats. Broadcast channels don't support read status operations due to Telegram API limitations.
Examples:
Mark specific messages as read in a group:
{
"name": "mark_messages_read",
"arguments": {
"channel": "@examplegroup",
"messageIds": [123, 124, 125]
}
}Mark messages as read in a private chat:
{
"name": "mark_messages_read",
"arguments": {
"channel": "@username"
}
}Mark all messages up to a specific ID as read:
{
"name": "mark_messages_read",
"arguments": {
"channel": "@examplegroup",
"maxId": 150
}
}7. check_unread_messages
Check for unread messages in private chats and groups.
Parameters:
limit(number, optional): Number of chats to check (default: 50, max: 200)includeChannels(boolean, optional): Include channels in addition to private chats and groups (default: false)onlyWithUnread(boolean, optional): Only return chats with unread messages (default: true)
Examples:
Check for unread messages in private chats and groups:
{
"name": "check_unread_messages",
"arguments": {
"limit": 100
}
}Include channels and show all chats (even with no unread messages):
{
"name": "check_unread_messages",
"arguments": {
"limit": 50,
"includeChannels": true,
"onlyWithUnread": false
}
}Check only chats with unread messages:
{
"name": "check_unread_messages",
"arguments": {
"onlyWithUnread": true
}
}8. get_chat_status
Get detailed status information about a chat including unread count, read status, and diagnostic information.
Parameters:
chat(string, required): Chat identifier: username (@username), phone number (+1234567890), or chat ID
Examples:
Get status of a private chat:
{
"name": "get_chat_status",
"arguments": {
"chat": "@username"
}
}Get status of a group:
{
"name": "get_chat_status",
"arguments": {
"chat": "@groupname"
}
}Note: This tool is particularly useful for debugging read status issues and understanding why mark_messages_read might not work as expected.
MCP Client Configuration
To use this server with an MCP client, add it to your client configuration:
Claude Desktop Configuration
Add to your claude_desktop_config.json:
{
"mcpServers": {
"telegram": {
"command": "node",
"args": ["/path/to/mcp-telegram-server/dist/index.js"],
"env": {
"TELEGRAM_API_ID": "your_api_id",
"TELEGRAM_API_HASH": "your_api_hash",
"TELEGRAM_SESSION": "your_session_string"
}
}
}
}Development
For development with auto-reload:
npm run devTo watch for changes and rebuild:
npm run watchSecurity Notes
Session Security: Keep your session string secure. It provides full access to your Telegram account.
API Credentials: Never share your API ID and hash publicly.
Channel Access: The server can only access channels that your Telegram account has permission to read.
Rate Limiting: Telegram has rate limits. The server doesn't implement rate limiting, so use responsibly.
Troubleshooting
Authentication Errors: Make sure your session string is valid and not expired.
Channel Access: Ensure your account has access to the channels you're trying to read.
API Limits: If you encounter rate limits, wait before making more requests.
Network Issues: The server includes connection retry logic, but network issues may still cause failures.
Mark Messages Read Issues:
If
mark_messages_readreturns success but messages aren't actually marked as read, useget_chat_statusto debugSome private chats may have restrictions on read status operations
Encrypted chats (secret chats) don't support read status marking via API
The function works best with regular groups and supergroups
Debugging Read Status Issues
If mark_messages_read isn't working:
Check chat status first:
"Get status information for my chat with @username"Verify chat type: The tool shows whether the chat supports read status operations
Check unread count: Use
check_unread_messagesto see if the operation actually workedTry different approaches: The server automatically tries multiple API methods for private chats
License
MIT License
Available Tools
8 toolscheck_unread_messagesC
Check for unread messages in private chats and groups
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of chats to check (default: 50, max: 200) | |
| onlyWithUnread | No | Only return chats with unread messages (default: true) | |
| includeChannels | No | Include channels in addition to private chats and groups (default: false) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden, yet it says nothing about read-only safety, return shape, pagination, or whether unread state is mutated. The verb 'check' weakly implies a read, but nothing concrete 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?
A single front-loaded sentence with no filler. It is efficient, though the brevity contributes to the gaps in guidance and behavioral disclosure rather than compensating for them.
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 zero-parameter-required read tool with full schema coverage and no output schema, this is minimally viable. The description omits any behavioral context that would let an agent reason about results or side effects.
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 three parameters (limit, onlyWithUnread, includeChannels) are fully documented in the schema. The description adds no parameter meaning beyond that, so 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?
States a specific verb ('Check') and resource ('unread messages') with a scope qualifier ('private chats and groups'). It is clearly distinct from siblings like search_messages or get_recent_messages, though it never names an alternative to reinforce the distinction.
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?
No when-to-use guidance, no exclusions, and no reference to the natural complement mark_messages_read. An agent must infer that this is the polling tool for unread status rather than a general message fetcher.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_available_channelsB
Get list of available channels and groups that the user has access to
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of channels to retrieve (default: 50, max: 200) | |
| includeGroups | No | Include groups in addition to channels (default: false) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does disclose that results are permission-filtered ('channels the user has access to'). However, it says nothing about pagination behavior, default/limit truncation, ordering, or rate limits, which matters for a list endpoint returning up to 200 items.
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?
A single tight sentence with no filler, and the resource plus scope are front-loaded. It is efficient but very thin for a tool with two filterable parameters.
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 simple two-parameter read-only list tool with full schema coverage and no output schema, the description is minimally adequate. An agent can call it correctly, but gets no hint of the return shape (channel objects, ids) or that results may be truncated at the limit.
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 clear descriptions and bounds for limit and includeGroups, so the schema does the heavy lifting. The description adds no meaning beyond the schema for either parameter, which is the expected 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 ('Get list of') and resource ('available channels and groups') with an access scope ('user has access to'). It separates itself conceptually from message-oriented siblings like get_recent_messages and search_messages, though it does not name or contrast any sibling 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?
No explicit when-to-use guidance, prerequisites, or named alternatives. The discovery use case (finding channels to then call get_channel_info or get_recent_messages on) is left entirely to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_channel_infoC
Get information about a Telegram channel, group, or private chat
| Name | Required | Description | Default |
|---|---|---|---|
| channel | Yes | Channel username (@channelname), group username, private chat username (@username), phone number (+1234567890), or chat ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure, and it says almost nothing. It does not state whether the call is read-only (implied but unstated), what happens for an invalid or unreachable channel, whether auth/bot membership is required, or how private chats behave. For a lookup tool interacting with external accounts, this is a meaningful gap.
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?
A single efficient sentence with the verb and resource front-loaded and no filler. It is appropriately short, though it is arguably too thin rather than too long.
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?
With no output schema and no annotations, the description must explain what 'information' is returned (title, description, member count, pinned message, etc.) and any behavioral caveats. It provides neither, so an agent cannot anticipate the response shape or error conditions.
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% and the single 'channel' parameter already enumerates accepted formats (@username, phone number, chat ID) in the schema. The description adds nothing beyond identifying the entity type, so 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?
States a specific verb ('Get') and resource ('information about a Telegram channel, group, or private chat'), and the entity types accepted are clear. However, it does nothing to separate itself from siblings like get_available_channels or get_chat_status, which an agent must disambiguate on its own.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no exclusions, and no mention of alternatives among the seven sibling tools. The agent is left to infer that this retrieves metadata for a channel it can already identify, versus listing channels or checking status.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_chat_statusC
Get detailed status information about a chat including unread count and read status
| Name | Required | Description | Default |
|---|---|---|---|
| chat | Yes | Chat identifier: username (@username), phone number (+1234567890), or chat ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It does not state whether this requires authentication, whether it is read-only or mutates read state, or what the returned status contains beyond two named fields.
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?
A single efficient sentence that front-loads the verb and resource with no wasted words. Appropriately sized for a one-parameter read 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?
Adequate for a simple one-param tool, but with no annotations and no output schema it should disclose more about the return payload and whether fetching status affects read state, which would help disambiguate from check_unread_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 description coverage is 100% and the 'chat' parameter already documents accepted identifier formats (@username, phone, chat ID). The description adds no further meaning beyond the schema. 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?
Clear verb (get) plus resource (chat status) with specific fields named ('unread count and read status'). It does not differentiate from siblings like check_unread_messages or get_channel_info, which overlap in the unread/channel domain.
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?
No indication of when to use this versus check_unread_messages, which also reports unread status, or get_channel_info for chat metadata. No exclusions or context provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_private_messagesC
Get messages from a private chat conversation
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of messages to retrieve (default: 10, max: 100) | |
| contact | Yes | Contact identifier: username (@username), phone number (+1234567890), or user ID | |
| sinceDate | No | Get messages since this date (ISO format: 2023-12-01T10:00:00Z) | |
| sinceHours | No | Get messages from the last N hours | |
| sinceMinutes | No | Get messages from the last N minutes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full disclosure burden, yet it says nothing about read-only safety profile, ordering of returned messages, pagination/limit behavior, auth requirements, or rate limits. Only the implicit (and underspecified) read semantics of "Get" are conveyed, which is a notable gap for a tool with no 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?
A single, front-loaded sentence with zero filler. It is efficient, though its brevity borders on under-specification rather than optimal tightness given the five parameters.
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?
With no annotations and no output schema, the description should compensate for return-format and filter-interaction gaps, but it does not: it never says what messages look like, their order, or how limit, sinceDate, sinceHours and sinceMinutes combine. For a 5-parameter read tool this leaves meaningful holes.
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% – limit, contact, sinceDate, sinceHours and sinceMinutes each have their own clear schema descriptions. The tool description adds no additional meaning (e.g., how the since* filters interact or precedence), so the baseline 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?
States a specific verb ("Get") and resource ("messages from a private chat conversation"), and the word "private" implicitly separates it from channel-based siblings like get_available_channels or get_channel_info. However, it never names an alternative such as search_messages or get_recent_messages to sharpen the distinction.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no statement of when to use this tool versus the siblings (get_recent_messages, search_messages, check_unread_messages), nor any prerequisites for the private chat context. The agent must infer usage entirely from the tool name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_recent_messagesC
Get recent messages from a Telegram channel, group, or private chat
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of recent messages to retrieve (default: 10, max: 100) | |
| channel | Yes | Channel username (@channelname), group username, private chat username (@username), phone number (+1234567890), or chat ID | |
| sinceDate | No | Get messages since this date (ISO format: 2023-12-01T10:00:00Z) | |
| sinceHours | No | Get messages from the last N hours | |
| sinceMinutes | No | Get messages from the last N minutes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations at all, the description carries the full behavioral burden and largely fails: it doesn't state that this is a read-only operation, whether authentication or channel membership is required, rate limits, or how the time filters interact. Only the implicit 'get' wording hints at a safe read.
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?
A single, front-loaded sentence with no filler or redundancy. It is appropriately sized, though it is arguably too thin for a five-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 five-parameter tool with no annotations and no output schema, the description omits the return shape (message fields, ordering, pagination) and the interplay of sinceDate/sinceHours/sinceMinutes, leaving real gaps an agent needs to call it correctly.
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 every parameter (limit, channel, sinceDate, sinceHours, sinceMinutes) is already documented in the schema. The description adds no extra meaning such as how the overlapping time filters combine, which is the baseline-3 expectation when 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 concrete verb (get) and resource (recent messages) plus the scope (Telegram channel, group, or private chat). It is clearly a read of recent messages, but it never names how it differs from siblings like search_messages or get_private_messages.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no exclusions, and no mention of the alternatives (search_messages for filtered lookup, get_private_messages for DMs). The agent must infer the intended use entirely from the word 'recent'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mark_messages_readB
Mark messages as read in a Telegram chat, group, or private conversation (not supported for broadcast channels)
| Name | Required | Description | Default |
|---|---|---|---|
| maxId | No | Mark all messages up to this message ID as read (alternative to messageIds) | |
| channel | Yes | Channel username, group username, private chat username (@username), phone number (+1234567890), or chat ID (works with groups/supergroups/private chats, not broadcast channels) | |
| messageIds | No | Specific message IDs to mark as read (optional - if not provided, marks all messages as read) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It does disclose one real constraint — broadcast channels are unsupported — which is genuine behavioral context (partially echoed by the channel param schema description). However, it omits permission requirements, side effects, and whether the operation is reversible or idempotent.
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?
A single, front-loaded sentence that conveys the action and its key scope limitation with no filler. Every clause earns its 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?
There is no output schema, so return values need not be explained, and the schema fully covers parameters. But for a mutation tool with zero annotations, the description does not fill the gaps around permissions, error cases, or effect on chat state, leaving it only minimally 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?
Schema description coverage is 100%, so all three parameters (maxId, channel, messageIds) are already documented in the schema, including that messageIds is optional and defaults to marking all messages. The description adds no parameter-level meaning beyond that, so 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?
States a specific verb+resource (mark messages as read) plus the scope of chats it applies to, and explicitly excludes broadcast channels, which distinguishes it from read-oriented siblings like get_recent_messages or check_unread_messages. It stops short of naming a sibling to contrast with, but the action is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to call this versus alternatives such as check_unread_messages or get_recent_messages, and no prerequisites (e.g. membership, auth state) are stated. Usage is only implied by the tool name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_messagesC
Search for messages in a Telegram channel, group, or private chat
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of messages to retrieve (default: 10, max: 100) | |
| query | Yes | Search query | |
| channel | Yes | Channel username (@channelname), group username, private chat username (@username), phone number (+1234567890), or chat ID | |
| sinceDate | No | Search messages since this date (ISO format: 2023-12-01T10:00:00Z) | |
| sinceHours | No | Search messages from the last N hours | |
| sinceMinutes | No | Search messages from the last N minutes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden, yet it says nothing about result ordering, pagination, rate limits, or authentication requirements. The only implicit signal is that it works across channel, group, and private chat types.
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?
A single efficient sentence with the resource front-loaded and zero padding. It is arguably too terse, but that is a completeness issue rather than verbosity.
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 six-parameter tool with no annotations and no output schema, the description is far too thin. It omits how results are returned, how the limit interacts with the date filters, and how it relates to sibling retrieval tools.
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 six parameters including the limit cap and the date filter formats. The description adds no semantics beyond what the schema provides, making the baseline 3 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?
States a specific verb (search) and resource (messages) plus the scope of chat types it covers. It does not distinguish itself from the sibling get_recent_messages or explain how a keyword search differs from that tool.
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?
No when-to-use guidance and no alternatives named, despite six siblings including the closely related get_recent_messages. The agent must infer that this is for keyword queries rather than browsing recent history.
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.
8 tool updates
v1.0.0- First observed
check_unread_messages - First observed
get_available_channels - First observed
get_channel_info - First observed
get_chat_status - First observed
get_private_messages - First observed
get_recent_messages - First observed
mark_messages_read - First observed
search_messages
TDQS
Scored across 8 tools
get_recent_messages overlaps with get_private_messages for private chats, and check_unread_messages overlaps with get_chat_status since both expose unread/read information. get_channel_info and get_chat_status also both provide chat metadata, so boundaries are somewhat blurred despite helpful descriptions.
Names are consistently snake_case and mostly follow a verb_noun pattern, such as get_recent_messages, search_messages, and mark_messages_read. Minor deviations like mark_messages_read and check_unread_messages are still readable and predictable.
Eight tools is well-scoped for a Telegram chat client and falls within the ideal 3-15 range. The set is not bloated, and each tool covers a reasonable operation even with some overlapping read/status use cases.
The surface covers reading, searching, listing channels, marking read, checking unread, and chat status. However, core Telegram actions like sending, editing, deleting, forwarding, or replying to messages are missing, which is a notable gap for a messaging server.
Maintenance
Related MCP Connectors
Unofficial Telegram MCP server — read, search, reply and react in your own Telegram account.
Unified inbox MCP for WhatsApp, Telegram, Email, voice — read/send messages, search, AI agents.
Unified messaging MCP server: WhatsApp, Instagram, Telegram, SMS, Messenger & email support inbox
Telegram bridge for your MCP-compatible agent. Bidirectional, no LLM in our stack.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to interact with Telegram accounts through MCP, supporting messaging, contacts, groups, media, and admin functions.4Apache 2.0
- AlicenseAqualityDmaintenanceEnables AI assistants to publish, edit, search, and manage messages in Telegram channels via a set of MCP tools.8MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI assistants like Claude to read, search, and send messages through your personal Telegram account via MCP tools.MIT
- FlicenseBqualityCmaintenanceEnables MCP clients to interact with Telegram user accounts, providing tools for messaging, contacts, groups, channels, and media management through the Telegram API.853-