Metadata-Version: 2.4
Name: st-mcp-mp-docs
Version: 0.5.0
Summary: Локальный MCP-сервер гибридного поиска (BM25+dense+rerank) по документации API маркетплейсов
Requires-Python: >=3.13
Requires-Dist: mcp[cli]==1.28.1
Requires-Dist: numpy==2.5.1
Requires-Dist: python-dotenv==1.2.2
Requires-Dist: pyyaml==6.0.3
Requires-Dist: rank-bm25==0.2.2
Requires-Dist: sentence-transformers==5.6.0
Requires-Dist: torch==2.13.0
Provides-Extra: dev
Requires-Dist: ruff==0.15.17; extra == 'dev'
Requires-Dist: ty==0.0.49; extra == 'dev'
Description-Content-Type: text/markdown

# MCP Marketplaces Docs

[![Python 3.13](https://img.shields.io/badge/Python-3.13-3776AB?style=flat&logo=python)](https://python.org/)
[![MCP](https://img.shields.io/badge/mcp%5Bcli%5D-1.28.1-000000?style=flat)](https://github.com/modelcontextprotocol/python-sdk)
[![rank-bm25](https://img.shields.io/badge/rank--bm25-0.2.2-3776AB?style=flat)](https://github.com/dorianbrown/rank_bm25)
[![torch](https://img.shields.io/badge/torch-2.13-EE4C2C?style=flat)](https://pytorch.org/)
[![sentence-transformers](https://img.shields.io/badge/sentence--transformers-5.6-blue?style=flat)](https://www.sbert.net/)

MCP-сервер гибридного поиска (BM25 + dense-эмбеддинги + cross-encoder rerank) по документации API и бизнес-справке маркетплейсов (Ozon, Yandex Market, Wildberries). Индексирует корпус [`marketplaces.docs`](../marketplaces.docs) и отдаёт агенту opencode инструменты ранжированного поиска с фильтрами по метаданным и навигацией по секциям.

## 🚀 Возможности

- Гибридный поиск BM25+dense (`intfloat/multilingual-e5-base`, GPU) через Reciprocal Rank Fusion — включается `MP_HYBRID` (по умолчанию `true`)
- Cross-encoder реранкинг top-N (`BAAI/bge-reranker-v2-m3`, GPU) поверх RRF — включается `MP_RERANK` (по умолчанию `true`), усекает текст кандидата против OOM на длинных чанках
- HyDE: опциональный `hyde_text` — гипотетический документ от агента-потребителя как третий dense-ретривер в RRF для абстрактных запросов
- Фильтрация по метаданным frontmatter в одном вызове: `marketplace`, `type`, `archived`
- Возврат сниппетов секций вместо целых файлов — экономия контекста агента
- Чанкинг по заголовкам H2 с объединением мелких секций
- Идемпотентная индексация: перестройка только при изменении корпуса или схемы индекса
- E2E-проверка инструментов, замер recall@k и поэтапное сравнение режимов из коробки

## 📚 Корпус

Индексируется весь `marketplaces.docs` через `MP_DOCS_PATH` — четыре слоя одного корпуса:

| Слой | `type` | Кто пишет | Перезапись |
|---|---|---|---|
| `api/`, `seller/` | `api`, `seller` | скрапер `marketplaces.docs.scraper` | перезаписывается при каждом скрапинге |
| `memory/` | `memory` | человек (сверка данных с ЛК/API) | никогда |
| `guide/` | `guide` | человек (накапливаемый опыт) | никогда |

Схема frontmatter и контракт — в `marketplaces.docs/CORPUS.md`. Правило потребления описано в
`AGENTS.md`: сначала `get_guide(marketplace)`, потом `search`.

## 🛠️ Технологический стек

| Технология           | Версия | Назначение                       |
| --------------------- | ------ | --------------------------------- |
| Python                | 3.13   | Язык разработки                  |
| mcp[cli]              | 1.28.1 | MCP SDK, транспорт stdio         |
| rank-bm25             | 0.2.2  | BM25-ранжирование                |
| sentence-transformers | 5.6.0  | Dense-эмбеддинги (`e5-base`) + реранкер (`bge-reranker-v2-m3`) |
| torch                 | 2.13.0 | GPU-инференс моделей эмбеддингов и реранкера  |
| numpy                 | 2.5.1  | Хранение и косинус эмбеддингов   |
| pyyaml                | 6.0.3  | Парсинг frontmatter              |
| python-dotenv         | 1.2.2  | Загрузка переменных окружения    |

## 🖥️ Требования к GPU

Построение индекса (`make index`) требует **CUDA-доступный GPU** в этой версии — dense-эмбеддинги
считаются всегда, без CPU-fallback. Поиск в рантайме (`search`) требует GPU при `MP_HYBRID=true`
(dense-ветка) и/или `MP_RERANK=true` (реранкер) — оба включены по умолчанию. `MP_HYBRID=false
MP_RERANK=false` отключает обе GPU-ветки и работает чисто на BM25 без обращения к GPU.

Модели кэшируются при первом запуске в `~/.cache/huggingface/` — это отдельный кэш от `MP_CACHE_DIR`
(тот хранит только `bm25.pkl`/`chunks.jsonl`/`embeddings.npy`/`manifest.json`). Первая установка
скачивает torch+CUDA (~2.5+ ГБ), `multilingual-e5-base` (~280 МБ, грузится при hybrid-запросе) и
`bge-reranker-v2-m3` (~2.2 ГБ, грузится при rerank-запросе). Обе модели грузятся лениво — только когда
соответствующая ветка реально вызывается.

## 📁 Структура проекта

```
marketplaces.mcp.docs/
├── src/st_mcp_mp_docs/
│   ├── main.py              # Точка входа: запуск сервера по stdio
│   ├── server.py            # FastMCP и регистрация инструментов
│   ├── tools.py             # Реализация инструментов поверх BM25+dense+rerank
│   ├── indexer.py           # Построение индекса: frontmatter, чанкинг, embeddings, кэш
│   ├── embedder.py          # Dense-эмбеддинги (e5-base) + encode_passage для HyDE
│   ├── reranker.py          # Cross-encoder реранкинг top-N (bge-reranker-v2-m3)
│   ├── hybrid.py            # Reciprocal Rank Fusion: слияние списка ретриверов
│   ├── tokenizer.py         # Токенизация camelCase/snake_case, стоп-слова
│   ├── format.py            # Сниппеты и форма результатов
│   └── config.py            # Пути и параметры из окружения
├── scripts/
│   ├── check.py             # E2E-прогон через MCP-клиент
│   ├── eval.py              # Замер recall@k и MRR
│   └── eval_compare.py      # Поэтапное сравнение: BM25 → +embeddings → +rerank
├── tests/
│   └── eval_queries.jsonl   # Набор поисковых запросов (36: api/seller)
├── cache/                   # BM25-индекс и метаданные (gitignored)
├── Makefile
├── pyproject.toml
├── AGENTS.md
└── README.md
```

## 🚀 Установка и запуск

### Предварительные требования

- Python 3.13+
- uv
- NVIDIA GPU + CUDA-совместимый драйвер (построение индекса и поиск при `MP_HYBRID=true`, дефолт)
- Репозиторий [`marketplaces.docs`](../marketplaces.docs) с корпусом документации

### Установка

```bash
make help       # Справка по командам
make install    # Создание окружения и установка зависимостей
make index      # Построение индекса (BM25 + dense) из marketplaces.docs
```

### Запуск

```bash
make serve      # Запуск MCP-сервера (stdio)
```

Регистрация в opencode — секция `mcp` в `opencode.json`:

```jsonc
{
  "mcp": {
    "mp-docs": {
      "type": "local",
      "command": [
        "uvx",
        "--from",
        "st-mcp-mp-docs",
        "--index",
        "https://forgejo.emptyvessel.ru/api/packages/st/pypi/simple",
        "st-mcp-mp-docs",
      ],
      "environment": {
        "MP_DOCS_PATH": "/path/to/marketplaces.docs",
      },
      "enabled": true,
    },
  },
}
```

## 🔧 Разработка

```bash
make index        # Построение индекса (BM25 + dense) из marketplaces.docs
make serve        # Запуск MCP-сервера (stdio)
make eval         # Замер recall@k на eval-наборе (36 запросов)
make eval-compare # Поэтапное сравнение: BM25 → +embeddings → +rerank
make e2e          # Прогон инструментов через MCP-клиент
make lint         # Проверка линтером
make fix          # Автоисправление и проверка типов
make format       # Форматирование кода
make clean        # Очистка кэша
make purge        # Полная очистка окружения, индекса и кэшей
make build        # Сборка wheel и sdist
make publish      # Публикация в forgejo registry
```

## 👥 Команда разработки

- **Станислав** ([@stanislavbajkov2](mailto:stanislavbajkov2@gmail.com))

## 📄 Лицензия

Проект разработан для коммерческого использования. Права защищены.

**© 2026 ДонНовоТех**
_Передовые программные и аппаратные решения для транспорта_

📍 **Адрес:** ул. М.Горького 205, Ростов-на-Дону, 344000, Россия <br>
📞 **Телефон:** +7-904-500-6087 <br>
📧 **Email:** [leojohn@yandex.ru](mailto:leojohn@yandex.ru) <br>
🌐 **Сайт:** [donnovotech.ru](https://donnovotech.ru) <br>
🏢 **ИНН:** 6163227601
