Skip to main content
Glama
EyalWerber

telegram-mcp

by EyalWerber
README.md
# 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

A4.4/5.0

Scored across 2 tools

Disambiguation5/5

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.

Naming Consistency4/5

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.

Tool Count3/5

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.

Completeness4/5

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.

Maintenance

ActivityMaintained
ResponsivenessNo issues