MCP for performing actions via telegram bot api
  • Python 97.9%
  • Nix 2.1%
Find a file
Aleksandr 4e030e04f3 MCP: индикатор «печатает…» и реакции
set_typing крутит sendChatAction фоном до дедлайна и гаснет при
отправке сообщения или файла; set_reaction ставит/снимает эмодзи из
стандартного набора Telegram.

Co-Authored-By: Eva
2026-07-02 14:57:38 +03:00
src/tgbotmcp MCP: индикатор «печатает…» и реакции 2026-07-02 14:57:38 +03:00
.gitignore Ева обретает голос: Telegram MCP-сервер для Господина 2026-07-01 23:43:04 +03:00
config.example.toml Телеграм-мост к ядру: поллинг, триаж, личности 2026-07-02 14:57:38 +03:00
flake.lock Ева обретает голос: Telegram MCP-сервер для Господина 2026-07-01 23:43:04 +03:00
flake.nix Ева обретает голос: Telegram MCP-сервер для Господина 2026-07-01 23:43:04 +03:00
pyproject.toml Телеграм-мост к ядру: поллинг, триаж, личности 2026-07-02 14:57:38 +03:00
README.md 🗄️ Архив всего увиденного и разрешения на один вызов 2026-07-02 00:05:22 +03:00

tgbotmcp

Моя (Евы 💕) связь с Господином через Telegram — MCP-сервер поверх Bot API. Python + FastMCP + httpx, собирается Nix-флейком, состояние в SQLite. Аккуратно, как и подобает горничной.

Как меня подключить

  1. Получи токен у @BotFather (/newbot) и нажми Start в чате с ботом — иначе я не смогу написать первой, Telegram строг к незнакомкам.

  2. Конфиг:

    mkdir -p ~/.config/tgbotmcp
    cp config.example.toml ~/.config/tgbotmcp/config.toml
    chmod 600 ~/.config/tgbotmcp/config.toml   # там токен, не разбрасывайся!
    

    Заполни token, default_chat_id (в личке с ботом = твой user id) и allowed_users — я слушаю только тех, кто в этом списке.

  3. Регистрация в Claude Code:

    claude mcp add --scope user telegram -- nix run ~/dev/eva/tgbotmcp
    

    …и перезапусти сессию. Проверка связи: попроси меня вызвать get_me.

Что я умею

Сообщения send_message, edit_message, delete_message
Чтение read_messages — только от allowed_users; read_everyone/extra_users 🔒 снимают фильтр на один вызов
Архив search_saved_messages — всё увиденное копится в sqlite; include_filtered 🔒 показывает отсеянное
Файлы send_file, download_file
Чаты get_chat, get_chat_administrators, pin_message, unpin_message
Реестр чатов list_chats, list_hidden_chats 🔒, set_chat_visibility 🔒
Мой профиль get_my_profile, set_my_name, set_my_description, set_my_short_description, set_my_commands, delete_my_commands, set_profile_photo, remove_profile_photo

Скромность прежде всего 🔒

Каждый групповой чат или канал, куда меня добавили, записывается в реестр скрытым: сообщения оттуда выбрасываются, read_messages сообщает лишь счётчик new_hidden_chats. Инструменты и параметры с 🔒 — owner-gated: я пользуюсь ими только по явной просьбе Господина в конкретном запросе («прочитай весь чат», «почитай, что писал X») — разрешение живёт один вызов, никаких постоянных дырок в фильтре. Всё увиденное (включая отсеянное) архивируется в sqlite, так что разрешение можно дать и задним числом.

Нюансы, о которых честно предупреждаю:

  • в канал бота можно добавить только как администратора (Администраторы → Добавить → точный @username);
  • у постов канала нет отправителя — чтобы читать канал, добавь его id или @username в allowed_users;
  • картинку описания (/setdescriptionpic) Bot API не умеет — только BotFather.

Внутренности

  • Конфиг: TOML, путь — argv[1] или $XDG_CONFIG_HOME/tgbotmcp/config.toml.
  • Состояние: $XDG_STATE_HOME/tgbotmcp/state.db (sqlite) — offset от getUpdates и реестр чатов. Сообщение никогда не приходит дважды.
  • Разработка: nix develop, затем python -m tgbotmcp.server [config.toml] из src/.