telegram-mcp-server
by Dmitrii-ive
README.md
# telegram-mcp-server
A local, **read-only**, **folder-scoped** MCP server that lets an AI agent
(Claude Code, etc.) read your **personal** Telegram chats — but only the chats
inside an allowlist of Telegram folders. No send/edit/delete capability exists.
Built for a common use case: let an agent read your client/lead conversations
and pull out tasks, without giving it the keys to your whole Telegram.
> ⚠️ This logs in as your **personal Telegram account** via the official MTProto
> API (GramJS). Automating a user account is a grey area under Telegram's ToS;
> the risk is low for read-only use but not zero. Use on your own account.
## How it stays safe
- **Read-only.** The server registers four tools, all read-only. There is no
tool that can send, edit, or delete anything.
- **Folder-scoped.** Only chats inside the folders listed in `config.json`
(`allowedFolders`) are reachable. Every tool resolves the requested chat
against that allowlist and refuses anything outside it. Chats in your other
folders (family, personal, etc.) are physically unreachable.
- **Secrets stay local.** `api_id`/`api_hash` live in `config.json` (gitignored).
The session string — which grants full account access — is stored in the
**macOS Keychain**, never on disk, never in git.
## Requirements
- [Bun](https://bun.sh) (runs the TypeScript directly)
- macOS (uses the Keychain via the `security` CLI for session storage)
- A Telegram account, and an `api_id` / `api_hash` from <https://my.telegram.org>
## Setup
```bash
# 1. install
bun install
# 2. configure
cp config.example.json config.json
# edit config.json: apiId, apiHash, allowedFolders (exact Telegram folder names)
# 3. log in (QR — the reliable method; see note below)
bun run qr
# On your phone: Telegram -> Settings -> Devices -> Link Desktop Device -> scan the QR
# 4. verify which folders/chats resolved
bun run folders
# 5. register with your MCP client (Claude Code example, user scope):
claude mcp add telegram -s user -- bun run "$(pwd)/src/server.ts"
```
### Why QR login, not the SMS/app code
`bun run login` (phone + code) often fails: Telegram frequently accepts the
`SendCode` request and reports "code sent to app", but never actually delivers
the code (and offers no SMS fallback) for third-party API logins — especially
with a freshly created `api_id`. **`bun run qr` sidesteps this entirely**: the
login is approved from your already-authorized phone, so no code delivery is
needed. Use QR first.
## Tools
| Tool | What it does |
|------|--------------|
| `tg_list_folders` | List allowed folders + resolved chat counts |
| `tg_list_chats` | List chats in allowed folders (optionally one folder) |
| `tg_read_chat` | Recent messages from one allowed chat |
| `tg_search` | Search messages across allowed chats / one folder / one chat |
## Troubleshooting
- **A folder shows 0 chats** → its name in `config.json` doesn't match Telegram
exactly. Run `bun run folders`; if needed, temporarily inspect all folder
titles (the diagnose output lists matched ones). Names are case-insensitive
but must otherwise match (watch for typos / emoji / extra words).
- **`FLOOD_WAIT_N`** → too many login attempts; wait N seconds. Don't spam
retries — each one extends the window.
- **`CHANNEL_PRIVATE` skipped** → a private channel you've left/been removed
from can't be resolved; it's skipped, harmless.
- **Login code never arrives** → use `bun run qr` (see above).
## Files
```
src/
server.ts MCP server (4 read-only tools)
client.ts GramJS client + folder allowlist (the privacy boundary)
qr-login.ts QR-code login (recommended)
login.ts phone+code login (fallback, with 'sms' resend)
config.ts loads config.json
keychain.ts session string <-> macOS Keychain
diagnose.ts 'bun run folders' — show allowed folders + counts
probe.ts 'bun run probe +NUMBER' — dump raw SendCode response
```
## License
MIT
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues