MCP server for Telegram Client API (MTProto)
mcp-tg
MCP server for Telegram Client API (MTProto). Provides 58 tools, 4 resources, 3 prompts, and argument completions for comprehensive Telegram account management.
Uses gotd/td for MTProto protocol — this is a user account client, not a bot.
MCP Protocol Support
| Feature | Status | | --- | --- | | Tools | 58 tools with annotations (read-only / idempotent / write / destructive) | | Resources | 4 (dialogs, profile, chat info, chat messages) | | Prompts | 3 (reply, summarize, search and reply) | | Completions | Peer argument autocompletion from dialogs | | Elicitation | Auth flow (phone, code, 2FA password) | | Progress | File uploads, media albums, message search | | Roots | File path validation for uploads/downloads | | Transports | stdio + HTTP/SSE | | KeepAlive | 30s ping interval | | Middleware | Auth guard, request logging |
Telegram Protocol Features
- Peer cache — resolved peers with access hashes are cached in memory, so numeric ID lookups reuse valid hashes instead of failing
- Invite links —
t.me/+hashandt.me/joinchat/hashare resolved viamessages.checkChatInvite - FLOOD_WAIT retry — automatic sleep and retry (up to 3 times) when Telegram rate-limits the client
- Auth guard — tool calls are blocked with a clear error until Telegram authentication completes
- Pagination —
offsetDatefor dialog listing,offsetIdfor message search and history
Tools (58)
Messages (11)
tg_messages_list— List messages in a chattg_messages_get— Get specific messages by IDtg_messages_context— Get messages around a specific messagetg_messages_search— Search messages in a chattg_messages_send— Send a text messagetg_messages_edit— Edit an existing messagetg_messages_delete— Delete messagestg_messages_forward— Forward messages between chatstg_messages_pin— Pin or unpin a messagetg_messages_react— Add or remove reactionstg_messages_mark_read— Mark messages as read
Dialogs (3)
tg_dialogs_list— List all dialogstg_dialogs_search— Search dialogs by querytg_dialogs_get_info— Get chat/channel metadata
Contacts & Users (6)
tg_contacts_get— Get contact infotg_contacts_search— Search contactstg_users_get— Get user infotg_users_get_photos— Get user profile photostg_users_block— Block or unblock a usertg_users_get_common_chats— Get chats shared with a user
Groups (9)
tg_groups_list— List groupstg_groups_info— Get group infotg_groups_join— Join a public channel or supergrouptg_groups_leave— Leave a group or channeltg_groups_rename— Rename a grouptg_groups_members_add— Add a membertg_groups_members_remove— Remove a membertg_groups_invite_link_get— Get invite linktg_groups_invite_link_revoke— Revoke invite link
Chat Management (8)
tg_chats_create— Create a new group or channeltg_chats_archive— Archive or unarchive a chattg_chats_mute— Mute or unmute notificationstg_chats_delete— Delete a channel or supergrouptg_chats_set_photo— Set chat phototg_chats_set_description— Set chat descriptiontg_chats_get_admins— List administrators (channels/supergroups)tg_chats_set_permissions— Set default permissions
Media & Files (4)
tg_messages_send_file— Send a file with captiontg_media_download— Download media from a messagetg_media_upload— Upload a filetg_media_send_album— Send a media album
Profile (4)
tg_profile_get— Get own profile infotg_profile_set_name— Update display nametg_profile_set_bio— Update biotg_profile_set_photo— Set profile photo
Forum Topics (2)
tg_topics_list— List forum topicstg_topics_search— Search forum topics
Stickers (3)
tg_stickers_search— Search sticker setstg_stickers_get_set— Get a sticker settg_stickers_send— Send a sticker
Drafts (2)
tg_drafts_set— Set a draft messagetg_drafts_clear— Clear a draft
Folders (4)
tg_folders_list— List chat folderstg_folders_create— Create a foldertg_folders_edit— Edit a foldertg_folders_delete— Delete a folder
Status (2)
tg_typing_send— Send typing indicatortg_online_status_set— Set online/offline status
Resources
tg://dialogs— List of all dialogs (JSON)tg://profile— Authenticated user's profile (JSON)tg://chat/{peer}— Chat/channel metadata (JSON, URI template)tg://chat/{peer}/messages— Recent messages (text, URI template)
Prompts
reply_to_message— Fetch context around a message for composing repliessummarize_chat— Fetch recent messages for conversation summarizationsearch_and_reply— Search messages and prepare reply context
Peer Resolution
All tools accept peer as a string. Supported formats:
@usernameusername(bare)https://t.me/usernamehttps://t.me/+invite_hash(invite links, if already joined)- Numeric ID (bot-API style: positive=user, negative=chat,
-100xxx=channel)
Peers resolved by username include a valid access hash. Numeric IDs use a cached access hash if available, otherwise AccessHash=0 (some API calls may fail — prefer @username).
Configuration
| Variable | Description | Default | Required |
| --- | --- | --- | --- |
| TELEGRAM_APP_ID | API app_id from my.telegram.org | — | Yes |
| TELEGRAM_APP_HASH | API app_hash from my.telegram.org | — | Yes |
| TELEGRAM_PHONE | Phone number (E.164 format) | — | No (prompted via elicitation) |
| TELEGRAM_PASSWORD | 2FA password | — | No (prompted via elicitation) |
| TELEGRAM_SESSION_FILE | Session file path | ~/.mcp-tg/session.json | No |
| TELEGRAM_AUTH_CODE | One-time auth code | — | No (prompted via elicitation) |
| TELEGRAM_DOWNLOAD_DIR | Media download directory | /tmp/mcp-tg/downloads | No |
| MCP_HTTP_PORT | HTTP/SSE transport port | disabled | No |
| MCP_HTTP_HOST | HTTP bind address | 127.0.0.1 | No |
Authentication
Authentication uses a cascade: environment variable, then MCP elicitation (the client prompts you), then error.
First run:
- Set
TELEGRAM_APP_IDandTELEGRAM_APP_HASH(always required) - Optionally set
TELEGRAM_PHONE— if not set, the server asks via elicitation - Telegram sends a code to your device
- Optionally set
TELEGRAM_AUTH_CODE— if not set, the server asks via elicitation - If 2FA is enabled, optionally set
TELEGRAM_PASSWORD— or the server asks - Session is saved to
TELEGRAM_SESSION_FILE
Subsequent runs: session file is loaded automatically, no auth needed.
Session persistence in containers: mount a volume for the session file:
-v ~/.mcp-tg:/home/nobody/.mcp-tg
Usage
With Claude Code (stdio via Docker)
claude mcp add mcp-tg -- docker run --rm -i \
-e TELEGRAM_APP_ID \
-e TELEGRAM_APP_HASH \
-v ~/.mcp-tg:/home/nobody/.mcp-tg \
ghcr.io/lexfrei/mcp-tg:latest
Direct binary
export TELEGRAM_APP_ID=12345
export TELEGRAM_APP_HASH=your_app_hash
./mcp-tg
Container
docker run --rm -i \
-e TELEGRAM_APP_ID=12345 \
-e TELEGRAM_APP_HASH=your_app_hash \
-v ~/.mcp-tg:/home/nobody/.mcp-tg \
ghcr.io/lexfrei/mcp-tg:latest
Requirements
- Go 1.26.1+
- Telegram API credentials from my.telegram.org
Building
go build ./cmd/mcp-tg
docker build --file Containerfile --tag mcp-tg .
License
BSD 3-Clause License