Telegram MCP: sendMessage / sendFile — практический гайд

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_chats
  • send_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 install

1.2. Аутентификация в Telegram (MTProto user session)

Обычно это делается командой:

bun run auth

Дальше появится QR/веб-страница для логина. После успешной авторизации появляется session (точное место зависит от src/env.ts/src/telegram.ts).

1.3. Запуск MCP-сервера

bun run start
# или
bun run dev

2) Включаем разрешённые чаты (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

Есть несколько способов:

  1. search_dialogs — найди диалог по имени/юзернейму
  2. message_from_link — дай ссылку на конкретное сообщение, вернёт объект с chat/displayName
  3. если знаешь 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 наборе:

  1. send_message:
    • разрешённый чат → ok
    • запрещённый чат → ошибка
  2. send_file:
    • существующий файл → ok
    • несуществующий файл → ошибка
  3. parseChatId:
    • numeric / @username / “me”
  4. get_messages:
    • history режим возвращает хотя бы структуру

Если хочешь «настоящий» интеграционный тест — его лучше делать отдельным job’ом и с отдельным Telegram тест-аккаунтом, чтобы не гонять личный.


Report Page