这里展示了在 Claude 中使用 Telegram MCP 的能力:
基本用法示例:



如您所见,AI 可以无缝地与您的 Telegram 账户交互,获取并显示您的聊天、消息和其他数据。
一个完整的 Telegram 集成,适用于 Claude、Cursor 和任何兼容 MCP 的客户端,由 Telethon 和 模型上下文协议 (MCP) 提供支持。此项目允许您通过编程方式与您的 Telegram 账户进行交互,从消息到群组管理的一切都可以自动化。
这个 MCP 服务器提供了一整套的 Telegram 工具。每个主要的 Telegram/Telethon 功能都可用作工具!
为了提高健壮性,所有接受 chat_id 或 user_id 参数的函数现在包括了输入验证。您可以使用以下任意格式之一来表示这些ID:
123456789 或 -1001234567890)。"123456789")。"@username" 或 "username")。服务器会自动验证输入,并将其转换为正确的格式后再向 Telegram 发送请求。如果输入无效,将返回清晰的错误消息。
请注意,需要直接访问服务器文件路径的工具(send_file, download_media, set_profile_photo, edit_chat_photo, send_voice, send_sticker, upload_file)已被移除自 main.py。这是由于当前 MCP 环境在处理文件附件和本地文件系统路径方面的限制。
此外,由于 Telethon 库或 Telegram API 交互中的可靠性问题,与 GIF 相关的工具(get_gif_search, get_saved_gifs, send_gif)也被移除。
git clone https://github.com/chigwell/telegram-mcp.git
cd telegram-mcp
uv sync
uv run session_string_generator.py
按照提示进行身份验证,并更新您的 .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
在 my.telegram.org/apps 获取您的 API 凭证。
如果您安装了 Docker 和 Docker Compose,可以通过构建容器来运行服务器,简化依赖管理。
从项目根目录,构建 Docker 镜像:
docker build -t telegram-mcp:latest .
您有两个选项:
选项 A:使用 Docker Compose(推荐用于本地使用)
此方法使用 docker-compose.yml 文件,并自动从 .env 文件中读取您的凭据。
.env 文件:确保项目根目录下有一个包含您的 TELEGRAM_API_ID、TELEGRAM_API_HASH 和 TELEGRAM_SESSION_STRING(或 TELEGRAM_SESSION_NAME)的 .env 文件。使用 .env.example 作为模板。docker compose up --build
docker compose up -d 以分离模式(后台)运行。Ctrl+C 停止服务器。选项 B:使用 docker run
您可以直接运行容器,传递凭据作为环境变量。
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 配置(~/.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:
"""
获取分页的聊天列表。
参数:
page: 页面编号(从1开始)。
page_size: 每页的聊天数量。
"""
try:
dialogs = await client.get_dialogs()
start = (page - 1) * page_size
end = start + page_size
if start >= len(dialogs):
return "页面超出范围。"
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", "未知")
lines.append(f"聊天ID: {chat_id}, 标题: {title}")
return "\n".join(lines)
except Exception as e:
logger.exception(f"get_chats 失败 (page={page}, page_size={page_size})")
return "发生错误 (代码: GETCHATS-ERR-001)。请查看 mcp_errors.log 获取详细信息。"
示例输出:
聊天ID: 123456789, 标题: John Doe
聊天ID: -100987654321, 标题: 我的项目小组
聊天ID: 111223344, 标题: Jane Smith
聊天ID: -200123456789, 标题: 新闻频道
@mcp.tool()
async def send_message(chat_id: int, message: str) -> str:
"""
向特定聊天发送消息。
参数:
chat_id: 聊天的ID。
message: 要发送的消息内容。
"""
try:
entity = await client.get_entity(chat_id)
await client.send_message(entity, message)
return "消息发送成功。"
except Exception as e:
logger.exception(f"send_message 失败 (chat_id={chat_id})")
return "发生错误 (代码: SENDMSG-ERR--001)。请查看 mcp_errors.log 获取详细信息。"
示例输出:
消息发送成功。
@mcp.tool()
async def list_inline_buttons(
chat_id: Union[int, str],
message_id: Optional[int] = None,
limit: int = 20,
) -> str:
"""
发现内联键盘布局,包括按钮索引、回调可用性和URL。
"""
示例用法:
list_inline_buttons(chat_id="@sample_tasks_bot")
这返回类似的内容:
消息42的按钮(日期 2025-01-01 12:00:00+00:00):
[0] 文本='📋 查看任务', 回调=是
[1] 文本='ℹ️ 帮助', 回调=是
[2] 文本='🌐 访问网站', 回调=否, URL=https://example.org
@mcp.tool()
async def press_inline_button(
chat_id: Union[int, str],
message_id: Optional[int] = None,
button_text: Optional[str] = None,
button_index: Optional[int] = None,
) -> str:
"""
通过标签或零基索引按下内联键盘按钮。
如果省略 message_id,服务器会在最近的消息中搜索最新的内联键盘。
"""
示例用法:
press_inline_button(chat_id="@sample_tasks_bot", button_text="📋 查看任务")
如果需要检查可用按钮,请先使用 list_inline_buttons —— 传递一个虚假的 button_text 快速列出选项或直接调用 list_inline_buttons。一旦知道文本或索引,press_inline_button 将发送回调,就像在原生 Telegram 客户端中点击按钮一样。
@mcp.tool()
async def subscribe_public_channel(channel: Union[int, str]) -> str:
"""
通过用户名(例如,“@examplechannel”)或ID加入公共频道或超级群组。
"""
示例用法:
subscribe_public_channel(channel="@daily_updates_feed")
如果账户已经是参与者,则该工具报告这一点而不是失败,使其在需要幂等连接的工作流中安全运行。
get_invite_link 函数特别强大,具有多种备用方法:
@mcp.tool()
async def get_invite_link(chat_id: int) -> str:
"""
获取群组或频道的邀请链接。
"""
try:
entity = await client.get_entity(chat_id)
# 尝试首先使用 ExportChatInviteRequest
try:
from telethon.tl import functions
result = await client(functions.messages.ExportChatInviteRequest(
peer=entity
))
return result.link
except AttributeError:
# 如果当前 Telethon 版本中不存在该功能
logger.warning("ExportChatInviteRequest 不可用,使用替代方法")
except Exception as e1:
# 如果失败,记录并尝试其他方法
logger.warning(f"ExportChatInviteRequest 失败: {e1}")
# 使用 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 失败: {e2}")
# 最后一招:直接获取聊天信息
try:
if isinstance(entity, (Chat, Channel)):
full_chat = await