Skip to main content
Glama
Telegram MCP

Telegram MCP

by salto-agancy

Telegram MCP AI Deploy

Self-hosted Telegram MCP that an AI coding agent can deploy for you.

CI Secret scan License: MIT

What it does

The server gives MCP clients controlled access to a Telegram user account through FastMCP and Telethon. It can search and read messages, inspect chats, fetch media and, only after explicit opt-in, send or edit messages. It supports remote deployment through Docker Compose, OAuth/bearer authentication and an outbound-only Cloudflare Tunnel.

WARNING

This MCP can expose Telegram content to an AI client. Defaults are deliberately strict:read-only, Saved Messages only, destructive tools blocked by ACL, and raw MTProto disabled. Expand permissions only after reviewing the threat model.

Related MCP server: my-tg-mcp

Architecture

Claude / ChatGPT -- OAuth -----┐
                               ├─ Cloudflare Tunnel ─ private Docker network ─ FastMCP ─ Telegram
Codex / Claude Code -- Bearer -┘

No application port is published on the VPS. Runtime secrets and Telegram sessions stay in ignored files or Docker volumes and never belong in the repository.

Deploy with AI

git clone https://github.com/salto-agancy/telegram-mcp-ai-deploy
cd telegram-mcp-ai-deploy

Open the directory in Codex, Claude Code or another capable coding agent and paste the prompt from INSTALL_WITH_AI.md. The agent performs preflight, prepares the VPS, opens a temporary SSH-forwarded QR login page in the local browser, provisions Cloudflare, deploys the stack and verifies the MCP protocol. The operator never needs to open a terminal manually.

Manual operator path: QUICKSTART.md.

Supported clients

Client

Connection

Guide

Claude

Remote MCP with OAuth

docs/CLAUDE.md

Claude Code

Streamable HTTP, OAuth or bearer

templates/claude-code

ChatGPT

Remote MCP with OAuth where supported

docs/CHATGPT.md

Codex

Streamable HTTP with bearer environment variable

docs/CODEX.md

Security

  • Secrets, sessions, ACLs, backups and runtime state are Git-ignored.

  • Cloudflare uses a temporary scoped API token, never a Global API Key.

  • ACL is fail-closed; raw MTProto requires two explicit opt-ins.

  • Every push and pull request runs tests and full-history secret scanning.

  • Never paste unredacted logs or credentials into an Issue or Pull Request.

Read SECURITY.md before enabling Telegram write access. Report vulnerabilities privately through GitHub Security Advisories.

Update

Ask your coding agent: Update my Telegram MCP to the latest stable version.

The reproducible path is make update: it scans the checkout, creates an encrypted backup, fetches the latest stable tag, deploys it, runs health checks and restores the previous commit if deployment fails. See docs/UPDATE.md.

Something doesn't work?

  1. Open an Issue.

  2. Attach only sanitized logs—remove tokens, hostnames, IPs, phone numbers, chat names, message content and session paths.

  3. Ask Codex or Claude Code to investigate using PROMPTS/CONTRIBUTE_WITH_AI.md.

  4. If it finds a fix, let it create a tested Pull Request.

If an installation agent already found local fixes, use the Russian retrospective prompt in PROMPTS/REPORT_INSTALLATION_WITH_AI_RU.md to extract only sanitized, still-missing changes into a fork and Pull Request.

Contribute

Contributions are welcome through forks and Pull Requests. Run make check before opening a PR and follow CONTRIBUTING.md. Architecture and deployment details live under docs/.

Licensed under MIT. The application began as a fork of leshchenko1979/fast-mcp-telegram; see NOTICE.md for attribution.

Available Tools

11 tools
edit_messageEdit messageB
DestructiveIdempotent

Replace text of an existing message you can edit in this chat. Success: edit result dict. Full documentation: https://github.com/leshchenko1979/fast-mcp-telegram/blob/main/docs/Tools-Reference.md

Inputs: chat_id (required), message (required), message_id (required), parse_mode. Returns: object

find_chatsFind chatsA
Read-onlyIdempotent

Find users/groups/channels by name, username, or phone. Global search (query required) searches all Telegram; with min_date, max_date, or filter, search uses dialog list or a named filter; include_peers filters use last-activity from GetPeerDialogs; flag-based filters use dialog list dates. Success: dict with key chats (list of chat objects). Full documentation: https://github.com/leshchenko1979/fast-mcp-telegram/blob/main/docs/Tools-Reference.md

Inputs: limit, query, folder, public, +3 more. Returns: object

get_chat_infoGet chat infoB
Read-onlyIdempotent

Load profile and metadata for one user, bot, group, or channel. Success: info dict; forum chats may include topics up to topics_limit. Full documentation: https://github.com/leshchenko1979/fast-mcp-telegram/blob/main/docs/Tools-Reference.md

Inputs: chat_id (required), topics_limit. Returns: object

get_media_contentGet media content inlineA
Read-onlyIdempotent

Fetch photos/images from specific messages and return them INLINE as native image content (base64), so web clients can read screenshots without fetching a URL. Non-image files return a short text note plus their download URL; voice / round video return a note pointing at get_messages field transcription. Limits: max 6 images per call; originals over 5 MB are skipped with a note. Full documentation: https://github.com/leshchenko1979/fast-mcp-telegram/blob/main/docs/Tools-Reference.md

Inputs: chat_id (required), message_ids (required).

get_messagesGet messages in chatA
Read-onlyIdempotent

Read chat history: the conversation, dialog, or DM with one person, group, or channel. Browse the latest messages, search text inside the chat, fetch by ids, or load replies to a message (comments, forum topics, threads). Accepts a @username directly as chat_id, so a known handle needs no lookup step. Filter a time window with min_date and max_date (e.g. what was written this morning). Do not combine message_ids with query or reply_to_id. Success: messages, has_more, optional total_count and discussion fields. Full documentation: https://github.com/leshchenko1979/fast-mcp-telegram/blob/main/docs/Tools-Reference.md

Inputs: chat_id (required), limit, query, max_date, +6 more. Returns: object

get_yandex_disk_contentGet Yandex.Disk content inlineA
Read-onlyIdempotent

Open a public Yandex.Disk link (folder or file) sent in Telegram and return its images INLINE as native image content (base64), recursing into subfolders. Non-image files return a short note plus a preview/download URL. Use when a chat message contains a disk.yandex / yadi.sk link and the user wants to see what is in it. Max 12 images per call. Full documentation: https://github.com/leshchenko1979/fast-mcp-telegram/blob/main/docs/Tools-Reference.md

Inputs: public_url (required), path.

recent_activityRecent activity snapshotA
Read-onlyIdempotent

One prepared snapshot of recent activity across chats, instead of discovering chats and then opening each one. Returns, per chat: Telegram's own unread state (unread_count, read_inbox_max_id, read_outbox_max_id), the messages in the window with direction and reply links, attachment metadata, voice transcripts that are already available, and last incoming / last outgoing. Voice without a ready transcript is marked pending, never omitted. Whether a message needs a reply is not decided here. Success: dict with keys chats and coverage. Full documentation: https://github.com/leshchenko1979/fast-mcp-telegram/blob/main/docs/Tools-Reference.md

Inputs: since, until, accounts, chat_type, +6 more. Returns: object

search_messages_globallySearch messages globallyA
Read-onlyIdempotent

Search all Telegram chats at once (not scoped to one chat). Comma-separated query terms; optional filters by date, chat kind, and public username. Success: message list and metadata dict. Global search ignores include_total_count. Full documentation: https://github.com/leshchenko1979/fast-mcp-telegram/blob/main/docs/Tools-Reference.md

Inputs: query (required), limit, public, source, +5 more. Returns: object

send_messageSend messageA
Destructive

Send text and optional attachments to a chat. Success: send result dict. Each item in files may be a public URL, a server-local path, OR a base64 data URI (data:;base64,) — use the data URI form to send a file the caller has in memory or attached locally, without needing a public link (supported up to ~30 MB). Full documentation: https://github.com/leshchenko1979/fast-mcp-telegram/blob/main/docs/Tools-Reference.md

Inputs: chat_id (required), message (required), files, parse_mode, +1 more. Returns: object

send_message_to_phoneSend message to phoneA
Destructive

Send to a phone number: may create a temporary contact, then send text or files. Success: send result plus contact_was_new / contact_removed when applicable. Full documentation: https://github.com/leshchenko1979/fast-mcp-telegram/blob/main/docs/Tools-Reference.md

Inputs: message (required), phone_number (required), files, last_name, +4 more. Returns: object

send_rich_messageSend rich messageA
Destructive

Send markdown as a Telegram Rich Message with REAL tables and headings (Bot API 10.1 sendRichMessage). Use this instead of send_message when the content has markdown tables (| ... |), headings (#), or structured report layout that should render natively in Telegram. Sent by the separately configured bot, so chat_id must identify a chat shared with that bot, NOT 'me'/Saved Messages. Success: {sent, id, chat_id, type}. Full documentation: https://github.com/leshchenko1979/fast-mcp-telegram/blob/main/docs/Tools-Reference.md

Inputs: chat_id (required), markdown (required), reply_to_id. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.8/5.0

    Scored across 11 tools

    Disambiguation4/5

    The tool set is clearly separated by resource and action, with distinct tools for reading messages, searching, editing, sending, and fetching media. The three send tools are differentiated by destination (phone, rich content vs plain) and the two media-fetch tools by source (message vs Yandex.Disk link), though send_message and send_rich_message could cause minor selection confusion for plain text.

    Naming Consistency4/5

    Almost all tools follow a consistent verb_noun pattern (get_, edit_, search_, send_, find_), with send_message_to_phone and get_yandex_disk_content being verbose but still predictable. Only recent_activity breaks the pattern by using a noun phrase instead of a verb, making it the single deviation.

    Tool Count5/5

    At 11 tools, the server covers a typical Telegram integration scope without bloat. Each tool addresses a distinct operation—sending, reading, searching, editing, chat discovery, and media retrieval—so no tool feels redundant or missing.

    Completeness3/5

    Core message lifecycle is mostly covered: send, read, search, edit, but delete_message is absent, which is a notable gap for a messaging client. Also lacks explicit mark-read or forward operations, though recent_activity provides unread state. Overall the surface is functional but not complete.

    Maintenance

    ActivitySlowing
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      A
      quality
      D
      maintenance
      Read-only MCP server for self-hosted Telegram access via Telethon. Enables reading messages, chats, and media but disallows any write operations.
      10
      -
    • F
      license
      Not graded
      quality
      B
      maintenance
      Read-only MCP access to a personal Telegram account. Allows querying chats, reading and searching messages via Streamable HTTP.
      -
    • A
      license
      Not graded
      quality
      B
      maintenance
      A safe-by-default MCP server for real Telegram accounts powered by TDLib, enabling AI agents to read and act on your account with read-only mode and human approval for destructive actions.
      13
      Apache 2.0
    • A
      license
      Not graded
      quality
      C
      maintenance
      A 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