Wildberries API MCP Server
by antondrpq
README.md
# Руководство по использованию Wildberries API MCP сервера
[](https://github.com/antondrpq/Wildberries-API-MCP-Server/actions/workflows/ci.yml)
[](https://github.com/antondrpq/Wildberries-API-MCP-Server/actions/workflows/docker-publish.yml)
> Репозиторий: https://github.com/antondrpq/Wildberries-API-MCP-Server
## Содержание
1. [Введение](#введение)
2. [Установка и запуск](#установка-и-запуск)
3. [Доступные инструменты API](#доступные-инструменты-api)
4. [MCP-агенты](#mcp-агенты)
5. [Примеры использования](#примеры-использования)
6. [Типичные сценарии использования](#типичные-сценарии-использования)
7. [Получение токена API](#получение-токена-api)
8. [Устранение неполадок](#устранение-неполадок)
9. [Деплой на Cloudflare Workers](#деплой-на-cloudflare-workers)
10. [Безопасность и продакшн-эксплуатация](#безопасность-и-продакшн-эксплуатация)
## Введение
Wildberries API MCP сервер представляет собой промежуточный сервис, который упрощает взаимодействие с API Wildberries. Он предоставляет унифицированный HTTP-интерфейс для аналитики, статистики продвижения, работы с остатками, CSV-отчётами и импорта данных EVIRMA PRO.
MCP сервер выполняет следующие функции:
* упрощает обращение к различным эндпоинтам API Wildberries;
* централизованно передаёт `api-key` клиента в `Authorization` при обращении к WB;
* обрабатывает ошибки API и ограничения частоты запросов;
* сохраняет совместимость локальных маршрутов при миграции WB API;
* унифицирует обработку ответов;
* принимает и нормализует выгрузки EVIRMA PRO.
## Установка и запуск
### Необходимые предварительные требования
* Node.js **20 или выше**;
* npm;
* Docker и Docker Compose (опционально, для контейнеризации);
* токен API Wildberries с необходимыми разрешениями.
### Способ 1: Прямая установка через Node.js
```bash
git clone https://github.com/antondrpq/Wildberries-API-MCP-Server.git
cd Wildberries-API-MCP-Server
npm install
npm start
```
Сервер запустится на порту `3000` по умолчанию.
Можно указать другой порт:
```bash
PORT=8080 npm start
```
### Переменные окружения
Скопируйте `.env.example` в `.env` и при необходимости отредактируйте:
```bash
cp .env.example .env
```
| Переменная | По умолчанию | Описание |
| ---------------- | -----------: | ----------------------------------------------- |
| `PORT` | `3000` | Порт HTTP-сервера |
| `NODE_ENV` | `production` | `production` / `development` / `test` |
| `RATE_LIMIT_MAX` | `100` | Максимум входящих запросов с одного IP в минуту |
### Тесты и линтер
```bash
npm test
npm run lint
```
Локально проект проверяется через Jest + Supertest и ESLint.
### Способ 2: Использование Docker
```bash
docker build -t wb-api-mcp-server .
docker run -p 3000:3000 -d --name wb-api-mcp wb-api-mcp-server
```
Проверка:
```bash
curl http://localhost:3000/health
```
Ожидаемый ответ:
```json
{
"status": "ok",
"timestamp": "2026-08-19T..."
}
```
### Способ 3: Использование Docker Compose
```bash
cp .env.example .env
docker-compose up -d
docker-compose down
```
### Способ 4: Готовый образ из GitHub Container Registry
Актуальный образ публикуется в GHCR:
```bash
docker pull ghcr.io/antondrpq/wildberries-api-mcp-server:latest
docker run -p 3000:3000 -d --name wb-api-mcp ghcr.io/antondrpq/wildberries-api-mcp-server:latest
```
Проверка:
```bash
curl http://localhost:3000/health
```
## Доступные инструменты API
Сервер предоставляет следующие группы эндпоинтов.
### 1. Статистика продвижения
#### Поисковые кластеры рекламы
* **POST `/api/adv/normquery/stats`** — статистика поисковых кластеров через WB `POST /adv/v0/normquery/stats`.
* **POST `/api/adv/normquery/stats-v1`** — статистика поисковых кластеров с детализацией через WB `POST /adv/v1/normquery/stats`.
#### Статистика рекламных кампаний
* **GET `/api/adv/fullstats`** — статистика рекламных кампаний через WB `GET /adv/v3/fullstats`.
* **POST `/api/adv/stats`** — статистика медийных кампаний через WB `POST /adv/v1/stats`.
#### Устаревающие методы
Следующие локальные маршруты сохранены для совместимости, но требуют отдельной проверки актуальных методов WB API:
* **GET `/api/adv/auto/stat-words`**
* **GET `/api/adv/stat/words`**
* **GET `/api/adv/stats/keywords`**
### 2. Воронка продаж (Sales Funnel)
Локальные маршруты сохранены для обратной совместимости, но внутри используют актуальный WB Analytics v3:
* **POST `/api/nm-report/detail`** → `POST /api/analytics/v3/sales-funnel/products`
* **POST `/api/nm-report/detail/history`** → `POST /api/analytics/v3/sales-funnel/products/history`
* **POST `/api/nm-report/grouped/history`** → `POST /api/analytics/v3/sales-funnel/grouped/history`
Сервер умеет преобразовывать legacy-поля старого формата (`period`, `nmIDs`, `objectIDs`, `tagIDs`) в формат v3 (`selectedPeriod`, `nmIds`, `subjectIds`, `tagIds` и другие).
### 3. Поисковые запросы
Текущая реализация использует WB Analytics v2:
* **POST `/api/search-report/report`** — основной отчёт по поисковым запросам.
* **POST `/api/search-report/table/groups`** — пагинация по группам поисковых запросов.
* **POST `/api/search-report/table/details`** — пагинация по товарам внутри группы.
* **POST `/api/search-report/product/search-texts`** — поисковые тексты конкретного товара.
* **POST `/api/search-report/product/orders`** — заказы и позиции по поисковым текстам товара.
Пример основного отчёта:
```javascript
const searchReport = await fetchFromMcp('/api/search-report/report', 'POST', {
currentPeriod: {
start: '2026-08-12',
end: '2026-08-18'
},
positionCluster: 'all',
orderBy: {
field: 'avgPosition',
mode: 'desc'
},
limit: 100,
offset: 0
});
```
### 4. Отчёт по остаткам (Stocks Report)
Текущая реализация использует WB Analytics v2:
* **POST `/api/stocks-report/products/groups`**
* **POST `/api/stocks-report/products/products`**
* **POST `/api/stocks-report/products/sizes`**
* **POST `/api/stocks-report/offices`**
Пример:
```javascript
const stocksReport = await fetchFromMcp('/api/stocks-report/products/products', 'POST', {
nmIDs: [178773045],
currentPeriod: {
start: '2026-08-12',
end: '2026-08-18'
},
stockType: '',
skipDeletedNm: true,
orderBy: {
field: 'avgOrders',
mode: 'desc'
},
offset: 0
});
```
### 5. CSV-отчёты продавца (Seller Analytics CSV)
* **POST `/api/nm-report/downloads`** — создание CSV-отчёта.
* **GET `/api/nm-report/downloads`** — получение списка отчётов.
* **POST `/api/nm-report/downloads/retry`** — повторная генерация отчёта.
* **GET `/api/nm-report/downloads/file/:downloadId`** — скачивание ZIP-файла отчёта.
### 6. Импорт данных EVIRMA PRO
* **POST `/api/evirma/import/keywords-report`** — импорт XLS/XLSX-отчёта «Статистика РК по ключевым фразам».
* **POST `/api/evirma/import/daily-zone-stats`** — импорт XLS/XLSX-отчёта «Статистика РК по дням и зонам показов».
EVIRMA PRO не предоставляет публичного API; сервер обрабатывает вручную экспортированные файлы.
### 7. Healthcheck
* **GET `/health`** — проверка работоспособности сервера без API-ключа.
## MCP-агенты
Помимо REST-эндпоинтов выше, сервер также отдаёт **MCP Streamable HTTP** эндпоинт (`POST /mcp`) с 32 инструментами, сгруппированными в четыре функциональных агента:
* **Финансист** — баланс, отчёты реализации, эквайринг, готовый P&L одним вызовом (`wb_finance_summary`).
* **Реклама** — кампании, баланс кабинета продвижения, бюджеты, ставки, агрегированная сводка (`wb_ads_summary`).
* **Ответы покупателям** — отзывы, вопросы, чаты с покупателями (чтение и ответ).
* **Управляющий магазина** — тарифы, FBS-заказы, сводка «здоровья бизнеса» (`wb_business_summary`).
Часть инструментов — `WRITE` (публикуют текст, видимый покупателю) или `WRITE / DESTRUCTIVE` (например, отмена заказа); полный список с пометками и требуемыми категориями токена — в [`MCP.md`](./MCP.md).
**Права на write-инструменты определяются токеном WB, а не этим сервером.** Сервер не фильтрует `tools/list` и не проверяет права заранее — он просто проксирует вызов с заголовком `Authorization: <WB_API_KEY>`. Если `WB_API_KEY` выпущен с флагом «Только чтение», Wildberries сам отклонит любой write-вызов (12 из 32 инструментов) с HTTP 403 — MCP-клиент увидит эти инструменты в `tools/list`, но выполнить их не сможет. Подробности и рекомендации по выпуску токена — в разделе [«Token permissions and read-only mode»](./MCP.md#token-permissions-and-read-only-mode) файла `MCP.md`.
Это отдельный протокол поверх того же порта, не подмножество REST API из раздела выше — предназначен для подключения к MCP-клиентам (например, Claude) как единый набор инструментов, а не для прямых HTTP-вызовов из своего кода.
Подробности: конфигурация, полный список всех 32 инструментов с описаниями, известные лимиты частоты запросов WB и пример smoke-теста через PowerShell — см. **[`MCP.md`](./MCP.md)**.
## Примеры использования
### Получение статистики рекламных кампаний
`/api/adv/fullstats` — локальный **GET**-маршрут, который проксирует актуальный WB `GET /adv/v3/fullstats`.
```javascript
const params = new URLSearchParams({
ids: '1234567',
beginDate: '2026-08-12',
endDate: '2026-08-18'
});
const response = await fetch(
`http://localhost:3000/api/adv/fullstats?${params.toString()}`,
{
headers: {
'api-key': 'ВАШ_ТОКЕН_WILDBERRIES_API'
}
}
);
const data = await response.json();
console.log(data);
```
> Параметры конкретного запроса должны соответствовать текущей схеме WB `GET /adv/v3/fullstats`.
### Статистика поисковых кластеров рекламы
Для `v0` и `v1` используются разные имена полей.
Пример `v0`:
```javascript
const response = await fetch('http://localhost:3000/api/adv/normquery/stats', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'api-key': 'ВАШ_ТОКЕН_WILDBERRIES_API'
},
body: JSON.stringify({
from: '2026-08-12',
to: '2026-08-18',
items: [
{
advert_id: 1234567,
nm_id: 178773045
}
]
})
});
```
Пример `v1`:
```javascript
const response = await fetch('http://localhost:3000/api/adv/normquery/stats-v1', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'api-key': 'ВАШ_ТОКЕН_WILDBERRIES_API'
},
body: JSON.stringify({
from: '2026-08-12',
to: '2026-08-18',
items: [
{
advertId: 1234567,
nmId: 178773045
}
]
})
});
```
### Получение статистики карточки товара
Сервер сохраняет привычный локальный маршрут, но внутри использует Sales Funnel v3:
```javascript
const response = await fetch('http://localhost:3000/api/nm-report/detail', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'api-key': 'ВАШ_ТОКЕН_WILDBERRIES_API'
},
body: JSON.stringify({
nmIDs: [178773045],
period: {
begin: '2026-08-12',
end: '2026-08-18'
}
})
});
const data = await response.json();
console.log(data);
```
### Анализ поисковой видимости
```javascript
const searchReport = await fetch('http://localhost:3000/api/search-report/report', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'api-key': 'ВАШ_ТОКЕН_WILDBERRIES_API'
},
body: JSON.stringify({
currentPeriod: {
start: '2026-08-12',
end: '2026-08-18'
},
positionCluster: 'all',
orderBy: {
field: 'avgPosition',
mode: 'desc'
},
limit: 100,
offset: 0
})
});
const data = await searchReport.json();
console.log(data);
```
### Поисковые тексты товара
```javascript
const searchTexts = await fetchFromMcp('/api/search-report/product/search-texts', 'POST', {
currentPeriod: {
start: '2026-08-12',
end: '2026-08-18'
},
nmIds: [178773045],
topOrderBy: 'openCard',
limit: 20
});
```
### Управление запасами
```javascript
const stocksReport = await fetchFromMcp('/api/stocks-report/products/products', 'POST', {
nmIDs: [178773045],
currentPeriod: {
start: '2026-08-12',
end: '2026-08-18'
},
stockType: '',
skipDeletedNm: true,
orderBy: {
field: 'avgOrders',
mode: 'desc'
},
offset: 0
});
```
### Импорт отчёта EVIRMA PRO
```bash
curl -X POST http://localhost:3000/api/evirma/import/keywords-report \
-H "api-key: ВАШ_ТОКЕН_WILDBERRIES_API" \
-F "file=@Экспорт_..._cmp-advert-keywords-stats_....xlsx"
```
Размер файла ограничен 15 МБ. Поддерживаются `.xlsx` и `.xls`.
## Типичные сценарии использования
### 1. Мониторинг эффективности рекламных кампаний
1. Получать статистику рекламных кампаний через `/api/adv/fullstats`.
2. Получать поисковые кластеры рекламы через `/api/adv/normquery/stats` или `/api/adv/normquery/stats-v1`.
3. Сохранять результаты в БД для исторического анализа.
4. Сравнивать показы, клики, расходы, корзины и заказы.
### 2. Анализ воронки продаж товаров
1. `/api/nm-report/detail` — детальная воронка по товарам.
2. `/api/nm-report/detail/history` — динамика по дням.
3. `/api/nm-report/grouped/history` — агрегированные данные по брендам, предметам и тегам.
4. Выявлять товары с низкими конверсиями и анализировать этапы просмотра → корзина → заказ → выкуп.
### 3. Оптимизация поисковой видимости
Используйте:
* `/api/search-report/report`;
* `/api/search-report/table/groups`;
* `/api/search-report/table/details`;
* `/api/search-report/product/search-texts`;
* `/api/search-report/product/orders`.
Это позволяет анализировать позиции, поисковые фразы, переходы и заказы.
### 4. Управление запасами
Используйте `stocks-report` для оценки:
* текущих остатков;
* средних заказов;
* скорости продаж;
* распределения по складам;
* потенциального времени покрытия запасами.
### 5. Генерация расширенных CSV-отчётов
Рекомендуемая последовательность:
```text
POST /api/nm-report/downloads
↓
GET /api/nm-report/downloads
↓
POST /api/nm-report/downloads/retry (если FAILED)
↓
GET /api/nm-report/downloads/file/:downloadId
```
## Получение токена API
1. Войдите в личный кабинет продавца Wildberries.
2. Откройте раздел управления API.
3. Создайте токен с необходимыми разрешениями.
4. Для аналитики и продвижения выдайте соответствующие права.
5. **Если сервер (в т.ч. MCP-агент) будет только читать данные — включите опцию «Только чтение».** WB физически откажет любому write-запросу с таким токеном (HTTP 403), независимо от того, какие категории ему выданы. Для MCP это значит, что 12 write-инструментов (`wb_feedback_answer`, `wb_order_cancel` и другие — полный список в [`MCP.md`](./MCP.md)) вернут ошибку 403, даже если MCP-клиент их вызовет: `tools/list` их всё равно покажет, но выполнить их через read-only токен нельзя. Это самый надёжный способ ограничить действия ИИ-агента — сильнее любой логики на стороне этого сервера.
6. Если какому-то сценарию действительно нужна запись (например, отдельный агент для отмены заказов) — выпустите под него **отдельный** токен без флага «Только чтение», а не снимайте этот флаг с общего аналитического токена.
7. Сохраните токен безопасно: сервер не сохраняет его и принимает в заголовке `api-key` на каждый запрос.
## Устранение неполадок
### `401 Unauthorized`
Проверьте наличие заголовка:
```text
api-key: ВАШ_ТОКЕН_WILDBERRIES_API
```
### `400 Bad Request`
Проверьте структуру `body` и обязательные поля конкретного WB endpoint.
### `429 Too Many Requests`
Сервер возвращает `429`. Если Wildberries передаёт заголовок `X-RateLimit-Retry`, сервер:
* возвращает его клиенту как HTTP-заголовок `X-RateLimit-Retry`;
* добавляет его значение в `details.retryAfter`.
Пример:
```json
{
"error": true,
"message": "Rate limit exceeded. Please try again later.",
"details": {
"status": 429,
"retryAfter": "1473"
}
}
```
Соблюдайте указанный WB интервал перед повторным запросом.
### `404 Not Found`
Проверьте путь локального маршрута и актуальность соответствующего WB API метода.
### Просмотр логов
```bash
docker logs wb-api-mcp
```
### Проверка работоспособности
```bash
curl http://localhost:3000/health
```
## Деплой на Cloudflare Workers
Сервер поддерживает отдельную обёртку для Cloudflare Workers через `wrangler`. Для обычного Node.js/Docker-деплоя эти файлы не требуются.
```bash
npm run deploy:cloudflare
```
Учитывайте:
* `express-rate-limit` хранит счётчик в памяти процесса;
* длительные или тяжёлые обработки `.xlsx` ограничены CPU и памятью среды;
* файлы EVIRMA обрабатываются в памяти запроса;
* для максимально предсказуемого Node.js-окружения рекомендуется Docker.
## Безопасность и продакшн-эксплуатация
* HTTPS обязателен в продакшне.
* API-токен не хранится сервером и передаётся клиентом через `api-key`.
* `/health` не требует авторизации.
* Встроен rate limit на входящие запросы.
* Для MCP-подключений, которым не требуется запись (аналитика, отчёты, дашборды), используйте `WB_API_KEY` с флагом WB «Только чтение» — это ограничивает возможности ИИ-агента на уровне самого Wildberries API, а не только на уровне логики сервера (подробнее — [`MCP.md`](./MCP.md#token-permissions-and-read-only-mode)).
* Рекомендуется включать Dependabot и CodeQL в настройках GitHub-репозитория.
* Docker-контейнер запускается от непривилегированного пользователя `appuser`.
* EVIRMA-загрузки ограничены 15 МБ и типами `.xlsx/.xls`.
* Файлы EVIRMA обрабатываются только в памяти и не сохраняются на диск.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues