
Telethon Plus
io.github.psyb0t由 GitHub 账号 psyb0t 发布v0.7.1更新于 Nov 7, 2026
Self-hosted MCP server: Telegram userbot control (Telethon) via HTTP and MCP.
概览
自托管的 Telegram 用户机器人服务器,让助手以你本人账号的身份通过 MCP 或 HTTP 读取、发送和管理 Telegram 会话。
- 可以做什么
- 读取账号资料、解析会话、列出对话、读取与搜索消息、下载媒体
- 发送、编辑、删除、转发、置顶、回应消息并标记已读,支持定时发送和按链接上传文件
- 管理会话:创建、加入、邀请、退出、删除,列出成员,查找关联讨论组
- 群组管理:封禁、解封、踢出、提升与撤销管理员
- 发起投票:创建、投票、查看结果
- 查看限流状态、账号封禁风险与 Prometheus 指标,并通过 WebSocket 或 webhook 接收新事件
- 适用场景
- 适合让助手操作你自己的 Telegram 账号而非机器人账号:整理对话、汇总或搜索频道、起草并发送消息、管理群组,或把收到的消息接入其他流程。定位为自托管服务,不适合临时一次性使用。
- 运行要求
- 以 Docker 容器运行(镜像 psyb0t/telethon-plus),对外提供 HTTP 与 streamable HTTP 的 MCP 端点。清单未声明环境变量,但 README 要求 TELETHON_API_ID 与 TELETHON_API_HASH(来自 my.telegram.org)以及由交互式登录助手生成的 TELETHON_SESSION。可选设置 TELETHON_AUTH_KEY 启用 Bearer 鉴权。需要能访问 Telegram 的网络。
安装
在 SourceWeft 中
- 打开 控制台中的 Telethon Plus,将其添加到工作区。
- 为需要使用其工具的对话启用该服务。
Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。
其他 MCP 客户端
参照 仓库 中的启动说明。
README
docker-telethon-plus
[CI] [version] [license] [Docker Pulls]
Your Telegram account, but it takes HTTP requests. Wraps Telethon — the real MTProto userbot client, not that neutered Bot API garbage — behind a JSON HTTP API and a Model Context Protocol endpoint.
Same tools, two doors. POST some JSON, or point your AI agent at /mcp and let it go nuts. Either way it's talking to Telegram as you, with full account access.
One login. One session string. Never type a code again.
Table of Contents
- How it works
- Quick start
- First-time login
- Configuration
- Tools
- HTTP API
- MCP
- Agent integrations
- Development
- Tests
- License
How it works
One Telethon client. One async lock. Both surfaces share the same tool registry — no duplication, no weird state, no bullshit.
Quick start
Get API_ID / API_HASH from https://my.telegram.org/apps. Get the session string from the login helper below.
First-time login
Telegram makes you prove you're a human once — phone number, SMS code, optionally 2FA. Do it once, never again.
make login builds the image, runs the interactive flow, and shoves TELETHON_SESSION straight into your .env. That's it. Run make run and you're live.
No repo? No problem:
Copy the session string it spits out, set it as TELETHON_SESSION, done.
The session string is full account access. Whoever has it is you. Don't commit it, don't paste it in Slack, don't tattoo it anywhere.
Configuration
All config via environment variables. Copy .env.example to get the full list with comments.
Throttling & cache (anti-flood)
Telegram bans accounts that hammer it. Defaults here are conservative — meant to keep you under the server-side limits without you having to think about it. Tune only if you know what you're doing.
How the layers stack:
- Entity cache short-circuits resolveUsername — first lookup of
@somechannelcalls Telegram; every subsequent lookup is free. Survives container restarts via the/cachevolume. - Per-method token buckets cap the dangerous methods. If you try to resolve 6 new usernames in one minute, the 6th sleeps until the oldest expires.
- Per-chat send interval throttles sends to each chat to ≤1/sec (with margin).
- Global gap + jitter humanizes the overall traffic shape.
- Adaptive backoff: a single FLOOD_WAIT halves your effective rate for an hour. Three in a row → ÷8. Auto-recovers after an idle hour.
For bulk scraping work (the scenario that caused 22-hour bans before): the cache + bucket_resolve_per_min=5 combination is what saves you. Resolving 200 new channels takes ~40 minutes instead of getting you banned in 5.
Tools
JSON in, JSON out. All inputs are pydantic-validated — send garbage, get a 400 back with exactly what's wrong.
Chat references (chat, from_chat, to_chat) accept whatever Telethon accepts:
Numeric IDs only resolve for entities Telethon has already seen — i.e. cached in your session via a prior
@username/t.melookup, dialog list, or incoming message. MTProto needs anaccess_hash, not just an ID, and bare numbers don't carry one. Especially relevant for bots: pass@botusernamefirst (or callGET /api/dialogs/GET /api/entities?chat=@botonce) before referring to it by numeric ID. If you only have the bot's token and no username, hit Telegram's Bot APIgetMeto fetch the username, then use that.
Response shape
Every 2xx returns the resource directly. No {"result": ...} wrapper, no envelope. Lists are JSON arrays, singles are JSON objects.
Errors return {"detail": "..."} (FastAPI standard). Telegram RPC errors arrive as 502 with detail = {"telegram_error": "...", "message": "..."}.
Quick reference
{chat} in path accepts the same formats as elsewhere: @username, numeric ID, me. Phone (+...) and t.me/... links need URL-encoding (%2B etc.) — usernames and IDs work inline.
HTTP API
Standard REST API. JSON in, JSON out. 2xx returns the resource directly; errors return {"detail": ...}.
If TELETHON_AUTH_KEY is set, every request (except /healthz) needs:
GET /api/me
Who am I right now.
GET /api/entities
Resolve any chat reference to a full profile.
GET /api/dialogs
GET /api/messages
Newest first. Returns [] if nothing matches.
POST /api/messages
Send a message. The same endpoint handles text and files — if the body contains file_url, the URL is fetched and sent as media (with text becoming the caption); otherwise text is sent as a plain message.
PATCH /api/messages/{id}
Edit a message. Message ID goes in the URL, everything else in the body.
DELETE /api/messages
Delete messages by ID.
POST /api/messages/forward
POST /api/messages/read
Mark messages as read.
GET /api/participants
List members of a group or channel.
Large public channels may return a limited set or require admin rights.
POST /api/chats
Create a supergroup or broadcast channel.
DELETE /api/chats
Delete a supergroup or channel you own. Irreversible.
POST /api/chats/join
Join a public channel or supergroup.
POST /api/chats/leave
Leave a channel or supergroup.
Errors
Health
authorized: false means the container started but the session is fucked — bad string, revoked, or Telegram unreachable. Always public, no auth required.
Observability
GET /metrics
Prometheus exposition. Scrape it. No auth (publicly readable inside your cluster — if you need it locked down, put it behind your usual scrape-network policy).
Series exported:
telethon_plus_tool_calls_total{tool=...}telethon_plus_tool_errors_total{tool=...}telethon_plus_flood_events_total{bucket=...}telethon_plus_cache_hits_total/_misses_total/_entriestelethon_plus_throttle_multipliertelethon_plus_bucket_used{bucket=...}/_bucket_limit{bucket=...}telethon_plus_uptime_seconds
GET /api/throttle/status
Live state of every bucket, multiplier, recent flood events, cache stats:
GET /api/account/health
risk is ok (multiplier 1×), warning (≥2×), or high (≥8×).
Throttle response headers
Every /api/... response carries:
X-Throttle-MultiplierX-Throttle-Flood-Events-1hX-RateLimit-Remaining-<bucket>for each bucket
Lets clients self-throttle without polling /api/throttle/status.
Updates / webhooks
Two ways to receive incoming Telegram events (new messages, edits, deletes, chat actions):
WebSocket — /ws/updates
If TELETHON_AUTH_KEY is set, pass it as ?token=. Browser WS clients can't set Authorization headers, hence query-string.
Multiple subscribers are supported — each gets its own queue. Slow consumers drop events at TELETHON_UPDATES_BUFFER_SIZE.
Outbound webhook — TELETHON_POST_TO_URL
Set the env var to your endpoint and every event gets POSTed there as JSON. Fire-and-forget — a slow or failing webhook never blocks Telethon's loop. Use for distributed workers, separate processes, anything that can't hold a WS open.
Event payload shape
For MessageEdited, MessageDeleted, ChatAction — same shape, fewer fields.
Safety switches
TELETHON_READ_ONLY=true
Every write endpoint returns 403. Reads, status, metrics still work. Killswitch for panic mode or for keeping a test deployment harmless.
TELETHON_DRY_RUN=true
Write endpoints accept the request, validate it, don't call Telegram, return {"dry_run": true, "would_...": {...}}. Useful for verifying scripts before pointing them at production.
MCP
Mounted at /mcp/ using the streamable HTTP transport. Every tool from the table above shows up automatically as an MCP tool with the same name and schema.
Point your agent at:
Stateless — every request is independent, no session juggling. Drop it into Claude Desktop, a custom agent, anything that speaks MCP over HTTP. Works out of the box.
Agent integrations
The skill works in any agent that reads .agents/skills/ (such as peen), and installs natively in the clients below.
Claude Code
Claude Code prompts for the telethon-plus server URL and, if auth is enabled, the bearer token — the token is stored in your OS keychain.
Codex
Installed via the marketplace, the skill invokes as $telethon-plus:telethon-plus. Codex also picks the skill up automatically with no install in any repo containing .agents/skills/, where it invokes as plain $telethon-plus.
OpenClaw
The skill is published to ClawHub on every release:
For MCP clients that speak local stdio, the @psyb0t/telethon-plus plugin bridges to the service's /mcp/ endpoint:
Then set TELETHON_PLUS_URL (and TELETHON_AUTH_KEY if the server requires auth).
Development
Tests
Real tests. Real Telegram. No mocking bullshit.
tests/ spins up the container and hammers both REST and MCP with your actual account. Messages get sent and deleted. If anything breaks, you'll know.
Setup:
TEST_CHAT is where test messages land. Use me for Saved Messages — private, yours, no one else sees it. All chat reference formats from the Tools section work here.
make test builds both images and runs pytest inside Docker with the socket mounted. No setup beyond .env. If credentials are missing, the suite skips cleanly.
License
WTFPL — do whatever the fuck you want.
来源:README.md,提交 1c2449c
工具
0版本历史
1- v0.5.7Sep 16, 2026
评分
已满足适用检查项的 50%
该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。
- 近 30 天内可连通25 分
请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。
- 已声明认证方式10 分
请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。
- 已列出工具15 分
请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。
- 描述必需15 分
- 图标10 分
- 文档15 分
- 许可证10 分