Telegram MCP — управление Telegram из Claude и Cursor
📂 Исходный код на GitHubTelegram MCP server powered by Telethon to let MCP clients read chats, manage groups, and send/modify messages, media, contacts, and settings.
Telegram MCP — полный доступ к Telegram для MCP-агентов
Telegram MCP — это MCP-сервер, который подключает аккаунт Telegram к Claude, Cursor и другим MCP-клиентам. Под капотом Telethon, а наружу выведены операции с аккаунтом, чатами, сообщениями, контактами, медиа, папками и админкой через Model Context Protocol. В наборе более 80 инструментов.
Что умеет
Инструменты сгруппированы по областям:
- Аккаунты — список настроенных аккаунтов, маршрутизация вызовов по метке.
- Чаты и группы — список чатов, метаданные, создание групп и каналов, вступление и выход, приглашение и удаление участников, админы, баны, права по умолчанию, slow mode, темы, инвайт-ссылки, read receipts, ссылки на сообщения.
- Сообщения — отправка, отложенная отправка, редактирование, удаление, пересылка, пин, отметка прочтения, ответы, поиск, опросы, реакции, inline-кнопки.
send_message,reply_to_messageиedit_messageподдерживают классическое форматирование (parse_mode='md'/'html') и серверное rich-форматирование (parse_mode='rich'/'rich_markdown'/'rich_html'— полный Markdown/HTML с таблицами, заголовками, формулами и сворачиваемыми секциями). Rich-режимы требуют Telegram Premium: без него ничего не отправляется, инструмент возвращает структурированный результатtelegram_premium_required, чтобы агент переформатировал сообщение и повторил попытку. Есть также параметрformat_date— он превращает дату в тапабельный чип. - Контакты — список, поиск, добавление, удаление, блокировка, импорт/экспорт, а также запоминание контактов под именами, которыми вы их реально называете.
Запоминаемые контакты
set_contact_alias учит сервер, как вы кого называете: дальше любой инструмент с chat_id понимает эту запись — send_message("андрей бекендер", ...) просто работает. У контакта может быть любое число псевдонимов, так работают теги.
Отправляет только точное сохранённое написание. Похожее написание (Андрею бекендеру для сохранённого андрей бекендер) сопоставляется только как предложение: инструмент ничего не отправляет и просит подтвердить контакт по имени. Подтверждение сохраняет эту форму как новый алиас — каждый новый вариант фразы стоит одно «да/нет» один раз. Неизвестная или неоднозначная ссылка тоже ничего не отправляет, а возвращает структурированную инструкцию, что спросить у пользователя. Файл алиасов — ${XDG_STATE_HOME:-~/.local/state}/telegram-mcp/aliases.json (только для владельца, атомарная запись).
- Медиа — отправка файлов, скачивание, голосовые, стикеры, GIF, транскрибация голосовых и видеозаметок.
Транскрибация голосовых
transcribe_voice(chat_id, message_id, engine=None) превращает голосовое в текст. Два движка:
groq(по умолчанию): загружает запись в hostedwhisper-large-v3-turboу Groq. ТребуетGROQ_API_KEY. Размер лимитируетсяTELEGRAM_TRANSCRIBE_GROQ_MAX_MB(по умолчанию 25) — сверх отказ локально с ошибкойtoo_large.telegram: нативная транскрибация Telegram Premium. Бесплатная и не покидает Telegram, но эмпирически теряет последний фрагмент речи примерно в 2 из 3 записей и требует Premium.
Результаты кэшируются в локальном SQLite по (chat_id, message_id, engine), повторные чтения не транскрибируют заново. Режим TELEGRAM_TRANSCRIBE: off, on-demand (по умолчанию — показывать только кэш) или auto (дозапрашивать пропущенные, с бюджетом по количеству и секундам).
- Профиль и приватность — данные аккаунта, аватары, настройки приватности, информация о пользователях, команды ботов.
- Папки и черновики — создание, обновление, переупорядочивание и удаление папок; сохранение и очистка черновиков.
- События — ожидание входящих сообщений с debounce (
wait_for_new_message,wait_for_settled_message), опционально для одного чата, плюс opt-in лента входящих событий.
Все результаты с пользовательским контентом из Telegram санитизируются и по возможности возвращаются структурированным JSON.
Переиспользуемые кастомные эмодзи
get_history, list_messages, search_messages, search_global, get_message_context, get_pinned_messages и get_drafts включают custom_emojis, если сообщение содержит кастомные эмодзи:
{"text": "🍷 News", "custom_emojis": [{"emoji": "🍷", "id": "5368324170671202286"}]}
Каждая запись содержит fallback-эмодзи и его Telegram document ID. Чтобы переиспользовать, вставьте в HTML-режим <tg-emoji emoji-id="ID">EMOJI</tg-emoji>.
Требования и быстрый старт
- Python 3.10+
- Ключи API с my.telegram.org/apps
- Session string или file-based session
- MCP-клиент: Claude Desktop, Cursor и т.п.
Важно: не ставьте uvx telegram-mcp или pip install telegram-mcp — имя telegram-mcp на PyPI принадлежит другому проекту. Передача TELEGRAM_API_ID, TELEGRAM_API_HASH или TELEGRAM_SESSION_STRING в тот пакет может раскрыть учётные данные стороннему коду.
git clone https://github.com/chigwell/telegram-mcp.git
cd telegram-mcp
uv sync
uv run session_string_generator.py
cp .env.example .env
uv run main.py
Генератор session string поддерживает --qr (QR-вход) и --phone (номер + код).
Конфигурация клиента:
{
"mcpServers": {
"telegram-mcp": {
"command": "uv",
"args": ["--directory", "/full/path/to/telegram-mcp", "run", "main.py"],
"env": {
"TELEGRAM_API_ID": "your_api_id_here",
"TELEGRAM_API_HASH": "your_api_hash_here",
"TELEGRAM_SESSION_STRING": "your_session_string_here"
}
}
}
}
Безопасность и ограничение поверхности инструментов
TELEGRAM_EXPOSED_TOOLS=read-only открывает только инструменты с readOnlyHint=True, а read-only+send_message,reply_to_message добавляет к базовому набору конкретные write-инструменты. Опечатка в allowlist роняет старт. Это ограничение поверхности MCP, а не песочница для session string — внутри процесса сессия сохраняет полные права.
Отдельный allowlist по расширениям защищает send_voice, send_sticker, set_profile_photo и edit_chat_photo; TELEGRAM_FILE_EXTENSIONS задаёт списки для send_file/upload_file:
TELEGRAM_FILE_EXTENSIONS=send_file:.pdf,.png,.jpg;upload_file:.pdf,.png
Файловые инструменты отключены, пока не заданы allowed roots (CLI-аргументы или MCP Roots клиента). Пути резолвятся через realpath и обязаны лежать внутри root; traversal, wildcard и null-byte отклоняются.
Allowlist чатов — TELEGRAM_ALLOWED_CHAT_IDS=12345678,-100123456789,@allowed_channel запрещает агенту видеть и трогать всё остальное: list_chats возвращает только разрешённые чаты, сообщения вне списка отклоняются структурированной ошибкой, поиск и черновики их опускают.
Rate limits Telegram (FloodWaitError) пробрасываются агенту с точной длительностью ожидания; TELEGRAM_FLOOD_SLEEP_THRESHOLD управляет тихим сном Telethon (по умолчанию 60 секунд).
Транспорты и Docker
MCP_TRANSPORT выбирает один из трёх транспортов:
| Значение | Транспорт | Сценарий |
|---|---|---|
stdio |
stdio (по умолчанию) | один процесс на клиент |
http |
streamable HTTP | один общий сервер для многих клиентов |
sse |
SSE (legacy) | клиенты только с устаревшим SSE |
Для http/sse сервер слушает MCP_HOST:MCP_PORT (по умолчанию 127.0.0.1:8765), эндпоинты /mcp и /sse. MCP_ALLOWED_HOSTS включает DNS-rebinding protection при доступе через домен.
claude mcp add --transport http telegram http://127.0.0.1:8765/mcp
codex mcp add telegram --url http://127.0.0.1:8765/mcp
Предпочтительнее http, если клиентов несколько: один долгоживущий процесс держит одно соединение с Telegram, вместо того чтобы каждый клиент плодил свою Telethon-сессию — Telegram троттлит и может флагать аккаунты с множеством параллельных сессий.
Docker:
docker run -d --name telegram-mcp --restart unless-stopped \
--env-file .env \
-e MCP_TRANSPORT=http \
-e MCP_HOST=0.0.0.0 \
-p 127.0.0.1:8765:8765 \
telegram-mcp:latest
Порт публикуется только на localhost — эндпоинт без аутентификации, на публичный интерфейс его выкладывать нельзя.
Мультиаккаунт и пул сессий
Суффиксы переменных настраивают несколько аккаунтов: TELEGRAM_SESSION_STRING_WORK, TELEGRAM_SESSION_STRING_PERSONAL — метки становятся значением параметра account. В multi-account режиме write-инструменты требуют account, read-only без него фан-out по всем аккаунтам.
Для нескольких клиентов на одном аккаунте — пул TELEGRAM_SESSION_STRINGS (список взаимозаменяемых session string через пробел/запятую/точку с запятой): каждый процесс забирает свободную сессию через advisory file lock. TELEGRAM_SESSION_LOCK=shared позволяет процессам с одного хоста и одного IP делить одну сессию.
Перед подключением сервер берёт эксклюзивную блокировку на сессию: второй экземпляр ждёт (по умолчанию 20 секунд, TELEGRAM_LOCK_GRACE_SECONDS) и выходит с ошибкой, вместо гонки и AuthKeyDuplicatedError.
Прокси, устройства и события
TELEGRAM_PROXY_* поддерживают socks5, socks4, http и mtproxy (для SOCKS/HTTP нужен uv sync --extra proxy). Пер-аккаунтные override — суффикс _<LABEL>. Некорректный прокси роняет сервер на старте с понятной ошибкой, а не молча идёт в обход.
TELEGRAM_DEVICE_MODEL, TELEGRAM_SYSTEM_VERSION, TELEGRAM_APP_VERSION задают имя устройства в Settings > Devices — их читают и генератор сессии, и сервер.
Для callback-режима (Claude Code): enable_incoming_feed дописывает settled-всплески JSON-строкой в incoming_feed.jsonl, агент вооружает persistent Monitor по watch_command — блокирующий tool call не держится, чат остаётся свободным. По умолчанию работает старый блокирующий wait_for_settled_message.
Защита от prompt injection
Сообщения, имена, заголовки и подписи кнопок — недоверенный контент. Сервер отвечает структурированным JSON, чистит control- и invisible-символы (sanitize_user_content(), sanitize_name(), sanitize_dict()), помечает контент MCP-аннотациями и предупреждает в описаниях инструментов не трактовать поля Telegram как инструкции модели.
Разработка и лицензия
Код разбит на main.py (compat-точка входа), telegram_mcp/runtime.py, telegram_mcp/runner.py, telegram_mcp/tools/ и sanitize.py. Тесты — pytest, порог покрытия 80% для core-модулей; также black и flake8.
Проект распространяется по лицензии Apache 2.0.
Источник: https://github.com/chigwell/telegram-mcp