telegram-search-mcp
# ๐ telegram-search-mcp
[](https://modelcontextprotocol.io)
[](https://github.com/KolyaMetallist/telegram-search-mcp/releases)
[](https://www.python.org/)
[](https://github.com/KolyaMetallist/telegram-search-mcp/actions)
[](LICENSE)
[](https://pypi.org/project/telethon/)
[](https://pypi.org/project/mcp/)
[](https://pypi.org/project/pytest/)
[](https://github.com/astral-sh/uv)
[](https://github.com/KolyaMetallist/telegram-search-mcp/commits/main)
[](https://github.com/KolyaMetallist/telegram-search-mcp)
An **MCP server** that gives Claude (or any MCP-compatible client) the ability to search Telegram messages and read documents attached to those messages โ using your **personal Telegram account** via [Telethon](https://github.com/LonamiWebs/Telethon).
> [!NOTE]
> This server uses the Telegram **user API** (MTProto), not the Bot API. It reads your account's chats just like the official Telegram client does.
---
## โจ Features
| Tool | Description |
|---|---|
| `search_messages` | Keyword search inside any chat or channel |
| `get_messages` | Fetch recent messages from a chat |
| `search_dialogs` | Find chats, channels, groups by name |
| `get_message_document` | Download and extract text from attached files (PDF, TXT, MD, CSV) |
All message results include a `has_document` field โ so Claude knows when to call `get_message_document` automatically.
---
## ๐ Requirements
- Python 3.10+
- Telegram API credentials from [my.telegram.org/apps](https://my.telegram.org/apps)
> [!IMPORTANT]
> You need to create an application on [my.telegram.org/apps](https://my.telegram.org/apps) to get your `api_id` and `api_hash`. This is free and takes ~1 minute.
---
## ๐ Installation
```bash
git clone https://github.com/KolyaMetallist/telegram-search-mcp.git
cd telegram-search-mcp
./install.sh
```
The script auto-detects **uv** and falls back to pip/venv. It creates `.venv`, installs all dependencies including `pdfplumber`, and prints the exact next steps.
### โก With uv (recommended)
> [!TIP]
> [uv](https://docs.astral.sh/uv/) installs packages 10-100ร faster than pip. One-time install: `curl -LsSf https://astral.sh/uv/install.sh | sh`
```bash
uv venv .venv
source .venv/bin/activate
uv pip install -e ".[pdf]"
```
Or run without activating the venv at all:
```bash
uv run --extra pdf python main.py --login
uv run --extra pdf python main.py
```
### ๐ With pip
```bash
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[pdf]"
```
---
## โ๏ธ Configuration
Set environment variables before running. Add them to `~/.zshrc` or `~/.bashrc` so you don't have to repeat this:
| Variable | Required | Description |
|---|---|---|
| `TELEGRAM_API_ID` | โ
| Integer API ID from my.telegram.org |
| `TELEGRAM_API_HASH` | โ
| API Hash from my.telegram.org |
| `TELEGRAM_SESSION_PATH` | โ | Custom session file path (default: `~/.local/state/telegram-search-mcp/session`) |
```bash
# Add to ~/.zshrc or ~/.bashrc
export TELEGRAM_API_ID=12345678
export TELEGRAM_API_HASH=abcdef1234567890abcdef1234567890
```
> [!WARNING]
> Never commit your `api_id` or `api_hash` to version control. The `.gitignore` already excludes `.env` files.
---
## ๐ First Login
Run **once** to authenticate your account:
```bash
source .venv/bin/activate
python main.py --login
```
Telethon will prompt for your phone number, the SMS code, and your 2FA password if enabled. The session is saved locally at `~/.local/state/telegram-search-mcp/session.session` โ you won't need to log in again.
> [!CAUTION]
> The session file grants full access to your Telegram account. Keep it secure and never share it. It is excluded from git via `.gitignore`.
---
## โถ๏ธ Running the Server
**stdio** โ for Claude Desktop, Claude Code, Codemie command mode:
```bash
python main.py
# or
python -m telegram_search_mcp
```
**SSE** โ HTTP server for Codemie URL mode or any web client:
```bash
python main.py --sse # port 8000
python main.py --sse --port 9000 # custom port
```
Stop with **Ctrl+C** โ the server shuts down cleanly (SIGINT and SIGTERM both handled).
---
## ๐ MCP Client Configuration
### Claude Desktop
Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
```json
{
"mcpServers": {
"telegram-search": {
"command": "/path/to/telegram-search-mcp/.venv/bin/python",
"args": ["/path/to/telegram-search-mcp/main.py"],
"env": {
"TELEGRAM_API_ID": "your_api_id",
"TELEGRAM_API_HASH": "your_api_hash"
}
}
}
}
```
### Codemie โ command mode
```json
{
"command": "/path/to/.venv/bin/python",
"args": ["/path/to/telegram-search-mcp/main.py"]
}
```
Add `TELEGRAM_API_ID` and `TELEGRAM_API_HASH` via the "Add Environment Variables" section.
### Codemie โ SSE / URL mode
Start the server first, then set MCP-Connect URL to `http://localhost:8000/sse`.
```bash
python main.py --sse --port 8000
```
---
## ๐ฌ Usage Examples
Once connected, ask Claude:
> *"Find messages about Python in @some_channel"*
> *"Search dialogs for 'Bulgaria Ukraine'"*
> *"Get the document attached to message 432583 in @Autochat_Bulgaria_Ukraine and summarize it"*
> *"Show me the last 20 messages in @my_group and extract any PDFs"*
---
## ๐๏ธ Architecture
The project follows **SOLID**, **DRY**, **KISS**, and **YAGNI** principles with these GoF patterns:
| Pattern | Where |
|---|---|
| Factory Method | `ClientFactory.create()`, `ExtractorRegistry.default()` |
| Strategy | `DocumentExtractor` ABC โ `PDFExtractor`, `PlainTextExtractor` |
| Registry | `ExtractorRegistry.find(mime, filename)` |
| Template Method | `ToolSet.register(mcp)` โ each subclass adds its own tools |
| Facade | MCP tools hide Telethon complexity behind simple dicts |
### ๐ Package layout
```
src/telegram_search_mcp/
config.py Config dataclass (from env)
client.py ClientFactory
auth.py AuthManager โ login without mcp-telegram
server.py build_server() โ wires all ToolSets
cli.py main() entry point
extractors/ DocumentExtractor ABC, PDFExtractor, PlainTextExtractor, ExtractorRegistry
tools/ ToolSet ABC, DialogTools, MessageTools, DocumentTools
```
### โ Adding a new extractor
Create `src/telegram_search_mcp/extractors/<name>.py` extending `DocumentExtractor`, register in `ExtractorRegistry.default()`. No other files change.
```python
class DocxExtractor(DocumentExtractor):
@property
def supported_mimes(self): return ("application/vnd.openxmlformats-officedocument.wordprocessingml.document",)
@property
def supported_extensions(self): return (".docx",)
async def extract(self, data, filename): ...
```
### โ Adding a new tool set
Create `src/telegram_search_mcp/tools/<name>.py` extending `ToolSet`, implement `register(mcp)`, add to list in `server.py`.
---
## ๐งช Tests
```bash
source .venv/bin/activate
python -m pytest tests/ -v
```
52 unit tests, zero network calls โ all Telegram interactions are mocked.
---
## ๐ค Contributing
Contributions are welcome! Here's how to get started:
1. **Fork** the repository and clone your fork
2. **Create a branch** for your change: `git checkout -b feat/my-feature`
3. **Install dev dependencies:**
```bash
uv pip install -e ".[pdf,dev]"
```
4. **Make your changes** โ add or update tests when behavior changes
5. **Run the test suite** before opening a PR:
```bash
python -m pytest tests/ -v
```
6. **Open a pull request** with a concise description of what changed and why
> [!NOTE]
> For new file-type extractors or tool sets, see the [Architecture](#๏ธ-architecture) section โ the design is intentionally extension-friendly.
Please keep PRs focused: one feature or fix per PR. If you're unsure whether something is in scope, open an issue first.
---
## ๐ License
This project is licensed under the **Apache License 2.0** โ see the [LICENSE](LICENSE) file for details.
Apache 2.0 was chosen over MIT because it includes an explicit **patent grant**, which is better for an open-source tool used in corporate environments.
TDQS
Scored across 4 tools
Each tool targets a distinct resource/action: dialog lookup, message listing, message search, and document extraction. get_messages and search_messages overlap only superficially because one returns recent unfiltered messages and the other returns keyword-filtered results.
All tools use lower_snake_case and follow a consistent verb_noun pattern such as search_dialogs, get_messages, search_messages, and get_message_document. The verbs match the operations clearly, and the nouns identify the resource being acted on.
Four tools is a tight, well-scoped set for a read-only Telegram search/retrieval server. Each tool earns its place in the workflow of finding a dialog, reading or searching messages, and extracting document text.
The read-oriented workflow is well covered: discover dialogs, list recent messages, search messages by keyword, and extract document text. Minor gaps such as global message search and pagination/offset support mean some advanced retrieval tasks may require workarounds.