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.
claude mcp add docker-telethon-plus -- uvx docker-telethon-plus{
"mcpServers": {
"docker-telethon-plus": {
"command": "uvx",
"args": ["docker-telethon-plus"]
}
}
}MCP Servers overview
# docker-telethon-plus
[](https://hub.docker.com/r/psyb0t/telethon-plus)
[](http://www.wtfpl.net/)
Your Telegram account, but it takes HTTP requests. Wraps [Telethon](https://codeberg.org/Lonami/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](#how-it-works)
- [Quick start](#quick-start)
- [First-time login](#first-time-login)
- [Configuration](#configuration)
- [Tools](#tools)
- [HTTP API](#http-api)
- [MCP](#mcp)
- [Development](#development)
- [Tests](#tests)
- [License](#license)
## How it works
```
+-------------------+ +-----------------------+
| Any HTTP client | -----> | REST /api/... | --+
+-------------------+ +-----------------------+ |
| +-----------+ Telegram
+-------------------+ +-----------------------+ +-> | Telethon | <----> Servers
| MCP-aware agent | -----> | /mcp (Streamable | --+ +-----------+ (MTProto)
| (Claude, etc.) | | HTTP transport) |
+-------------------+ +-----------------------+
```
One Telethon client. One async lock. Both surfaces share the same tool registry — no duplication, no weird state, no bullshit.
## Quick start
```yaml
services:
telethon-plus:
image: psyb0t/telethon-plus
ports:
- "8080:8080"
environment:
TELETHON_API_ID: "123456"
TELETHON_API_HASH: "your-api-hash"
TELETHON_SESSION: "1Aa...long-string-from-login-helper..."
restart: unless-stopped
```
Get `API_ID` / `API_HASH` from <https://my.telegram.org/apps>. Get the session string from the [login helper](#first-time-login) below.
## First-time login
Telegram makes you prove you're a human once — phone number, SMS code, optionally 2FA. Do it once, never again.
```bash
cp .env.example .env
$EDITOR .env # put in TELETHON_API_ID and TELETHON_API_HASH
make login
```
`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:
```bash
docker run --rm -it \
-e TELETHON_API_ID=123456 \
-e TELETHON_API_HASH=your-api-hash \
psyb0t/telethon-plus login
```
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.
| Variable | Required | Default | Description |
|---|---|---|---|
| `TELETHON_API_ID` | yes | — | API ID from my.telegram.org |
| `TELETHON_API_HASH` | yes | — | API hash from my.telegram.org |
| `TELETHON_SESSION` | yes | — | StringSession from the login helper |
| `TELETHON_HTTP_LISTEN_ADDRESS` | no | `0.0.0.0:8080` | `host:port` to bind |
| `TELETHON_LOG_LEVEL` | no | `INFO` | `DEBUG`, `INFO`, `WARNING`, `ERROR` |
| `TELETHON_REQUEST_TIMEOUT` | no | `60` | Per-request timeout in seconds |
| `TELETHON_FLOOD_SLEEP_THRESHOLD` | no | `60` | Auto-sleep through `FLOOD_WAIT` errors below this many seconds. Telegram will rate-limit you — this is the safety valve. |
| `TELETHON_DEVICE_MODEL` | no | `docker-telethon-plus` | What Telegram thinks your device is |
| `TELETHON_SYSTEM_VERSION` | no | `1.0` | Ditto for OS |
| `TELETHON_APP_VERSION` | no | `1.0` | Ditto for app |
| `TELETHON_DOWNLOAD_DIR` | no | `/tmp/telethon-plus` | Scratch space for `send_file` uploads |
| `TELETHON_AUTH_KEY` | no | `""` | When set, all endpoints require `Authorization: Bearer <key>`. `/healthz` stays public. Empty = no auth. |
### 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.
| Variable | Default | What it does |
|---|---|---|
| `TELETHON_THROTTLE_ENABLED` | `true` | Master switch for all rate-limiting below |
| `TELETHON_THROTTLE_GLOBAL_INTERVAL_MS` | `50` | Min gap between any two outgoing requests |
| `TELETHON_THROTTLE_JITTER_MS` | `200` | Random ±jitter added on top (kills metronome traffic patterns) |
| `TELETHON_THROTTLE_PER_CHAT_INTERVAL_MS` | `1100` | Min gap between sends to the same chat (Telegram's "1/sec/chat" ceiling, with margin) |
| `TELETHON_THROTTLE_PER_CHAT_READ_INTERVAL_MS` | `250` | Min gap between reads from the same chat. Stops single-channel scraping from monopolizing the read bucket. |
| `TELETHON_THROTTLE_ADAPTIVE` | `true` | On each `FLOOD_WAIT`, multiply all waits ×2 for an hour. Resets after a quiet hour. |
| `TELETHON_BUCKET_RESOLVE_PER_MIN` | `5` | Cap on `resolveUsername` — **the main thing that gets accounts 22-hour-banned** |
| `TELETHON_BUCKET_GET_FULL_PER_MIN` | `10` | Cap on `getFullChannel` / `getFullUser` / `get_participants` |
| `TELETHON_BUCKET_JOIN_PER_HOUR` | `5` | Cap on channel/group joins |
| `TELETHON_BUCKET_CREATE_PER_HOUR` | `5` | Cap on channel/group creation |
| `TELETHON_BUCKET_SEND_PER_MIN` | `20` | Cap on sends across all chats |
| `TELETHON_BUCKET_READ_PER_MIN` | `600` | Cap on read ops. **Counted per server-side API call**, not per tool call: `get_messages(limit=300)` charges 3 slots (Telegram caps GetHistory at 100/page); `get_dialogs(limit=500)` similarly charges 5. |
| `TELETHON_CACHE_ENABLED` | `true` | Persist resolved entities to disk |
| `TELETHON_CACHE_PATH` | `/cache/entities.json` | Mount `/cache` as a host volume to keep this across rebuilds |
| `TELETHON_CACHE_TTL_SECONDS` | `604800` | 7 days. Set `0` for no expiry. |
| `TELETHON_FLOOD_SLEEP_THRESHOLD` | `60` | Telethon's reactive auto-sleep: if a `FLOOD_WAIT` is shorter than this many seconds, sleep through it. Above this, raise. Set very high (e.g. `86400`) to never raise — but then a hostile FLOOD_WAIT will block your process for the full duration. |
**How the layers stack:**
1. Entity cache short-circuits resolveUsername — first lookup of `@somechannel` calls Telegram; every subsequent lookup is free. Survives container restarts via the `/cache` volume.
2. 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.
3. Per-chat send interval throttles sends to each chat to ≤1/sec (with margin).
4. Global gap + jitter humanizes the overall traffic shape.
5. 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:
| Format | Example |
|---|---|
| Username | `@psyb0t` |
| Phone number | `+1234567890` |
| t.me link | `https://t.me/psyb0t` |
| Numeric ID | `123456789` |
| Supergroup/channel ID | `-1001234567890` |
| Your own Saved Messages | `me` |
> **Numeric IDs only resolve for entities Telethon has already seen** — i.e. cached in your session via a prior `@username` / `t.me` lookup, dialog list, or incoming message. MTProto needs an `access_hash`, not just an ID, and bare numbers don't carry one. Especially relevant for bots: pass `@botusername` first (or call `GET /api/dialogs` / `GET /api/entities?chat=@bot` once) before referring to it by numeric ID. If you only have the bot's token and no username, hit Telegram's Bot API `getMe` to 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
| Endpoint | Required params | What it does |
|---|---|---|
| `GET /api/me` | — | Account profile. |
| `GET /api/entities` | `chat` | Resolve a username/ID/link to a profile. |
| `POST /api/entities/bulk` | `chats` | Bulk resolve, honoring the resolve-username bucket. |
| `GET /api/dialogs` | — | List dialogs. Optional: `limit`, `archived`, `search` (substring on title/@). |
| `GET /api/messages` | `chat` | Read recent messages. Optional: `limit`, `offset_id`, `search`. |
| `GET /api/messages/{id}` | `chat` | Fetch a single message. |
| `GET /api/messages/{id}/media` | `chat` | Download attachment as **raw bytes** (binary stream). Returns `Content-Type` from Telegram + `Content-Disposition: attachment; filename=...`. Optional: `max_bytes`. MCP clients should use the `download_media` tool which returns base64. |
| `POST /api/messages` | `chat`, **`text` or `file_url`** | Send a message. If `file_url` is present, fetches it and sends as media (with `text` as caption). Otherwise sends `text`. Optional: `parse_mode`, `reply_to`, `silent`, `link_preview`, `schedule`, `force_document`, `max_bytes`. |
| `POST /api/messages/forward` | `from_chat`, `to_chat`, `message_ids` | Forward messages. |
| `POST /api/messages/read` | `chat` | Mark as read. Optional `max_id`. |
| `PATCH /api/messages/{id}` | `chat`, `text` | Edit. |
| `DELETE /api/messages` | `chat`, `messWhat people ask about docker-telethon-plus
What is psyb0t/docker-telethon-plus?
+
psyb0t/docker-telethon-plus is mcp servers for the Claude AI ecosystem. 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. It has 0 GitHub stars and was last updated today.
How do I install docker-telethon-plus?
+
You can install docker-telethon-plus by cloning the repository (https://github.com/psyb0t/docker-telethon-plus) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is psyb0t/docker-telethon-plus safe to use?
+
psyb0t/docker-telethon-plus has not been audited yet by our security agent. Review the original repository on GitHub before using it in production.
Who maintains psyb0t/docker-telethon-plus?
+
psyb0t/docker-telethon-plus is maintained by psyb0t. The last recorded GitHub activity is from today, with 0 open issues.
Are there alternatives to docker-telethon-plus?
+
Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.
Deploy docker-telethon-plus to your cloud
Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.
Maintain this repo? Add a badge to your README
Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.
[](https://claudewave.com/repo/psyb0t-docker-telethon-plus)<a href="https://claudewave.com/repo/psyb0t-docker-telethon-plus"><img src="https://claudewave.com/api/badge/psyb0t-docker-telethon-plus" alt="Featured on ClaudeWave: psyb0t/docker-telethon-plus" width="320" height="64" /></a>More MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
The fastest path to AI-powered full stack observability, even for lean teams.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!