Телеграм MCP-сервер
🤖 MCP в действии
Вот демонстрация возможностей Telegram MCP в Claude :
Пример простого использования:

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

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

Как вы видите, ИИ может беспрепятственно взаимодействовать с вашим аккаунтом 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.
📋 Требования
Питон 3.10+
Claude Desktop или Cursor (или любой MCP-клиент)
🔧 Установка и настройка
1. Форк и клонирование
git clone https://github.com/chigwell/telegram-mcp.git
cd telegram-mcp2. Создайте виртуальную среду
python3 -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
pip install -r requirements.txt3. Сгенерируйте строку сеанса
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 .
Создайте файл Убедитесь, что в корне проекта есть файл
.env, содержащийTELEGRAM_API_ID,TELEGRAM_API_HASHиTELEGRAM_SESSION_STRING(илиTELEGRAM_SESSION_NAME). Используйте.env.exampleв качестве шаблона.Запустить 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.
🛠️ Руководство по внесению вклада
Форк этого репозитория: chigwell/telegram-mcp
Клонируйте свою вилку:
git clone https://github.com/<your-github-username>/telegram-mcp.gitСоздайте новую ветку:
git checkout -b my-featureВнесите изменения, при необходимости добавьте тесты/документы.
Отправьте и откройте запрос на извлечение в chigwell/telegram-mcp с четким описанием.
Отметьте @chigwell или @l1v0n1 в своем PR для проверки.
🔒 Вопросы безопасности
Никогда не фиксируйте файл
Строка сеанса предоставляет полный доступ к вашему аккаунту Telegram — берегите ее!
Вся обработка происходит локально; данные никуда не отправляются, кроме API Telegram.
Используйте
.env.exampleв качестве шаблона и сохраните свой настоящий файл.envв тайне.Тестовые файлы автоматически исключаются в
.gitignore.
🛠️ Устранение неполадок
Проверьте журналы в вашем MCP-клиенте (Claude/Cursor) и терминале на наличие ошибок.
Подробные журналы ошибок можно найти в
mcp_errors.log.Ошибки интерпретатора? Убедитесь, что ваш
.venvсоздан и выбран.Блокировка базы данных? Используйте аутентификацию на основе строки сеанса, а не сеансов на основе файлов.
Проблемы с iCloud/Dropbox? Переместите свой проект в локальный путь без пробелов, если вы видите странные ошибки.
Повторно создайте строку сеанса , если вы изменили пароль Telegram или столкнулись с ошибками аутентификации.
Функции, предназначенные только для ботов, будут показывать понятные сообщения при использовании с учетными записями обычных пользователей.
Сбои тестового сценария? Проверьте тестовую конфигурацию в
.envна предмет допустимых тестовых учетных записей/групп.
📄 Лицензия
Данный проект лицензирован под лицензией Apache 2.0 .
🙏 Благодарности
chigwell/telegram-mcp (вверх по течению)
Поддерживается