cv-2026/docs/telegram-integration.md

136 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Telegram MCP — setup on a new machine
Reproduces the working integration this project uses: read Oleg's Telegram channels/DMs as a user (MTProto, not a bot) through the `chigwell/telegram-mcp` server, registered in Claude Code + Claude Desktop.
Time: ~10 minutes. Most of it is one-time Telegram credentials.
---
## 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 per Telegram account)
Open https://my.telegram.org/apps and create a new application:
- **App title:** anything (e.g. `telegram-mcp`)
- **Short name:** 532 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`:
```
TELEGRAM_API_ID=<id>
TELEGRAM_API_HASH=<hash>
TELEGRAM_SESSION_STRING=
```
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 the session string (one-time, interactive)
From the cv-2026 project root (where `.env` lives):
```bash
set -a && source .env && set +a && \
/projects/my-utils/telegram/.venv/bin/telegram-mcp-generate-session
```
At the prompts:
- **Account label:** *leave empty* (Enter). A label adds a `_<LABEL>` suffix to env var names and we don't need multi-account.
- **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.
Output ends with a ~350-char string. Paste it into `.env` as `TELEGRAM_SESSION_STRING=<value>`.
---
## 4. Register in Claude Code + Claude Desktop
[`add-mcp`](https://www.npmjs.com/package/add-mcp) writes the server entry into both client configs in one shot. **Important gotcha:** with `--yes`, `add-mcp` stores `${VAR}` placeholders literally instead of resolving them — Claude Desktop won't expand env vars at runtime, so we resolve them manually with `jq` right after.
```bash
# from the cv-2026 project root
set -a && source .env && set +a && \
npx -y add-mcp "/projects/my-utils/telegram/.venv/bin/telegram-mcp" \
-n telegram \
--env 'TELEGRAM_API_ID=${TELEGRAM_API_ID}' \
--env 'TELEGRAM_API_HASH=${TELEGRAM_API_HASH}' \
--env 'TELEGRAM_SESSION_STRING=${TELEGRAM_SESSION_STRING}' \
-a claude-code -a claude-desktop \
-g -y
# fix the literal-placeholder issue — substitute actual values into both configs
set -a && source .env && set +a && \
for CFG in ~/.config/Claude/claude_desktop_config.json ~/.claude.json; do
jq --arg id "$TELEGRAM_API_ID" --arg hash "$TELEGRAM_API_HASH" --arg sess "$TELEGRAM_SESSION_STRING" \
'.mcpServers.telegram.env.TELEGRAM_API_ID = $id
| .mcpServers.telegram.env.TELEGRAM_API_HASH = $hash
| .mcpServers.telegram.env.TELEGRAM_SESSION_STRING = $sess' \
"$CFG" > "$CFG.tmp" && mv "$CFG.tmp" "$CFG"
done
```
macOS Claude Desktop config path is `~/Library/Application Support/Claude/claude_desktop_config.json` — adjust the loop.
---
## 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 `mcp__telegram__get_me` and return your handle.
If tools never appear, check the server starts cleanly:
```bash
set -a && source .env && set +a && /projects/my-utils/telegram/.venv/bin/telegram-mcp
# Ctrl+C after it prints startup logs — it's an stdio MCP server, this just smoke-tests it
```
---
## 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.