# agent-news Telegram-бот на Dart: по команде `/news` (или `/news <тема>`) запускает Claude Code для ресёрча и присылает выжимку в чат. Тестовый/учебный проект — пока гоняем локально в Docker, без деплоя в кластер. ## Как это работает Один контейнер, три процесса: 1. `agent-news-bot` (Dart, long polling) — слушает `/news <тема>`, спавнит `claude` как сабпроцесс. 2. `claude` (Claude Code CLI) — делает ресёрч; по ходу и в конце сам вызывает MCP-тул `send_to_telegram` (промежуточные статусы + финальная выжимка). 3. `agent-news-mcp` (Dart, stdio MCP-сервер) — спавнится самим `claude`, шлёт готовый текст в Telegram Bot API. Все тексты, которые бот показывает пользователю или подставляет в промпт Claude, лежат в одном месте — `bot/lib/lexicon.dart`. ## Запуск локально ```bash cp .env.example .env # заполнить TELEGRAM_BOT_TOKEN и ALLOWED_CHAT_IDS (через запятую) docker compose up -d --build ``` `~/.claude` (авторизация Claude Code) хранится в именованном volume `claude-home` — переживает пересборку и рестарт контейнера. ### Первичная авторизация Claude Code Claude Code CLI использует OAuth-логин через Claude.ai (подписка, не API-ключ). Один раз после первого запуска нужно зайти в контейнер и залогиниться: ```bash docker compose exec agent-news claude auth login ``` CLI напечатает ссылку — открой её в браузере, авторизуйся, вставь код обратно в терминал, если попросит. Учти: и `~/.claude/`, и `~/.claude.json` — оба нужны для логина, поэтому в volume смонтирован **весь `/home/agent`** (см. `docker-compose.yml`), не только `~/.claude/`. После `docker compose restart` логин не слетит. ### Проверка Напиши боту `/news <тема>` (или просто `/news` — возьмёт `DEFAULT_TOPIC`) из чата с id из `ALLOWED_CHAT_IDS`. Бот сразу ответит "начинаю…", дальше Claude сам присылает статусы по ходу ресёрча и в конце — готовую выжимку, всё через `send_to_telegram`. Ресёрч занимает несколько минут — это нормально, статусы как раз для этого. ```bash docker compose logs -f agent-news ``` ## Локальная разработка (без Docker) ```bash cd bot && dart pub get && dart analyze cd ../mcp_server && dart pub get && dart analyze ``` ## Переменные окружения | Переменная | Обязательна | Назначение | |---|---|---| | `TELEGRAM_BOT_TOKEN` | да | токен бота, используется и ботом, и MCP-сервером | | `ALLOWED_CHAT_IDS` | да | список chat_id через запятую — кому отвечает бот | | `DEFAULT_TOPIC` | нет | тема для `/news` без аргумента (по умолчанию — «главные новости дня») | | `CLAUDE_TIMEOUT_SECONDS` | нет | таймаут на ресёрч (по умолчанию 600) | | `MCP_CONFIG_PATH` | нет | путь к `mcp.json` (по умолчанию `/app/claude-config/mcp.json`) |