mcp-telegram-bridge
A stdio MCP bridge that lets a local agent perform Telegram Bot API I/O with fail-closed chat admission, outbound secret scrubbing, and untrusted-input labeling.
Check connectivity / bot identity —
telegram_get_mereturns the bot's identity (not rate limited).Fetch chat metadata —
telegram_get_chatfor an allowed chat.Send text messages —
telegram_send_messagewith optionalparse_modeand inlinebuttons=[{id,label}](outbound text scrubbed for token-shaped secrets).Edit or clear inline buttons —
telegram_edit_reply_markupon an existing message.Acknowledge callback queries —
telegram_answer_callbackwith optional toast/alert text.Long-poll for updates —
telegram_get_updates, returning untrusted-labeled, size-capped, rate-limited batches (bots and self-messages omitted, duplicates text-stripped, heuristic safety labels); the agent owns the offset loop.Enforce admission — chats denied unless in
ALLOWED_CHAT_IDSor open mode is explicitly enabled.
Allows sending and managing Telegram messages through a bot, including sending messages with inline buttons, editing reply markup, answering callback queries, and fetching updates and chat metadata, with outbound text scrubbing and optional chat allowlist enforcement.
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., "@mcp-telegram-bridgeSend 'Build #42 passed' to the DevOps Telegram group"
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-bridge
Stdio MCP bridge to the Telegram Bot API, with fail-closed chat admission and outbound scrubbing.
A small Model Context Protocol server that a local agent (Cursor, Claude Desktop, Windsurf, and others) launches on your machine. The agent owns the conversation. This process does Bot API I/O, scrubs outbound secrets, and refuses chats you have not allowed.
Version 0.2.0 changes admission: an empty allowlist denies every chat. Set ALLOWED_CHAT_IDS, or opt in to open mode with ALLOW_ALL_CHATS=1.
Built for client-owned deployments. The bridge is not a hosted bot service. Games and game-master flows are one demo use case, not the product.
Owner: Antonio Castellon / Castellon.CH.
Quick start
Requirements: Python 3.11+, a bot token from @BotFather, and the numeric id of the chat you want the bot to use.
git clone https://github.com/antonio-castellon/mcp-telegram-bridge.git
cd mcp-telegram-bridge
uv sync --extra dev # or: python -m venv .venv && pip install -e ".[dev]"
cp .env.example .env # set TELEGRAM_BOT_TOKEN and ALLOWED_CHAT_IDS
uv run mcp-telegram-bridge # waits on stdin for MCP JSON-RPC; Ctrl+C to stopuv.lock pins every dependency with hashes. CI installs from that lock (uv sync --frozen). pip install -e ".[dev]" still works and uses the version ranges in pyproject.toml.
Cursor or Claude Desktop (mcp.json / claude_desktop_config.json):
{
"mcpServers": {
"telegram-bridge": {
"command": "uvx",
"args": ["--from", "mcp-telegram-bridge", "mcp-telegram-bridge"],
"env": {
"TELEGRAM_BOT_TOKEN": "YOUR_BOT_TOKEN_HERE",
"ALLOWED_CHAT_IDS": "-1001234567890"
}
}
}
}Do not commit a real token. Leave ALLOW_ALL_CHATS unset.
Related MCP server: Telegram MCP
Use as a Python library
The same operations are available without the MCP server. import mcp_telegram_bridge loads TelegramBridge and Settings only. It does not import the mcp package. Pass Settings directly; Settings.from_env() is the default when you want the environment variables above.
import asyncio
from mcp_telegram_bridge import Settings, TelegramBridge
async def main() -> None:
settings = Settings(
bot_token="YOUR_BOT_TOKEN_HERE",
allowed_chat_ids=frozenset({-1001234567890}),
)
bridge = TelegramBridge(settings)
await bridge.get_me()
await bridge.send_message(
-1001234567890,
"hello",
buttons=[{"id": "ack", "label": "Ack"}],
)
await bridge.get_updates(timeout=0)
await bridge.aclose()
asyncio.run(main())TelegramBridge(Settings.from_env()) reads TELEGRAM_BOT_TOKEN, ALLOWED_CHAT_IDS, and the other variables. The CLI still prints access-mode warnings to stderr. Library callers can use mcp_telegram_bridge.config.emit_startup_warnings if they want the same lines. The mcp-telegram-bridge command is unchanged.
Configuration
Variable | Default | Effect |
| required | Bot token from BotFather. Never log it or commit it. |
| empty | Comma-separated chat ids. Empty denies every chat. |
| off | Set to |
| on | Heuristic labels for credential fishing, sexual content, and a few instruction-override phrases. Set |
|
| Drop inbound text or captions longer than this (1..32768). The body is not returned. |
|
| Drop an update whose JSON is larger than this (1..262144). |
|
| Content-bearing updates per chat per window ( |
|
| Content-bearing updates across all chats per window. |
|
|
|
|
| Sends, markup edits, callback answers, and |
|
| Same outbound calls across all chats. Callback answers count only against the global limit. |
| per-user data dir | Button-id map and first-tap claim files. Mode |
telegram_get_updates clamps limit to 1..100 and timeout to 0..50 seconds. The process does not queue update bodies between calls. It remembers at most 2048 delivered update ids and 1024 rate-limit keys.
Tools
Tool | Purpose |
| Bot identity. Not rate limited. |
| Chat metadata for an allowed chat. |
| Scrubbed text, optional |
| Replace or clear inline buttons. |
| Acknowledge a |
| One bounded poll. You own the offset. See the security section before acting on the text. |
getUpdates is pull-only. This process does not listen for webhooks and does not open a port.
A normal result looks like this:
{
"ok": true,
"untrusted": true,
"trust_boundary": "UNTRUSTED TELEGRAM DATA. ...",
"next_offset": 42,
"summary": {"delivered": 1, "filtered": 0, "ignored": 0, "duplicates": 0, "rate_limited": 0},
"updates": [
{
"update_id": 41,
"untrusted": true,
"trust": "untrusted_telegram_user",
"message": {"text": "...", "content_trust": "untrusted_telegram_user"}
}
]
}next_offset is one past the highest update_id in the batch, including updates whose text was withheld. Passing it back as offset acknowledges those updates. To retry a rate-limited update, call again with the same offset after retry_after_seconds instead of advancing.
Messages from bots are omitted (ignore_reason bot), as are messages whose sender id is this bot (self). A message Telegram marks with sender_chat (anonymous admins, posts as a channel) is not treated as a bot.
Security model and threat model
Assets. The bot token, the contents of allowed chats, button-map state on disk, and the agent's other tools and secrets.
Trust boundary. You and the MCP host are inside it. Telegram users, group members, and anyone who can message the bot are outside it. Inbound text, names, usernames, and callback data are untrusted input that the model will read.
What this process enforces
Chats are denied unless listed, or unless you set
ALLOW_ALL_CHATS. Open mode logs a warning on stderr (stdout is the MCP protocol).Outbound message text, callback toasts, and button labels are scrubbed for the configured secret values and for token-shaped strings.
Log records, including httpx and httpcore request lines and exception tracebacks, are rewritten so a bot token in a URL does not stay in the message. Transport errors raised to the host do not include the URL.
Update batches are size-capped. Polls, delivered updates, and outbound calls are rate limited. Update ids whose text was already returned are not returned again. The caches are bounded.
With
SAFETY_STRICTon (the default), updates gainsafety.kind,safety.blocked, andsafety.warningfor a few patterns. Flagged text is still in the result. The host decides what to do with it.
What you still have to do. Run the process as a normal user, keep the token in a secret store or a permission-restricted .env, and set an allowlist. Treat every inbound string as data. Do not give the same agent a tool that reads credentials if untrusted chats can reach it. Review prompts before they can send.
The deployment checklist, data stored on disk, and a longer residual-risk note are in SAFETY.md. Report vulnerabilities as described in SECURITY.md.
Limits and residual risk
These controls reduce blast radius. They do not make a bot that an agent reads and answers safe against a hostile sender.
The untrusted label can be ignored by the model. A regex will not catch a rephrased instruction. The agent still has send tools.
SAFETY_STRICTis a heuristic for a few phrases. It misses other languages, encodings, and ordinary requests that are still untrusted.Rate limits are in-memory and per process. Restarting clears them.
offremoves that limit. A chat id that falls out of the 1024-key cache gets a fresh per-chat budget; the global limit still applies.Advancing
next_offsetpast a rate-limited or over-long update drops it. Telegram will not deliver it again.Deduping remembers 2048 ids. An older id can be shown again if the host polls it once more.
Scrubbing and log redaction are best-effort. A token split across fields, or a secret that does not match the patterns and is not in the environment, can still pass.
The bridge does not offer a read-only tool set. A host that exposes every tool can send messages.
Button-map and claim files are pruned by count (2000 mappings, 500 claims), not by age. They do not store message text. Delete the data directory to remove them.
There is no audit log. Whatever the MCP host stores (transcripts, provider logs) is outside this process.
Disabling httpx debug logging is still wise. Redaction covers the log record path this package installs; it is not a guarantee about every other tracer.
Architecture
+---------------------------+
| MCP host / agent | conversation, offset, product policy
+-------------+-------------+
| MCP (stdio)
v
+---------------------------+
| mcp-telegram-bridge | allowlist, scrub, bounds, untrusted labels
+-------------+-------------+
| HTTPS Bot API (getUpdates poll)
v
+---------------------------+
| api.telegram.org |
+-------------+-------------+
v
Telegram chatsUsage
Group or ops channel. One bridge per bot. Use the group for notes, triage, and handoff. Keep a person in the loop for anything hard to undo.
Buttons. buttons=[{id,label}, ...] becomes an inline keyboard. On a callback, answer it, then edit or clear the markup. Long ids are mapped to short callback data under the data directory.
Notify channel. Alerts with ack / snooze / escalate buttons. Telegram is the pager, not the source of truth.
Moderation drafts. The bridge has no ban, restrict, or delete tool. Say that in the agent prompt.
Agent skills
A companion skill can tell the agent when to call these tools and that it owns the offset. One is published as Telegram Bridge on Agensi. The skill is instructions only. This server remains the I/O and safety layer.
What this is not
Not a hosted or multi-tenant bot service
Not tied to one MCP host
Not a game engine
Not an admin bot
Not a webhook receiver
Sibling demos
Optional. This project does not require them.
grokgame is a tabletop demo surface
grok2telegram is an earlier experiment whose scrubbing rules informed
SAFETY.md
Development
uv sync --extra dev
uv run pytestTests mock Telegram with respx. No live token is required.
After a dependency change, run uv lock and commit uv.lock. CI uses the lock, audits it with pip-audit on Python 3.12, and runs gitleaks against the working tree. A pull request that only changes Markdown, docs/, or LICENSE does not start that workflow.
MCP registry
Canonical name: io.github.antonio-castellon/mcp-telegram-bridge
Also listed on mcpservers.org, MCP Marketplace, and Agensi.
Listing copy for marketplaces is in LAUNCHGUIDE.md.
Contact
General: info@castellon.ch
Support: support@castellon.ch
Security: security@castellon.ch (SECURITY.md)
License
MIT (c) Antonio Castellon / Castellon.CH
Available Tools
6 toolstelegram_answer_callbackC
Acknowledge a callback_query (optional toast text / alert).
| Name | Required | Description | Default |
|---|---|---|---|
| text | No | ||
| show_alert | No | ||
| callback_query_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It states the action and optional text/alert, but does not mention that this is a required acknowledgment to avoid the Telegram loading indicator, or any constraints (e.g., invalid callback_query_id behavior). It is too terse to convey the operational context.
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 a single concise sentence with no waste. It is front-loaded with the core action and includes the optional parameters in parentheses. However, it is so brief that it borders on under-specification, though it earns a 4 for efficiency.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool is a mutation with no annotations and an output schema (which likely describes the result), the description should still cover prerequisites and typical usage context. It fails to mention that this should be called after receiving a callback_query, or that it is necessary to prevent UI spinning. The description is incomplete for an agent to understand when and why to invoke it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It adds meaning by explaining 'toast text / alert', which maps to the 'text' and 'show_alert' parameters, giving agents a hint about their purpose. However, it does not clarify the distinction between toast and alert (i.e., show_alert=true forces a popup), nor does it explain the required callback_query_id beyond its obvious name.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action: acknowledging a callback_query, which is a specific verb and resource. It also hints at optional parameters (toast text/alert). However, it does not explicitly differentiate from sibling tools like telegram_send_message or telegram_edit_reply_markup, though the resource is distinct enough to infer.
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 guidance on when to use this tool versus alternatives. It does not mention that this is typically called in response to a callback_query from the user, nor does it state any conditions or exclusions. The description provides no context for selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
telegram_edit_reply_markupA
Edit or clear inline buttons on an existing message. Pass buttons=null/omit to strip markup; or a new [{id,label}] list.
| Name | Required | Description | Default |
|---|---|---|---|
| clear | No | ||
| buttons | No | ||
| chat_id | Yes | ||
| row_width | No | ||
| message_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the responsibility for behavioral disclosure. It does explicitly disclose that null/omitted buttons strip markup, which is a destructive action, and that the target must be an existing message. However, it does not mention side effects on message content, permission requirements, or the separate clear parameter's 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?
The description is two concise sentences with no fluff. The core action is front-loaded, and the parameter guidance follows naturally without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the primary use case well and benefits from an output schema, but it leaves material gaps: the clear flag and row_width are undocumented, and there are no notes about constraints or failure modes. For a mutation tool with zero annotations, a bit more context would be needed for fully confident invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description compensates partially by explaining the buttons parameter's two modes: null/omit to clear and a [{id,label}] list to set. However, it does not explain the clear boolean or row_width parameter, which are both non-obvious and absent from the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Edit or clear') and resource ('inline buttons on an existing message'), making the tool's purpose immediately clear. It also distinguishes this tool from sibling tools like telegram_send_message and telegram_get_updates by focusing on modifying an existing message's markup.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear operational guidance: pass buttons=null/omit to strip markup, or provide a new list to set buttons. It does not name sibling alternatives or explicitly state when not to use the tool, but the context of editing an existing message is sufficiently clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
telegram_get_chatC
Fetch chat metadata (getChat) for a chat_id.
| Name | Required | Description | Default |
|---|---|---|---|
| chat_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
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. It only says the operation fetches metadata and offers no context about read-only behavior, authentication requirements, failure modes, or what happens if the chat_id is invalid or inaccessible.
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 a single front-loaded sentence with no filler and no redundant information. Every word contributes to the meaning, which is ideal for a simple one-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?
With a simple one-parameter schema and an output schema present, the description covers the core mechanics. However, the absence of annotations and usage guidance leaves gaps around when to call it and what behavioral expectations exist, making it only minimally adequate overall.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, but it merely repeats the chat_id parameter name without explaining accepted formats, constraints, or meaning. It adds little beyond the input schema itself.
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 ('Fetch'), a clear resource ('chat metadata'), and names the underlying API ('getChat'). It clearly conveys the tool's purpose, though it does not explicitly differentiate it from siblings like telegram_get_me or telegram_get_updates.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives, nor does it mention any exclusions or preferred contexts. An agent must infer the intended use solely from the tool name and the word 'metadata'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
telegram_get_meA
Return the bot identity (getMe). Useful as a connectivity check.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden, and it does convey the read-only behavior by saying 'Return' and framing the call as a check. It adds the useful operational context of connectivity verification, though it does not discuss auth or error behavior, which is acceptable for this simple tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences with no filler. The core action and resource are stated first, and the diagnostic use case is added in a single appended clause.
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-argument, read-only endpoint with an output schema available, the description is complete. It tells the agent what the tool returns and when to use it, and nothing else is needed to invoke 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?
The tool has zero parameters and the schema confirms this, so there are no parameter semantics to clarify. The baseline score of 4 applies because the description has nothing meaningful to add 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?
The description names the specific verb 'Return' and the resource 'bot identity', and explicitly references the getMe API. This clearly distinguishes it from sibling tools like telegram_get_chat or telegram_send_message, which act on different resources.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly frames the tool as useful for a connectivity check, which is clear usage context. It does not name exclusions or alternatives, but for a zero-argument diagnostic method this is sufficient guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
telegram_get_updatesA
Long-poll getUpdates. The agent owns the offset loop. limit is clamped to 1..100 and timeout to 0..50. Every returned batch is labeled untrusted. Messages from bots and from this bot are omitted. Duplicate update ids are returned without text. When SAFETY_STRICT is enabled (the default), each delivered update includes safety.{kind,blocked,warning}. The classifier is a heuristic and does not stop prompt injection.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| offset | No | ||
| timeout | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full load and does so well: it discloses clamping ranges (limit 1..100, timeout 0..50), that batches are labeled untrusted, that bot-originated and duplicate updates are filtered or stripped of text, and that SAFETY_STRICT adds a safety.{kind,blocked,warning} object by default. It also honestly warns the classifier is heuristic and does not stop prompt injection.
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?
Six short sentences, each carrying unique operational information (clamping, trust labeling, filtering, safety payload, caveat) with the core behavior front-loaded. No sentence restates another or repeats the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and the description still adds the shape of the safety field and the filtering/duplicate rules that affect what actually comes back. For a long-poll reader with three optional params, nothing material 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 0%, so the description must compensate, and it does for limit and timeout by stating their clamped ranges. Offset is only alluded to via 'the agent owns the offset loop' rather than stating the confirm-and-increment semantics, and units for timeout are not given, so it falls short of fully documenting all three parameters.
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 opening 'Long-poll getUpdates' names a specific verb and resource, and 'The agent owns the offset loop' pins down the polling semantics. It is clearly distinct from siblings like telegram_send_message or telegram_get_chat, though the description never explicitly contrasts them.
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 agent owns the offset loop' implies the intended usage pattern (drive the loop yourself), but there is no explicit when-to-use or when-not-to-use guidance and no named alternative. Given the siblings are send/edit/answer tools rather than competing readers, the missing routing guidance is a minor gap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
telegram_send_messageA
Send a text message. Outbound text is scrubbed for token-shaped secrets. Optional buttons=[{id,label}] become an inline keyboard.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | ||
| buttons | No | ||
| chat_id | Yes | ||
| row_width | No | ||
| parse_mode | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations to carry safety or side-effect information, the description discloses two meaningful behaviors: outbound text is scrubbed for token-shaped secrets, and optional buttons become an inline keyboard. It does not cover all possible behaviors (e.g., parse_mode side effects), but it adds real value beyond a bare 'send message' statement.
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 the main action front-loaded and no filler. The token-scrubbing warning and button behavior each earn their 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?
The tool has five parameters, no annotations, and no schema description coverage, so the description carries a heavy load. It covers the core action and a critical gotcha (secret scrubbing), but omits semantics for parse_mode and row_width, which an agent would need to format messages or arrange buttons 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 0%, so the description must explain parameters. It only clarifies that optional buttons=[{id,label}] produce an inline keyboard, leaving chat_id, text, row_width, and parse_mode unexplained beyond their schema names and types.
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?
Opens with a specific verb and resource: 'Send a text message.' This clearly distinguishes it from sibling tools like telegram_get_me and telegram_get_updates, which are read/polling operations, and from telegram_edit_reply_markup, which modifies existing messages rather than creating a new one.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description makes the core use case clear—sending a message—and implies it should be used whenever the agent needs to post text to a chat. However, it provides no explicit guidance on when not to use it or how it differs from siblings such as telegram_answer_callback or telegram_edit_reply_markup.
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.
6 tool updates
v0.1.0- First observed
telegram_answer_callback - First observed
telegram_edit_reply_markup - First observed
telegram_get_chat - First observed
telegram_get_me - First observed
telegram_get_updates - First observed
telegram_send_message
TDQS
Scored across 6 tools
Each tool targets a distinct resource and action: fetching chat metadata, bot identity, polling updates, acknowledging callbacks, editing inline markup, and sending messages. There is no overlap in purpose, and an agent can select the right tool unambiguously from the descriptions.
All tools follow a consistent telegram_verb_noun pattern (get_chat, get_me, get_updates, answer_callback, edit_reply_markup, send_message). Verb choices are predictable and readable.
Six tools is well-scoped for a Telegram bridge, covering the core send/receive/callback loop without bloat. Every tool earns its place in the minimal agent workflow.
The surface covers the essential bridge lifecycle: polling updates, sending messages, acknowledging callbacks, editing markup, and fetching chat/bot metadata. Minor gaps exist for non-text message sending or message editing/deletion, but agents can work around these for the core bridge purpose.
Maintenance
Related MCP Connectors
Telegram bridge for your MCP-compatible agent. Bidirectional, no LLM in our stack.
Managed MCP gateway with OAuth, per-agent permissions, shared accounts and activity logs.
Hosted Telegram MCP server for Claude, ChatGPT and Cursor, with each action switched per account.
Unofficial Telegram MCP server — read, search, reply and react in your own Telegram account.
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
- FlicenseBqualityDmaintenanceEnables MCP clients to interact with Telegram user accounts, providing tools for messaging, contacts, groups, channels, and media management through the Telegram API.853-
- AlicenseAqualityAmaintenanceEnables 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
- AlicenseNot gradedqualityBmaintenanceEnables MCP clients like Codex or ChatGPT to securely receive, acknowledge, and send Telegram messages with durable delivery guarantees and idempotency.MIT