Skip to main content
Glama
FloppaProg

Vibe-Marketolog MCP Server

by FloppaProg
README.md
# Vibe-Marketolog Agent API → MCP (POC)

Один инструмент, журнал вызовов, понятная цена цикла.

## Состав

- `vibe_client.py` — клиент к `https://lk.vibemarketolog.ru/api/agent`.
  Пишет каждый вызов в `call_log.jsonl` и считает расход за сессию.
- `server.py` — MCP-сервер на FastMCP. Четыре тула: `landing_audit`,
  `cycle_cost_summary`, `call_log`, `account_status`. Подключается как
  обычный MCP-сервер в Cursor, VS Code или любой MCP-совместимой среде.
- `demo_run.py` — прогон без MCP-клиента: вызов, повтор, журнал, сводка.
- `test_client.py` — 13 тестов на моке HTTP-слоя.

## Запуск

```bash
pip install -r requirements.txt
export VIBE_API_KEY=ваш_ключ_из_раздела_AGI_Агент

python demo_run.py https://ваш-сайт.ru   # демонстрация
python server.py                          # как MCP-сервер
```

Тесты:

```bash
python -m pytest test_client.py -v
```

Версия SDK закреплена как `mcp==1.9.4`: в 2.x нет пути импорта
`mcp.server.fastmcp`, под неё сервер нужно переписывать отдельно.

## Почему landing-audit

Это единственный существующий роут семейства `direct/*`. Проверял
запросами без ключа, живой роут отвечает 401, несуществующий 404:

```
POST /api/agent/direct/landing-audit   -> 401 missing_token
POST /api/agent/direct/waste           -> 404 not_found
POST /api/agent/direct/search-queries  -> 404 not_found
POST /api/agent/direct/campaigns       -> 404 not_found
```

Плюс инструменту не нужен ни рекламный кабинет, ни кампания на
платформе, только URL. Значит, POC можно проверить сразу после
получения ключа.

## Журнал вызовов

`call_log.jsonl`, построчно. Пишутся все вызовы, включая упавшие,
иначе цена цикла считается по неполным данным:

```json
{"timestamp": "...", "session_id": "6c90b72e", "tool": "direct/landing-audit", "params": {"url": "..."}, "status": "ok", "cached": false, "price_rub": 39.0, "price_source": "api", "duration_ms": 1240, "note": "новый платный вызов"}
{"timestamp": "...", "session_id": "6c90b72e", "tool": "direct/landing-audit", "params": {"url": "..."}, "status": "ok", "cached": true, "price_rub": 0.0, "price_source": "cache", "duration_ms": 180, "note": "из кеша (бесплатно)"}
{"timestamp": "...", "session_id": "6c90b72e", "tool": "me", "params": {}, "status": "error", "cached": false, "price_rub": 0.0, "price_source": "none", "duration_ms": 519, "note": "HTTP 401 missing_token: Не передан ключ доступа."}
```

`price_source` показывает, откуда цифра: `api` пришла в ответе, `cache`
вызов бесплатный, `unknown` API цену не сообщил.

## Цена цикла

`cycle_cost_summary()` по умолчанию считает только текущий запуск.
Журнал дописывается между запусками, и сумма за всю историю файла это
не цена цикла; за всю историю считает `scope="all"`.

```json
{
  "scope": "session",
  "session_id": "6c90b72e",
  "total_calls": 2,
  "paid_calls": 1,
  "cached_free_calls": 1,
  "unknown_price_calls": 0,
  "errors": 0,
  "total_spent_rub": 39.0,
  "cost_confirmed": true
}
```

`cost_confirmed: false` значит, что по какому-то вызову API не сообщил
цену и сумма занижена. Нулём это не маскируется.

## Границы

Проверено вживую без ключа: базовый URL, `/me`, `/capabilities`,
существование роута `direct/landing-audit`, формат ошибок
`{status, error, message, request_id}`.

Проверено на моке: журнал, подсчёт стоимости, обработка ошибок,
запускаемость MCP-сервера. 13 тестов.

Не проверено — имена полей стоимости и кеша в ответе `landing-audit`.
Документация называет стоимость `cost`, а `/capabilities` этот
инструмент не описывает. Клиент принимает `price_rub`, `cost` и
`charged_rub`, при отсутствии всех трёх помечает цену неизвестной.
Наличие бесплатного кеша на 24 часа тоже не подтверждено: если второй
вызов придёт платным, `demo_run.py` скажет об этом прямо.

Не проверено — хватает ли скоупов промо-ключа на `direct/*`. Раздел
`partner_only` в `/capabilities` относит программную работу с Директом
к партнёрскому соглашению, возможен 403.

Остальные инструменты директолога не обёрнуты, потому что обёртывать
нечего: других роутов `direct/*` в API нет. Слой дельт в MVP не
показан: `landing-audit` не кампанейский, дельте там взяться не из чего.

## Дальше

1. Прогнать `demo_run.py` на реальном ключе, приложить фактический
   `call_log.jsonl` и баланс до/после. Это заодно закроет вопрос об
   именах полей стоимости и о наличии кеша.
2. Если скоупов на `direct/*` не хватит, перенести тот же контур
   (смета, потолок бюджета, журнал, цена цикла) на `/generate`, где
   биллинг трёхфазный: `reserved`, `cost`, `refunded`.
3. Слой дельт на том, что реально отдаёт API.