Telegram MCP
Connects to a personal Telegram account via TDLib to read messages from an allowlist of chats, search message history, fetch chat and message details, and optionally send text messages after explicit user approval.
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 MCPsearch my Telegram chats for messages about the project deadline"
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.
Telegram MCP
A local Model Context Protocol server that connects to your personal Telegram account through TDLib, Telegram's official client library. It is read-only by default, limited to an explicit allowlist of chats, with optional approval-gated sending.
Every tool resolves its target and rejects anything outside the allowlist.
Sending is off unless enabled, and every message requires your explicit approval in an approval prompt. The AI agent cannot approve on your behalf.
No edit, delete, forward, join, leave, or reaction operations exist in the server.
The Telegram session, database, and config stay on your machine and are gitignored.
One shared daemon owns TDLib, so any number of MCP client sessions can use it at once.
Requirements
Node.js 20 or newer
A Telegram account
Telegram API credentials from my.telegram.org
Related MCP server: telegram-mcp
Setup
git clone https://github.com/aminkh17/telegrammcp.git
cd telegrammcp
npm install
npm run build
cp config.example.json config.jsonThen edit config.json and set apiId and apiHash.
API credentials
This project does not ship API credentials. Create your own application at
my.telegram.org → API development tools, then copy its api_id
and api_hash into config.json:
{
"apiId": 123456,
"apiHash": "your_api_hash_here"
}config.json is ignored by git and never leaves your machine.
Authentication
Authentication is done through MCP tools, so it works entirely from your MCP client:
auth_status— see what step is needed.auth_startwith your international phone number, e.g.+14155550123.auth_codewith the code Telegram sent.auth_passwordwith your two-step verification password, if enabled.
The session is persisted under data/tdlib, so this is a one-time flow. auth_logout destroys
the local session and cached Telegram data.
MCP client setup
OpenCode
Add the server to your global ~/.config/opencode/opencode.json:
{
"mcp": {
"telegram": {
"type": "local",
"command": ["node", "/absolute/path/to/telegrammcp/dist/index.js"],
"enabled": true
}
}
}Other MCP clients
Use the built entry point as a stdio server:
{
"mcpServers": {
"telegram": {
"command": "node",
"args": ["/absolute/path/to/telegrammcp/dist/index.js"]
}
}
}Tools
Tool | Purpose |
| Check login state and required step |
| Phone login flow |
| Destroy the local session (requires |
| List chat ids/titles (metadata only) to build the allowlist |
| Show resolved allowlist entries and errors |
| Chat details: type, username, member count, description |
| Read history, oldest first, with pagination |
| Search text in one or all allowlisted chats |
| Fetch one message by id |
| Send a text message to an allowlisted chat, only after user approval |
Sending messages (approval required)
Sending is disabled by default. To enable it, set this in config.json:
{
"allowSending": true
}Every send_message call then works like this:
The server checks that sending is enabled and that the chat is allowlisted, and stores the exact message as a short-lived draft.
The server asks you to approve it through an MCP approval prompt (form elicitation). The prompt shows the target chat, any reply target, and the full text.
Only if you turn on Send this message and submit is that exact draft sent. Declining, cancelling, or ignoring the prompt for 10 minutes sends nothing.
The approval prompt comes from the server, not from the AI, so the agent cannot approve its own messages. If your MCP client does not support approval prompts, sending is refused.
Messages are plain text, up to 4096 characters, and can optionally reply to a message in the same chat or be sent silently. Sending uses the same allowlist as reading.
Allowlist
Only chats listed in allowedChats can be read. Each entry accepts:
Form | Example |
Username |
|
Public link |
|
Numeric chat id |
|
Exact chat title |
|
Numeric ids and usernames are the most stable. If two chats share a title, resolution fails and asks for an id or username.
To find chats:
Keep
"allowChatDiscovery": true(default).Call
discover_chats, optionally with a query, to get ids and titles.Add the ids or usernames to
allowedChatsinconfig.json.Optionally set
"allowChatDiscovery": falseto make even chat metadata unavailable.
config.json is re-read on every tool call, so allowlist and limit changes apply immediately.
No restart is needed.
Discovery never returns message contents.
Configuration reference
config.json:
Key | Default | Meaning |
| unset | Telegram API credentials from my.telegram.org |
|
| Chats that may be read |
|
| Enable |
|
| Enable |
|
| Default page size |
|
| Upper bound for |
|
| Max characters per message text |
|
| Idle time before the shared daemon exits |
|
| TDLib log verbosity (stderr) |
Environment overrides:
TELEGRAM_MCP_CONFIG— absolute path toconfig.jsonTELEGRAM_MCP_DATA_DIR— absolute path for the TDLib database and filesTELEGRAM_MCP_DEBUG=1— verbose MCP-level logging to stderr
Shared daemon
TDLib allows only one process to open a database at a time. MCP clients usually start one server
process per session, so every dist/index.js is a thin proxy: the first tool call starts a
detached dist/daemon.js that owns TDLib, and all sessions talk to it over data/daemon.sock.
The daemon starts automatically on demand. There is only ever one.
After
daemonIdleTimeoutSecondsof inactivity it closes TDLib, removes the socket, and exits. The next tool call starts a fresh daemon.config.jsonis reloaded per request. ChangingallowedChatsor limits takes effect immediately; changingapiId/apiHashrecreates the TDLib client on the next request.Daemon logs go to
data/daemon.log(rotated todata/daemon.log.oldat 5 MB).The socket is created with mode
0600.
Useful commands:
# Show daemon health and PID
curl --unix-socket data/daemon.sock http://localhost/health
# Run the daemon in the foreground for debugging
npm run daemon
# Stop it manually (it restarts on the next tool call)
pkill -f 'telegrammcp/dist/daemon.js'Security model
Reads only use TDLib
get*andsearch*methods. The only write issendMessage.The allowlist is enforced before any history, search, or send call.
Sending requires
allowSending: trueplus explicit user approval of each exact message.Chat discovery is metadata-only and can be disabled.
All logs go to stderr; stdout is reserved for MCP JSON-RPC.
Daemon RPC uses a Unix socket with mode
0600, so only your user can connect.API credentials, session data, and
config.jsonare gitignored; nothing sensitive is in the repo.
The MCP client (your AI agent) can read messages from allowlisted chats. That is the intended trust boundary. Do not allowlist chats you do not want an agent to read.
Approval is enforced on the MCP tool path. Any program running as your user, including an agent with unrestricted shell access, could still use your local Telegram session directly. If that matters, restrict shell access with your MCP client's permission settings.
Troubleshooting
"Telegram API credentials are not configured" — set
apiIdandapiHashinconfig.json.Daemon problems — check
data/daemon.log; delete a staledata/daemon.sockif no daemon is running.Signed out — call
auth_status, thenauth_startto log in again."Sending is disabled" — set
"allowSending": trueinconfig.json."This MCP client does not support approval prompts" — use a client that supports MCP form elicitation; sending is refused otherwise.
Reboots — nothing to do. The daemon starts again on the next tool call.
Limitations
Media is described, not downloaded. Message text and captions only.
Secret chats and email-only login are not supported.
Reading user accounts through unofficial automation is a grey area under Telegram's terms; this server is intentionally read-only and low-volume.
Each machine or separate
data/directory needs its own login and daemon.
License
Available Tools
12 toolsauth_codeSubmit Telegram login codeC
Submit the login code Telegram sent to the account.
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | The login code from Telegram (digits, sometimes with letters). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=false and openWorldHint=true, so the description must carry the rest. It does not say whether the code is single-use, what happens on an incorrect code, whether a 2FA password step follows, or what a successful submission yields.
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 its brevity contributes to the missing flow context rather than making room for it.
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 one-parameter tool with full schema coverage, the basics are covered. However, an authentication step in a multi-tool flow benefits from noting the expected sequence and outcomes, and there is no output schema to fill that 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 description coverage is 100% and already explains that the value is the Telegram login code with digits sometimes containing letters. The description adds only the framing that the code was sent to the account, which is marginal beyond 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?
States a specific verb+resource: submitting the login code Telegram sent. That is clearly distinct from auth_password, auth_start, and auth_status without needing the schema. It stops short of naming that distinction 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?
There is no guidance on when to call this versus auth_password or auth_start, nor any prerequisite such as having called auth_start first. An agent must infer the position of this step in the auth flow from the tool name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
auth_logoutLog out of TelegramADestructive
Log out and destroy all local Telegram session data. This requires network access and cannot be undone without logging in again.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | Yes | Must be true to confirm logout. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructive and open-world behavior; the description adds that all local session data is destroyed, network access is required, and re-login is needed to recover. This is useful context beyond the annotations, though it does not detail server-side session invalidation or confirm-flag behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two front-loaded sentences with no filler; destructive scope and reversibility are communicated efficiently. Every sentence adds meaning.
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 one-parameter destructive logout, the description supplies the key operational facts: what is destroyed, network dependency, and irreversibility. The schema handles the confirmation parameter, and no output schema requires return-value explanation.
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% and the single required confirm parameter is fully documented in the schema. The description adds no parameter-specific meaning, such as what happens if confirm is false, so it meets the baseline only.
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 action, 'Log out,' and scope, 'destroy all local Telegram session data,' clearly distinguishing it from auth_start, auth_status, auth_code, and auth_password. An agent can identify this as the session-termination tool without inspecting the 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?
It implies use when ending a session and notes network access and irreversibility, but does not explicitly say when to choose this over auth_status or auth_start, nor does it state when not to use it. Guidance is present but mostly inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
auth_passwordSubmit Telegram two-step passwordA
Submit the two-step verification password, if the account has one enabled.
| Name | Required | Description | Default |
|---|---|---|---|
| password | Yes | The Telegram two-step verification password. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false and openWorldHint=true, so the mutating, externally-dependent nature is already visible. The description usefully adds the conditional 2FA requirement, but says nothing about failure behavior for an incorrect password, attempt limits/flood waits, or the effect on session state, which matter a great deal for an auth credential submission.
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?
One short sentence with the action front-loaded and the only meaningful condition attached. Nothing redundant and nothing that could be trimmed without losing 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 one-parameter tool with full schema coverage and no output schema, the description covers what it does and the key precondition. The remaining gap is flow placement relative to auth_start and auth_code and error handling, which are useful but secondary for a tool this simple.
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?
There is a single parameter with 100% schema description coverage, so the schema already explains that it is the Telegram two-step verification password. The description adds no format, source, or handling guidance beyond that, which is the expected baseline when the schema does the work.
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 names a specific verb (submit) and a specific resource (the two-step verification password), which clearly separates it from siblings such as auth_code (login code) and auth_status. It stops short of explicitly naming those siblings as alternatives, so it is clear but not maximally differentiated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The clause 'if the account has one enabled' gives a real precondition, which is more than most definitions offer. However, it never states where this sits in the auth flow (after auth_start/auth_code), how to determine whether 2FA is enabled, or what to do if submission fails, so the agent must infer sequencing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
auth_startStart Telegram loginA
Start phone-number login. Telegram sends a login code to the account. After calling this, call auth_code with the code, and auth_password if two-step verification is enabled.
| Name | Required | Description | Default |
|---|---|---|---|
| phoneNumber | Yes | International phone number including country code, for example +14155550123. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already mark this as non-read-only and open-world. The description adds important behavior: Telegram sends a login code to the account and the flow continues through auth_code and auth_password when 2FA is enabled. It does not cover failure cases, rate limits, or session side effects, but it provides strong workflow context beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is short, front-loaded with the action, and every sentence contributes either the side effect or the required follow-up calls. There is no unnecessary wording.
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 login-start tool with annotations and a fully documented single parameter, the description covers the essential action, side effect, and next steps. Because no output schema exists, it could say more about what auth_start returns, but the workflow guidance is otherwise 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%, and the single phoneNumber parameter is fully documented in the schema with an international format example. The description only refers to 'phone-number login' and adds no format or validation detail beyond the schema, so the baseline score 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 uses a specific verb and resource: 'Start phone-number login.' It also distinguishes this step from the sibling tools auth_code and auth_password by explaining the sequence.
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 explicitly states when to use this tool and names the follow-up tools: call auth_code after receiving the code, and auth_password if two-step verification is enabled. This gives clear sequencing with no ambiguity about the next step.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
auth_statusTelegram auth statusARead-only
Check whether the Telegram session is signed in and which login step is required. Start here if Telegram tools return an authentication error.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description usefully signals that the response indicates which login step is required, but it does not enumerate the possible steps or explain what a signed-out result looks like, so the agent must infer the recovery path.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no waste: the capability comes first and the usage trigger second. Nothing is redundant or buried.
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 explaining returns, the description carries the burden of telling the agent what comes back, and it does so at a high level (signed-in flag plus required login step). Naming the concrete step values would close the remaining gap for this small diagnostic tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4. The description correctly implies a parameterless status probe and adds no misleading argument expectations.
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 check (whether the Telegram session is signed in) and an additional output (which login step is required). It is clearly distinct from the mutating siblings auth_start, auth_code, auth_password and auth_logout, though it does not name them 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?
It gives an explicit entry condition: 'Start here if Telegram tools return an authentication error.' That tells the agent when to reach for this tool, but it does not say when to skip it (e.g. once already signed in, proceed directly to discover_chats).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
discover_chatsDiscover Telegram chatsARead-only
List chat ids and titles to help populate the allowlist. This returns metadata only, never message contents. Requires allowChatDiscovery in config.json. Pass a query to search, or omit it to list top chats.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of chats to return (default 100). | |
| query | No | Optional text to search in chat titles and usernames. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, but the description adds genuinely new behavioral facts: returns metadata only and never message contents, and requires a config flag to be enabled. The main remaining gap is nothing about result ordering or whether the underlying chat list is fetched live from Telegram each call.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, each carrying distinct information: purpose, safety/scope, prerequisite, and usage mode. The most decision-relevant content (what it returns and what it does not) is front-loaded with no filler.
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 two-parameter read-only tool with full schema coverage and no output schema, the description covers purpose, return content, precondition, and both usage modes. Minor omissions like ordering or whether limit applies to search results are not described, but nothing critical to a correct call 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 coverage is 100%, so both parameters are already documented, but the description adds the meaningful default behavior that omitting the query switches the tool from search to top-chats listing. That semantic (mode selection via presence/absence of a param) is not conveyed by the schema alone.
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 gives a specific verb and resource ('List chat ids and titles') plus the intent ('to help populate the allowlist') and an explicit scope boundary ('metadata only, never message contents'). It does not name the sibling it is distinguished from (list_allowed_chats), so the differentiation is implied rather than stated.
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 states two clear usage modes: pass a query to search, or omit it to list top chats, and it discloses the prerequisite that allowChatDiscovery must be enabled in config.json. It stops short of explicitly excluding cases where get_chat or list_allowed_chats would be the better call.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_chatGet chat infoARead-only
Get details about one allowlisted chat: title, type, username, member count, and description.
| Name | Required | Description | Default |
|---|---|---|---|
| chat | Yes | Allowlisted chat: @username, t.me link, numeric id, or exact title. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety and reach profile is covered externally. The description adds the meaningful constraint that only allowlisted chats are retrievable and, since no output schema exists, lists the fields returned. It does not say what happens on a non-allowlisted or unknown chat (error vs empty result), which is the main remaining behavioral 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?
One sentence, front-loaded with the verb and resource, with the return-field list appended where it is most useful. No redundant or filler wording; it stops slightly short of being fully self-contained rather than being padded.
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 one-parameter read tool this is nearly complete: the parameter is fully documented and, with no output schema, the description usefully names the return fields. The only missing piece an agent might want is failure behavior for chats outside the allowlist.
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% and the single 'chat' parameter already documents the accepted formats (@username, t.me link, numeric id, exact title). The description restates 'allowlisted chat' without adding format or resolution guidance beyond the schema, 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?
The description gives a specific verb ('Get details about') and a precisely scoped resource ('one allowlisted chat'), then enumerates the returned attributes (title, type, username, member count, description). The 'one' contrast against the sibling list_allowed_chats is implied but never stated outright, so it falls just short of full sibling differentiation.
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?
Usage is only implied: an agent can infer this is the single-chat lookup as opposed to the bulk list_allowed_chats or the message-oriented get_messages, but nothing in the text says when to prefer one over the other. There are no stated prerequisites or exclusions beyond the 'allowlisted' qualifier.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_messageGet one messageARead-only
Fetch a single message by id from an allowlisted chat.
| Name | Required | Description | Default |
|---|---|---|---|
| chat | Yes | Allowlisted chat: @username, t.me link, numeric id, or exact title. | |
| messageId | Yes | Message id within the chat. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered. The description adds one genuinely useful constraint — the chat must be allowlisted — but says nothing about what happens when the id or chat is not allowlisted, nor about error/no-result behavior.
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; the resource, the lookup key, and the access constraint are all stated up front.
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 with full schema coverage and no output schema, the definition is minimally sufficient — an agent knows what to call and how. It stops short of describing failure modes (non-allowlisted chat, unknown message id) that would matter for a tool restricted to an allowlist.
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 both parameters (chat formats, messageId bounds) are already documented in the schema. The description adds no format or semantics 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?
The description names a specific verb and resource ("Fetch a single message by id") and narrows scope to "an allowlisted chat." The word "single" implicitly separates it from the bulk sibling get_messages, though no sibling is named 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?
Usage is only implied: retrieving one message by id vs listing via get_messages or querying via search_messages. There is no explicit when-to-use/when-not clause and no statement of prerequisites beyond the passing mention of the allowlist.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_messagesRead chat historyARead-only
Read recent messages from one allowlisted chat, oldest first. Paginate older messages by passing the previous nextBeforeMessageId as beforeMessageId.
| Name | Required | Description | Default |
|---|---|---|---|
| chat | Yes | Allowlisted chat: @username, t.me link, numeric id, or exact title. | |
| limit | No | Number of messages to return (default from config). | |
| sinceDate | No | Only return messages at or after this ISO date or Unix timestamp in seconds. | |
| beforeMessageId | No | Return messages older than this message id. Use nextBeforeMessageId from a previous call. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish this as a safe read (readOnlyHint) against an open system (openWorldHint). The description adds meaningful behavior beyond that: results are ordered oldest first and paging is backward-only via a cursor, which shapes how an agent must consume the results. It does not state what the response contains (notably whether nextBeforeMessageId is returned) or what happens for a non-allowlisted chat.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero waste. Scope and ordering come first, then the paging mechanic, which is the order an agent needs 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?
With no output schema, the description should ideally confirm that the response carries nextBeforeMessageId, since the whole pagination workflow depends on it. Otherwise it covers scope, ordering, and paging adequately for a small read-only tool whose parameters are fully documented.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, with chat formats, limit bounds, sinceDate formats, and the beforeMessageId cursor all documented inline. The description's pagination sentence restates what the schema already says about nextBeforeMessageId, so it adds little parameter meaning beyond the structured fields.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb and resource (read messages), scopes it to one allowlisted chat, and states the ordering (oldest first). It is clearly distinct from get_message (single message) and search_messages (query-driven), though it never names those siblings 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?
Context is clear: use for recent history of a single allowlisted chat, and use the beforeMessageId/nextBeforeMessageId loop to walk backwards. There is no explicit routing statement about when to prefer search_messages or get_message instead, so the guidance stops short of full when/when-not coverage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_allowed_chatsList allowlisted chatsBRead-only
List every chat in the allowlist, with ids, types, usernames, and any resolution errors.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds one genuinely useful behavioral detail beyond that: entries may carry resolution errors, implying partial/failed lookups rather than a clean list. It says nothing about ordering, pagination, or how entries enter the allowlist.
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 sentence with zero filler, front-loading the action and then the payload. Nothing is repeated from the title or annotations.
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, enumerating the returned fields is a valuable addition that partially compensates. However, the description never explains what the allowlist is, how it relates to discover_chats, or what a resolution error means for the caller — gaps that matter for a zero-param tool whose result shape is otherwise undocumented.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is no parameter semantics to convey and the baseline of 4 applies. The description correctly implies the call is unfiltered and unscoped.
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?
"List every chat in the allowlist" is a specific verb plus resource, and the trailing clause names the returned fields (ids, types, usernames, resolution errors). It stops short of distinguishing itself from the sibling discover_chats, so an agent cannot tell from the description alone which listing tool applies.
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 and no named alternative, even though discover_chats and get_chat sit right beside it in the sibling list. The agent must infer from the name that this returns the allowlisted subset rather than discovered or individual chats.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_messagesSearch messagesARead-only
Search messages by text inside one allowlisted chat, or across all allowlisted chats. Results are newest first.
| Name | Required | Description | Default |
|---|---|---|---|
| chat | No | Optional allowlisted chat to search. Omit to search every allowlisted chat. | |
| limit | No | Maximum number of results (default from config). | |
| query | Yes | Text to search for. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered. The description adds genuinely new behavior: the allowlist restriction and result ordering ("newest first"). It does not address pagination behavior, matching semantics (substring vs token), or whether results are ranked vs purely chronological beyond the ordering note.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with zero waste: scope first, ordering second. Nothing is padded and nothing needs to be read twice.
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 three-parameter read-only search with full schema coverage and no output schema, the definition covers scope and ordering adequately. A brief note on result fields or matching behavior would close the remaining 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 description coverage is 100%, with chat, limit, and query all documented in-schema, so baseline is 3. The description restates the chat-omission rule already present in the schema and adds nothing about query matching or limit interaction.
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?
Names a specific verb and resource ("Search messages by text") and states the scope precisely: one allowlisted chat or all allowlisted chats. That scope distinction is what separates it from get_messages, but the description never names or contrasts with that sibling, leaving the agent to infer the difference.
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 usable context (omit chat to search everything) which tells the agent how to broaden scope, but offers no explicit when-to-use versus get_messages or get_message, and no exclusions or prerequisites besides the implicit allowlist constraint.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_messageSend message (requires user approval)A
Send a plain-text message to one allowlisted chat as the signed-in user. Requires allowSending in config.json. Every call shows the user an approval prompt with the exact chat and text; nothing is sent unless the user approves. Returns sent: false if the user declines. Do not retry a declined message unless the user asks.
| Name | Required | Description | Default |
|---|---|---|---|
| chat | Yes | Allowlisted chat: @username, t.me link, numeric id, or exact title. | |
| text | Yes | Plain-text message to send (max 4096 characters). | |
| replyToMessageId | No | Optional message id in the same chat to reply to. | |
| disableNotification | No | Send silently, without a notification for recipients. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations by disclosing the human-in-the-loop approval prompt showing exact chat and text, the failure return shape ('sent: false' on decline), and the config prerequisite. These are the details an agent needs to avoid blind retries and to explain outcomes to the user.
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?
Four short sentences, front-loaded with the action and scope, followed by the prerequisite, the approval behavior, and the retry rule. No filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description supplies the key return semantics ('sent: false' if declined) along with the approval gate and config dependency. For a four-parameter mutation tool with annotations, nothing an agent needs before calling 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 chat formats, the 4096-character bound, replyToMessageId, and disableNotification are already documented. The description only reinforces 'plain-text' and the single-allowlisted-chat constraint, adding little parameter-level meaning beyond 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?
States a specific verb and resource ('Send a plain-text message') plus the scope constraint ('to one allowlisted chat as the signed-in user'), which immediately separates it from the read-oriented siblings like get_messages and search_messages. An agent can identify the operation without opening the 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?
Gives clear preconditions ('Requires allowSending in config.json') and an explicit when-not-to rule ('Do not retry a declined message unless the user asks'). It does not name a sibling alternative, though the sibling list contains no other write tool, so the omission is minor.
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.
12 tool updates
v0.1.0- First observed
auth_code - First observed
auth_logout - First observed
auth_password - First observed
auth_start - First observed
auth_status - First observed
discover_chats - First observed
get_chat - First observed
get_message - First observed
get_messages - First observed
list_allowed_chats - First observed
search_messages - First observed
send_message
TDQS
Scored across 12 tools
Each tool has a distinct purpose: authentication steps are sequential and clearly separated, chat tools cover discovery/listing/details, and message tools cover listing, searching, fetching one, and sending. There is little risk of confusing one tool for another.
All tool names use consistent snake_case with clear verb_noun or auth_* prefixes. The pattern is predictable across authentication, chat, and message operations.
Twelve tools is well-scoped for a Telegram MCP server, covering authentication, chat discovery, message reading, search, and sending without excessive surface area.
The server covers the core lifecycle: login/logout/status, chat discovery and allowlist inspection, message reading/searching, and sending. Minor gaps exist around message editing/deletion, replies, and media, but core workflows are supported.
Maintenance
Related MCP Connectors
Search, read and reply to your Telegram Business chats, transcribed voice included.
WhatsApp and Telegram for AI agents, behind a policy gateway. OAuth or access key.
Your Telegram, WhatsApp, Instagram, mail and calendar in Claude or ChatGPT. Never sends messages.
Live Telegram data: trending topics, channel profiles & metrics, post history incl. edits/deletions.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to scoped, permissioned access to Telegram chats with per-chat read/write levels and human approval for sending messages.1MIT
- AlicenseNot gradedqualityCmaintenanceA read-only Telegram MCP server that only exposes a user-defined allowlist of chats, providing tools to list chats, fetch messages, search, and get context while stripping untrusted text and with no write capabilities.MIT
- AlicenseAqualityBmaintenanceEnables MCP-compatible clients to securely access and manage Telegram accounts, chats, messages, media, and contacts, with tiered permissions, write controls, and local caching.22Apache 2.0
- AlicenseAqualityCmaintenanceEnables agents to perform read-only access to explicitly permitted chats on Telegram Web, including history, native search, post comments, photos and files, multi-chat context collection, and persistent local conversation history via a dedicated browser profile without Telegram API registration.10MIT