Skip to main content
Glama
pokkop280

mcp-telegram-local

by pokkop280
README.md
# mcp-telegram-local

A **local MCP (Model Context Protocol) server** that connects [Claude](https://claude.ai) to your **personal Telegram account** using MTProto — the same encrypted protocol used by Telegram's own apps.

Claude gets 11 tools and 4 resources to read messages, search chats, send replies, forward files, and more — all through your real Telegram account, not a bot.

```bash
npx mcp-telegram-local
```

---

## What makes this different

Most Telegram integrations use the Bot API, which requires a separate bot account and can't access your personal chats. This server uses **MTProto** (via [gramjs](https://github.com/gram-js/gramjs)) to log in as **you** — the same way the official Telegram desktop app works. Claude sees exactly what you see: all your chats, groups, channels, contacts, and message history.

---

## Privacy & security

- **MTProto encryption.** All traffic between your computer and Telegram's servers is encrypted using MTProto — Telegram's own protocol. From Telegram's perspective, this is just another device you're logged into.
- **100% local.** Your `api_id`, `api_hash`, and session file live only on your computer at `~/.mcp-telegram/` with `600` permissions (owner read/write only). Nothing is sent to Anthropic, npm, or any third party — only to Telegram's own servers.
- **Claude runs it locally.** When Claude Code uses this server, it spawns `npx mcp-telegram-local serve` as a local process on your machine. The MCP communication happens over stdio — no network port is opened, no data leaves your computer.
- **Session = login.** The saved session is equivalent to a logged-in Telegram session. Keep `~/.mcp-telegram/session.json` private. To revoke it, run `npx mcp-telegram-local logout` — this signs the session out on Telegram's side and deletes the local file.

---

## Requirements

- **Node.js 18 or later**
- **Telegram account**
- **`api_id` and `api_hash`** from [my.telegram.org](https://my.telegram.org) — free, takes 2 minutes (see below)

---

## Quick start

### Option A — Web panel (recommended)

```bash
npx mcp-telegram-local ui
```

This opens a local web page at `http://127.0.0.1:8765` (only accessible from your computer). From there you can:

1. Enter your `api_id` and `api_hash`
2. Log in via **QR code** (scan with your phone) or **phone number** (code sent via SMS or Telegram)
3. Handle **2FA password** if you have one enabled (wrong password can be re-entered, up to 3 attempts)
4. Click **"Add to Claude Code"** to register the server automatically
5. See example prompts you can use with Claude right away

After adding to Claude Code, restart Claude Code and type `/mcp` — you should see `telegram` listed as a connected server.

### Option B — Terminal login

```bash
npx mcp-telegram-local auth
```

Walks you through login interactively in the terminal (phone number or QR code printed as ASCII art), then automatically registers the server in Claude Code.

---

## Getting api_id and api_hash

You need these once. They identify your app to Telegram and are stored locally.

1. Open **https://my.telegram.org** and log in with your phone number
2. Click **"API development tools"**
3. Fill in any app name and short name (e.g. `MyApp` / `myapp`) — the values don't matter
4. Copy the **`api_id`** (a number) and **`api_hash`** (a long hex string)

Paste them into the web panel or terminal when prompted. They're saved to `~/.mcp-telegram/config.json` and never needed again.

---

## All commands

```bash
npx mcp-telegram-local              # Show this command list
npx mcp-telegram-local ui           # ⭐ Open the web control panel
npx mcp-telegram-local auth         # Log in via terminal + auto-add to Claude Code
npx mcp-telegram-local status       # Check if your session is valid
npx mcp-telegram-local add_mcp      # Register server in Claude Code (no re-login)
npx mcp-telegram-local logout       # Sign out of Telegram + delete local session
npx mcp-telegram-local delete_key   # Delete api_id/api_hash + sign out (full reset)
npx mcp-telegram-local config       # Print the Claude Code config JSON snippet
npx mcp-telegram-local serve        # Force MCP server mode on stdio (used by Claude)
npx mcp-telegram-local help         # Show help
```

---

## How Claude Code uses this server

Once registered, Claude Code automatically starts `npx mcp-telegram-local serve` as a background process whenever it needs Telegram access. The server communicates over **stdio** (standard input/output) using the MCP protocol — no web server, no open ports, no background daemon to manage. It starts on demand and exits when Claude is done.

The config Claude Code stores looks like this:

```json
{
  "mcpServers": {
    "telegram": {
      "command": "npx",
      "args": ["mcp-telegram-local", "serve"]
    }
  }
}
```

You can also add it manually by running:

```bash
claude mcp add --scope user telegram -- npx mcp-telegram-local serve
```

---

## MCP tools available to Claude

| Tool | Parameters | What it does |
|---|---|---|
| `get_dialogs` | `limit`, `offset` | List your chats and channels |
| `get_messages` | `chat_id`, `limit` | Fetch message history from a chat |
| `search_messages` | `query`, `chat_id?`, `limit` | Search messages globally or in a specific chat |
| `get_unread` | `max_chats`, `max_messages_per_chat` | Fetch all unread messages across chats |
| `send_message` | `chat_id`, `text` | Send a text message |
| `reply_to_message` | `chat_id`, `message_id`, `text` | Reply to a specific message |
| `forward_message` | `from_chat`, `to_chat`, `message_id` | Forward a message between chats |
| `download_file` | `chat_id`, `message_id`, `include_base64?` | Download a file or photo from a message |
| `send_file` | `chat_id`, `file_path`, `caption?` | Send a file from your computer |
| `get_contacts` | — | List your Telegram contacts |
| `get_chat_members` | `chat_id`, `limit` | List members of a group or channel |

> `chat_id` accepts a numeric ID, `@username`, or a `t.me/...` link.

## MCP resources available to Claude

| URI | Description |
|---|---|
| `telegram://dialogs` | All your dialogs/chats |
| `telegram://chat/{id}` | A specific chat with recent messages |
| `telegram://unread` | All unread messages |
| `telegram://me` | Your Telegram profile |

---

## What you can ask Claude

Once connected, just describe what you want in plain English:

- *"Summarize the last 50 messages from my chat with Alex"*
- *"Reply to Maria that I'll be there at 7pm"*
- *"Show me all unread messages and tell me which ones are urgent"*
- *"Search my chats for any messages about the contract"*
- *"Forward the last message from @news_channel to my Saved Messages"*
- *"Send the file report.pdf to the Work group"*
- *"Write a digest of @somechannel posts from the last week"*
- *"Who messaged me today?"*

---

## Local data storage

All data is stored locally with restrictive file permissions:

```
~/.mcp-telegram/
├── config.json     # api_id and api_hash
├── session.json    # gramjs session string (equivalent to a Telegram login)
└── downloads/      # files downloaded via the download_file tool
```

To fully reset everything:
```bash
npx mcp-telegram-local delete_key
```

This revokes the session on Telegram's servers, deletes `session.json`, and deletes `config.json`. You'll start fresh next time.

To only sign out (keep api credentials):
```bash
npx mcp-telegram-local logout
```

After logout, go to **Telegram → Settings → Devices** if you want to confirm the session was removed there too.

---

## Error handling

- **Expired session.** If your session expires (e.g. you signed out from another device), tools return a friendly error with instructions to run `npx mcp-telegram-local auth` again.
- **FLOOD_WAIT.** Telegram rate-limits heavy requests. Short waits are handled automatically by gramjs; longer waits (up to 5 minutes) are retried automatically by a built-in wrapper.
- **Wrong 2FA password.** The web panel lets you re-enter your 2FA password up to 3 times before giving up. The terminal login does the same.

---

## Development

```bash
git clone https://github.com/pokkop/mcp-telegram-local
cd mcp-telegram-local
npm install
npm run build        # compile TypeScript → dist/
npm run dev          # watch mode
node dist/index.js status
```

Source layout:

```
src/
├── index.ts             # entry point: CLI commands + MCP server on stdio
├── auth.ts              # terminal login (phone + QR), MTProto/privacy banner
├── web.ts               # local web panel HTTP server + gramjs login bridge
├── web-page.ts          # full SPA (HTML/CSS/JS) served by web.ts
├── client.ts            # TelegramClient wrapper, JSON serializers, logout
├── tools.ts             # all 11 MCP tools
├── resources.ts         # all 4 MCP resources
├── storage.ts           # ~/.mcp-telegram/ read/write helpers
├── claude.ts            # auto-registration with Claude Code
├── notice.ts            # English MTProto/privacy notices for terminal output
└── suppress-warnings.ts # suppresses gramjs's Node.js localStorage warning
```

TypeScript compiles to ESM (`"type": "module"`) targeting Node 18+. gramjs logging is fully silenced (`LogLevel.NONE`) to prevent any stray output from corrupting the MCP stdio stream.

---

## License

MIT