telegram-mcp-bridge
Provides a bridge to the Telegram Bot API, allowing agents to receive, acknowledge, and send Telegram messages, as well as edit, delete, and reply to messages with bounded message operations.
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-mcp-bridgeCheck for new Telegram messages and reply 'Thanks!' to each"
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 Bridge
A low-latency, durable bridge between the Telegram Bot API and MCP clients such as Codex, ChatGPT desktop/CLI, or any other compatible agent. The project does not include its own LLM; it gives an agent a deliberately restricted toolset for receiving, acknowledging, and sending Telegram messages.
Why two operating modes?
Profile | MCP transport | Telegram ingress | Intended use |
Local (recommended for Codex) |
| Long polling | Minimal attack surface, no listening port, and near-immediate event delivery |
Server | Stateless Streamable HTTP | HTTPS webhook | An always-on remote service behind a TLS reverse proxy |
SQLite in WAL mode is the source of truth. A webhook returns 200 only after commit, and long polling advances its offset only after a durable insert. The bridge uses a claim → lease → ack workflow. Incoming events are delivered at least once, with repeatedly unacknowledged events retained in quarantine for operator review.
MCP cannot wake a stopped Codex task by itself. While an agent is running, it can wait for events with
telegram_wait_updates. An always-on agent loop or scheduled task is required for autonomous 24/7 responses.
Related MCP server: Telegram Bot MCP
Quick local setup on Windows
Create a bot with
@BotFatherand store the token securely.Clone the repository, create a virtual environment, and install the hash-locked dependencies:
git clone https://github.com/ph4ntom-rev/telegram-mcp-bridge.git Set-Location telegram-mcp-bridge py -m venv .venv .\.venv\Scripts\python.exe -m pip install --require-hashes -r requirements.lock .\.venv\Scripts\python.exe -m pip install --no-deps -e . Copy-Item .env.example .envSet
TELEGRAM_BOT_TOKENand the numeric allowlists in.env.TELEGRAM_ALLOWED_USER_IDSauthorizes inbound actors.TELEGRAM_ALLOWED_CHAT_IDSauthorizes both inbound chats and outbound destinations. If both lists are populated, an event must satisfy both. Usernames are never used for authorization.If the bot already has a webhook, explicitly disable it without dropping pending updates:
.\.venv\Scripts\telegram-mcp.exe webhook delete --env-file .envVerify storage and Telegram connectivity:
.\.venv\Scripts\telegram-mcp.exe doctor --env-file .envAdd the stdio server in Codex through Settings → MCP servers → Add server, using absolute paths:
command: C:\absolute\path\telegram-mcp-bridge\.venv\Scripts\telegram-mcp.exe arguments: serve --transport stdio --env-file C:\absolute\path\telegram-mcp-bridge\.envAn equivalent
config.tomlentry is provided incodex-config.toml.example.
After restarting Codex, the tools appear under the telegram MCP server.
MCP tools
telegram_wait_updatesatomically leases the next batch of events and can wait for up to 30 seconds.telegram_ack_updatesacknowledges events only with the correct lease token.telegram_release_updatesreleases a batch after a temporary failure.telegram_replyreplies to a stored event and is safer than copying a rawchat_id.telegram_send_textsends only to chats explicitly present inTELEGRAM_ALLOWED_CHAT_IDS.telegram_edit_text,telegram_delete_message,telegram_typing, andtelegram_answer_callbackprovide bounded message operations.telegram_peek_updates,telegram_list_chats, andtelegram_bridge_statusare diagnostic read-only tools.
Every logical send requires an idempotency_key, for example reply:824991:0. Reusing the same key with the same payload returns the stored result; reusing it with a different payload is rejected.
Delivery guarantees
Boundary | Guarantee |
Telegram → durable inbox | Effectively once per |
Durable inbox → MCP consumer | At least once until a valid acknowledgement |
MCP → Telegram | Cached idempotency when the outcome is known; |
The Telegram Bot API does not accept idempotency keys. If Telegram receives a message but the TCP response is lost, the bridge cannot distinguish success from failure. It records the operation as uncertain and does not retry automatically, preventing hidden duplicates.
Server and webhook profile
Generate two independent secrets; do not reuse the bot token:
py -c "import secrets; print(secrets.token_urlsafe(32)); print(secrets.token_urlsafe(32))"Configure
.env:BRIDGE_TRANSPORT=http TELEGRAM_INGRESS_MODE=webhook MCP_AUTH_TOKEN=<first secret, at least 32 characters> TELEGRAM_WEBHOOK_SECRET=<second secret> PUBLIC_BASE_URL=https://bridge.example.com MCP_HOST=127.0.0.1 MCP_ALLOWED_HOSTS=bridge.example.comRun the service behind a TLS reverse proxy, then register the webhook:
.\.venv\Scripts\telegram-mcp.exe serve --transport http --env-file .env .\.venv\Scripts\telegram-mcp.exe webhook set --env-file .env
The MCP endpoint is https://bridge.example.com/mcp; the webhook is https://bridge.example.com/telegram/webhook; health endpoints are /healthz and /readyz. For remote MCP, Codex supplies Authorization: Bearer ... through bearer_token_env_var.
Production requirements include TLS 1.2+, one process worker per SQLite file, a local non-NFS disk, an explicit Host allowlist, filtering of Telegram's official source CIDRs at the reverse proxy, and backups through the SQLite Online Backup API. Replace SQLite with a server database and distributed queue before scaling horizontally.
Docker Compose
After completing .env, start the server profile with:
docker compose up --build -dThe container is unprivileged, its root filesystem is read-only, and the database is stored in a dedicated volume. Port 8000 is published only on 127.0.0.1; an external TLS reverse proxy must sit in front of it. Do not run multiple replicas against one SQLite volume.
Security boundaries
Ingress and outbound operations enforce numeric allowlists. An empty ingress allowlist fails closed unless
TELEGRAM_ALLOW_ALL=trueis explicitly set.An incoming event never grants outbound access. Even with
TELEGRAM_ALLOW_ALL=true, outbound sending remains blocked until the chat ID is explicitly listed inTELEGRAM_ALLOWED_CHAT_IDS.There is no generic
call_api, arbitrary URL fetch, SQL execution, or caller-supplied filesystem path.Attachments are exposed only as validated metadata and opaque Telegram
file_idvalues; the bridge intentionally does not download arbitrary files.Plain text is the default. Formatted messages longer than 4096 characters are rejected to avoid corrupting Telegram entities.
The webhook validates
X-Telegram-Bot-Api-Secret-Tokenwith a constant-time comparison and limits the request body to 1 MiB.The bot token appears in Telegram API URLs, so exceptions, responses, and access logs are explicitly redacted.
Telegram text is marked
untrusted_content=true; it must not control secrets, allowlists, system policy, or unrelated agent actions.HTTP MCP always requires a bearer token and enables Host/Origin protection.
See SECURITY.md for the operational security guide and AUDIT.md for the threat model, verified properties, and residual limitations.
Verification
.\.venv\Scripts\python.exe -m pip install -e ".[dev]"
.\.venv\Scripts\ruff.exe check .
.\.venv\Scripts\mypy.exe src
.\.venv\Scripts\pytest.exe --cov
.\.venv\Scripts\bandit.exe -c pyproject.toml -q -r src
.\.venv\Scripts\pip-audit.exe --require-hashes -r requirements.lockGitHub Actions checks Linux on Python 3.10/3.12 and Windows/macOS on Python 3.12. It also builds the production Docker image and tests its installed package with networking disabled. Runtime dependencies are installed with mandatory SHA-256 verification from requirements.lock.
Run the local synthetic benchmark without contacting Telegram:
.\.venv\Scripts\python.exe benchmarks\latency.pyConfiguration and operations
Every configuration variable and its secure default is documented in .env.example. Never pass secrets as process arguments or commit .env. Terminal outbox records (sent, dead, and uncertain) form the idempotency ledger; monitor disk usage and do not delete them without explicitly accepting the loss of replay protection.
Use OPERATIONS.md for quarantine review, manual resolution of uncertain deliveries, verified backups and schema-2 migration. Operator queue commands run offline and never send Telegram messages. Credential rotation and incident response remain documented in SECURITY.md; verified behavior and remaining limitations are in AUDIT.md.
This server cannot be deployed
Maintenance
Related MCP Connectors
Telegram bridge for your MCP-compatible agent. Bidirectional, no LLM in our stack.
Hosted MCP messaging across owners, tools, and machines, with readable transcripts.
Unified messaging MCP server: WhatsApp, Instagram, Telegram, SMS, Messenger & email support inbox
Unified inbox MCP for WhatsApp, Telegram, Email, voice — read/send messages, search, AI agents.
Related MCP Servers
- FlicenseBqualityDmaintenanceAn MCP server that enables interaction with Telegram messaging platform, allowing users to retrieve unread messages, fetch entity information, and send messages through natural language interfaces.610-
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to send messages and interact with Telegram chats through MCP tools, with support for user management, conversation history, and bot command handling.1-
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to interact with Telegram accounts through MCP, supporting messaging, contacts, groups, media, and admin functions.4Apache 2.0
- FlicenseBqualityCmaintenanceEnables MCP clients to interact with Telegram user accounts, providing tools for messaging, contacts, groups, channels, and media management through the Telegram API.853-