telegram-mcp
# telegram-mcp
Hands Claude the newest image from one Telegram group.
The screenshots are posted by a bot, and the Telegram Bot API never returns a
bot's own messages — so this reads the group with a *user* account over
MTProto (Telethon). That is the only way to see those photos.
## Setup (once)
1. Get an api id and hash from https://my.telegram.org → API development tools.
2. `cp .env.example .env` and fill in `TELEGRAM_API_ID`, `TELEGRAM_API_HASH`,
and `TELEGRAM_CHAT_ID` (the group's numeric id, negative).
3. Create the environment:
```
python -m venv .venv
.venv\Scripts\pip install -e .[dev]
```
4. Sign in — in a terminal, not through Claude:
```
.venv\Scripts\telegram-mcp-login
```
It asks for your phone number, the code Telegram sends, and your two-factor
password if you have one, then writes `session/telegram.session`.
It also lists your dialogs once and prints the group's name back at you. The
listing is what lets the session resolve a supergroup later -- Telegram turns
a group into one as soon as a bot joins it -- and the name is your
confirmation that `TELEGRAM_CHAT_ID` points where you think it does. If it
cannot find the group, it says so and exits non-zero.
## Install into Claude
```
claude mcp add --scope user telegram -- <abs path>\.venv\Scripts\python -m telegram_mcp.server
```
User scope, so every project gets it.
## Tools
- `get_latest_image()` — the most recent photo in the group, looking back 200
messages.
- `wait_for_next_image(timeout_seconds=120)` — blocks until a photo newer than
the moment of the call arrives. Waiting costs no tokens; the process idles on
a socket. Clamped to 1–240 s to stay inside the MCP client's tool timeout.
Both return the image (JPEG, long edge ≤1568 px) plus a line of text: the path
to the untouched original first, then the message id, timestamp, sender, and the
caption, quoted. Crop that original when the downscale loses fine print.
Only one process can hold the session at a time. A second Claude Code session
calling a tool while the first is mid-call is told to try again in a moment,
rather than being handed a SQLite error.
## Tests
```
.venv\Scripts\python -m pytest
```
No network, no Telegram account needed — Telethon is faked throughout.
## Security
`session/telegram.session` is a full login to your Telegram account. It is
gitignored and never leaves this machine. Anyone holding that file can read
your messages; delete it and re-run the login if you suspect it has been
copied. Credentials live only in `.env` — never in docs, prompts, or tickets.
TDQS
Scored across 2 tools
The two tools are clearly distinct: get_latest_image retrieves a previously posted photo, while wait_for_next_image blocks for a new one. The use cases do not overlap in an ambiguous way.
Both names follow a verb-noun structure and clearly communicate function. The slight mix of 'get_' and 'wait_for_' is a minor deviation but still predictable.
Two tools is at the low end of a reasonable scope for a narrow image-receiving server. They cover the core need without bloat, but the server feels rather thin.
The pair covers the two key workflows: retrieving a previous screenshot and waiting for a new one. Missing features like explicit image search or sending could be useful, but they are not essential for the server's obvious intent.