Telegram MCP: sendMessage / sendFile — практический гайд
Этот гайд про репозиторий telegram-mcp/ в нашем workspace (проект на Bun + TypeScript + mtcute + MCP SDK). В нём уже реализованы MCP-инструменты:
send_message— отправка текстаsend_file— отправка локального файла как документа
Ниже: как включить, как безопасно ограничить чаты, как пользоваться агенту, и как это протестировать.
0) Важно про безопасность (почему может “не работать”)
В telegram-mcp/src/server.ts отправка сообщений/файлов заблокирована по умолчанию и требует явного allowlist:
send_messageразрешается только для чатов, прописанных вallowed_chatssend_file— аналогично
Если не добавить чат в allowlist, инструмент упадёт с ошибкой вида:
send_message is not allowed for chat "...". Add it to allowed_chats in bot-data/config.yml
Это сделано специально, чтобы агент не мог внезапно начать писать “куда угодно”.
1) Установка и запуск
1.1. Зависимости
Проект рассчитан на Bun.
cd telegram-mcp
bun install1.2. Аутентификация в Telegram (MTProto user session)
Обычно это делается командой:
bun run authДальше появится QR/веб-страница для логина. После успешной авторизации появляется session (точное место зависит от src/env.ts/src/telegram.ts).
1.3. Запуск MCP-сервера
bun run start
# или
bun run dev2) Включаем разрешённые чаты (allowlist)
Конфиг читается из файла:
- по умолчанию:
bot-data/config.yml - либо путь из переменной:
TELEGRAM_MCP_CONFIG
2.1. Добавляем чат в allowed_chats
Точный формат смотри в telegram-mcp/src/config.ts, но логика такая:
- инструмент (
send_message/send_file) проверяетisChatAllowed(toolName, chatId) chatIdможет быть:- числовой ID (как строка)
@username"me"для Saved Messages
Минимальный пример (идея):
allowed_chats:
- chat: "me"
tools: ["send_message", "send_file"]
- chat: "@my_ai_factory_bot"
tools: ["send_message"]
- chat: "-1001234567890" # пример канала/группы
tools: ["send_message", "send_file"]2.2. Как узнать chatId
Есть несколько способов:
search_dialogs— найди диалог по имени/юзернеймуmessage_from_link— дай ссылку на конкретное сообщение, вернёт объект с chat/displayName- если знаешь numeric ID — используй его напрямую
3) Как агенту пользоваться инструментами
3.1. Отправить текст
Tool: send_message
Параметры: - chatId (string): numeric / @username / me - text (string) - replyTo (number, optional)
Пример:
{ "chatId": "me", "text": "Проверка отправки", "replyTo": 123 }3.2. Отправить файл
Tool: send_file
локальный путь
- Параметры:
- chatId (string)
- filePath (string): локальный путь на машине, где запущен telegram-mcp
- caption (string, optional)
- replyTo (number, optional)
Пример:
{
"chatId": "me",
"filePath": "memory/marketing/userbot_guide_full.md",
"caption": "Полный гайд (актуальная версия)"
}Ограничения: - filePath должен существовать (existsSync проверяется) - если чат не в allowlist — будет ошибка
4) Типовые проблемы и как чинить
4.1. “send_message not allowed”
Причина: чат не добавлен в allowlist.
Решение: добавь chatId в allowed_chats для нужного инструмента.
4.2. “Dialog not found” / “ничего не приходит при onlyUnread”
- для
get_messagesв режимеonlyUnreadиспользуетсяlastReadIngoing— если диалог не найден или Telegram API возвращает нестандартно, будет пусто. - надёжнее: сначала
search_dialogs, потомget_messagesпо найденному ID.
4.3. parse_mode / форматирование
send_message сейчас отправляет чистый текст через tg.sendText. Если нужно HTML/Markdown — лучше добавить отдельный флаг и строгую политику (иначе агенты легко ломают разметку).
5) Тестирование (минимальный «пакет уверенности»)
У проекта уже есть тестовый режим:
bun testзапускается сTELEGRAM_MOCK=true(см.package.json)
cd telegram-mcp
bun testЧто стоит иметь в smoke/regression наборе:
send_message:- разрешённый чат → ok
- запрещённый чат → ошибка
send_file:- существующий файл → ok
- несуществующий файл → ошибка
parseChatId:- numeric / @username / “me”
get_messages:- history режим возвращает хотя бы структуру
Если хочешь «настоящий» интеграционный тест — его лучше делать отдельным job’ом и с отдельным Telegram тест-аккаунтом, чтобы не гонять личный.