feat: init commit
This commit is contained in:
parent
544c0b6477
commit
1f7474aa5c
5 changed files with 248 additions and 1 deletions
3
.env.example
Normal file
3
.env.example
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
TELEGRAM_SESSION_NAME=anon
|
||||
TELEGRAM_API_ID=12345678
|
||||
TELEGRAM_API_HASH=12345678123456781234567812345678
|
||||
1
.python-version
Normal file
1
.python-version
Normal file
|
|
@ -0,0 +1 @@
|
|||
3.13
|
||||
132
README.md
132
README.md
|
|
@ -1 +1,131 @@
|
|||
# telegram-mcp
|
||||

|
||||
[](https://opensource.org/licenses/Apache-2.0)
|
||||
[](https://www.linkedin.com/in/eugene-evstafev-716669181/)
|
||||
|
||||
# Telegram MCP Server
|
||||
|
||||
A Telegram MCP (Model Context Protocol) server built using Python, Telethon, and MCP Python SDK. This MCP server provides simple tools for interacting with Telegram chats directly through MCP-compatible hosts, such as Claude for Desktop.
|
||||
|
||||
## Tools Provided
|
||||
|
||||
- **`get_chats`**: Retrieve a paginated list of your Telegram chats.
|
||||
- **`get_messages`**: Retrieve paginated messages from a specific chat.
|
||||
- **`send_message`**: Send a message to a specific chat.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Python 3.10 or higher
|
||||
- [Telethon](https://docs.telethon.dev/) package
|
||||
- [MCP Python SDK](https://modelcontextprotocol.io/docs/)
|
||||
- [UV](https://astral.sh/uv/) (optional but recommended)
|
||||
|
||||
## Installation and Setup
|
||||
|
||||
### Clone the Repository
|
||||
|
||||
```bash
|
||||
git clone https://github.com/chigwell/telegram-mcp
|
||||
cd telegram-mcp
|
||||
```
|
||||
|
||||
### Create Environment File
|
||||
|
||||
Copy and rename `.env.example` to `.env` and fill it with your Telegram credentials obtained from [https://my.telegram.org/apps](https://my.telegram.org/apps):
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
Your `.env` file should look like:
|
||||
|
||||
```env
|
||||
TELEGRAM_API_ID=your_api_id_here
|
||||
TELEGRAM_API_HASH=your_api_hash_here
|
||||
TELEGRAM_SESSION_NAME=your_session_name
|
||||
```
|
||||
|
||||
### Setup Python Environment
|
||||
|
||||
Use `uv` to set up the Python environment and install dependencies:
|
||||
|
||||
```bash
|
||||
uv venv
|
||||
source .venv/bin/activate
|
||||
uv add "mcp[cli]" telethon python-dotenv nest_asyncio
|
||||
```
|
||||
|
||||
### Run the Server (First-time Auth)
|
||||
|
||||
The first time you run the server, Telethon will prompt you to enter a Telegram authentication code:
|
||||
|
||||
```bash
|
||||
uv run main.py
|
||||
```
|
||||
|
||||
Authenticate by entering the code sent to your Telegram client. This step is only required once.
|
||||
|
||||
## Integrating with Claude for Desktop
|
||||
|
||||
### macOS/Linux
|
||||
|
||||
Edit your Claude Desktop configuration:
|
||||
|
||||
```bash
|
||||
nano ~/Library/Application\ Support/Claude/claude_desktop_config.json
|
||||
```
|
||||
|
||||
Add this MCP server configuration:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"telegram-mcp": {
|
||||
"command": "uv",
|
||||
"args": [
|
||||
"--directory",
|
||||
"/ABSOLUTE_PATH/telegram-mcp",
|
||||
"run",
|
||||
"main.py"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Ensure you replace `/ABSOLUTE_PATH/telegram-mcp` with your project's absolute path.
|
||||
|
||||
### Windows
|
||||
|
||||
Edit your Claude Desktop configuration:
|
||||
|
||||
```powershell
|
||||
nano $env:AppData\Claude\claude_desktop_config.json
|
||||
```
|
||||
|
||||
Add this MCP server configuration:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"telegram-mcp": {
|
||||
"command": "uv",
|
||||
"args": [
|
||||
"--directory",
|
||||
"C:\\ABSOLUTE_PATH\\telegram-mcp",
|
||||
"run",
|
||||
"main.py"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Ensure you replace `C:\ABSOLUTE_PATH\telegram-mcp` with your project's absolute path.
|
||||
|
||||
## Usage
|
||||
|
||||
Once integrated, your Telegram tools (`get_chats`, `get_messages`, and `send_message`) will become available within the Claude for Desktop UI or any other MCP-compatible client.
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the [Apache 2.0 License](https://opensource.org/licenses/Apache-2.0).
|
||||
100
main.py
Normal file
100
main.py
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
import os
|
||||
from dotenv import load_dotenv
|
||||
import asyncio
|
||||
import nest_asyncio
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
from telethon import TelegramClient
|
||||
|
||||
load_dotenv()
|
||||
|
||||
TELEGRAM_API_ID = int(os.getenv("TELEGRAM_API_ID"))
|
||||
TELEGRAM_API_HASH = os.getenv("TELEGRAM_API_HASH")
|
||||
TELEGRAM_SESSION_NAME = os.getenv("TELEGRAM_SESSION_NAME")
|
||||
|
||||
|
||||
mcp = FastMCP("telegram")
|
||||
client = TelegramClient(TELEGRAM_SESSION_NAME, TELEGRAM_API_ID, TELEGRAM_API_HASH)
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
async def get_chats(page: int, page_size: int = 20) -> str:
|
||||
"""
|
||||
Get a paginated list of chats.
|
||||
|
||||
Args:
|
||||
page: Page number (1-indexed).
|
||||
page_size: Number of chats per page.
|
||||
"""
|
||||
dialogs = await client.get_dialogs()
|
||||
start = (page - 1) * page_size
|
||||
end = start + page_size
|
||||
if start >= len(dialogs):
|
||||
return "Page out of range."
|
||||
chats = dialogs[start:end]
|
||||
lines = []
|
||||
for dialog in chats:
|
||||
# For groups or channels, use the title; for users, show first name.
|
||||
entity = dialog.entity
|
||||
chat_id = entity.id
|
||||
title = getattr(entity, "title", None) or getattr(entity, "first_name", "Unknown")
|
||||
lines.append(f"Chat ID: {chat_id}, Title: {title}")
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
async def get_messages(chat_id: int, page: int, page_size: int = 20) -> str:
|
||||
"""
|
||||
Get paginated messages from a specific chat.
|
||||
|
||||
Args:
|
||||
chat_id: The ID of the chat.
|
||||
page: Page number (1-indexed).
|
||||
page_size: Number of messages per page.
|
||||
"""
|
||||
try:
|
||||
entity = await client.get_entity(chat_id)
|
||||
except Exception as e:
|
||||
return f"Could not resolve chat with ID {chat_id}: {e}"
|
||||
|
||||
offset = (page - 1) * page_size
|
||||
messages = await client.get_messages(entity, limit=page_size, add_offset=offset)
|
||||
if not messages:
|
||||
return "No messages found for this page."
|
||||
lines = []
|
||||
for msg in messages:
|
||||
lines.append(f"ID: {msg.id} | Date: {msg.date} | Message: {msg.message}")
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
async def send_message(chat_id: int, message: str) -> str:
|
||||
"""
|
||||
Send a message to a specific chat.
|
||||
|
||||
Args:
|
||||
chat_id: The ID of the chat.
|
||||
message: The message content to send.
|
||||
"""
|
||||
try:
|
||||
entity = await client.get_entity(chat_id)
|
||||
except Exception as e:
|
||||
return f"Could not resolve chat with ID {chat_id}: {e}"
|
||||
|
||||
try:
|
||||
await client.send_message(entity, message)
|
||||
return "Message sent successfully."
|
||||
except Exception as e:
|
||||
return f"Failed to send message: {e}"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
nest_asyncio.apply()
|
||||
|
||||
async def main() -> None:
|
||||
# Start the Telethon client.
|
||||
await client.start()
|
||||
print("Telegram client started. Running MCP server...")
|
||||
# Use the asynchronous entrypoint instead of mcp.run()
|
||||
await mcp.run_stdio_async()
|
||||
|
||||
asyncio.run(main())
|
||||
13
pyproject.toml
Normal file
13
pyproject.toml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
[project]
|
||||
name = "telegram-mcp"
|
||||
version = "2025.3.201549"
|
||||
description = "A Telegram MCP (Model Context Protocol) server built using Python, Telethon, and MCP Python SDK. This MCP server provides simple tools for interacting with Telegram chats directly through MCP-compatible hosts, such as Claude for Desktop."
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.13"
|
||||
dependencies = [
|
||||
"dotenv>=0.9.9",
|
||||
"httpx>=0.28.1",
|
||||
"mcp[cli]>=1.4.1",
|
||||
"nest-asyncio>=1.6.0",
|
||||
"telethon>=1.39.0",
|
||||
]
|
||||
Loading…
Reference in a new issue