@Eugene Sukhodolskiy Eugene Sukhodolskiy authored 5 hours ago
backend tgclient: регистрация me_router в main.py 5 hours ago
.env.example tgclient: backend M1-M5 — FastAPI + Telethon + MCP (core, media, voice/rounds, login-тулы) 5 hours ago
.gitignore tgclient: backend M1-M5 — FastAPI + Telethon + MCP (core, media, voice/rounds, login-тулы) 5 hours ago
README.md tgclient: backend M1-M5 — FastAPI + Telethon + MCP (core, media, voice/rounds, login-тулы) 5 hours ago
docker-compose.yml tgclient: backend M1-M5 — FastAPI + Telethon + MCP (core, media, voice/rounds, login-тулы) 5 hours ago
README.md

tgclient-mcp

Telegram-клиент формата MCP для экосистемы Gnexus (конвенции gnexus-handbook): мульти-аккаунтный MTProto юзер-клиент (Telethon), MCP-сервер для ИИ-агентов (/mcp-protocol/, alias /mcp) и SPA-админка, закрытая SSO gnexus-auth, с персональными MCP-токенами.

Возможности

  • Мульти-аккаунтность: каждый SSO-пользователь логинит свои Telegram-аккаунты (phone → код → 2FA в SPA-визарде или текстом через MCP-тулы) и работает только со своими; админ видит все.
  • 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).

Разработка (без docker)

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/

Pitfalls (из плана)

  1. Telethon-сессии — только StringSession в БД (SQLiteSession конфликтует с aiosqlite).
  2. TL-объекты сериализуются только через mcp/serializers.py, никогда to_dict(); наружу — id в bot-API-маркировке (юзер >0, группа -id, канал -100id).
  3. Кружок требует mp4 H.264/AAC квадрат ≤60 с, иначе уйдёт как обычное видео; waveform голосового считаем сами (63 семпла × 5 бит).
  4. base64 в JSON ≈ +33%: cap TGCLIENT_MEDIA_MAX_BYTES (по умолчанию 20 MB).
  5. Повторный send_code_request на живую pending-сессию не дёргается; код/пароль не логируются и не хранятся.
  6. FloodWait ≤60 с Telethon спит сам; длинный — 429 как данные + Synapse-репорт.