Skip to main content
Glama
julijakvetna

Telegram Read-Only MCP Server

by julijakvetna
README.md
# Telegram → Claude Desktop: read-only MCP server

A small MCP server that gives Claude Desktop **read-only** access to selected chats of your personal Telegram account. Runs locally on your Mac via [Telethon](https://github.com/LonamiWebs/Telethon). There are no tools for sending messages — the server physically cannot write to Telegram.

Why: ask Claude "what was discussed in group X in the last 24 hours", "show me the forum topics", "find where we talked about Y" — and get an answer with links to the messages.

---

## What's inside

| File | Purpose |
|---|---|
| `server.py` | MCP server: `list_chats`, `list_topics`, `read_messages`, `search_messages` |
| `login.py` | One-time authorization, creates the `.session` file |
| `.env.example` | Settings template — copy to `.env` |
| `claude_desktop_config.example.json` | What to add to the Claude Desktop config |
| `requirements.txt` | Dependencies with pinned versions (see "Pitfalls") |
| `.gitignore` | Excludes `.env`, `*.session`, `.venv` — **do not remove** |

## Requirements

- macOS (works on Linux too; config paths differ)
- **Python 3.10+** — the system Python on macOS is too old (see step 1)
- Claude Desktop
- A Telegram account with two-step verification enabled (strongly recommended)

---

## Step-by-step setup

### 1. Fresh Python

```bash
brew install python@3.13
python3.13 --version
```

No `brew`? Install it from [brew.sh](https://brew.sh).

### 2. Telegram API keys

1. Go to [my.telegram.org](https://my.telegram.org) → **API development tools**.
2. Create an application (any name).
3. Note down `api_id` and `api_hash`.
4. In Telegram: Settings → Privacy and Security → **Two-Step Verification** → enable if not already.

### 3. Folder and environment

```bash
git clone https://github.com/julijakvetna/telegram-readonly-mcp.git ~/tg-mcp
cd ~/tg-mcp
python3.13 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
```

### 4. The `.env` file

```bash
cp .env.example .env
open -e .env
```

Fill in:

```
TG_API_ID=12345
TG_API_HASH=your_hash
TG_ALLOWED_CHATS=Chat name 1,Chat name 2
TG_DEFAULT_CHAT=Chat name 1
TG_SESSION_NAME=telegram
```

`TG_ALLOWED_CHATS` is a whitelist: the server sees **only** these dialogs. Use the exact titles as shown in your Telegram chat list; case-insensitive; comma-separated.

### 5. Authorization (once)

```bash
python login.py
```

It asks for your phone number (international format, `+1...`), the code Telegram sends you, and your 2FA password. It should finish with `Authorized as: …` and the list of whitelisted chats. A `telegram.session` file appears — restrict its permissions:

```bash
chmod 600 telegram.session
```

### 6. Test the server

```bash
python server.py
```

Correct behavior: **the command hangs and prints nothing** (an MCP server waits for a connection). Stop with `Ctrl+C`. If you see a traceback instead, see "Pitfalls" below.

### 7. Connect to Claude Desktop

Claude Desktop → Settings → Developer → **Edit Config**. Add the block from `claude_desktop_config.example.json`, replacing your Mac username (find it with `whoami`):

```json
{
  "mcpServers": {
    "telegram": {
      "command": "/Users/YOUR_USER/tg-mcp/.venv/bin/python",
      "args": ["/Users/YOUR_USER/tg-mcp/server.py"]
    }
  }
}
```

Or do it with one terminal command (backs up the config and adds the block without touching other servers):

```bash
cd ~/tg-mcp && source .venv/bin/activate && python - <<'EOF'
import json, shutil
from pathlib import Path
p = Path.home() / "Library/Application Support/Claude/claude_desktop_config.json"
shutil.copy(p, p.with_suffix(".json.bak"))
cfg = json.loads(p.read_text())
here = Path.home() / "tg-mcp"
cfg.setdefault("mcpServers", {})["telegram"] = {
    "command": str(here / ".venv/bin/python"),
    "args": [str(here / "server.py")],
}
p.write_text(json.dumps(cfg, indent=2, ensure_ascii=False))
print("Servers:", ", ".join(cfg["mcpServers"]))
EOF
```

**Fully restart Claude Desktop** (⌘Q, then reopen — closing the window is not enough).

### 8. Test in Claude

New chat → the `telegram` connector should appear under the "+" menu. Ask:

> show me the topics of <chat name> and what was posted there in the last 24 hours

---

## Tools

| Tool | What it does |
|---|---|
| `list_chats()` | Whitelisted chats |
| `list_topics(chat)` | Topics of a forum-style group: `id` and title |
| `read_messages(chat, topic_id, hours=24, limit=300)` | Text messages from the last N hours, newest first, with `t.me/c/...` links |
| `search_messages(query, chat, limit=50)` | Full-text search inside a chat |

Empty `chat` = `TG_DEFAULT_CHAT`.

---

## Pitfalls we hit (and fixes)

All of these are real errors from the first install, in the order they appeared.

**`pip` version 21 / error installing `mcp`**
The system Python on macOS is 3.8–3.9; the `mcp` package needs 3.10+. Fix: `brew install python@3.13`, recreate the venv (`rm -rf .venv && python3.13 -m venv .venv`).

**`ImportError: cannot import name 'GetForumTopicsRequest' from 'telethon.tl.functions.channels'`**
In recent Telethon the request moved to `telethon.tl.functions.messages` and the argument was renamed `channel` → `peer`. `server.py` already has a `try/except` that works with both versions. If you edit the code yourself, don't forget the closing `}` in `**{_TOPICS_ARG: e}`.

**`ModuleNotFoundError: No module named 'mcp.server.fastmcp'` … This is mcp 2.x**
`pip install mcp` installs 2.x, where `FastMCP` was renamed to `MCPServer`. The code targets 1.x, so `requirements.txt` pins `mcp[cli]<2`. If 2.x is already installed: `pip install "mcp[cli]<2"`.

**The connector doesn't show up in Claude Desktop**
Either the config wasn't saved, Claude wasn't restarted with ⌘Q, or the server crashes on start. Run `python server.py` by hand — if there's a traceback, the cause is there.

**The terminal complains about a line from the README**
If you paste a block together with a `# …` comment, bash tries to execute it. Harmless, ignore.

---

## Security — read this

- **`<name>.session` = full access to your Telegram account.** Whoever gets the file can log in as you. Don't copy it, don't put it in cloud storage, don't commit it. `chmod 600`.
- **`.env` contains your `api_hash`** — also a secret. `.gitignore` already excludes both files; check before your first `git push`: `git status` must not show `.env` or `*.session`.
- The server only sees chats from `TG_ALLOWED_CHATS` and has no write tools.
- Works while the Mac is on and Claude Desktop is open.
- To revoke access: Telegram → Settings → Devices → terminate the app's session; then delete the `.session` file.

---

MIT © 2026 Judith Kvetna