Telegram-клиент формата MCP для экосистемы Gnexus (конвенции gnexus-handbook): мульти-аккаунтный MTProto юзер-клиент (Telethon), MCP-сервер для ИИ-агентов (/mcp-protocol/, alias /mcp) и SPA-админка, закрытая SSO gnexus-auth, с персональными MCP-токенами.
/mcp-protocol/, streamable HTTP + Bearer mcp_*):
accounts_list, me_get, dialogs_list, messages_history, messages_read, messages_search, message_send/reply/edit/delete;download_media (base64), upload_file; голосовые (upload_voice ogg-opus + waveform 63×5 бит) и кружки (upload_round, mp4-квадрат ≤60 с);contacts_list, chat_info, chat_participants;account_login_start/code/password/status/cancel.{"error": code, "detail": ...}), перс. ключи по канону mcp.md (≤10 на юзера, снейпшот роли, plaintext один раз, ревок вместо архива), блокировка юзера гасит ключи тем же 401, rate-limit мутаций и логинов, Synapse-уведомления (логин/логаут/auth-lost/флуд).FastAPI + uvicorn, aiosqlite (WAL, одна БД SQLite в /data), Telethon (только StringSession), mcp python-sdk (FastMCP), gnexus-gauth SDK (OAuth PKCE + cookie-сессии + вебхуки), gnexus-synapse (нотификации), Vue 3 + Vite + gnexus-ui-kit (SPA).
cp .env.example .env && chmod 600 .env # заполнить: TGCLIENT_API_ID/_API_HASH (my.telegram.org), TGCLIENT_ADMIN_TOKEN, # TGCLIENT_AUTH_* ( gnexus-auth приложение), TGCLIENT_SYNAPSE_* (опционально) docker compose up -d --build # http://<host>:TGCLIENT_PORT — SPA; MCP: http://<host>:TGCLIENT_PORT/mcp-protocol/
claude mcp add --transport http tgclient https://<host>/mcp-protocol/ \ --header "Authorization: Bearer mcp_<персональный ключ>"
Ключ выпускается на странице «MCP-ключи» сервиса; показывается один раз. Статический TGCLIENT_ADMIN_TOKEN — супер-бэкдор для скриптов (роль superadmin).
10-platform/notifications.md)Конверты v1, fire-and-forget, клиент gnexus-synapse; конфиг — TGCLIENT_SYNAPSE_URL/_API_KEY (+ _DEFAULT_SOURCE=tgclient-mcp). Кому и куда доставить — решает маршрутизация Synapse; в конверте только факт. payload.user_id — sub gnexus-auth.
| событие | subject/action | prio | dedup | когда |
|---|---|---|---|---|
tg_account_logged_in |
account/logged_in | high | день+аккаунт | Telegram-сессия добавлена (новая или повторная) |
tg_account_logged_out |
account/logged_out | normal | — | логаут аккаунта из SPA |
tg_account_auth_lost |
account/auth_lost | high | день+аккаунт | MTProto-ключ умер (сессия отозвана в ТГ) |
tg_login_failed |
account/login_failed | normal | день+логин | 3 неверных кода / 2 пароля — логин отменён |
tg_flood_wait |
api/flood_wait | high | день+аккаунт | длинный FloodWait (>60 с) в Telethon |
mcp_token_issued |
token/issued | normal | — | выпуск персонального MCP-ключа |
mcp_token_revoked |
token/revoked | normal | — | ревок ключа (свой или админский) |
tg_message_received |
message/received | normal | — | новое сообщение (text + media-мета: voice/round/duration/waveform) |
tg_message_edited |
message/edited | normal | — | правка сообщения |
tg_message_deleted |
message/deleted | low | — | удаление (ids; ttl 1 ч) |
Пуш-события сообщений — то, на что реагирует ИИ-агент/скрипт: подписка через Synapse Target (webhook) — MCP подписок не даёт (stateless request/response). Включается env TGCLIENT_NOTIFY_MESSAGES=1 (payload несёт личные переписки — по умолчанию выключено). Plaintext MCP-ключа в конверты не уходит.
cd backend && python3 -m venv .venv && .venv/bin/pip install -e . TGCLIENT_DB_PATH=./data/tgclient.db .venv/bin/uvicorn app.main:app --reload # SPA: cd frontend && npm ci && npm run dev (vite proxy /api,/auth → 8710)
TGCLIENT_AUTH_CLIENT_ID пуст → auth-off: всё принадлежит служебному юзеру local, MCP открыт без ключей (только для разработки!)./api/v1/health → {status, version, accounts:{active,connected,pending_logins}, db}.backend/app/ config.py db.py schema.sql security.py auth.py locales.py synapse_report.py errors.py main.py # lifespan (telethon-пул, GC, persist), роуты, /mcp, SPA api/ auth_routes accounts mcp_tokens admin tg/ manager login_flow limits waveform mcp/ server context tools serializers frontend/src/ App.vue router.js api.js i18n/ pages/
StringSession в БД (SQLiteSession конфликтует с aiosqlite).mcp/serializers.py, никогда to_dict(); наружу — id в bot-API-маркировке (юзер >0, группа -id, канал -100id).TGCLIENT_MEDIA_MAX_BYTES (по умолчанию 20 MB).send_code_request на живую pending-сессию не дёргается; код/пароль не логируются и не хранятся.