186 lines
7.0 KiB
Markdown
186 lines
7.0 KiB
Markdown
# Telegram MCP — setup on a new machine
|
||
|
||
Reproduces the working integration this project uses: two Telegram accounts wired up as separate MCP servers via `chigwell/telegram-mcp` (MTProto, not bots), registered in Claude Code + Claude Desktop.
|
||
|
||
| Account | MCP server name | Tool prefix | Role |
|
||
|---|---|---|---|
|
||
| **usulsu** (main) | `telegram-usulpro` | `mcp__telegram-usulpro__*` | Job channels, recruiter outreach |
|
||
| **samuishechka** (helper) | `telegram-helper` | `mcp__telegram-helper__*` | Notifications to Oleg + Ekaterina, workflow triggers |
|
||
|
||
Time: ~15 minutes. Most of it is one-time Telegram credentials and two session strings.
|
||
|
||
---
|
||
|
||
## 0. Prereqs
|
||
|
||
- `git`, `curl`, `jq`, `node` (for `npx`)
|
||
- A clone of this repo (`cv-2026`) — it holds the `.env` shape and the CLAUDE.md safety policy that govern this integration.
|
||
|
||
---
|
||
|
||
## 1. Get Telegram API credentials (one-time — shared across both accounts)
|
||
|
||
The `api_id` / `api_hash` identify the *app*, not the account. One app serves both sessions.
|
||
|
||
Open https://my.telegram.org/apps and create a new application:
|
||
|
||
- **App title:** anything (e.g. `telegram-mcp`)
|
||
- **Short name:** 5–32 alphanumeric, e.g. `tgmcp`
|
||
- **URL:** *must not be empty* — put `https://t.me` (form says optional but errors otherwise)
|
||
- **Platform:** Desktop
|
||
- **Description:** optional
|
||
|
||
You'll get `api_id` (number) and `api_hash` (32-char hex). Treat them like a password.
|
||
|
||
If you see a generic `ERROR` popup, fill in the URL field — that's the most common cause.
|
||
|
||
Save both into the project `.env` (session strings filled in after step 3):
|
||
|
||
```
|
||
TELEGRAM_API_ID=<id>
|
||
TELEGRAM_API_HASH=<hash>
|
||
TELEGRAM_SESSION_STRING= # usulsu — main account (job channels + outreach)
|
||
TELEGRAM_SESSION_STRING_HELPER= # samuishechka — notifications + workflow triggers
|
||
```
|
||
|
||
Confirm `.env` is in `.gitignore`.
|
||
|
||
---
|
||
|
||
## 2. Install the server (Python, isolated via `uv`)
|
||
|
||
The server is `chigwell/telegram-mcp` — a Telethon-based MCP server. Python lives inside its own `uv`-managed venv, nothing leaks into the project.
|
||
|
||
```bash
|
||
# install uv if missing (goes into ~/.local/bin, no sudo)
|
||
curl -LsSf https://astral.sh/uv/install.sh | sh
|
||
|
||
# clone + sync (creates .venv with locked deps)
|
||
mkdir -p /projects/my-utils && cd /projects/my-utils
|
||
git clone https://github.com/chigwell/telegram-mcp.git telegram
|
||
cd telegram
|
||
~/.local/bin/uv sync
|
||
```
|
||
|
||
Two binaries appear at `/projects/my-utils/telegram/.venv/bin/`:
|
||
- `telegram-mcp` — the MCP server
|
||
- `telegram-mcp-generate-session` — one-shot session-string generator
|
||
|
||
---
|
||
|
||
## 3. Generate session strings (one per account, interactive)
|
||
|
||
Run the generator twice — once per account. From the cv-2026 project root:
|
||
|
||
```bash
|
||
set -a && source .env && set +a && \
|
||
/projects/my-utils/telegram/.venv/bin/telegram-mcp-generate-session
|
||
```
|
||
|
||
### 3a. usulsu — main account
|
||
|
||
At the prompts:
|
||
|
||
- **Account label:** *leave empty* (Enter) — output var will be `TELEGRAM_SESSION_STRING`
|
||
- **Login method:** `1` (QR) is the fastest — scan from any device where Telegram is already open (Settings → Devices → Link Desktop Device).
|
||
- Alternative: `2` (phone). The code arrives **inside Telegram** as a message from the official `Telegram` account, not via SMS — check there first.
|
||
|
||
Paste the output into `.env` as `TELEGRAM_SESSION_STRING=<value>`.
|
||
|
||
### 3b. samuishechka — helper account
|
||
|
||
Run the same command again, this time logged in as (or switching to) the samuishechka account:
|
||
|
||
- **Account label:** `helper` — output var will be `TELEGRAM_SESSION_STRING_HELPER`
|
||
- **Login method:** same options; use whichever device has samuishechka logged in.
|
||
|
||
Paste the output into `.env` as `TELEGRAM_SESSION_STRING_HELPER=<value>`.
|
||
|
||
Alternatively, use the `--phone` flag to avoid the interactive menu:
|
||
|
||
```bash
|
||
TELEGRAM_API_ID=<id> TELEGRAM_API_HASH=<hash> \
|
||
/projects/my-utils/telegram/.venv/bin/python \
|
||
/projects/my-utils/telegram/session_string_generator.py --phone
|
||
```
|
||
|
||
---
|
||
|
||
## 4. Register both servers in Claude Desktop config
|
||
|
||
Edit `~/.config/Claude/claude_desktop_config.json` (macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`) and add two entries under `mcpServers`:
|
||
|
||
```json
|
||
"telegram-usulpro": {
|
||
"command": "/projects/my-utils/telegram/.venv/bin/telegram-mcp",
|
||
"args": [],
|
||
"env": {
|
||
"TELEGRAM_API_ID": "<id>",
|
||
"TELEGRAM_API_HASH": "<hash>",
|
||
"TELEGRAM_SESSION_STRING": "<usulsu session string>"
|
||
}
|
||
},
|
||
"telegram-helper": {
|
||
"command": "/projects/my-utils/telegram/.venv/bin/telegram-mcp",
|
||
"args": [],
|
||
"env": {
|
||
"TELEGRAM_API_ID": "<id>",
|
||
"TELEGRAM_API_HASH": "<hash>",
|
||
"TELEGRAM_SESSION_STRING": "<samuishechka session string>"
|
||
}
|
||
}
|
||
```
|
||
|
||
Or use `jq` to inject from `.env` in one shot (run from project root):
|
||
|
||
```bash
|
||
set -a && source .env && set +a && \
|
||
CFG=~/.config/Claude/claude_desktop_config.json && \
|
||
jq --arg id "$TELEGRAM_API_ID" --arg hash "$TELEGRAM_API_HASH" \
|
||
--arg sess "$TELEGRAM_SESSION_STRING" \
|
||
--arg sess_h "$TELEGRAM_SESSION_STRING_HELPER" '
|
||
.mcpServers["telegram-usulpro"] = {
|
||
"command": "/projects/my-utils/telegram/.venv/bin/telegram-mcp",
|
||
"args": [], "env": {
|
||
"TELEGRAM_API_ID": $id, "TELEGRAM_API_HASH": $hash,
|
||
"TELEGRAM_SESSION_STRING": $sess }} |
|
||
.mcpServers["telegram-helper"] = {
|
||
"command": "/projects/my-utils/telegram/.venv/bin/telegram-mcp",
|
||
"args": [], "env": {
|
||
"TELEGRAM_API_ID": $id, "TELEGRAM_API_HASH": $hash,
|
||
"TELEGRAM_SESSION_STRING": $sess_h }}' \
|
||
"$CFG" > "$CFG.tmp" && mv "$CFG.tmp" "$CFG"
|
||
```
|
||
|
||
---
|
||
|
||
## 5. Restart and verify
|
||
|
||
- **Claude Desktop:** quit and reopen.
|
||
- **Claude Code:** start a new session (this CLI loads MCP servers at session start).
|
||
|
||
In the new session, ask: *"проверь доступ к обоим телеграм аккаунтам"*. The agent should call both `mcp__telegram-usulpro__get_me` (→ @UsulPro) and `mcp__telegram-helper__get_me` (→ @samuishka) and return the respective handles.
|
||
|
||
If tools never appear, smoke-test each server manually:
|
||
|
||
```bash
|
||
# usulsu
|
||
set -a && source .env && set +a && /projects/my-utils/telegram/.venv/bin/telegram-mcp
|
||
|
||
# samuishechka
|
||
TELEGRAM_SESSION_STRING="$TELEGRAM_SESSION_STRING_HELPER" \
|
||
/projects/my-utils/telegram/.venv/bin/telegram-mcp
|
||
# Ctrl+C after startup logs — it's a stdio MCP server
|
||
```
|
||
|
||
---
|
||
|
||
## 6. Safety policy (already in CLAUDE.md, do not skip)
|
||
|
||
The server is **write-capable** — it can send/edit/delete messages on Oleg's behalf. Safety is enforced by `CLAUDE.md` (section *"Telegram MCP — safety policy"*), not by tool exposure, because read-only mode was too limiting. Two absolute rules:
|
||
|
||
1. **Never** destructive/irreversible actions, even on explicit request (delete messages/chats/folders, terminate sessions, change profile, bulk operations).
|
||
2. **Writes** (send/edit messages, join/leave, add to folder, etc.) need per-conversation permission for the specific target chat — except for chats listed in [`.claude/telegram-write-whitelist.md`](../.claude/telegram-write-whitelist.md) (currently empty).
|
||
|
||
Both files (`CLAUDE.md` section and the whitelist) live in this repo — cloning cv-2026 brings them with you.
|