Content
<h1 align="center">Claudegram</h1>
<p align="center">
<em>Личный Telegram-аккаунт как полноценный инструмент Claude Code — через MTProto, не Bot API.</em>
</p>
<p align="center">
<a href="https://github.com/sanjar-x/claudegram/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/sanjar-x/claudegram/actions/workflows/ci.yml/badge.svg"></a>
<a href="https://github.com/sanjar-x/claudegram/actions/workflows/codeql.yml"><img alt="CodeQL" src="https://github.com/sanjar-x/claudegram/actions/workflows/codeql.yml/badge.svg"></a>
<a href="https://github.com/sanjar-x/claudegram/blob/main/LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-blue.svg"></a>
<a href="https://www.python.org/downloads/release/python-3140/"><img alt="Python 3.14+" src="https://img.shields.io/badge/python-3.14%2B-blue.svg"></a>
<a href="https://github.com/astral-sh/ruff"><img alt="Code style: ruff" src="https://img.shields.io/badge/code%20style-ruff-261230.svg"></a>
<a href="https://github.com/astral-sh/uv"><img alt="uv" src="https://img.shields.io/badge/managed%20by-uv-261230.svg"></a>
<a href="https://modelcontextprotocol.io"><img alt="MCP" src="https://img.shields.io/badge/MCP-1.27%2B-8A2BE2.svg"></a>
<a href="https://code.claude.com/docs/en/plugins-reference"><img alt="Claude Code Plugin" src="https://img.shields.io/badge/Claude%20Code-Plugin-D97757.svg"></a>
</p>
<p align="center">
<strong>120 MCP-tools</strong> · <strong>9 resources</strong> · <strong>6 templates</strong> · <strong>7 prompts</strong> · <strong>6 skills</strong> · <strong>4 уровня PreToolUse-гейтов</strong>
</p>
---
## TL;DR
Claudegram — production-grade плагин Claude Code, превращающий личный Telegram в управляемый AI-инструмент:
- **MTProto, не Bot API** — видит **всю** переписку, истории, поиск, медиа, статистику.
- **120 типизированных MCP-tools** через FastMCP, разбиты на 9 доменов; покрыты `safe_tool` middleware с FloodWait/RPCError handling и санитизацией секретов.
- **Channel-режим**: входящие сообщения push-ятся в активную сессию Claude как `<channel>` теги с permission relay (yes/no через `<id>`).
- **4-слойная safety net**: PreToolUse hooks (`guard-delete`, `guard-destructive`, `guard-confirm`) + `disable-model-invocation` для отправки сообщений + sensitive userConfig в системный keychain.
- **Skills + Prompts**: `tg-digest`, `tg-search`, `tg-history`, `tg-send`, `tg-reply`, `telegram-workflow` — готовые сценарии для рекрутерского тестового запуска.
Полный список возможностей — в таблице ниже.
## Why this project
- Реальный production-ready MCP-сервер: типизированные tools, structured output, prompt templates, completions, resource templates.
- Безопасность спроектирована up-front: модель угроз, hook-гейты, allowlist, sanitize в логах. См. [SECURITY.md](SECURITY.md).
- Чистая архитектура: 75 модулей, ~6.3k строк server-кода, ~900 строк тестов, ruff + mypy, CI на GitHub Actions, Codecov, CodeQL.
- Каждое решение объяснено docstring'ом и CHANGELOG'ом, без «магии».
## Quick start
```bash
git clone https://github.com/sanjar-x/claudegram.git && cd claudegram
uv sync
cp .env.example .env # вставь api_id/api_hash/phone с https://my.telegram.org
uv run claudegram-auth
# затем в Claude Code: /plugin add . && /plugin install claudegram
```
Подробнее — в разделе «Установка» ниже.
В отличие от Bot API, Claudegram видит **всю историю**, **все чаты** и поддерживает **поиск**.
Архитектура и компоненты выровнены под официальную
[спеку Claude Code Plugins](https://code.claude.com/docs/en/plugins-reference).
## Возможности
| Слой | Что внутри |
|-------------------|------------------------------------------------------------------------|
| **MCP-сервер** | **118 типизированных tool'ов** через FastMCP + Telethon, разбиты по 9 доменам с подпакетами в `server/tools/` |
| **Production middleware** | `safe_tool` decorator с graceful FloodWait/RPCError handling, latency logging, sensitive-sanitization |
| **Health probe** | `health_check` + `get_server_version` для readiness/liveness |
| **Channel-режим** | Push входящих Telegram-сообщений в активную сессию Claude как `<channel source="claudegram">` теги + permission relay (yes/no `<id>`) |
| **Skills** | 6 skill'ов: `tg-digest`, `tg-search`, `tg-history`, `tg-send`, `tg-reply` + фоновые `telegram-workflow` и `tg-channel-incoming` |
| **Hooks** | `SessionStart` — авто-проверка авторизации; `PreToolUse` — гейт перед `delete revoke=true` (с jq/python3 fallback) |
| **bin/** | `claudegram-auth` — попадает в PATH **Bash tool** Claude Code (не в shell хоста); снаружи — `uv run claudegram-auth` |
| **userConfig** | Креденшелы + sender-allowlist запрашиваются GUI-промптом плагина, сенситивные в системном keychain |
| **Persistent data** | `*.session` живёт в `${CLAUDE_PLUGIN_DATA}` — не теряется при апдейте плагина |
| **Marketplace** | `.claude-plugin/marketplace.json` — каталог из одного плагина для `/plugin install` |
## Структура
```
Claudegram/
├── .claude-plugin/
│ └── plugin.json # манифест с userConfig (api_id/hash/phone/2fa)
├── .mcp.json # MCP stdio-сервер, env через ${user_config.*}
├── hooks/
│ ├── hooks.json # SessionStart auth-check, PreToolUse delete-guard
│ └── scripts/
│ ├── check-auth.sh
│ └── guard-delete.sh
├── skills/ # каждая команда — отдельный каталог с SKILL.md
│ ├── telegram-workflow/SKILL.md # фоновые правила (user-invocable: false)
│ ├── tg-channel-incoming/SKILL.md # обработка <channel source="claudegram"> тегов
│ ├── tg-digest/SKILL.md # /claudegram:tg-digest [N]
│ ├── tg-search/SKILL.md # /claudegram:tg-search <запрос> [@chat]
│ ├── tg-history/SKILL.md # /claudegram:tg-history <@chat> [limit]
│ ├── tg-send/SKILL.md # /claudegram:tg-send <@chat> <текст> (disable-model-invocation)
│ └── tg-reply/SKILL.md # /claudegram:tg-reply <@chat> <id> <текст>
├── bin/
│ └── claudegram-auth # шелл-обёртка над server.auth
├── server/ # Python MCP-сервер (FastMCP + Telethon)
│ ├── __init__.py
│ ├── config.py # plugin-mode + standalone-mode env loading
│ ├── auth.py # одноразовый интерактивный логин
│ ├── client.py # singleton TelegramClient
│ ├── formatters.py # сериализация в JSON
│ ├── channel.py # channel-режим: push + permission relay
│ ├── main.py # FastMCP entry + custom stdio runner с experimental caps
│ └── tools/ # 92 tools в 8 доменах с подпакетами
│ ├── __init__.py # register_all(mcp) — диспатчит по доменам
│ ├── _common.py # shared utils (ParseMode, normalize_chat, clamp, to_jsonable)
│ ├── identity/ # account, sessions
│ │ ├── account.py # get_me, update_profile, set_online, update_username, get_full_user
│ │ └── sessions.py # get_authorizations, terminate_authorization
│ ├── peers/ # discovery + метаданные сущностей
│ │ ├── lookup.py # resolve_username, get_chat_info, search_global, get_top_peers, get_input_peer
│ │ ├── users.py # get_profile_photos, download_profile_photo, get_common_chats
│ │ └── contacts.py # CRUD + block/unblock + import + get_blocked
│ ├── messaging/ # send/edit/history/pins/reactions
│ │ ├── messages.py # send/edit/delete/forward
│ │ ├── history.py # get_history (+filter_type), search_messages
│ │ ├── pins.py # pin_message, unpin_message
│ │ └── reactions.py # react_message
│ ├── dialogs/ # список и состояния диалогов
│ │ ├── list_.py # list_chats, get_drafts
│ │ ├── folders.py # archive/unarchive/pin_dialog
│ │ └── notify.py # mark_read, mute, unmute, delete_dialog
│ ├── chats/ # управление группами/каналами
│ │ ├── create.py # create_group, create_channel
│ │ ├── settings.py # title/about/photo/forum_mode
│ │ ├── members.py # participants, kick, ban, unban, restrict, promote, demote
│ │ ├── invites.py # join, leave, export_invite
│ │ └── admin.py # admin_log, stats
│ ├── media/ # файлы и attachments
│ │ ├── files.py # send_file, send_album
│ │ ├── download.py # download_media, get_media_info
│ │ ├── attachments.py # send_location, send_contact, send_dice
│ │ └── stickers.py # все sticker-операции
│ ├── content/ # контент-фичи
│ │ ├── polls.py # send/vote/results
│ │ ├── stories.py # all stories operations
│ │ └── forums.py # forum-topics
│ └── advanced/
│ └── raw.py # invoke_raw — ANY MTProto method
├── pyproject.toml + uv.lock # uv-проект
├── .env.example # для standalone-режима
├── .gitignore # игнорит .env, *.session, .venv, кеши
└── README.md
```
## Стек
- Python 3.14, [uv](https://docs.astral.sh/uv/)
- [Telethon](https://docs.telethon.dev/) 1.43+ — MTProto-клиент
- [`mcp[cli]`](https://github.com/modelcontextprotocol/python-sdk) 1.x — официальный SDK MCP
## Установка
### 1. Получить API-креденшелы
1. Открой <https://my.telegram.org> → **API development tools**.
2. Создай приложение (любые `App title` / `Short name`).
3. Скопируй `api_id` и `api_hash`.
### 2. Установить зависимости (uv создаст `.venv/`)
```bash
cd ~/Desktop/Claudegram
uv sync
```
### 3. Подключить плагин в Claude Code
Самый быстрый способ для разработки — `--plugin-dir` (грузит как сессионный плагин,
без установки):
```bash
claude --plugin-dir ~/Desktop/Claudegram
```
Постоянная установка через локальный marketplace (`marketplace.json` уже включён
в `.claude-plugin/`):
```
/plugin marketplace add ~/Desktop/Claudegram
/plugin install claudegram@claudegram-local
```
`claudegram-local` — имя локального marketplace из `.claude-plugin/marketplace.json`.
При первом включении Claude Code откроет промпт и попросит ввести
`tg_api_id`, `tg_api_hash`, `tg_phone` (поля `userConfig` из манифеста).
Сенситивные значения уйдут в системный keychain, не в `settings.json`.
### 4. Авторизоваться (один раз)
⚠️ Важно: `bin/claudegram-auth` попадает в PATH **только Bash tool внутри
Claude Code**, не в обычный shell хоста (это ограничение Claude Code, см.
[plugins-reference](https://code.claude.com/docs/en/plugins-reference#file-locations-reference)).
Вариант **A** (рекомендуемый, из активной Claude-сессии):
```
! claudegram-auth
```
Префикс `!` запускает команду в shell сессии, и тогда `bin/claudegram-auth`
из плагина уже в PATH.
Вариант **B** (из обычного терминала, standalone):
```bash
cd ~/Desktop/Claudegram
uv run python -m server.auth
# или
uv run claudegram-auth # после `uv sync` появляется console-script
```
В обоих случаях — введи код из Telegram. Файл сессии создастся:
- **Plugin-mode**: `~/.claude/plugins/data/claudegram-claudegram-local/claudegram.session` (переменная `${CLAUDE_PLUGIN_DATA}`) — не теряется при апдейте плагина.
- **Standalone**: в корне проекта `~/Desktop/Claudegram/claudegram.session`.
### 5. Проверить
```
/mcp # должен появиться сервер "claudegram"
/reload-plugins # после правок без рестарта
/hooks # увидишь SessionStart + PreToolUse гейт
```
## Использование
### Slash-skills (тип `/claudegram:<skill>`)
- `/claudegram:tg-digest [N]` — сводка непрочитанных по N чатам.
- `/claudegram:tg-search <запрос> [@chat]` — поиск.
- `/claudegram:tg-history <@chat> [N]` — последние N сообщений чата.
- `/claudegram:tg-send <@chat> <текст>` — отправка с подтверждением. Только пользователь вызывает (`disable-model-invocation: true`).
- `/claudegram:tg-reply <@chat> <id> <текст>` — ответ на конкретное сообщение. Только пользователь.
### Авто-активация
Skill `telegram-workflow` (`user-invocable: false`) подгружается, когда ты пишешь
"что у меня в Telegram?", "найди в чатах", "напиши Пете". Claude по описанию
выбирает правильный MCP-tool и следует safety-правилам из этого skill.
### Прямые MCP-инструменты (58 шт)
Полный namespace: `mcp__plugin_claudegram_claudegram__<tool>`. Wildcard для
permission-rule: `mcp__plugin_claudegram_claudegram__*`.
Полный каталог с описаниями и сигнатурами — в skill'е [`telegram-workflow/SKILL.md`](skills/telegram-workflow/SKILL.md).
Краткая сводка по категориям:
- **Account** (5): `get_me`, `get_authorizations`, `terminate_authorization`, `update_profile`, `set_online`
- **Messages** (11): `send_message`, `edit_message`, `delete_message`, `forward_message`, `get_history`, `search_messages`, `mark_read`, `pin_message`, `unpin_message`, `react_message`, `send_dice`
- **Dialogs** (7): `list_chats`, `get_drafts`, `archive_dialog`, `unarchive_dialog`, `delete_dialog`, `mute_dialog`, `unmute_dialog`
- **Users** (7): `get_chat_info`, `resolve_username`, `get_participants`, `get_profile_photos`, `block_user`, `unblock_user`, `get_common_chats`
- **Chats** (12): `create_group`, `create_channel`, `edit_chat_title`, `edit_chat_about`, `join_chat`, `leave_chat`, `kick_participant`, `ban_participant`, `unban_participant`, `promote_admin`, `demote_admin`, `get_admin_log`, `get_stats`
- **Media** (7): `download_media`, `download_profile_photo`, `send_file`, `send_album`, `send_location`, `send_contact`, `get_media_info`
- **Contacts** (4): `get_contacts`, `add_contact`, `delete_contact`, `search_global`
- **Polls** (2): `send_poll`, `vote_poll`
- **Raw API** (2): `invoke_raw`, `get_input_peer` — escape hatch для **любого** MTProto-метода через `telethon.tl.functions.<module>.<MethodNameRequest>`. Покрывает Stories, Payments, Stickers, Channels admin, Folders, Themes — всё, что не обёрнуто high-level API.
## Как работает безопасность
- `.env` и `*.session` в `.gitignore`.
- Sensitive userConfig (api_hash, phone, 2FA) уходят в системный keychain (или `~/.claude/.credentials.json`), не в `settings.json`.
- `*.session` лежит в `${CLAUDE_PLUGIN_DATA}` — не утекает с апдейтом, но даёт полный доступ к аккаунту, храни как пароль.
- `PreToolUse`-хук на `delete_message` принудительно спрашивает, если `revoke=true`.
- Skill `telegram-workflow` обязывает Claude получать явное подтверждение перед `send_message`/`mark_read`/`delete_message`.
- Telegram может посчитать активность подозрительной → возможна блокировка. Для экспериментов используй **отдельный** аккаунт.
## Standalone-режим (без плагина)
Можно запустить MCP-сервер вне Claude Code:
```bash
cp .env.example .env
$EDITOR .env # заполни TG_API_ID/HASH/PHONE
uv run python -m server.auth # логин, .session ляжет в корень
uv run python -m server.main # MCP stdio-сервер
```
`server/config.py` сначала читает `TG_*` (или `.env`), затем —
`CLAUDE_PLUGIN_OPTION_TG_*`, которые экспортируются плагином. Один и тот же код
работает в обоих режимах.
## Расширение
- **Новый MCP-tool** → функция в `server/main.py` с `@mcp.tool()`. FastMCP сам сгенерирует JSON-схему по type-hints + docstring.
- **Новый skill** → каталог `skills/<name>/` с `SKILL.md`. Frontmatter: `name`, `description`, опционально `argument-hint`, `arguments`, `allowed-tools`, `disable-model-invocation`, `paths`, `model`, `effort`.
- **Новый hook** → редактируй `hooks/hooks.json`. Доступные события см. [hooks reference](https://code.claude.com/docs/en/hooks).
- **Бинарь** → положи в `bin/<name>` + chmod +x. Автоматически попадёт в PATH.
После любых изменений: `/reload-plugins` в Claude Code (рестарт не нужен).
## Channel-режим
[Channels](https://code.claude.com/docs/en/channels) (research preview Claude Code v2.1.80+) —
двусторонний bridge: входящие Telegram-сообщения **сами** появляются в активной
Claude-сессии как XML-теги, Claude отвечает обратно через `send_message`.
### Что под капотом
- В `.mcp.json` плагин выставляет `CLAUDEGRAM_CHANNEL_MODE=1` → `server/main.py`
объявляет experimental capabilities `claude/channel` и `claude/channel/permission`
через кастомный stdio-runner (FastMCP сам не умеет — обходим через `_mcp_server.create_initialization_options(experimental_capabilities=...)`).
- `server/channel.py` подписывается на Telethon `@client.on(events.NewMessage(incoming=True))`.
- Каждое входящее от ID из allowlist (`tg_allowed_sender_ids`) пушится как
raw `JSONRPCNotification(method='notifications/claude/channel', ...)` напрямую
через write_stream stdio-сессии.
- Тег у Claude выглядит так:
```xml
<channel source="claudegram"
chat_id="-1001234567890"
message_id="42"
sender_id="111222333"
user="Pete">
привет, как дела?
</channel>
```
- Skill `tg-channel-incoming` (auto-active) объясняет Claude'у, что делать
с такими тегами + правила безопасности (никакого автоответа без подтверждения).
- **Permission relay**: ответные сообщения вида `yes abcde` / `no abcde`
(5 строчных букв без `l`, regex case-insensitive) парсятся как verdict и шлются
обратно как `notifications/claude/channel/permission` — Claude Code применяет автоматически.
### Включение
Channel-режим **opt-in** через userConfig поле `enable_channel_mode`:
1. В `/plugin` интерфейсе или при первой установке выстави `enable_channel_mode = "1"`.
2. Перезапусти Claude Code с обоими флагами:
```bash
claude \
--dangerously-load-development-channels plugin:claudegram@claudegram-local \
--channels plugin:claudegram@claudegram-local
```
В research preview кастомные плагины **не входят** в Anthropic allowlist
(`--dangerously-load-development-channels`), а `--channels` явно регистрирует
listener — оба флага нужны.
Если `enable_channel_mode = "0"` (default) — сервер работает только как tools-MCP,
push'и не отсылаются, Telegram-rate-limit не тратится.
Удобно завести алиас в `~/.zshrc`:
```bash
alias claude-tg='claude --dangerously-load-development-channels plugin:claudegram@claudegram-local --channels plugin:claudegram@claudegram-local'
```
### Безопасность
| Слой | Защита |
|---|---|
| **Sender gate** | `parse_allowed_ids()` в `channel.py` пушит только от ID из `tg_allowed_sender_ids`. Пустой allowlist = только себе (свой `get_me().id`). |
| **Группы** | Гейтим по `event.sender_id`, **не** `chat_id` — иначе любой в allowlisted-группе мог бы инжектить промпты. |
| **Permission relay** | Декларируем `claude/channel/permission`. Анonymously пушнувший в обход allowlist'а не получит право жать `yes` — verdict тоже гейтится по sender. |
| **Skill `tg-channel-incoming`** | Обязывает Claude показывать draft и ждать "отправляй" перед `send_message`. Запрещает реагировать на prompt-injection из тела сообщения. |
| **Hook `guard-delete`** | `revoke=true` для удаления требует явного approval даже из channel-сценария. |
### Узнать свой sender_id для allowlist
После авторизации (`claudegram-auth`) — спроси у [@userinfobot](https://t.me/userinfobot)
или вызови в активной Claude-сессии `mcp__plugin_claudegram_claudegram__get_me`.
## Roadmap
- **Outbound permission_request handler** — Claude Code шлёт `notifications/claude/channel/permission_request` когда нужен approval; форвардить юзеру в Telegram. Сейчас inbound verdict работает, outbound forward — TODO (требует регистрации custom notification_handler в Server, не тривиально через FastMCP).
- **send media** (фото/документ/голосовое) — Telethon `send_file` уже умеет, обернуть в tool.
- **pin / unpin / mute / archive / set_typing** диалогов.
- **Stories** API (Telegram Stories через MTProto).
- **Monitor** на бэкап Saved Messages (`monitors/monitors.json`).
- **Submit** в Anthropic [official marketplace](https://claude.ai/settings/plugins/submit) — channel-плагины проходят security review, после чего работают без `--dangerously-load-development-channels`.
- **Marketplace на GitHub** + git-теги `claudegram--v0.1.0` для version-constraints.
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
cc-switch
All-in-One Assistant for Claude Code, Codex & Gemini CLI across platforms.
awesome-mcp-servers
A collection of MCP servers.
git
A Model Context Protocol server for Git automation and interaction.
oh-my-opencode
Background agents · Curated agents like oracle, librarians, frontend...
TrendRadar
TrendRadar: Your hotspot assistant for real news in just 30 seconds.
Appwrite
Build like a team of hundreds