Skip to main content
Glama
chigwell

Telegram MCP Server

by chigwell

Телеграм MCP-сервер

Значок MCP Лицензия: Apache 2.0 Проверка Python Lint и формата Проверка сборки и компоновки Docker


🤖 MCP в действии

Вот демонстрация возможностей Telegram MCP в Claude :

Пример простого использования:

Telegram MCP в действии

  1. Пример: просим Клода проанализировать историю чата и отправить ответ:

Телеграмма MCP Запрос

  1. Сообщение успешно отправлено группе:

Результат MCP Telegram

Как вы видите, ИИ может беспрепятственно взаимодействовать с вашим аккаунтом Telegram, извлекая и отображая ваши чаты, сообщения и другие данные естественным образом.


Полнофункциональная интеграция Telegram для Claude, Cursor и любого MCP-совместимого клиента, работающая на основе Telethon и Model Context Protocol (MCP) . Этот проект позволяет вам взаимодействовать с вашим аккаунтом Telegram программно, автоматизируя все: от обмена сообщениями до управления группами.


Related MCP server: Telegram MCP Server

🚀 Функции и инструменты

Этот сервер MCP предоставляет огромный набор инструментов Telegram. Каждая крупная функция Telegram/Telethon доступна как инструмент!

Управление чатом и группами

  • get_chats(page, page_size) : постраничный список чатов

  • list_chats(chat_type, limit) : список чатов с метаданными и фильтрацией

  • get_chat(chat_id) : Подробная информация о чате

  • create_group(title, user_ids) : создать новую группу

  • create_channel(title, about, megagroup) : создать канал или супергруппу

  • edit_chat_title(chat_id, title) : Изменить название чата/группы/канала

  • delete_chat_photo(chat_id) : Удалить фотографию чата/группы/канала

  • leave_chat(chat_id) : Покинуть группу или канал

  • get_participants(chat_id) : Список всех участников

  • get_admins(chat_id) : Список всех администраторов

  • get_banned_users(chat_id) : список всех забаненных пользователей

  • promote_admin(chat_id, user_id) : повысить пользователя до администратора

  • demote_admin(chat_id, user_id) : Понизить администратора до пользователя

  • ban_user(chat_id, user_id) : Забанить пользователя

  • unban_user(chat_id, user_id) : Разбанить пользователя

  • get_invite_link(chat_id) : Получить ссылку приглашения

  • export_chat_invite(chat_id) : Экспортировать ссылку приглашения

  • import_chat_invite(hash) : Присоединиться к чату по хэшу приглашения

  • join_chat_by_link(link) : Присоединиться к чату по пригласительной ссылке

Обмен сообщениями

  • get_messages(chat_id, page, page_size) : постраничные сообщения

  • list_messages(chat_id, limit, search_query, from_date, to_date) : Отфильтрованные сообщения

  • send_message(chat_id, message) : Отправить сообщение

  • reply_to_message(chat_id, message_id, text) : Ответить на сообщение

  • edit_message(chat_id, message_id, new_text) : Отредактируйте свое сообщение

  • delete_message(chat_id, message_id) : Удалить сообщение

  • forward_message(from_chat_id, message_id, to_chat_id) : Переслать сообщение

  • pin_message(chat_id, message_id) : Закрепить сообщение

  • unpin_message(chat_id, message_id) : Открепить сообщение

  • mark_as_read(chat_id) : Отметить все как прочитанные

  • get_message_context(chat_id, message_id, context_size) : Контекст вокруг сообщения

  • get_history(chat_id, limit) : Полная история чата

  • get_pinned_messages(chat_id) : Список закрепленных сообщений

  • get_last_interaction(contact_id) : Последнее сообщение с контактом

Управление контактами

  • list_contacts() : Список всех контактов

  • search_contacts(query) : Поиск контактов

  • add_contact(телефон, имя, фамилия) : Добавить контакт

  • delete_contact(user_id) : Удалить контакт

  • block_user(user_id) : Заблокировать пользователя

  • unblock_user(user_id) : Разблокировать пользователя

  • import_contacts(contacts) : Массовый импорт контактов

  • export_contacts() : экспорт всех контактов в формате JSON

  • get_blocked_users() : Список заблокированных пользователей

  • get_contact_ids() : список всех идентификаторов контактов

  • get_direct_chat_by_contact(contact_query) : Найти прямой чат с контактом

  • get_contact_chats(contact_id) : список всех чатов с контактом

Пользователь и профиль

  • get_me() : Получить информацию о пользователе

  • update_profile(first_name, last_name, about) : Обновите свой профиль

  • delete_profile_photo() : Удалить фотографию вашего профиля

  • get_user_photos(user_id, limit) : Получить фотографии профиля пользователя

  • get_user_status(user_id) : Получить статус пользователя в сети

СМИ

  • get_media_info(chat_id, message_id) : Получить информацию о медиа в сообщении

Поиск и обнаружение

  • search_public_chats(query) : Поиск публичных чатов/каналов/ботов

  • search_messages(chat_id, query, limit) : Поиск сообщений в чате

  • resolve_username(имя пользователя) : Преобразовать имя пользователя в идентификатор

Наклейки, GIF-файлы, боты

  • get_sticker_sets() : Список наборов наклеек

  • get_bot_info(bot_username) : Получить информацию о боте

  • set_bot_commands(bot_username, commands) : Установить команды бота (только для учетных записей ботов)

Конфиденциальность, настройки и прочее

  • get_privacy_settings() : Получить настройки конфиденциальности

  • set_privacy_settings(key, allow_users, disallow_users) : Установить настройки конфиденциальности

  • mute_chat(chat_id) : Отключить уведомления

  • unmute_chat(chat_id) : Включить уведомления

  • archive_chat(chat_id) : Архивировать чат

  • unarchive_chat(chat_id) : Разархивировать чат

  • get_recent_actions(chat_id) : Получить последние действия администратора

Удаленная функциональность

Обратите внимание, что инструменты, требующие прямого доступа к пути файла на сервере ( send_file , download_media , set_profile_photo , edit_chat_photo , send_voice , send_sticker , upload_file ), были удалены из main.py Это связано с ограничениями в текущей среде MCP в отношении обработки вложений файлов и путей локальной файловой системы.

Кроме того, инструменты, связанные с GIF ( get_gif_search , get_saved_gifs , send_gif ), были удалены из-за сохраняющихся проблем с надежностью в библиотеке Telethon или взаимодействиях с API Telegram.


📋 Требования


🔧 Установка и настройка

1. Форк и клонирование

git clone https://github.com/chigwell/telegram-mcp.git
cd telegram-mcp

2. Создайте виртуальную среду

python3 -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate
pip install -r requirements.txt

3. Сгенерируйте строку сеанса

python3 session_string_generator.py

Следуйте инструкциям по аутентификации и обновлению файла .env .

4. Настройте .env

Скопируйте .env.example в .env и заполните нужные значения:

TELEGRAM_API_ID=your_api_id_here
TELEGRAM_API_HASH=your_api_hash_here
TELEGRAM_SESSION_NAME=anon
TELEGRAM_SESSION_STRING=your_session_string_here

Получите свои учетные данные API на my.telegram.org/apps .


🐳 Работа с Docker

Если у вас установлены Docker и Docker Compose, вы можете собрать и запустить сервер в контейнере, что упрощает управление зависимостями.

1. Создайте образ

Из корневого каталога проекта соберите образ Docker:

docker build -t telegram-mcp:latest .

2. Запуск контейнера

У вас есть два варианта:

Вариант A: использование Docker Compose (рекомендуется для локального использования)

Этот метод использует файл docker-compose.yml и автоматически считывает ваши учетные данные из файла .env .

  1. Создайте файл Убедитесь, что в корне проекта есть файл .env , содержащий TELEGRAM_API_ID , TELEGRAM_API_HASH и TELEGRAM_SESSION_STRING (или TELEGRAM_SESSION_NAME ). Используйте .env.example в качестве шаблона.

  2. Запустить Compose:

    docker compose up --build
    • Используйте docker compose up -d для запуска в отсоединенном режиме (фоновом режиме).

    • Нажмите Ctrl+C , чтобы остановить сервер.

Вариант Б: использование

Вы можете запустить контейнер напрямую, передав учетные данные в качестве переменных среды.

docker run -it --rm \
  -e TELEGRAM_API_ID="YOUR_API_ID" \
  -e TELEGRAM_API_HASH="YOUR_API_HASH" \
  -e TELEGRAM_SESSION_STRING="YOUR_SESSION_STRING" \
  telegram-mcp:latest
  • Замените заполнители своими реальными учетными данными.

  • Используйте -e TELEGRAM_SESSION_NAME=your_session_file_name вместо TELEGRAM_SESSION_STRING , если вы предпочитаете сеансы на основе файлов (требуется монтирование тома, см. пример docker-compose.yml ).

  • Флаги -it имеют решающее значение для взаимодействия с сервером.


⚙️ Конфигурация для Клода и Курсора

Конфигурация МКП

Отредактируйте конфигурацию рабочего стола Claude (например, ~/Library/Application Support/Claude/claude_desktop_config.json ) или конфигурацию курсора ( ~/.cursor/mcp.json ):

{
  "mcpServers": {
    "telegram-mcp": {
      "command": "uv",
      "args": [
        "--directory",
        "/full/path/to/telegram-mcp",
        "run",
        "main.py"
      ]
    }
  }
}

📝 Примеры инструментов с кодом и выводом

Ниже приведены примеры наиболее часто используемых инструментов с их реализацией и образцами выходных данных.

Получайте ваши чаты

@mcp.tool()
async def get_chats(page: int = 1, page_size: int = 20) -> str:
    """
    Get a paginated list of chats.
    Args:
        page: Page number (1-indexed).
        page_size: Number of chats per page.
    """
    try:
        dialogs = await client.get_dialogs()
        start = (page - 1) * page_size
        end = start + page_size
        if start >= len(dialogs):
            return "Page out of range."
        chats = dialogs[start:end]
        lines = []
        for dialog in chats:
            entity = dialog.entity
            chat_id = entity.id
            title = getattr(entity, "title", None) or getattr(entity, "first_name", "Unknown")
            lines.append(f"Chat ID: {chat_id}, Title: {title}")
        return "\n".join(lines)
    except Exception as e:
        logger.exception(f"get_chats failed (page={page}, page_size={page_size})")
        return "An error occurred (code: GETCHATS-ERR-001). Check mcp_errors.log for details."

Пример вывода:

Chat ID: 123456789, Title: John Doe
Chat ID: -100987654321, Title: My Project Group
Chat ID: 111223344, Title: Jane Smith
Chat ID: -200123456789, Title: News Channel

Отправка сообщений

@mcp.tool()
async def send_message(chat_id: int, message: str) -> str:
    """
    Send a message to a specific chat.
    Args:
        chat_id: The ID of the chat.
        message: The message content to send.
    """
    try:
        entity = await client.get_entity(chat_id)
        await client.send_message(entity, message)
        return "Message sent successfully."
    except Exception as e:
        logger.exception(f"send_message failed (chat_id={chat_id})")
        return "An error occurred (code: SENDMSG-ERR-001). Check mcp_errors.log for details."

Пример вывода:

Message sent successfully.

Получение ссылок-приглашений в чат

Функция get_invite_link особенно надежна при использовании нескольких резервных методов:

@mcp.tool()
async def get_invite_link(chat_id: int) -> str:
    """
    Get the invite link for a group or channel.
    """
    try:
        entity = await client.get_entity(chat_id)
        
        # Try using ExportChatInviteRequest first
        try:
            from telethon.tl import functions
            result = await client(functions.messages.ExportChatInviteRequest(
                peer=entity
            ))
            return result.link
        except AttributeError:
            # If the function doesn't exist in the current Telethon version
            logger.warning("ExportChatInviteRequest not available, using alternative method")
        except Exception as e1:
            # If that fails, log and try alternative approach
            logger.warning(f"ExportChatInviteRequest failed: {e1}")
            
        # Alternative approach using client.export_chat_invite_link
        try:
            invite_link = await client.export_chat_invite_link(entity)
            return invite_link
        except Exception as e2:
            logger.warning(f"export_chat_invite_link failed: {e2}")
            
        # Last resort: Try directly fetching chat info
        try:
            if isinstance(entity, (Chat, Channel)):
                full_chat = await client(functions.messages.GetFullChatRequest(
                    chat_id=entity.id
                ))
                if hasattr(full_chat, 'full_chat') and hasattr(full_chat.full_chat, 'invite_link'):
                    return full_chat.full_chat.invite_link or "No invite link available."
        except Exception as e3:
            logger.warning(f"GetFullChatRequest failed: {e3}")
            
        return "Could not retrieve invite link for this chat."
    except Exception as e:
        logger.exception(f"get_invite_link failed (chat_id={chat_id})")
        return f"Error getting invite link: {e}"

Пример вывода:

https://t.me/+AbCdEfGhIjKlMnOp

Присоединение к чатам с помощью ссылок-приглашений

@mcp.tool()
async def join_chat_by_link(link: str) -> str:
    """
    Join a chat by invite link.
    """
    try:
        # Extract the hash from the invite link
        if '/' in link:
            hash_part = link.split('/')[-1]
            if hash_part.startswith('+'):
                hash_part = hash_part[1:]  # Remove the '+' if present
        else:
            hash_part = link
            
        # Try checking the invite before joining
        try:
            # Try to check invite info first (will often fail if not a member)
            invite_info = await client(functions.messages.CheckChatInviteRequest(hash=hash_part))
            if hasattr(invite_info, 'chat') and invite_info.chat:
                # If we got chat info, we're already a member
                chat_title = getattr(invite_info.chat, 'title', 'Unknown Chat')
                return f"You are already a member of this chat: {chat_title}"
        except Exception:
            # This often fails if not a member - just continue
            pass
            
        # Join the chat using the hash
        result = await client(functions.messages.ImportChatInviteRequest(hash=hash_part))
        if result and hasattr(result, 'chats') and result.chats:
            chat_title = getattr(result.chats[0], 'title', 'Unknown Chat')
            return f"Successfully joined chat: {chat_title}"
        return f"Joined chat via invite hash."
    except Exception as e:
        err_str = str(e).lower()
        if "expired" in err_str:
            return "The invite hash has expired and is no longer valid."
        elif "invalid" in err_str:
            return "The invite hash is invalid or malformed."
        elif "already" in err_str and "participant" in err_str:
            return "You are already a member of this chat."
        logger.exception(f"join_chat_by_link failed (link={link})")
        return f"Error joining chat: {e}"

Пример вывода:

Successfully joined chat: Developer Community

Поиск в публичных чатах

@mcp.tool()
async def search_public_chats(query: str) -> str:
    """
    Search for public chats, channels, or bots by username or title.
    """
    try:
        result = await client(functions.contacts.SearchRequest(q=query, limit=20))
        return json.dumps([format_entity(u) for u in result.users], indent=2)
    except Exception as e:
        return f"Error searching public chats: {e}"

Пример вывода:

[
  {
    "id": 123456789,
    "name": "TelegramBot",
    "type": "user",
    "username": "telegram_bot"
  },
  {
    "id": 987654321,
    "name": "Telegram News",
    "type": "user",
    "username": "telegram_news"
  }
]

Получение прямых чатов с контактами

@mcp.tool()
async def get_direct_chat_by_contact(contact_query: str) -> str:
    """
    Find a direct chat with a specific contact by name, username, or phone.
    
    Args:
        contact_query: Name, username, or phone number to search for.
    """
    try:
        # Fetch all contacts using the correct Telethon method
        result = await client(functions.contacts.GetContactsRequest(hash=0))
        contacts = result.users
        found_contacts = []
        for contact in contacts:
            if not contact:
                continue
            name = f"{getattr(contact, 'first_name', '')} {getattr(contact, 'last_name', '')}".strip()
            username = getattr(contact, 'username', '')
            phone = getattr(contact, 'phone', '')
            if (contact_query.lower() in name.lower() or 
                (username and contact_query.lower() in username.lower()) or 
                (phone and contact_query in phone)):
                found_contacts.append(contact)
        if not found_contacts:
            return f"No contacts found matching '{contact_query}'."
        # If we found contacts, look for direct chats with them
        results = []
        dialogs = await client.get_dialogs()
        for contact in found_contacts:
            contact_name = f"{getattr(contact, 'first_name', '')} {getattr(contact, 'last_name', '')}".strip()
            for dialog in dialogs:
                if isinstance(dialog.entity, User) and dialog.entity.id == contact.id:
                    chat_info = f"Chat ID: {dialog.entity.id}, Contact: {contact_name}"
                    if getattr(contact, 'username', ''):
                        chat_info += f", Username: @{contact.username}"
                    if dialog.unread_count:
                        chat_info += f", Unread: {dialog.unread_count}"
                    results.append(chat_info)
                    break
        
        if not results:
            return f"Found contacts matching '{contact_query}', but no direct chats with them."
        
        return "\n".join(results)
    except Exception as e:
        return f"Error searching for direct chat: {e}"

Пример вывода:

Chat ID: 123456789, Contact: John Smith, Username: @johnsmith, Unread: 3

🎮 Примеры использования

  • «Показать мои последние чаты»

  • «Отправьте «Привет, мир» в чат 123456789»

  • «Добавить контакт с телефоном +1234567890, имя Джон Доу»

  • «Создать группу «Проектная команда» с пользователями 111, 222, 333»

  • «Загрузить медиафайл из сообщения 42 в чате 123456789»

  • «Отключить уведомления для чата 123456789»

  • «Повысить пользователя 111 до администратора в группе 123456789»

  • «Поиск публичных каналов по теме «новости»»

  • «Присоединяйтесь к группе Telegram по ссылке https://t.me/+AbCdEfGhIjK »

  • «Отправить стикер в мои сохраненные сообщения»

  • «Получить все мои наборы наклеек»

Вы можете использовать эти инструменты с помощью естественного языка в Claude, Cursor или любом MCP-совместимом клиенте.


🧠 Обработка ошибок и надежность

Эта реализация включает в себя комплексную обработку ошибок:

  • Управление сеансами : работает как с файловыми, так и с строковыми сеансами.

  • Отчет об ошибках : подробные ошибки регистрируются в mcp_errors.log

  • Постепенная деградация : несколько резервных подходов для критических функций

  • Удобные для пользователя сообщения : понятные и понятные сообщения об ошибках вместо технических ошибок.

  • Определение типа учетной записи : функции, требующие учетных записей ботов, обнаруживают и уведомляют при использовании с учетными записями пользователей.

  • Обработка ссылок-приглашений : обрабатывает различные форматы ссылок и случаи уже зарегистрированных участников.

Код разработан с учетом устойчивости к распространенным проблемам и ограничениям API Telegram.


🛠️ Руководство по внесению вклада

  1. Форк этого репозитория: chigwell/telegram-mcp

  2. Клонируйте свою вилку:

    git clone https://github.com/<your-github-username>/telegram-mcp.git
  3. Создайте новую ветку:

    git checkout -b my-feature
  4. Внесите изменения, при необходимости добавьте тесты/документы.

  5. Отправьте и откройте запрос на извлечение в chigwell/telegram-mcp с четким описанием.

  6. Отметьте @chigwell или @l1v0n1 в своем PR для проверки.


🔒 Вопросы безопасности

  • Никогда не фиксируйте файл

  • Строка сеанса предоставляет полный доступ к вашему аккаунту Telegram — берегите ее!

  • Вся обработка происходит локально; данные никуда не отправляются, кроме API Telegram.

  • Используйте .env.example в качестве шаблона и сохраните свой настоящий файл .env в тайне.

  • Тестовые файлы автоматически исключаются в .gitignore .


🛠️ Устранение неполадок

  • Проверьте журналы в вашем MCP-клиенте (Claude/Cursor) и терминале на наличие ошибок.

  • Подробные журналы ошибок можно найти в mcp_errors.log .

  • Ошибки интерпретатора? Убедитесь, что ваш .venv создан и выбран.

  • Блокировка базы данных? Используйте аутентификацию на основе строки сеанса, а не сеансов на основе файлов.

  • Проблемы с iCloud/Dropbox? Переместите свой проект в локальный путь без пробелов, если вы видите странные ошибки.

  • Повторно создайте строку сеанса , если вы изменили пароль Telegram или столкнулись с ошибками аутентификации.

  • Функции, предназначенные только для ботов, будут показывать понятные сообщения при использовании с учетными записями обычных пользователей.

  • Сбои тестового сценария? Проверьте тестовую конфигурацию в .env на предмет допустимых тестовых учетных записей/групп.


📄 Лицензия

Данный проект лицензирован под лицензией Apache 2.0 .


🙏 Благодарности


Поддерживается

История Звезды

Звездная история диаграммы

-
security - not tested
A
license - permissive license
-
quality - not tested

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/chigwell/telegram-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server