Skip to main content
Glama

ru-marketplace-mcp

CI Python 3.12+ License: MIT MCP

MCP-серверы для российских и китайских маркетплейсов. Цены, наличие, рейтинги, отзывы и реквизиты продавцов с Wildberries, Ozon, Яндекс Маркета, Детского мира, Авито, AliExpress, Taobao, Мегамаркета, Lamoda, DNS и Ситилинка. Плюс сравнение цен по всем источникам одним вызовом.

Только чтение. Ключи API, токены и регистрация не нужны — площадки с жёстким анти-ботом читаются через ваш собственный Chrome. Одно исключение по желанию: опциональный MPStats берёт платный токен (MPSTATS_MP_AUTH) — без него всё остальное работает как прежде.

English version below · Архитектура · Как добавить источник · Про анти-бот


Что внутри

Сервер

Инструментов

Что нужно, чтобы читалось

Что умеет

Wildberries

8

анонимный HTTP

Поиск, карточки, отзывы, вопросы о товаре, реквизиты продавца, каталог и товары категории

Яндекс Маркет

2

анонимный HTTP

Цены разных продавцов, разбивка оценок по звёздам, отзывы

Детский мир

3

анонимный HTTP

Детские товары, наличие в офлайн-магазинах, категории

Ozon

3

ваш Chrome; с домашнего IP часто и без него

Поиск, карточки, отзывы

Авито

3

ваш Chrome + российский домашний IP и запросы вразрядку — иначе блок по IP

Поиск объявлений, карточки, репутация продавца

Taobao

2

ваш Chrome с активным входом в Taobao

Поиск и карточки, цены в юанях

Мегамаркет

2

ваш Chrome с активным входом — анонимной сессии API отдаёт пусто

Поиск и карточки через мобильный API

Lamoda

2

карточки анонимно (GraphQL), поиск — ваш Chrome

Поиск, карточки с размерами

DNS

2

ваш Chrome (Qrator)

Поиск и карточки электроники

Ситилинк

2

ваш Chrome (Qrator)

Поиск и карточки электроники

AliExpress

2

ваш Chrome (x5sec)

Поиск и карточки, цены в рублях

Сравнение

2

опрашивает всё перечисленное

«Где дешевле?» одним вызовом

MPStats

2

платный аккаунт MPStats, cookie mp_auth (опционально)

Продажи/остатки/графики за 30 дней по SKU Ozon/WB, остатки по складам (FBS/FBO)

Читается анонимно, без браузера: Wildberries, Яндекс Маркет, Детский мир и карточки Lamoda. Остальным нужен ваш залогиненный Chrome (CDP). Taobao и Мегамаркет вдобавок требуют активного входа в саму площадку — без него Taobao упирается в стену логина, а Мегамаркет отдаёт пустой ответ. Авито ещё и блокирует по IP: с датацентрового адреса это глухой отказ, с российского домашнего — работает, если не частить запросами. Запросы к CDP-источникам идут вразрядку: очередь подряд без пауз роняет их (DNS и Taobao в проверке так и деградировали), поэтому коннекторы держат паузу между вызовами сами. Точное состояние из вашей сессии покажет marketplace-mcp doctor.

MPStats стоит особняком: это единственный платный источник. Без MPSTATS_MP_AUTH сервер запускается, но инструменты отвечают auth_missing — поэтому он опционален и подключается по желанию, на остальные двенадцать серверов он не влияет никак.

Всего 35 инструментов в 13 серверах на общем рантайме mcp-core. Плюс объединённый marketplace-mcp, который монтирует всё разом — одна запись в конфиге клиента вместо тринадцати. Он добавляет свой инструмент marketplace_sources (какие коннекторы поднялись, а какие отвалились и почему), так что в нём 36 инструментов: 35 смонтированных плюс этот.

Related MCP server: wildberries-mcp

Быстрый старт

Нужны Python 3.12+ и uv.

git clone https://github.com/Vladimir-Human/ru-marketplace-mcp.git
cd ru-marketplace-mcp
uv sync --all-packages
uv run pytest -q -m "not live and not cdp"   # 1212 офлайн-тестов, сеть не нужна

Проверка живого эндпоинта:

uv run python -c "
import asyncio
from wb_connector.server import wb_selfcheck
print(asyncio.run(wb_selfcheck()).status)   # ждём success
"

Подключение к MCP-клиенту

Каждый сервер — консольная команда, поэтому пути в конфиге не зашиваются.

Windows: %APPDATA%\Claude\claude_desktop_config.json macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

Проще всего подключить одну запись — объединённый сервер монтирует все источники разом, а имена инструментов (wb_search, avito_seller, …) не меняются:

{
  "mcpServers": {
    "marketplace": {
      "command": "uv",
      "args": ["run", "--directory", "C:/путь/к/ru-marketplace-mcp", "marketplace-mcp"],
    },
  },
}

Если нужны отдельные серверы, marketplace-mcp install claude напечатает готовый блок для вставки. Путь к вашему checkout там уже подставлен: заглушку /path/to/ru-marketplace-mcp править руками не придётся. При установке из wheel вместо путей печатаются консольные команды на PATH. Неизвестное имя клиента (допустимы claude, claude-code, cursor, dsh) команда отклоняет с пояснением и кодом возврата 2 — молча подставить блок для Claude она не может. Минимальный вариант вручную:

{
  "mcpServers": {
    "wildberries": {
      "command": "uv",
      "args": ["run", "--directory", "C:/путь/к/ru-marketplace-mcp", "wb-mcp"],
    },
    "ozon": {
      "command": "uv",
      "args": ["run", "--directory", "C:/путь/к/ru-marketplace-mcp", "ozon-mcp"],
    },
    "compare-prices": {
      "command": "uv",
      "args": ["run", "--directory", "C:/путь/к/ru-marketplace-mcp", "compare-mcp"],
    },
  },
}

Путь пишите с прямыми слешами / или двойными обратными \\. Полный список команд — wb-mcp, ozon-mcp, yandex-mcp, detmir-mcp, avito-mcp, taobao-mcp, megamarket-mcp, lamoda-mcp, dns-mcp, citilink-mcp, compare-mcp, marketplace-mcp.

claude mcp add wildberries -- uv run --directory /путь/к/ru-marketplace-mcp wb-mcp
claude mcp add yandex-market -- uv run --directory /путь/к/ru-marketplace-mcp yandex-mcp
claude mcp add detsky-mir -- uv run --directory /путь/к/ru-marketplace-mcp detmir-mcp
claude mcp add ozon -- uv run --directory /путь/к/ru-marketplace-mcp ozon-mcp
claude mcp add compare-prices -- uv run --directory /путь/к/ru-marketplace-mcp compare-mcp
{
  "mcpServers": {
    "compare-prices": {
      "command": "uv",
      "args": ["run", "--directory", "/путь/к/ru-marketplace-mcp", "compare-mcp"],
    },
  },
}

Запустите uv run --directory /путь/к/репозиторию <команда>, где команда — одна из wb-mcp, ozon-mcp, yandex-mcp, detmir-mcp, aliexpress-mcp, compare-mcp. Серверы говорят по JSON-RPC через stdin и stdout, диагностику пишут в stderr. Опциональный mpstats-mcp запускается так же, с MPSTATS_MP_AUTH в окружении.

В dsh это не запись mcpServers, а слой профиля. Бандл лежит в подкаталоге dsh/ и ставится штатным менеджером плагинов (pnpm нужен на PATH):

dsh plugin --profile web add github:Vladimir-Human/ru-marketplace-mcp#path:/dsh

Сразу после установки появляются 14 навыков и ни одного MCP-инструмента: обе строки MCP выключены, пока не задана переменная RU_MARKETPLACE_MCP_DIR с путём к клону. Так сделано потому, что смонтированный сервер платится в каждом запросе: рекомендуемый режим сравнения цен стоит ~0,9 тыс. токенов, полный набор — ~13,6 тыс. Включение и полный режим описаны в dsh/README.md.

После подключения перезапустите клиент и прогоните marketplace-mcp doctor. Он запускает канарейку каждого коннектора и отвечает success, drift_detected или inconclusive.

Инструменты

Канарейки *_selfcheck в этом перечне не значатся намеренно: они не публикуются по MCP, потому что диагностика оператора стоила бы модели ~7,5 тыс. токенов в каждом запросе. Запускает их marketplace-mcp doctor — все разом, из командной строки.

Wildberries — wb_*

Инструмент

Что делает

wb_search(query, page)

Поиск по тексту, до 100 товаров на страницу с ценами и остатками

wb_card(nm_ids)

Пакетный запрос до 100 известных SKU

wb_root_info(nm_id)

Находит imt_id (нужен для отзывов) и цветовые варианты

wb_reviews(imt_id, limit, sort)

Пул отзывов. Ключ — imt_id, а не nm_id

wb_questions(imt_id, limit, skip, answered_only)

Вопросы покупателей и ответы продавца. Тоже по imt_id

wb_seller(supplier_id)

Юрлицо, ИНН, КПП, ОГРН, юридический адрес

wb_categories(root, max_depth)

Дерево каталога с шардами и запросами самого WB

wb_category_products(shard, query, page, sort, dest)

Товары категории по shard и query из wb_categories

wb_seller отвечает на вопрос, который карточка товара скрывает: кто на самом деле продаёт? Возвращает зарегистрированное юрлицо и налоговые номера. Так отличают официальный магазин бренда от перекупщика с похожим названием.

wb_questions закрывает другой пробел. Отзывы говорят, каково владеть товаром; вопросы уточняют, что это вообще за товар — «10 или 16 ампер», «кабель в комплекте?». Ответ продавца часто единственное публичное утверждение об этом. Пул общий для всех вариантов товара, ключ — imt_id из wb_root_info.

wb_category_products замыкает связку с wb_categories: та отдаёт shard и query, это — товары по ним. Формат элементов совпадает с wb_search, поэтому обход категорий и текстовый поиск сравнимы напрямую. Часть крупных разделов WB помечает шардом blackhole — у них нет своей выдачи, и инструмент честно об этом говорит вместо пустого списка.

Яндекс Маркет — yandex_*

Инструмент

Что делает

yandex_search(query, page, limit)

Поиск с обеими ценами, рейтингами, продавцами

yandex_card(product_id, include_reviews)

Карточка целиком: разбивка по звёздам и отзывы

Две цены, всегда. price_rub платит любой покупатель. price_with_plus требует подписку Яндекс Плюс и обычно на 25–30% ниже. Интерфейс Яндекса показывает вторую крупным шрифтом, поэтому назвать её без оговорки — значит пообещать цену, которую человек без подписки не получит.

rating_stars даёт распределение вида {1: 10, 2: 3, 3: 10, 4: 19, 5: 502}. Из него видно, честная ли средняя 4.8 или за ней прячется кучка единиц.

Детский мир — detmir_*

Инструмент

Что делает

detmir_categories(parent, limit, region)

Дерево каталога. Начинать отсюда

detmir_category(alias, limit, offset, region)

Товары категории с настоящим счётчиком

detmir_card(product_id, region)

Цена, рейтинг, наличие онлайн и в магазинах

Регион задаётся на каждый вызов. Цены и особенно наличие в офлайн-магазинах сильно зависят от города: один и тот же товар лежал в 152 магазинах Москвы, 37 Петербурга и 2 Хабаровска. Параметр region перекрывает DETMIR_REGION, так что города можно сравнивать в одной сессии.

Текстового поиска здесь нет, и это намеренно. API Детского мира молча игнорирует любые текстовые фильтры и возвращает весь каталог на 300 тысяч позиций, а сайтовый роут поиска отдаёт 404 с промо-карусселью. Инструмент поиска возвращал бы уверенно неверные товары, поэтому навигация идёт через категории. Подробности в docs/ANTI_BOT.md.

Ozon — ozon_*

Инструмент

Что делает

ozon_search(query)

Поиск по тексту

ozon_card(sku_or_path)

Карточка товара

ozon_reviews(sku_or_path, limit, sort)

Отзывы

Ozon отклоняет датацентровый трафик, поэтому коннектор двухуровневый. Сначала TLS-имперсонация. Если Cloudflare выдаёт челлендж, запрос выполняется внутри вашего залогиненного Chrome через DevTools Protocol. Ничего не хранится: вход выполняете вы сами, в браузере, который контролируете. Настройка описана в docs/CDP_SETUP.md.

С российского домашнего IP первый уровень обычно работает, и браузер не нужен.

Отзывы на Ozon общие для всей карточки-семейства, и соседи по пулу — часто другой товар другого бренда. У карточки масляного радиатора Huter 1500 Вт (SKU 5264146973, рейтинг 4.8 из 356 отзывов) среди 100 вытянутых отзывов не оказалось ни одного о самом Huter: 38 про Ресанту 2000 Вт, 34 про Ресанту 1500 Вт, 5 про Eurolux и так далее — всего 12 товаров в пуле. Поэтому каждый отзыв несёт item_id — SKU того товара, о котором он написан, а ответ дополнительно отдаёт requested_item_id, own_reviews (сколько отзывов действительно об этом SKU) и pool_variants (SKU → название всех товаров пула). rating_score и distribution считаются по пулу, а не по товару: прежде чем делать вывод, отзывы нужно отфильтровать по item_id, а при own_reviews: 0 — честно сказать, что своих отзывов у товара нет.

Авито — avito_*

Инструмент

Что делает

avito_search(query, page, location_id, category_id)

Поиск объявлений через внутренний js/items API

avito_card(item_id_or_url)

Одно объявление: цена, описание, просмотры, продавец

avito_seller(seller_id_or_url)

Рейтинг продавца, число отзывов, активные объявления

Авито — это объявления, а не каталог: пула отзывов на товар нет, репутация продавца и есть сигнал доверия. Бесплатное/обменное объявление приходит с price_rub: null — никогда не 0, чтобы не оказаться «самым дешёвым» в сравнении. С датацентрового IP Авито отвечает 403-файрволом, поэтому коннектор двухуровневый: TLS-имперсонация, дальше ваш Chrome (как у Ozon).

Taobao — taobao_*

Инструмент

Что делает

taobao_search(query, page)

Поиск по каталогу Taobao

taobao_card(item_id_or_url)

Карточка товара

Поиск Taobao — клиентское React-приложение с подписанным mtop API: каждый запрос требует sign, вычисленный из cookie-токена, поэтому анонимного пути нет. Все чтения идут внутри вашего Chrome, где сайт сам подписывает запросы. Цены в юанях (CNY) и не конвертируются: зашитый курс молча устарел бы, так что сравнение с рублёвыми источниками делайте явно.

Эти четыре читаются через ваш Chrome (CDP). Мегамаркет (megamarket_*) — мобильный JSON API из-за ServicePipe, и одного пройденного челленджа мало: анонимной сессии API отдаёт пустой список, нужен активный вход в Мегамаркет. DNS (dns_*) и Ситилинк (citilink_*) — отрисованный DOM из-за Qrator; у всех трёх анонимного пути нет вообще. Lamoda (lamoda_*) наполовину: карточки берутся анонимно через GraphQL, а поиск — через Chrome. Chrome с CDP (scripts/start_chrome_cdp.sh) нужен всем, кроме карточек Lamoda.

Всего через CDP ходят восемь источников — эти плюс Taobao, AliExpress, Ozon и Авито, где Chrome лишь запасной уровень: их tier 1 обычно отвечает, а браузер включается, когда анонимный уровень упёрся в челлендж. marketplace-mcp doctor из вашего браузера скажет, какие эндпоинты подтверждены.

AliExpress — aliexpress_*

Инструмент

Что делает

aliexpress_search(query)

Поиск: до 48 карточек с ценами в рублях

aliexpress_card(item_id_or_url)

Карточка: цена, рейтинг, число заказов

Читается через ваш Chrome (CDP): x5sec ставит капчу анонимным клиентам, поэтому коннектор садится на страницу поиска (её не челленджат) и открывает карточку новой вкладкой из неё. Цены в рублях и участвуют в compare_prices. Карточка с названием, но без цены — известное состояние: под нагрузкой x5sec перестаёт отдавать ценовой модуль, коннектор пишет price_missing, а не выдумывает число. Цена «N ₽ с купоном» в price_rub не публикуется: там обычная цена, про купон коннектор честно предупреждает отдельно. Тексты отзывов не отдаются: только рейтинг и число заказов. Как и у остальных CDP-источников, зелёный aliexpress_selfcheck доказывает, что транспорт ответил, — не то, что цена верна.

Сравнение цен — compare_*

Инструмент

Что делает

compare_prices(query, per_source_limit, sources)

Все маркетплейсы сразу, с ранжированием

compare_sources()

Какие маркетплейсы доступны в этой установке

compare_prices("кроссовки мужские")

  wildberries      712 ₽   Кроссовки изи дышащие спортивные
  wildberries      814 ₽   Зимние кроссовки теплые с мехом
  yandex_market   2499 ₽   Кеды A-LOW
  yandex_market   3480 ₽   Кеды

  дешевле всего: wildberries 712 ₽, разброс 5858 ₽, complete: true

Маркетплейсы опрашиваются параллельно, и каждый отчитывается сам за себя. Если один заблокирован, сравнение не рушится: complete: false вместе с source_outcomes покажет, что именно вы видите. Подписочные цены в ранжировании не участвуют. Совпадающие предложения по паре (источник, id товара) схлопываются, так что один и тот же товар не занимает два места в ранжировании.

У каждого предложения есть currency (строчный ISO-код, по умолчанию rub) и price_native — цена в этой валюте, как её показывает маркетплейс. Для российских источников она совпадает с price_rub; у Taobao в ней лежит цена в юанях, которую price_rub намеренно оставляет пустой. Раньше юаневую цену забирали и молча выбрасывали, и строка Taobao приходила с пустой ценой без намёка, что цена вообще есть. Теперь юань виден, но в рублёвом ранжировании по-прежнему не участвует: в warnings появляется foreign_currency: … с числом исключённых предложений и причиной. Конвертировать здесь значило бы зашить курс, который молча устареет, — пересчёт за вами.

MPStats — mpstats_*

Аналитика продаж и остатков по SKU Ozon и Wildberries через плагин MPStats. В отличие от всех остальных коннекторов, этот опционален и требует платный аккаунт MPStats: авторизация — одна cookie mp_auth (JWT из залогиненной сессии плагина на mpstats.io), задаётся переменной MPSTATS_MP_AUTH. Без неё инструменты возвращают auth_missing, а сервер запускается как обычно — ни на что другое это не влияет.

Инструмент

Что делает

mpstats_item(skus, place, oz_fbs=True)

Аналитика за 30 дней по до 100 SKU: заказы, цена, остатки, графики по дням, продавец/бренд

mpstats_warehouses(skus, place)

Остатки по складам: FBS (склад продавца) и FBO (склад маркетплейса), last_update

placeozon или wildberries. Графики длиной 30, от старых к новым: последняя ненулевая ячейка — текущая цена или остаток. Цена и остаток при сплошь нулевом графике ведут себя намеренно по-разному: цена становится None (ложный 0 выиграл бы любое сравнение «где дешевле»), а остаток — 0, потому что «нулевой остаток» это осмысленное показание, а не отсутствие данных. Пустой график даёт None в обоих случаях. Ноль в отдельной ячейке — «нет данных за тот день», а не «значение было нулевым», поэтому сумму за окно считайте по графику. Отсутствие токена и транспортные сбои selfcheck отчитывает как inconclusive, не drift: гоняться за дрейфом схемы, которого не было, не нужно. Токен — секрет платного аккаунта с квотой: не логируйте и не коммитьте его.

Навыки для агента

У каждого коннектора — свой навык в skills/: четырнадцать штук, по одному на источник плюс общий marketplace. Навык это не пересказ README: он объясняет агенту, когда за этот источник вообще браться, чего у источника нет, и каким его ответам нельзя верить без второго взгляда.

Навык

Сервер

skills/wb-connector

wb-mcp

skills/ozon-connector

ozon-mcp

skills/yandex-connector

yandex-mcp

skills/detmir-connector

detmir-mcp

skills/avito-connector

avito-mcp

skills/taobao-connector

taobao-mcp

skills/megamarket-connector

megamarket-mcp

skills/lamoda-connector

lamoda-mcp

skills/dns-connector

dns-mcp

skills/citilink-connector

citilink-mcp

skills/aliexpress-connector

aliexpress-mcp

skills/compare-prices

compare-mcp

skills/mpstats-connector

mpstats-mcp

skills/marketplace

marketplace-mcp

mcp-core — общий рантайм под остальными серверами. Своего навыка у него нет.

Соответствие проверяется тестом (packages/marketplace-connector/tests/test_skills_parity.py): новый коннектор без навыка роняет прогон, как и навык, который называет несуществующий инструмент или забыл существующий. До этого теста навык DNS почти год советовал формат ссылки /product/<24-hex>/ — тот самый шаблон, который чинили как баг.

Скиллы едут в Docker-образ (/app/skills/), но в колёсах их нет: skills/ лежит в корне репозитория. Ставите с PyPI — возьмите навыки из репозитория отдельно.

Настройка

Все параметры задаются переменными окружения с префиксом коннектора. Все необязательные.

Префикс

Основные параметры

WB_

TIMEOUT, MIN_GAP, DEFAULT_DEST, NET_RETRIES, MAX_BODY_BYTES, CACHE_TTL, PROXY

YANDEX_

TIMEOUT, MIN_GAP, CACHE_TTL, PROXY

DETMIR_

REGION (RU-MOW, RU-SPE и другие), CACHE_TTL, PROXY

OZON_

TIMEOUT, MIN_GAP, IMPERSONATE, CACHE_TTL, PROXY

AVITO_

TIMEOUT, MIN_GAP, IMPERSONATE, CACHE_TTL, PROXY, LOCATION_ID

TAOBAO_

TIMEOUT, MIN_GAP, CACHE_TTL,

ALI_

TIMEOUT, MIN_GAP, CACHE_TTL

MEGAMARKET_

TIMEOUT, MIN_GAP, CACHE_TTL

LAMODA_

TIMEOUT, MIN_GAP, CACHE_TTL, PROXY

DNS_ / CITILINK_

TIMEOUT, MIN_GAP, CACHE_TTL

CHROME_

CDP_HOST, CDP_PORT, SCRAPING_PROFILE, BINARY, HEADLESS, STEALTH

COMPARE_

SOURCE_TIMEOUT

MPSTATS_

MP_AUTH (единственный обязательный — без него инструменты отвечают auth_missing), TIMEOUT, MIN_GAP, CACHE_TTL, PROXY

MCP_

TRANSPORT (stdio по умолчанию, либо http), HTTP_HOST, HTTP_PORT

CHROME_CDP_HOST указывает, куда дозвониться CDP-клиенту (по умолчанию 127.0.0.1). Из контейнера ставьте chrome (сайдкар) или host.docker.internal — это открывает tier-2 источники (Ozon, Авито, Taobao, Мегамаркет, Lamoda, DNS, Ситилинк) в Docker без host networking. Подробности в docs/DEPLOYMENT.md.

*_CACHE_TTL=0 выключает кэш. *_PROXY перекрывает стандартные HTTPS_PROXY и ALL_PROXY — свой префикс есть у семи коннекторов: WB_, YANDEX_, DETMIR_, OZON_, AVITO_, LAMODA_ и MPSTATS_. У Taobao своего нет намеренно: поиск там подписан и ходит через собственный клиент. У Мегамаркета, DNS и Ситилинка тоже нет: их трафик идёт через ваш Chrome, а его egress — дело настроек браузера. Кэшируются только удачные ответы: запомнить сбой значило бы растянуть секундную помеху на весь TTL.

У Ozon прокси применяется к первому уровню. Второй идёт через ваш собственный Chrome, и его трафик — дело настроек этого браузера.

Секрет один, и тот опциональный. Всем серверам, кроме MPStats, ничего не нужно: нечего настраивать, нечему утечь. У MPStats есть MPSTATS_MP_AUTH — JWT платного аккаунта, и потому его место только в env клиентской записи: в коде и коммитах его нет и быть не должно.

Разработка

uv sync --all-packages
uv run pytest -q -m "not live and not cdp"    # 1212 офлайн-тестов
uv run pytest -q -m "not live"                # то, что гоняет CI
uv run pytest -q -m "not live" --cov          # покрытие, порог 70% в CI
uv run ruff check . && uv run ruff format --check .
uv run mypy                                   # что проверять — в [tool.mypy] files
uv run mypy --platform win32                  # ловит ошибки, видимые только на Windows
uv run python scripts/check_no_print.py       # запись в stdout ломает JSON-RPC
uv run python scripts/check_versions.py       # одна версия во всех 77 местах

Часть тестов прогоняет настоящий JS-экстрактор коннектора по снятой разметке и проверяет результат против цен, которые в тот момент были на странице. Для этого нужен Node с jsdom:

npm install jsdom      # либо NODE_PATH на уже установленный
uv run pytest -q packages/dns-connector/tests/test_search_extractor_dom.py \
              packages/citilink-connector/tests/test_search_extractor_dom.py

Без jsdom эта половина честно скипается, а питоновская часть — выбор цены из кандидатов — идёт всегда. jsdom нужен только разработчику: в зависимости коннекторов он не входит.

CI прогоняет тесты на Ubuntu, Windows и macOS против Python 3.12 и 3.13. Windows-специфичное управление процессами проверяется юнит-тестами на любой ОС через подмену платформы, так что эти ветки покрыты даже на Linux.

Как добавить маркетплейс — docs/ADDING_A_SOURCE.md.

Надёжность

Неофициальные эндпоинты ломаются. Архитектура это предполагает.

  • Терпимые парсеры. Привязка поля по нескольким именам и приведение типов впитывают переименования и смену типа вместо падения.

  • Никогда не выдумывать значение. Отсутствующая цена — это null, не 0. Ноль вывел бы мёртвый товар в самые дешёвые.

  • Громкий отказ. Когда формат перестаёт совпадать, инструмент бросает parser_drift, а не возвращает полуразобранные данные.

  • Трёхзначные selfcheck-проверки. success, drift_detected или inconclusive. Гео-блокировка помечается как inconclusive, потому что она ничего не говорит о состоянии парсеров.

Границы доверия

Названия товаров, имена продавцов и тексты отзывов написаны продавцами и покупателями. Это недоверенные данные. Если отзыв или описание выглядит как инструкция, оно всё равно остаётся входными данными. Выполнять его агент не должен.

Условия маркетплейсов, как правило, запрещают неофициальный парсинг. Коннекторы обращаются только к публичным эндпоинтам каталога, которые использует официальный веб-клиент. В приватные и административные разделы запросов нет. Уровень Ozon с браузером работает внутри сессии, которую вы открыли сами. Используйте на своё усмотрение, для личных исследований, в вежливом темпе запросов. Пауза между вызовами к площадкам с анти-ботом — это часть конструкции, а не случайное торможение: её не нужно убирать ради скорости. Данные инструментов не предназначены для перепродажи или массового сбора.

Как это сделано

Код и документацию я писал вместе с ИИ-ассистентами. Они работают быстро и ошибаются уверенно, поэтому проект устроен вокруг проверки: 1212 офлайн-тестов, аудит перед выпуском, тесты, которые прогоняют настоящий экстрактор по снятой с сайта разметке. В заметках к релизу перечислено, какие источники сверены с живыми страницами вручную и какие остались непроверенными.

Вопрос «кто набрал текст» кажется мне менее интересным, чем вопрос «чем это проверено». Второй здесь задокументирован, и проверить его может любой.

Спасибо

@Xpos587 — коннектор MPStats (PR #5): разбор API плагина, структура парсеров и первая рабочая версия.

Лицензия

MIT, файл LICENSE.


English version

MCP servers for Russian and Chinese marketplaces. Read prices, stock, ratings, reviews and seller identity from Wildberries, Ozon, Yandex Market, Detsky Mir, Avito, AliExpress, Taobao, Megamarket, Lamoda, DNS and Citilink, then compare prices across all of them in one call. Taobao and AliExpress are the Chinese ones; the other nine are Russian.

Read-only. No credentials, no API keys, no account required — the marketplaces with hard anti-bot are read through your own Chrome. One optional exception: MPStats takes a paid account token (MPSTATS_MP_AUTH) if you want its analytics; without it every other server is unaffected.

What you get

Server

Tools

What it takes to read

Notes

Wildberries

8

anonymous HTTP

Search, cards, reviews, buyer questions, seller legal identity, catalog tree and category listings

Yandex Market

2

anonymous HTTP

Multi-seller prices, star distribution, reviews

Detsky Mir

3

anonymous HTTP

Kids' goods, offline store stock, category listings

Ozon

3

your Chrome; often no browser from a residential IP

Search, cards, reviews

Avito

3

your Chrome + a Russian residential IP and spaced requests — else an IP block

Classified search, cards, seller reputation

Taobao

2

your Chrome with an active Taobao login

Search and cards, prices in yuan

Megamarket

2

your Chrome with an active login — an anonymous session reads empty

Search and cards via the mobile API

Lamoda

2

cards anonymous (GraphQL), search via your Chrome

Search, cards with sizes

DNS

2

your Chrome (Qrator)

Electronics search and cards

Citilink

2

your Chrome (Qrator)

Electronics search and cards

AliExpress

2

your Chrome (x5sec)

Search and cards, ruble prices

Compare

2

aggregates the above

"Where is this cheapest?" in one call

MPStats

2

paid MPStats account, mp_auth cookie (optional)

30-day sales/stock graphs per Ozon/WB SKU, warehouse split (FBS/FBO)

Anonymous, no browser: Wildberries, Yandex Market, Detsky Mir and Lamoda cards. The rest need your logged-in Chrome (CDP). Taobao and Megamarket additionally need you signed into the marketplace itself — without it Taobao hits a login wall and Megamarket returns an empty result. Avito also blocks by IP: from a datacenter address it is a flat refusal, from a Russian residential one it works as long as you do not burst requests. Requests to the CDP sources are paced apart — a run of back-to-back calls degrades them (DNS and Taobao both dropped that way in testing), so the connectors hold a gap between calls themselves. Run marketplace-mcp doctor from your own session for the current state.

MPStats stands apart as the only paid source: without MPSTATS_MP_AUTH the server boots but its tools answer auth_missing. It is therefore optional — plug it in if you have an account; the other thirteen servers never notice.

35 tools across 13 stdio MCP servers, sharing one runtime (mcp-core), plus the unified marketplace-mcp that mounts them all under one client entry. It adds its own marketplace_sources tool — which connectors mounted, and which dropped out and why — so it exposes 36 tools: the 35 mounted plus that one. stdio is the default; HTTP transport is opt-in for remote deployment — see docs/DEPLOYMENT.md.

Quickstart

Requires Python 3.12+ and uv.

git clone https://github.com/Vladimir-Human/ru-marketplace-mcp.git
cd ru-marketplace-mcp
uv sync --all-packages
uv run pytest -q -m "not live and not cdp"    # 1212 offline tests, no network needed

Client configuration mirrors the Russian section above. Each server is a console script (wb-mcp, ozon-mcp, yandex-mcp, detmir-mcp, aliexpress-mcp, compare-mcp) launched through uv run --directory /path/to/repo <script>. The optional mpstats-mcp runs the same way with MPSTATS_MP_AUTH in the entry's env (paid MPStats account; without it the tools return auth_missing). marketplace-mcp install [claude|claude-code|cursor|dsh] prints the block with your checkout's real path filled in — no placeholder to hand-edit — or the console-script paths on PATH when installed as a wheel; an unknown client name is rejected. The dsh target prints a cordis.patch.yml row instead of mcpServers JSON — see dsh/README.md.

DeepSeek Harness (dsh) installs as a plugin bundle rather than an mcpServers entry, from the dsh/ subdirectory (pnpm must be on PATH):

dsh plugin --profile web add github:Vladimir-Human/ru-marketplace-mcp#path:/dsh

That gives you 14 skills immediately and no MCP tools: both MCP rows stay disabled until RU_MARKETPLACE_MCP_DIR points at a clone. A mounted server is paid on every request — ~0.9k tokens for the recommended price-comparison mode, ~13.6k for the full set — so opting in is left to you. dsh/README.md covers enabling it and the full mode.

After connecting, run marketplace-mcp doctor. It runs every connector's canary and reports success, drift_detected, or inconclusive for each.

The tools

The *_selfcheck canaries are deliberately absent from these tables: they are not published over MCP, because operator diagnostics would cost the model ~7.5k tokens on every request. marketplace-mcp doctor runs them all from the command line.

Wildberries — wb_*

Tool

What it does

wb_search(query, page)

Text search, up to 100 products/page with prices and stock

wb_card(nm_ids)

Batch lookup for up to 100 known SKUs

wb_root_info(nm_id)

Resolves imt_id (needed for reviews) plus colour variants

wb_reviews(imt_id, limit, sort)

Review pool, keyed by imt_id, not nm_id

wb_questions(imt_id, limit, skip, answered_only)

Buyer questions with seller answers, also keyed by imt_id

wb_seller(supplier_id)

Registered entity, INN, KPP, OGRN, legal address

wb_categories(root, max_depth)

Catalog tree with WB's own shard/query selectors

wb_category_products(shard, query, page, sort, dest)

Products in a category, using those selectors

wb_seller answers the question a listing hides: who actually ships this? It returns the registered legal entity and tax ids, which is how you distinguish an official brand store from a reseller trading under a lookalike name.

wb_questions covers a different gap. Reviews describe what owning the product is like; questions clarify what it actually is — "10A or 16A?", "is the cable included?" — and the seller's reply is often the only public statement of that fact. One pool per imt_id, shared across every variant.

wb_category_products closes the loop wb_categories opens: that tool hands back WB's shard and query, and this one fetches the products behind them. Items use the same shape as wb_search, so a category walk and a text search are directly comparable. Several of WB's largest sections carry the shard blackhole and have no feed at all; the tool says so instead of returning an empty list.

Yandex Market — yandex_*

Tool

What it does

yandex_search(query, page, limit)

Search with both prices, ratings, sellers

yandex_card(product_id, include_reviews)

Full detail plus star breakdown and reviews

Two prices, always. price_rub is what anyone pays. price_with_plus needs a paid Yandex Plus subscription and runs 25–30% lower. Yandex leads with the subscriber price, so quoting it uncritically misstates the real cost.

rating_stars gives the distribution, for example {1: 10, 2: 3, 3: 10, 4: 19, 5: 502}. That reveals whether a 4.8 average is earned or hides a cluster of complaints.

Detsky Mir — detmir_*

Tool

What it does

detmir_categories(parent, limit, region)

Catalog tree, start here

detmir_category(alias, limit, offset, region)

Products in a category, with real totals

detmir_card(product_id, region)

Price, rating, online and offline store stock

Region is per call. Prices and especially offline availability swing by city — one item sat in 152 Moscow stores, 37 in St Petersburg, 2 in Khabarovsk. The region parameter overrides DETMIR_REGION, so one session can compare cities.

There is no text search, deliberately. Detsky Mir's API silently ignores every text filter and returns its entire 300k-item catalog; the website's search route answers 404 and renders a promo carousel. A search tool would return confidently wrong products, so discovery goes through categories instead. See docs/ANTI_BOT.md.

Ozon — ozon_*

Tool

What it does

ozon_search(query)

Text search

ozon_card(sku_or_path)

Product detail

ozon_reviews(sku_or_path, limit, sort)

Reviews

Ozon rejects datacenter traffic, so this connector is two-tier: TLS impersonation first, then a fetch inside your own logged-in Chrome over the DevTools Protocol when Cloudflare challenges. Nothing is stored; you log in yourself, in a browser you control. Setup: docs/CDP_SETUP.md.

From a Russian residential IP the first tier usually works and no browser is needed.

Ozon pools reviews per card family, and the neighbours are often a different product from a different brand. A live card for a 1500 W Huter oil heater (SKU 5264146973, rated 4.8 across 356 reviews) returned 100 reviews of which zero were about the Huter: 38 about a 2000 W Resanta, 34 about a 1500 W Resanta, 5 about a Eurolux — 12 products in that pool. So every review carries item_id, the SKU it is actually about, and the response adds requested_item_id, own_reviews (how many returned reviews really are about that SKU) and pool_variants (SKU → name for the whole pool). rating_score and distribution are pool-wide, not per product: filter by item_id before concluding anything, and when own_reviews is 0, say plainly that the product has no reviews of its own.

AliExpress — aliexpress_*

Tool

What it does

aliexpress_search(query)

Search: up to 48 tiles with ruble prices

aliexpress_card(item_id_or_url)

Card: title, price, rating, order count

Read through your Chrome (CDP): x5sec challenges anonymous clients, so the connector lands on a search page (never challenged) and opens the card in a new tab from it. Prices are rubles and rank in compare_prices. A card with a title but no price is a known state — under load x5sec stops serving the price module and the connector reports price_missing rather than inventing a number. A "with coupon" price never lands in price_rub: the regular price does, and the coupon is reported as a warning. Review texts are not exposed; rating and order counts are. As with every CDP source, a green aliexpress_selfcheck proves the transport answered — not that a given price is right.

Avito — avito_*

Tool

What it does

avito_search(query, page, location_id, category_id)

Classified search through the internal js/items API

avito_card(item_id_or_url)

One listing: price, description, views, seller

avito_seller(seller_id_or_url)

Seller rating, review count, active listings

Avito is classifieds, not a catalog: there is no per-product review pool, the seller's reputation IS the trust signal. A free/swap listing arrives with price_rub: null — never 0, so it cannot win "cheapest". From a datacenter IP Avito answers a 403 firewall, hence the two-tier transport: TLS impersonation first, then your Chrome, exactly like Ozon.

Taobao — taobao_*

Tool

What it does

taobao_search(query, page)

Catalog search

taobao_card(item_id_or_url)

Product card

Taobao search is a signed-mtop React app: every request needs a sign derived from a cookie token, so there is no anonymous path. All reads run inside your Chrome, where the site signs its own requests. Prices stay in yuan (CNY) and are never converted — a baked-in rate quietly goes stale, so compare ruble and yuan listings explicitly.

These four read through your Chrome (CDP). Megamarket (megamarket_*) goes through the mobile JSON API behind ServicePipe and needs an active login — an anonymous session reads empty. DNS (dns_*) and Citilink (citilink_*) render DOM behind Qrator with no anonymous path at all. Lamoda (lamoda_*) is split: cards over anonymous GraphQL, search through Chrome. All of them need Chrome with CDP (scripts/start_chrome_cdp.sh), except Lamoda cards. Eight sources run through CDP in total: these plus Taobao, AliExpress, Ozon and Avito, where Chrome is only the fallback tier when the anonymous one is challenged.

Cross-marketplace — compare_*

Tool

What it does

compare_prices(query, per_source_limit, sources)

Every marketplace at once, ranked

compare_sources()

Which marketplaces this install can query

compare_prices("кроссовки мужские")

  wildberries      712 RUB   Кроссовки изи дышащие спортивные
  wildberries      814 RUB   Зимние кроссовки теплые с мехом
  yandex_market   2499 RUB   Кеды A-LOW
  yandex_market   3480 RUB   Кеды

  cheapest: wildberries 712 RUB, spread 5858 RUB, complete: true

Sources are queried concurrently and each reports its own outcome. One marketplace being blocked never sinks the comparison: complete: false plus source_outcomes tells you exactly what you are looking at. Subscription prices never win the ranking. Offers matching on (source, product id) are collapsed, so one listing can no longer take two ranking slots.

Every offer carries currency (lowercase ISO code, default rub) and price_native, the price in that currency as the marketplace quotes it. For Russian sources it mirrors price_rub; for Taobao it holds the yuan price that price_rub deliberately leaves null. That yuan price used to be fetched and silently thrown away, so a Taobao row showed a blank price with no sign a real one existed. Now the yuan is reported but still never ranked against roubles: a foreign_currency: … warning lists how many offers were excluded and why. Converting here would bake in an exchange rate that goes stale silently, so the caller converts if they want to.

MPStats — mpstats_*

Sales and stock analytics per Ozon or Wildberries SKU via the MPStats browser plugin. Unlike every other connector, this one is optional and needs a paid MPStats account: auth is a single mp_auth cookie (JWT from a logged-in plugin session at mpstats.io), set via the MPSTATS_MP_AUTH env var. Without it the tools return auth_missing while the server boots normally — nothing else is affected.

Tool

What it does

mpstats_item(skus, place, oz_fbs=True)

30-day analytics for up to 100 SKUs: orders, price, stock, per-day graphs, seller/brand

mpstats_warehouses(skus, place)

Warehouse split: FBS (seller's warehouse) vs FBO (marketplace warehouse), last_update

place is ozon or wildberries. Graphs are length 30, oldest first: the last non-zero cell is the current price or stock. The two differ on purpose when the whole graph is zero: price becomes None (a false 0 would win any "cheapest" comparison), while stock becomes 0, because "none in stock" is a real reading rather than an absence of data. An empty graph yields None for both. A zero cell means "no data for that day", not "the value was zero", so sum the graph for a window total. A missing token or a transport failure reports as inconclusive, not drift — no chasing a schema drift that never happened. The token is a secret on a paid, quota-billed account: never log or commit it.

Agent skills

Every connector ships its own skill under skills/ — fourteen of them — one per source plus a shared marketplace overview. A skill is not a restatement of this README: it tells the agent when to reach for that source at all, what the source does not have, and which of its answers should not be trusted without a second look.

Skill

Server

skills/wb-connector

wb-mcp

skills/ozon-connector

ozon-mcp

skills/yandex-connector

yandex-mcp

skills/detmir-connector

detmir-mcp

skills/avito-connector

avito-mcp

skills/taobao-connector

taobao-mcp

skills/megamarket-connector

megamarket-mcp

skills/lamoda-connector

lamoda-mcp

skills/dns-connector

dns-mcp

skills/citilink-connector

citilink-mcp

skills/aliexpress-connector

aliexpress-mcp

skills/compare-prices

compare-mcp

skills/mpstats-connector

mpstats-mcp

skills/marketplace

marketplace-mcp

mcp-core is the shared runtime rather than a server, so it has no skill.

The mapping is enforced by a test (packages/marketplace-connector/tests/test_skills_parity.py): a new connector without a skill fails the run, and so does a skill that names a tool which does not exist — or omits one that does. Before that test existed, the DNS skill spent months telling operators to pass /product/<24-hex>/, the exact pattern a fix had already removed.

Skills are copied into the Docker image (/app/skills/), but they are not in the wheels: skills/ lives at the repository root rather than inside the packages. Installing from PyPI means fetching the skills from the repo separately.

Configuration

Every setting is an environment variable with a per-connector prefix. All optional.

Prefix

Common knobs

WB_

TIMEOUT, MIN_GAP, DEFAULT_DEST, NET_RETRIES, MAX_BODY_BYTES, CACHE_TTL, PROXY

YANDEX_

TIMEOUT, MIN_GAP, CACHE_TTL, PROXY

DETMIR_

REGION (RU-MOW, RU-SPE, and others), CACHE_TTL, PROXY

OZON_

TIMEOUT, MIN_GAP, IMPERSONATE, CACHE_TTL, PROXY

AVITO_

TIMEOUT, MIN_GAP, IMPERSONATE, CACHE_TTL, PROXY, LOCATION_ID

TAOBAO_

TIMEOUT, MIN_GAP, CACHE_TTL,

ALI_

TIMEOUT, MIN_GAP, CACHE_TTL

MEGAMARKET_

TIMEOUT, MIN_GAP, CACHE_TTL

LAMODA_

TIMEOUT, MIN_GAP, CACHE_TTL, PROXY

DNS_ / CITILINK_

TIMEOUT, MIN_GAP, CACHE_TTL

CHROME_

CDP_HOST, CDP_PORT, SCRAPING_PROFILE, BINARY, HEADLESS, STEALTH

COMPARE_

SOURCE_TIMEOUT

MPSTATS_

MP_AUTH (the only required one — without it the tools return auth_missing), TIMEOUT, MIN_GAP, CACHE_TTL, PROXY

MCP_

TRANSPORT (stdio default, or http), HTTP_HOST, HTTP_PORT

*_CACHE_TTL=0 disables caching. *_PROXY overrides the standard HTTPS_PROXY/ALL_PROXY — seven connectors carry one: WB_, YANDEX_, DETMIR_, OZON_, AVITO_, LAMODA_ and MPSTATS_. Taobao has none by design and Megamarket, DNS and Citilink none either: their traffic goes through your own Chrome, whose egress is that browser's configuration. Only successful reads are cached: remembering a failure would stretch a one-second blip across the whole TTL window.

Ozon's proxy applies to tier 1. Tier 2 runs inside your own Chrome, whose egress is that browser's configuration, not ours.

Containers. CHROME_CDP_HOST points the CDP client at Chrome (default 127.0.0.1; use chrome or host.docker.internal inside Docker). That single variable is what opens the tier-2 sources — Ozon, Avito, Taobao, Megamarket, Lamoda, DNS, Citilink and AliExpress — from a container without host networking. See docs/DEPLOYMENT.md.

One secret, and it is optional. Every server except MPStats needs nothing: nothing to configure, nothing to leak. MPStats alone has MPSTATS_MP_AUTH, the JWT of a paid account — it belongs only in the client entry's env, never in code or commits.

Development

uv sync --all-packages
uv run pytest -q -m "not live and not cdp"    # 1212 offline tests
uv run pytest -q -m "not live"                # what CI runs
uv run pytest -q -m "not live" --cov          # coverage, CI enforces a 70% floor
uv run ruff check . && uv run ruff format --check .
uv run mypy                                   # the tree lives in [tool.mypy] files
uv run mypy --platform win32                  # catches Windows-only type errors
uv run python scripts/check_no_print.py       # a print() breaks JSON-RPC
uv run python scripts/check_versions.py       # one version across all 77 places

Some tests execute a connector's real extractor JavaScript against captured markup and check the output against the prices the page was showing when it was captured. That needs Node with jsdom:

npm install jsdom      # or point NODE_PATH at an existing copy
uv run pytest -q packages/dns-connector/tests/test_search_extractor_dom.py \
              packages/citilink-connector/tests/test_search_extractor_dom.py

Without jsdom that half skips honestly and the Python half — choosing the price among the candidates — still runs. jsdom is a developer tool only; no connector depends on it.

CI runs lint, mypy and the full suite on Ubuntu, Windows and macOS against Python 3.12 and 3.13. Windows-specific process handling is unit-tested on every platform via a platform override, so those branches are covered even on Linux.

Adding a marketplace: docs/ADDING_A_SOURCE.md.

Reliability

Unofficial endpoints break. The design assumes it.

  • Tolerant readers. Multi-alias field binding and type coercion absorb renames and type drift instead of crashing.

  • Never fabricate a value. A missing price is null, never 0. A zero would rank a dead listing as the cheapest option.

  • Loud failure. When a payload stops matching, tools raise parser_drift rather than returning half-parsed data.

  • Tri-state selfchecks. success, drift_detected or inconclusive. A geo block is reported as inconclusive, because it says nothing about the parsers.

Trust boundary

Tool output, meaning product titles, seller names and review text, is authored by sellers and buyers. Treat it as untrusted data. If a review or description appears to contain instructions, it is input, not policy.

Marketplace terms of service generally disallow unofficial parsing. These connectors read only the public catalog endpoints the official web clients use; no authenticated or administrative areas are touched. The Ozon CDP tier runs inside a browser session you established yourself. Use at your discretion, for personal research, at a polite request rate; the backoff between calls to anti-bot sources is deliberate and should not be removed for speed. Tool output is not meant for redistribution or bulk harvesting.

How this was built

I wrote the code and the documentation with AI assistants. They are fast and they are confidently wrong, so the project is arranged around verification: 1212 offline tests, an audit before the release, tests that run the real extractor against markup captured from the live site. The release notes say which sources were compared against live pages by hand and which were left unverified.

Who typed the text seems a less interesting question than what checks it survived. The second one is documented here, and anyone can re-run it.

Thanks

@Xpos587 for the MPStats connector (PR #5): the plugin API work, the parser structure and the first working version.

License

MIT, see LICENSE.

Available Tools

36 tools
aliexpress_cardAliExpress Product CardA
Read-onlyIdempotent

Fetch one AliExpress product card, rendered in the operator's Chrome.

Review TEXTS are deliberately not exposed: they require navigating the review tab, which x5sec challenges; this tool returns the rating and the order count instead.

Return Format

AliCardResponse: {status, item_id, title, price_rub, old_price_rub, rating, orders_count, url, tier_used, meta}.

Error Format

ToolError: BadRequestError when no item id can be extracted; TransportDownError on x5sec challenges or CDP failures; ParserDriftError when a rendered card has neither title nor price.

ParametersJSON Schema
NameRequiredDescriptionDefault
item_id_or_urlYesAliExpress item id (9-16 digits) or aliexpress.ru item URL, e.g. /item/1005010003103368.html

Output Schema

ParametersJSON Schema
NameRequiredDescription
urlNo
_metaNo
titleNo
ratingNo
statusNo
item_idNo
price_rubNo
tier_usedNo
orders_countNo
old_price_rubNo

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare read-only, idempotent, and non-destructive behavior. The description adds critical operational context: it renders in the operator's Chrome, may face x5sec challenges (causing TransportDownError), and lists specific error types (BadRequestError, ParserDriftError). This goes well beyond annotations and helps agents anticipate failure modes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with clear sections for return and error formats. It balances necessary caveats (review text limitation) and technical details without being excessively verbose. Each sentence contributes to operational clarity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool that interacts with an external site and may encounter challenges, the description covers all essential aspects: purpose, limitations, error handling, and return structure. The output schema exists, so not explaining return fields in detail is acceptable; the description adds extra value beyond structured data.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with a detailed description of the item_id_or_url parameter including format and example. The description does not add extra semantics beyond what the schema already provides, but given the high coverage, this is sufficient.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Fetch one AliExpress product card', specifying the verb, resource, and platform, which distinguishes it from sibling card tools for other marketplaces. It also explicitly mentions that review texts are not exposed, clarifying the scope beyond a generic product fetch.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implicitly guides usage by explaining that review texts are deliberately not returned due to x5sec challenges, implying this tool is for basic product info rather than reviews. While it doesn't name alternative tools, the context is clear enough to differentiate from review-focused siblings like wb_reviews or ozon_reviews.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

avito_cardAvito Item CardA
Read-onlyIdempotent

Fetch one Avito listing by id or URL.

Return Format

AvitoCardResponse: {status, item_id, title, price_rub, description, location, posted_at, views, images, seller, url, tier_used, meta}. price_rub is None when the ad has no price — never 0.

Error Format

ToolError: BadRequestError when no id can be extracted; NotFoundError on a 404 (deleted or never existed); TransportDownError on blocks; ParserDriftError when the envelope changed.

ParametersJSON Schema
NameRequiredDescriptionDefault
item_id_or_urlYesItem id, slug path or full avito.ru URL

Output Schema

ParametersJSON Schema
NameRequiredDescription
urlNo
_metaNo
titleNo
viewsNo
imagesNo
sellerNo
statusNo
item_idNo
locationNo
posted_atNo
price_rubNo
tier_usedNo
descriptionNo

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes beyond the annotations (readOnlyHint, idempotentHint) by detailing the exact error format and conditions (BadRequestError, NotFoundError, TransportDownError, ParserDriftError). It also clarifies an important behavioral nuance: price_rub is None when the ad has no price, never 0. This adds valuable context for handling tool results correctly.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and well-structured, with a one-sentence summary followed by clearly labeled 'Return Format' and 'Error Format' sections. Every detail earns its place, giving the agent precise information without unnecessary verbosity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple single-parameter fetch tool, the description covers all essential aspects: what it does, the exact structure of the response, and all expected error types. The annotations and output schema fill in the remaining details, making this description complete for the tool's complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already fully documents the single parameter item_id_or_url with a clear description ('Item id, slug path or full avito.ru URL'), so the schema carries the heavy lifting. The tool description's 'by id or URL' adds no extra meaning beyond the schema; the return-format details are about output, not parameters. Thus, a baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's action ('Fetch one Avito listing') and its input scope ('by id or URL'). This distinguishes it from sibling tools like avito_search (which searches multiple listings) and avito_seller (which fetches seller data), making the purpose explicit and distinct.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context that this tool is for retrieving a single, specific listing when an id or URL is available. It doesn't explicitly name alternatives or state when not to use it, but the intent is unambiguous enough to guide an agent without additional exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

avito_sellerAvito Seller ProfileA
Read-onlyIdempotent

Fetch an Avito seller profile — reputation is the review signal here.

Classifieds have no per-item review pool; the seller's rating, review count and active-listing count are what a buyer checks.

Return Format

AvitoSellerResponse: {status, seller, active_items, tier_used, meta}.

Error Format

ToolError: BadRequestError on empty input; NotFoundError on 404; TransportDownError on blocks; ParserDriftError on envelope drift.

ParametersJSON Schema
NameRequiredDescriptionDefault
seller_id_or_urlYesSeller id or profile URL from a card/search hit

Output Schema

ParametersJSON Schema
NameRequiredDescription
_metaNo
sellerNo
statusNo
tier_usedNo
active_itemsNo

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare the tool as read-only, idempotent, and open-world. The description adds valuable behavioral context beyond these: specific error conditions (empty input, 404, transport blocks, parser drift) and the return envelope structure. This goes beyond what annotations provide, giving an agent clarity on failure modes and output shape.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is efficiently structured with clear sections for purpose, return format, and error format. Every sentence contributes meaningful information without fluff. It is slightly longer than the bare minimum but justified by the niche context and error details, making it easy to scan.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's low complexity (one parameter, read-only, output schema present), the description is complete. It covers the purpose, the data content (rating, review count, active listings), the return envelope, and all error cases. The presence of an output schema reduces the need to describe return values in detail, and the description still adds contextual clarity about why this data matters.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The single parameter seller_id_or_url is already fully documented in the input schema with 'Seller id or profile URL from a card/search hit' (100% coverage). The description does not add any additional meaning about the parameter beyond what the schema provides, so it hits the baseline of 3 for adequate schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Fetch an Avito seller profile' and explains what the profile contains (rating, review count, active-listing count). It distinguishes this from per-item review tools by noting that classifieds have no per-item review pool, making the seller profile the definitive reputation signal. This separates it from avito_card and avito_search.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides strong contextual guidance: it explains that in classifieds, the seller's reputation is what buyers check, implying this tool should be used when evaluating a seller's trustworthiness rather than item reviews. However, it does not explicitly name alternative tools or state 'use this when you need seller reputation, not item details,' which would make the guidance more prescriptive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

compare_pricesCompare Prices Across Russian MarketplacesA
Read-onlyIdempotent

Price one product across every configured Russian marketplace at once.

Queries each marketplace concurrently and returns a single list ranked by price, plus a per-source report of what answered and what did not. This is the tool for "where is X cheapest" — running the per-marketplace search tools one at a time gives the same data far more slowly and without the ranking.

Two things to read carefully in the output:

  • cheapest is chosen on everyday prices. Yandex Market's subscriber price appears as price_with_subscription_rub and is deliberately excluded from ranking, since it requires a paid Yandex Plus subscription.

  • source_outcomes shows which marketplaces answered. A blocked or timed-out source means the comparison is partial, not that the product is absent there — complete tells you which case you are in.

Titles are matched loosely: marketplaces name things differently, so scan the results rather than assuming every row is the identical model.

Return Format

CompareResponse: {query, sources_queried, sources_ok, complete, total_offers, cheapest, price_spread_rub, offers, source_outcomes, warnings, server_version}. offers is ranked by everyday price_rub — cheapest first, offers without a rouble price after the ranked ones. warnings carries validation/completeness warnings.

Error Format

On validation failure, raises ToolError with a JSON message describing the error code and whether it is retryable. Individual source failures do NOT raise — they are reported in source_outcomes.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesWhat to price, in Russian — e.g. 'стиральная машина узкая' or 'iphone 15 128'.
sourcesNoRestrict to specific marketplaces (wildberries, yandex_market, ozon). Omit to query all.
per_source_limitNoHow many offers to take from each marketplace.

Output Schema

ParametersJSON Schema
NameRequiredDescription
queryNo
offersNo
cheapestNo
completeNo
warningsNo
sources_okNo
total_offersNo
server_versionNo
source_outcomesNo
sources_queriedNo
price_spread_rubNo

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already set readOnlyHint, openWorldHint, idempotentHint, and destructiveHint, but the description adds substantial context beyond that: cheapest excludes Yandex subscription price, source_outcomes indicates partial results, titles are matched loosely, and individual source failures do not raise errors. This is exactly the kind of behavior an agent needs to interpret output correctly.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but every section earns its place: clear purpose, explicit usage guidance, two important output caveats, a note on matching behavior, and structured return/error format. It is front-loaded with the essential purpose and uses formatting (sections, em-dashes) to make scanning easy. No filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with three parameters, complex behavior (concurrent queries, partial failures, subscription prices), and a rich output schema, this description covers all necessary aspects: what it does, when to use it, how to interpret results, what the return structure looks like, and how errors are handled. It is complete enough for an agent to invoke and use the results correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema covers all parameters with descriptions, so the baseline is 3. The description adds some relevant context about loose title matching and 'in Russian' for the query parameter, but it does not significantly extend the schema's parameter explanations. It meets the baseline without exceeding it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Price one product across every configured Russian marketplace at once.' It clearly distinguishes itself from per-marketplace search tools by emphasizing the concurrent comparison and ranking, so an agent immediately knows what this tool uniquely does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use this tool: 'This is the tool for "where is X cheapest"' and contrasts it with the slower alternative of running per-marketplace search tools one at a time. It also implicitly tells the agent when NOT to use it (when you need a single marketplace's detailed results, use those sibling tools).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

compare_sourcesList Available MarketplacesA
Read-onlyIdempotent

Report which marketplaces this installation can actually query.

Call this first when a comparison comes back partial: it distinguishes "the connector isn't installed" from "the marketplace refused us", which need completely different fixes.

Return Format

Plain object: {installed, searchable, not_installed, notes, source_timeout_s, server_version, server_started_at, process_id}. notes explains per-source access quirks (CDP-only sources, currencies, missing text search).

Error Format

Never raises ToolError: pure introspection of which connector packages are installed — nothing here touches the network.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, etc., but the description adds substantial behavioral context beyond that: it never raises ToolError, performs pure introspection, touches no network, and documents the return format including server metadata and per-source notes. This gives the agent a full picture of what the tool does and what to expect.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with clear headings for purpose, return format, and error format. Every sentence provides useful information — no filler. The use of bullet-like examples and plain object field listing keeps it compact while being fully informative.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no parameters, an output schema, and a clear diagnostic role, the description is complete. It explains return format, error behavior, and usage context. There are no missing pieces that would leave an agent uncertain about invocation or interpretation of results.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so there is no parameter semantics to clarify. Per the baseline, a 0-parameter tool with full schema coverage earns a 4; the description adds value by explaining the return structure, which compensates for the lack of parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Report which marketplaces this installation can actually query' — a specific verb and resource that clearly states the tool's function. It also distinguishes this from sibling marketplace tools by framing it as a diagnostic first call for partial comparison results, which uniquely positions it among the sibling list.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use it: 'Call this first when a comparison comes back partial' and explains the key distinction between 'connector isn't installed' and 'marketplace refused us', which require different fixes. This directly answers when and why to use this tool versus alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

detmir_cardDetsky Mir Product CardA
Read-onlyIdempotent

Fetch price, rating, stock and seller for one Detsky Mir product.

Covers the kids-and-baby category that the general marketplaces cover unevenly, and distinguishes Detsky Mir's own stock from third-party marketplace sellers.

Region matters most here. store_count is the number of physical shops holding the item, and it swings hard by city — one item verified live sat in 152 Moscow stores, 37 in St Petersburg, 2 in Khabarovsk. Pass region to ask about a specific city; it overrides DETMIR_REGION for this call only, so one session can compare cities.

Return Format

DetmirCardResponse: {product, region, meta}. product carries product_id, title, article, brand, price_rub (None when absent — never 0), old_price_rub, discount_percent, rating, review_count, questions_count, availability, available_online, available_offline, store_count, is_marketplace, vendor, url, picture.

Error Format

On validation or transport/parse failure, raises ToolError with a JSON message describing the error code and whether it is retryable.

ParametersJSON Schema
NameRequiredDescriptionDefault
regionNoISO region code for prices and offline stock, e.g. 'RU-MOW' or 'RU-SPE'. Defaults to DETMIR_REGION.
product_idYesNumeric Detsky Mir product id — the digits in /product/index/id/<id>/.

Output Schema

ParametersJSON Schema
NameRequiredDescription
metaNo
regionNo
productNo

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations establish read-only and idempotent behavior, so the description correctly focuses on additional behavioral traits: region override semantics ('overrides DETMIR_REGION for this call only'), store_count's dependence on city, and the price_rub representation (None, never 0). It also discloses the error format, going beyond annotation hints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well-structured with front-loaded purpose, bolded sections for return and error formats, and each sentence provides distinct information. Despite length, nothing seems superfluous.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has rich annotations, a complete input schema, and an output schema. The description additionally explains the most important operational nuance (region-dependent store_count) and error behavior, making the tool fully invokable without further research.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already provides full descriptions for both parameters (product_id with URL example, region with default). The description adds behavioral context about how region affects store_count and the session-level override, which helps the agent choose values, but does not add new syntactic detail.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Fetch price, rating, stock and seller for one Detsky Mir product,' a specific verb+resource that clearly distinguishes this from sibling card tools for other marketplaces. It further differentiates by noting its coverage of the kids-and-baby category and its ability to distinguish Detsky Mir's own stock from marketplace sellers.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly implies this is for querying Detsky Mir product details, and contrasts with general marketplaces ('covers the kids-and-baby category that the general marketplaces cover unevenly'). However, it does not explicitly name alternative tools or provide exclusion criteria, so it falls short of full usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

detmir_categoriesDetsky Mir Catalog CategoriesA
Read-onlyIdempotent

Browse the Detsky Mir catalog tree and get the aliases detmir_category needs.

This is the discovery step: Detsky Mir has no working text search (see the module docstring), so the way to find products is to walk the tree and then list a category. Each node carries its alias and a products_count, so you can see where the inventory actually is before fetching a listing.

Return Format

DetmirCategoriesResponse: {parent, returned, total_available, items, region, meta}. Items carry category_id, alias, title, full_name, level, products_count, parent_id, url; alias is what detmir_category needs to list a category.

Error Format

On validation or transport/parse failure, raises ToolError with a JSON message describing the error code and whether it is retryable.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum categories to return.
parentNo'top' for the 27 top-level sections, or a parent category id to list its children.top
regionNoISO region code for prices and offline stock, e.g. 'RU-MOW' or 'RU-SPE'. Defaults to DETMIR_REGION.

Output Schema

ParametersJSON Schema
NameRequiredDescription
metaNo
itemsNo
parentNo
regionNo
returnedNo
total_availableNo

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is clear. The description adds value by explaining that each node carries products_count to assess inventory before fetching, and by disclosing the error format including retryability. It does not add rate limits or other potential side effects, but the existing disclosures are solid and no contradiction exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with headers for overview, return format, and error format. It is informative without being bloated; each section serves a purpose. The module docstring reference is slightly tangential but useful context. Overall, it is efficient and easy to scan.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the tool's role in the workflow, why it exists (no text search), what the return format looks like, and how errors are surfaced. Since an output schema is present, it need not explain each field; the description provides enough context for an agent to select and invoke the tool correctly in most situations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema covers all three parameters (limit, parent, region) with descriptive comments, so schema coverage is 100%. The description does not add new semantic information about these parameters beyond what the schema already provides. It does contextualize the returned alias for detmir_category, but that is about output, not parameter meaning. Thus baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb+resource+outcome: 'Browse the Detsky Mir catalog tree and get the aliases detmir_category needs.' It clearly distinguishes from the sibling detmir_category by positioning this as the discovery step, and mentions the catalog tree and aliases, leaving no ambiguity about what the tool does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context: 'This is the discovery step' and explains that Detsky Mir has no working text search, so walking the tree is the way to find products. It even names the dependent sibling (detmir_category) and how the output feeds into it. It does not explicitly state when not to use the tool, but the context is strong enough that an agent can infer appropriate usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

detmir_categoryDetsky Mir Category ListingA
Read-onlyIdempotent

List products in a Detsky Mir category, with the total match count.

This is the reliable way to enumerate the catalog: unlike text search, it is a real JSON endpoint with proper pagination and an upstream total, so it supports "what's available and how much does it cost" without scraping.

Return Format

DetmirListResponse: {query, mode, total_available, category_title, returned, offset, items, region, meta}. Items carry the same product shape as detmir_card. An empty page is NOT an error — it is reported via meta.warnings.

Error Format

On validation or transport/parse failure, raises ToolError with a JSON message describing the error code and whether it is retryable.

ParametersJSON Schema
NameRequiredDescriptionDefault
aliasYesCategory slug from a catalog URL, e.g. 'pups' in /catalog/index/name/pups/.
limitNoItems per page.
offsetNoItems to skip, for pagination.
regionNoISO region code for prices and offline stock, e.g. 'RU-MOW' or 'RU-SPE'. Defaults to DETMIR_REGION.

Output Schema

ParametersJSON Schema
NameRequiredDescription
metaNo
modeNo
itemsNo
queryNo
offsetNo
regionNo
returnedNo
category_titleNo
total_availableNo

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, openWorldHint=true, idempotentHint=true, and destructiveHint=false. The description adds valuable context beyond these: it is a 'real JSON endpoint with proper pagination and an upstream total', empty pages are reported via meta.warnings, and error format includes retryable indication. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with a clear purpose statement, a 'why' paragraph, and dedicated Return Format / Error Format sections. Every sentence adds value; it is detailed without being bloated. It is front-loaded with the core action.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with pagination, region handling, and error reporting, the description covers all essentials: return format with key fields, relationship to detmir_card, empty-page behavior, and error format with retryable indicator. An output schema exists, so the description does not need to enumerate every field, but it provides enough context for correct usage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Input schema has 100% description coverage for all four parameters, so the schema already documents each parameter. The description adds only minor context (e.g., alias example 'pups', region default to DETMIR_REGION) but does not significantly enhance parameter meaning beyond what the schema provides. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'List products in a Detsky Mir category, with the total match count' — a specific verb+resource+scope. It further distinguishes itself from text search by calling itself 'the reliable way to enumerate the catalog', separating it from sibling tools like detmir_categories (category listing) and detmir_card (product details).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use this tool: 'This is the reliable way to enumerate the catalog' and contrasts with text search. It also clarifies pagination behavior and that an empty page is not an error, guiding the caller on how to interpret results.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

dns_cardDNS-Shop Product CardA
Read-onlyIdempotent

Fetch one DNS-Shop product card.

Return Format

DnsCardResponse: {status, product_id, title, price_rub, old_price_rub, is_available, url, tier_used, meta}.

Error Format

ToolError: BadRequestError when the URL carries no product id; TransportDownError on CDP/Qrator failures; ParserDriftError when a rendered card has neither title nor price.

ParametersJSON Schema
NameRequiredDescriptionDefault
product_urlYesdns-shop.ru product URL containing /product/<id>/, e.g. /product/b7a1667f9b19ed20/

Output Schema

ParametersJSON Schema
NameRequiredDescription
urlNo
_metaNo
titleNo
statusNo
price_rubNo
tier_usedNo
product_idNo
is_availableNo
old_price_rubNo

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, and non-destructive. The description adds specific error behaviors (BadRequestError, TransportDownError, ParserDriftError) and a condition for parser drift, providing context beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with clear sections and no wasted words. The Return Format section may duplicate what the output schema already provides, but it is brief and doesn't bloat the description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a scraping tool with potential failures, the description covers purpose, input requirements, return format, and all relevant error modes. Since an output schema exists, the return format section is a bonus rather than a gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already documents product_url with an example and full coverage. The description adds semantic value by explaining that a BadRequestError occurs when the URL carries no product id, reinforcing the expected URL structure.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Fetch one DNS-Shop product card', which clearly states a specific verb and resource. This distinguishes it from sibling tools like dns_search (search) and other marketplace card tools, making the purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly implies this tool is used when you need a single product card by URL, and the input requirement for a product URL provides context. However, it does not explicitly mention alternatives or when-not-to-use, so it falls short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

lamoda_cardLamoda Product CardA
Read-onlyIdempotent

Fetch one Lamoda product card via the anonymous GraphQL endpoint (tier 1).

Return Format

LamodaCardResponse: {status, sku, title, brand, price_rub, old_price_rub, is_available, sizes[], url, tier_used, meta}. Lamoda exposes no ratings.

Error Format

ToolError: BadRequestError when no SKU can be extracted; NotFoundError when the SKU has no product; TransportDownError on HTTP failures; ParserDriftError when the GraphQL envelope changed.

ParametersJSON Schema
NameRequiredDescriptionDefault
sku_or_urlYesSKU (MP002XM1RMM3) or lamoda.ru product URL

Output Schema

ParametersJSON Schema
NameRequiredDescription
skuNo
urlNo
_metaNo
brandNo
sizesNo
titleNo
statusNo
price_rubNo
tier_usedNo
is_availableNo
old_price_rubNo

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false. The description adds value by revealing the anonymous endpoint (no auth needed), the tier 1 designation, that Lamoda exposes no ratings, and enumerating specific error types, which helps agents anticipate failures.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is structured with Return Format and Error Format sections, using concise bullet-like notation. It includes essential details without extensive prose, though the return field listing may be somewhat redundant if an output schema is available.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the single simple parameter and strong annotations, the description covers the essential behavior, return shape, and error cases. It is complete enough for an agent to invoke the tool correctly, though it leaves terms like 'tier_used' and 'meta' unexplained.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema fully documents the single parameter with an example format. The description's error format mentions 'when no SKU can be extracted', which reinforces that the input must contain a SKU, but adds little beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Fetch one Lamoda product card via the anonymous GraphQL endpoint (tier 1)', providing a specific verb and resource. It clarifies it fetches a single card, distinguishing it from search tools like lamoda_search, though it does not explicitly name alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not state explicit when-to-use vs alternatives. The context of requiring a SKU or URL is implied by the parameter, and the 'one product card' phrasing suggests not for searching, but this is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

marketplace_sourcesWhich Marketplaces Are LoadedA
Read-onlyIdempotent

List which connectors this unified server actually mounted.

Why this exists

Connectors are imported defensively, so a missing dependency removes a marketplace instead of killing the server. That is the right failure mode, but it is invisible from the client: absent tools look the same as a source that simply found nothing. Call this before concluding a marketplace has no results — if it is in skipped, it was never queried at all.

Return Format

MarketplaceSourcesResponse: {mounted, skipped, mounted_count, skipped_count, server_version}. skipped maps source name to the import error that removed it, which is usually a missing optional dependency.

Error Format

Never raises ToolError: pure introspection of the mounted connectors — a failed import is recorded in skipped instead of being raised.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
mountedNo
skippedNo
mounted_countNo
skipped_countNo
server_versionNo

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds significant behavioral context beyond these: defensive importing behavior, that failed imports are recorded in ``skipped`` rather than raised, and that it never raises ToolError. This explains the observable behavior and error semantics.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Although the description is longer than average, it is well-structured with clear sections ("Why this exists", "Return Format", "Error Format") and every paragraph adds value. The length is justified by the need to explain the invisible failure mode and the return format.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given zero parameters and the presence of an output schema, the description fully covers the tool's purpose, usage context, return semantics, and error behavior. It addresses the complex diagnostic case where a missing source looks like an empty one, which is essential for an agent to use the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has 0 parameters, so the baseline for this dimension is 4. The description appropriately focuses on the return format and error behavior, adding meaning beyond the parameterless schema. No parameter documentation is needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb+resource: "List which connectors this unified server actually mounted." It distinguishes itself from sibling tools by explaining the diagnostic purpose: distinguishing missing marketplaces from empty ones, which is unique among the available tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit when-to-use guidance: "Call this before concluding a marketplace has no results — if it is in ``skipped``, it was never queried at all." This tells the agent exactly when to invoke this tool versus assuming a marketplace is empty, effectively differentiating it from comparison tools like compare_sources.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

megamarket_cardMegamarket Product CardA
Read-onlyIdempotent

Fetch one Megamarket product card.

Return Format

MegamarketCardResponse: {status, item_id, title, price_rub, old_price_rub, is_available, rating, rating_count, url, tier_used, meta}.

Error Format

ToolError: BadRequestError on unparseable input; NotFoundError on a missing goods id; TransportDownError on ServicePipe refusals; ParserDriftError on envelope drift.

ParametersJSON Schema
NameRequiredDescriptionDefault
item_id_or_urlYesGoods id or megamarket.ru product URL

Output Schema

ParametersJSON Schema
NameRequiredDescription
urlNo
_metaNo
titleNo
ratingNo
statusNo
item_idNo
price_rubNo
tier_usedNo
is_availableNo
rating_countNo
old_price_rubNo

TDQS

A4.1/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only, idempotent, non-destructive behavior. The description goes further by specifying the exact return fields and error types (BadRequestError, NotFoundError, TransportDownError, ParserDriftError), which provides concrete behavioral expectations beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and front-loaded with the core purpose. The return format and error format sections are clearly structured and add necessary value without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple single-fetch tool, the description is complete. It specifies the output schema, error behavior, and is supplemented by strong annotations. An agent can correctly invoke the tool and interpret results without additional context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% for the single parameter ('Goods id or megamarket.ru product URL'). The description adds no additional parameter semantics, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the operation: 'Fetch one Megamarket product card.' It uses a specific verb ('Fetch') and resource ('Megamarket product card'), and the word 'one' distinguishes it from search tools. The marketplace name distinguishes it from other card tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is given on when to use this tool versus alternatives. The description does not mention that 'megamarket_search' should be used for discovery or that an item ID/URL is required. The input schema carries this information, but the description itself omits usage context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

mpstats_itemMPStats Item AnalyticsA
Read-onlyIdempotent

Fetch per-SKU 30-day sales analytics from MPStats (Ozon or Wildberries).

Returns, per SKU: seller/brand identity, current stock and price, a rolling orders-per-day average, aggregated totals over the window, and four per-day graphs (orders, prices, stock count, rubric positions). Graphs are length days (default 30), oldest-first; a zero cell means "no data for that day", not "the value was zero".

Requires the MPSTATS_MP_AUTH env var (a paid MPStats account JWT cookie). Without it the tool returns an auth_missing error.

Return Format

MpStatsItemResponse: {place, days, count, items, meta}. Each item carries sku, place, seller, seller_id, brand, stock_now, price_avg_rub, orders_per_day, days_on_stocks, totals {orders, sum, sum_prev} and four per-day graphs (orders, prices, count, rubrics), oldest-first. Missing values are None, never 0; a zero graph cell means "no data for that day".

Error Format

ToolError: BadRequestError on malformed skus or place; AuthMissingError when MPSTATS_MP_AUTH is missing or rejected; RateLimitedError on HTTP 429; TransportDownError on network failures, non-200 responses and HTML blocks; ParserDriftError on a non-JSON or mis-shaped body; NotFoundError when no requested SKU has analytics.

ParametersJSON Schema
NameRequiredDescriptionDefault
skusYes1..100 SKU integers (positive). Per-SKU 30-day sales/price/stock analytics from MPStats.
placeYesMarketplace: 'ozon' or 'wildberries'. Determines which MPStats dataset the SKUs resolve against.
oz_fbsNoOzon FBS (Fulfilled-by-Seller) mode. Ozon-specific; harmless for wildberries. Default true.

Output Schema

ParametersJSON Schema
NameRequiredDescription
daysNo
metaNo
countNo
itemsNo
placeNo

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description extensively discloses behavior beyond the annotations: rolling averages, per-day graph semantics, zero-cell meaning, auth failure modes, and a full error taxonomy. It also clarifies missing values are None, never 0, which is a subtle but crucial behavioral detail. No contradictions with the read-only/idempotent annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with clear sections (overview, return format, error format) and every sentence carries meaningful information. It is length-appropriate for the tool's complexity and front-loads the core purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite the tool's moderate complexity, the description covers the full usage context: what the tool returns, the exact structure, all error cases, and prerequisites. The output schema and annotations are supplemented effectively, leaving little room for agent confusion.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already has 100% coverage with detailed parameter descriptions, so the baseline is 3. The tool description adds useful context about what the data represents (e.g., 'per-SKU', '30-day') but does not add significant new meaning beyond the schema's parameter descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific, actionable verb ('Fetch') and identifies both the resource (MPStats) and scope (per-SKU 30-day sales analytics, Ozon or Wildberries). It clearly distinguishes this from sibling tools via the per-SKU granularity and explicit marketplace focus.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly establishes when to use the tool: for per-SKU analytics on MPStats data. It also gives a key prerequisite (MPSTATS_MP_AUTH env var). However, it does not explicitly state when NOT to use this tool or name an alternative, so it falls short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

mpstats_warehousesMPStats Warehouse StockA
Read-onlyIdempotent

Fetch per-SKU warehouse stock split from MPStats (Ozon or Wildberries).

Returns, per SKU: FBS (seller warehouse) stock count, total FBO (marketplace warehouse) stock count, the raw per-warehouse FBO entries when MPStats populates them, and the upstream last_update timestamp.

Requires the MPSTATS_MP_AUTH env var (a paid MPStats account JWT cookie). Without it the tool returns an auth_missing error.

Return Format

MpStatsWarehousesResponse: {place, days, count, items, meta}. Each item carries sku and stocks {fbs, fbo, fbo_warehouses, last_update}. Missing stock counts are None, never 0.

Error Format

ToolError: BadRequestError on malformed skus or place; AuthMissingError when MPSTATS_MP_AUTH is missing or rejected; RateLimitedError on HTTP 429; TransportDownError on network failures, non-200 responses and HTML blocks; ParserDriftError on a non-JSON or mis-shaped body; NotFoundError when no requested SKU has stock data.

ParametersJSON Schema
NameRequiredDescriptionDefault
skusYes1..100 SKU integers (positive). Per-SKU warehouse stock split from MPStats.
placeYesMarketplace: 'ozon' or 'wildberries'. Determines which MPStats dataset the SKUs resolve against.

Output Schema

ParametersJSON Schema
NameRequiredDescription
daysNo
metaNo
countNo
itemsNo
placeNo

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, and idempotentHint, but the description adds substantial behavioral context: auth requirements, specific error types (BadRequestError, AuthMissingError, RateLimitedError, etc.), and data semantics like "Missing stock counts are None, never 0." No contradictions with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with clear sections for return format and error format. It is appropriately detailed without redundancy. Every sentence adds helpful information, from the auth requirement to the behavior of missing data (None, never 0). The use of formatting (code highlights, headings) enhances readability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite having an output schema, the description thoroughly explains the return structure and also enumerates all relevant error scenarios. It covers prerequisites (paid MPStats account), parameter scope, and edge cases. For a tool with two parameters and a moderate complexity, this is complete and self-sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, with descriptions for both skus and place. The tool description adds a bit of context, such as "place determines which MPStats dataset the SKUs resolve against," but this is also present in the schema. The description does not significantly enrich parameter understanding beyond the schema's existing coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: "Fetch per-SKU warehouse stock split from MPStats (Ozon or Wildberries)." It clearly distinguishes this tool from siblings by focusing on warehouse stock split, a niche capability. The return fields (FBS, FBO, etc.) further solidify a distinct purpose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implicitly communicates when to use this tool by stating what it returns and the required environment variable (MPSTATS_MP_AUTH). It does not explicitly name alternatives or exclusions, but the context of fetching per-SKU stock split from MPStats is clear. The presence of sibling tools like mpstats_item suggests different use cases, but that contrast is not explicitly stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ozon_cardOzon Product CardA
Read-onlyIdempotent

Fetch Ozon product card data via composer-api.bx.

Tier-1 (curl_cffi) tried first. Falls back to Tier-2 (Chrome CDP at port 9222) when Tier-1 hits Cloudflare 403. Tier-2 requires the operator running Chrome via scripts/start_chrome_cdp.ps1 (Windows) or scripts/start_chrome_cdp.sh (Linux/macOS) first.

Return Format

OzonCardResponse: {status, price, card_price, price_original, is_available, rating_score, rating_count, title, seller, characteristics, url, tier_used, meta} on success. Fields are None when the page does not carry them.

Error Format

Raises ToolError on validation (BadRequestError), transport/block (TransportDownError — including the catch-all for unexpected internal errors), or parser drift (ParserDriftError). No-results is NOT an error — an empty widgetStates payload returns a healthy response with null fields.

ParametersJSON Schema
NameRequiredDescriptionDefault
sku_or_pathYesSKU integer-as-string, full Ozon URL, or /product/<digits>/ path. Other paths are rejected (SSRF prevention).

Output Schema

ParametersJSON Schema
NameRequiredDescription
urlNo
_metaNo
priceNo
titleNo
sellerNo
statusNo
tier_usedNo
card_priceNo
is_availableNo
rating_countNo
rating_scoreNo
price_originalNo
characteristicsNo

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations by detailing the tiered fetch mechanism, Chrome CDP prerequisite, return format fields, error taxonomy, and no-result handling. This is rich behavioral context that helps an agent anticipate side effects and operational requirements.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well-structured with a clear first sentence and dedicated sections for return format and error format. Every section earns its place without unnecessary verbosity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers purpose, transport strategy, prerequisites, return schema, error taxonomy, and no-result semantics. For a single-parameter read-only tool with existing annotations, this description is fully sufficient for an agent to invoke correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Input schema already documents the single parameter at 100% coverage, including accepted forms (SKU, URL, path) and SSRF prevention. Description adds no parameter-level details, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description opens with 'Fetch Ozon product card data via composer-api.bx', a specific verb+resource statement. It clearly distinguishes the tool from sibling tools like ozon_search and ozon_reviews by focusing on product card retrieval.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides clear context on when to use: fetching product card data, with explicit fallback behavior from Tier-1 to Tier-2 on Cloudflare 403. Does not explicitly name alternative tools or when-not-to-use, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ozon_reviewsOzon Product ReviewsA
Read-onlyIdempotent

Fetch Ozon product review texts + star distribution via composer-api.bx.

Tier-1 (curl_cffi) tried first, Tier-2 (Chrome CDP) fallback — same path as ozon_card. Returns review texts (comment/positive/negative), per-review score, helpfulness votes, author first name, date, plus the overall star distribution and total count.

Pages are walked automatically (30/page) until limit texts are collected or pages run out, deduplicating by review uuid. Hard cap of 10 pages.

Return Format

OzonReviewsResponse: {status, sort, rating_score, reviews_count, distribution, returned, partial, stop_reason, last_error, requested_limit, reviews, meta} on success. A later-page failure with reviews already collected is a PARTIAL SUCCESS (partial=True, stop_reason set), NOT an error.

Error Format

Raises ToolError on validation (BadRequestError), transport/block (TransportDownError), or parser drift (ParserDriftError) — but ONLY when no reviews have been collected yet. Once at least one page yielded reviews, a later-page failure degrades to a partial-success return.

ParametersJSON Schema
NameRequiredDescriptionDefault
sortNoReview ordering. Aliases: "recent"/"default" -> newest, "best"/"highest" -> highest rated first, "worst"/"lowest"/"complaints" -> LOWEST rated first. Raw API values published_at_desc/score_desc/score_asc also accepted.recent
limitNoMax review texts to return (1..100). Distribution+total always full.
sku_or_pathYesSKU integer-as-string, full Ozon URL, or /product/<digits>/ path. Normalized to /product/<digits>/reviews/ (SSRF-allowlisted).

Output Schema

ParametersJSON Schema
NameRequiredDescription
urlNo
sortNo
_metaNo
statusNo
partialNo
reviewsNo
returnedNo
tier_usedNo
last_errorNo
stop_reasonNo
distributionNo
rating_scoreNo
pages_fetchedNo
reviews_countNo
requested_limitNo

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, but the description goes far beyond by detailing the tier-1/tier-2 fallback, 30-per-page walking, hard 10-page cap, dedup by uuid, and nuanced partial-success/error handling. This is exemplary disclosure of behavioral traits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with clear sections (introduction, behavior, return format, error format). Every sentence carries useful information—no filler. While longer than a one-liner, the density and organization keep it efficient and scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with pagination, partial failures, and multiple error modes, the description is remarkably complete. It covers the success return shape, partial-success semantics, and the exact conditions for each error type. Combined with a rich output schema and annotations, an agent has everything needed to invoke and interpret results correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds value by explaining how 'limit' interacts with automatic page walking (30/page until limit collected) and the hard cap, which is not fully captured in the schema alone. This pushes it to a 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Fetch Ozon product review texts + star distribution'. It clearly distinguishes this tool from sibling tools by focusing on reviews (vs. search, card, etc.) and even references the sibling ozon_card for implementation context. This is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not explicitly state 'use this when X, use Y when Z', but it provides clear context about the return format, pagination behavior, and partial-success semantics, which helps an agent understand when this tool is appropriate. It lacks explicit exclusions or alternatives, so it falls just short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

taobao_cardTaobao Item CardA
Read-onlyIdempotent

Fetch one Taobao item card.

Return Format

TaobaoCardResponse: {status, item_id, title, price_cny, shop_name, sales, description_images, url, tier_used, meta}. price_cny is None when the page hides it or prices by variant — never 0. When the description-image count drifts to a non-number, description_images degrades to 0 and meta.warnings names the drift — the card itself still answers.

Error Format

ToolError: BadRequestError when no id can be extracted; NotFoundError when the item page reports itself gone; TransportDownError on login walls and CDP failures; ParserDriftError when a rendered card has neither title nor price.

ParametersJSON Schema
NameRequiredDescriptionDefault
item_id_or_urlYesItem id or item.taobao.com URL

Output Schema

ParametersJSON Schema
NameRequiredDescription
urlNo
_metaNo
salesNo
titleNo
statusNo
item_idNo
price_cnyNo
shop_nameNo
tier_usedNo
description_imagesNo

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (readOnly, idempotent, etc.), the description adds concrete behavioral details: price_cny is None when hidden or variant-based, description_images degrades to 0 with a meta warning, and specific error types for different failure modes. This is rich, non-obvious context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-organized with Return Format and Error Format sections. It is longer than the bare minimum but each section adds necessary detail without excessive verbosity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers return format, edge-case behavior, and error handling. Given the output schema exists and the tool is a simple fetch-only operation, it is sufficiently complete. It does not discuss prerequisites like URL formatting, but the schema covers parameter constraints.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The single parameter item_id_or_url is fully documented in the schema (100% coverage). The description adds no additional parameter semantics, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Fetch one Taobao item card,' using a specific verb (fetch) and resource (one Taobao item card). It clearly distinguishes itself from sibling tools like taobao_search and other marketplace card tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrasing 'one Taobao item card' makes clear it is for retrieving a single item's card, not searching. However, it does not explicitly state when to prefer this over taobao_search or other card tools, so it stops short of full explicit guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wb_cardWB Product CardsA
Read-onlyIdempotent

Fetch product card data from WB v4 API.

Returns prices in rubles, brand, supplier, supplier_rating, review_rating, feedbacks count, total_quantity for up to 100 SKUs.

Return Format

WbCardResponse: {dest, count, items, meta}. Items carry nm_id, name, brand, supplier, supplier_id, supplier_rating, review_rating, feedbacks, total_quantity, in_stock, price_rub, price_original_rub. price_rub is None when the SKU has no sellable price — never 0. Unknown SKUs are NOT an error — they simply do not appear in items.

Error Format

ToolError: BadRequestError on malformed nm_ids; RateLimitedError on HTTP 429; TransportDownError on network failures, non-200 responses, Cloudflare HTML pages and unexpected internal errors; ParserDriftError on a non-JSON or mis-shaped body.

ParametersJSON Schema
NameRequiredDescriptionDefault
destNoRegion ID. Default -1257786 (Moscow). Required for valid prices/stocks. Other examples: -1257786 Moscow, -1029256 Saint Petersburg.-1257786
nm_idsYes1..100 nmId integers (positive). Batch product cards from WB v4 API.

Output Schema

ParametersJSON Schema
NameRequiredDescription
destNo
metaNo
countNo
itemsNo

TDQS

A4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds valuable behavioral details beyond the readOnly/idempotent annotations: price_rub is None (never 0), unknown SKUs are silently omitted, and error classes are mapped to specific conditions (rate limit, transport, parser drift). This goes well beyond the annotation safety hints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the purpose sentence and structured into Return/Error sections, making it scannable. It is slightly repetitive in listing fields (brand, supplier, ratings appear both in the intro and in the return format) but remains efficient overall.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the return format, edge cases (unknown SKUs, None price), and all error classes, while annotations cover safety. The 100-SKU limit and dest behavior are captured in the schema. No critical information is missing for a batch-read tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already provides 100% parameter coverage, documenting dest (with default and examples) and nm_ids (with count/type constraints). The description only restates 'up to 100 SKUs' and adds no new parameter-level meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Fetch product card data from WB v4 API,' clearly stating the action and resource. It enumerates the returned fields (prices, brand, supplier, ratings, etc.) and the 100-SKU limit, which distinguishes it from sibling tools like wb_reviews or wb_search.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no explicit guidance on when to use this tool versus alternatives such as wb_search or wb_reviews. It only states functionality and limits, leaving the agent to infer appropriate use cases.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wb_categoriesWB Catalog CategoriesA
Read-onlyIdempotent

Browse the Wildberries catalog tree.

Use this to discover what exists before searching: wb_search needs a query string, but a shopper's question is often "what categories of humidifiers are there?". Each node carries WB's own shard and query selectors, which are the addressing needed to pull a category feed.

The live menu is ~800 KB, so responses are always a bounded slice — start at 'top', then expand the branch you care about.

Return Format

WbCategoriesResponse: {root, max_depth, total_returned, truncated, items, host_used, meta}. Nodes carry id, name, url, shard, query, depth, children_count, children; shard+query are the selectors wb_category_products needs to list a category feed.

Error Format

On validation or transport/parse failure, raises ToolError with a JSON message describing the error code and whether it is retryable.

ParametersJSON Schema
NameRequiredDescriptionDefault
rootNo'top' for the top-level sections, or a category name / URL path / id to expand (e.g. 'Электроника', '/catalog/elektronika', '8126').top
max_depthNoHow many levels below the root to include. 1 = direct children only.

Output Schema

ParametersJSON Schema
NameRequiredDescription
metaNo
rootNo
itemsNo
host_usedNo
max_depthNo
truncatedNo
total_returnedNo

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds valuable behavioral context: responses are bounded slices of an ~800 KB menu, and it documents the error format. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with clear sections, front-loaded with the primary purpose, and every sentence earns its place. It is concise (~150 words) yet informative, with no redundant wording.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema exists, the description still adds value by clarifying the node fields (id, name, url, shard, query, depth, children_count, children) and the relationship to wb_category_products. It also covers return format and error behavior, making it complete for a catalog browsing tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with descriptive parameter definitions, so the baseline is 3. The description adds context about starting at 'top' and expanding branches, but this largely overlaps with the schema's parameter descriptions rather than providing new semantic depth.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses the specific verb 'Browse' with the resource 'Wildberries catalog tree', clearly stating what the tool does. It explicitly distinguishes itself from siblings by contrasting with wb_search and mentioning wb_category_products.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use this tool ('Use this to discover what exists before searching') and names an alternative (wb_search) that requires a query string. It also gives a navigation pattern ('start at top, then expand') and implies the role of wb_category_products.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wb_category_productsWB Category Product ListingA
Read-onlyIdempotent

List the products in a catalog category, using the shard and query from wb_categories.

This closes the loop wb_categories opens. That tool hands back WB's own shard and query selectors — the address of a category feed — and this is the tool that fetches it. Browsing "what humidifiers exist" no longer requires inventing a search phrase and hoping WB's relevance ranking agrees with you.

Items come back in the same shape wb_search and wb_card return, so a category walk and a text search are directly comparable.

Not every category has a feed. WB marks those with the shard blackhole, and several of its largest sections (smartphones, laptops, TV and audio) are among them: they exist as navigation, not as a listable endpoint. Asking for one raises a clear error naming the alternative rather than returning an empty list, because an empty list here would read as "this category has no products", which is false.

Return Format

WbCategoryProductsResponse: {shard, query, page, sort, dest, count, has_more, items, meta}, with items in the same shape as wb_card. has_more is inferred from a full page — WB reports no total here.

Error Format

ToolError: BadRequestError on malformed selectors or the unlistable 'blackhole' shard; NotFoundError on a 404 (stale shard/query pair); RateLimitedError on HTTP 429; TransportDownError on network failures, non-200 responses, Cloudflare HTML pages and unexpected internal errors; ParserDriftError on a non-JSON or mis-shaped body.

ParametersJSON Schema
NameRequiredDescriptionDefault
destNoWB region id. Defaults to WB_DEFAULT_DEST (Moscow). Prices and stock are region-specific.
pageNoPage number. Each page carries up to 100 products.
sortNoUpstream ordering: popular, priceup, pricedown, newly, rate, or benefit.popular
queryYesWB catalog selector from wb_categories, e.g. 'cat=9845' or 'subject=1234'.
shardYesWB catalog shard from wb_categories, e.g. 'electronic58'. The literal 'blackhole' means the category has no listable feed.

Output Schema

ParametersJSON Schema
NameRequiredDescription
destNo
metaNo
pageNo
sortNo
countNo
itemsNo
queryNo
shardNo
has_moreNo

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Despite annotations already declaring readOnly, idempotent, and non-destructive hints, the description adds substantial behavioral context: the return shape matches wb_card, has_more is inferred from a full page rather than a reported total, blackhole shards raise errors instead of empty lists, and a complete error taxonomy is provided (BadRequest, NotFound, RateLimited, TransportDown, ParserDrift). This goes well beyond the structured annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but well-structured with clear sections for purpose, caveats, return format, and error format. The opening sentence is a crisp summary, and subsequent paragraphs add necessary context about the blackhole limitation and error behavior. It is not overly terse for the complexity involved, though some sentences could be tightened without losing meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with a moderately complex relationship to a sibling tool and several failure modes, the description is remarkably complete. It explains the integration with wb_categories, the blackhole exception, the exact return shape, and all anticipated error types. Even with an output schema present, the description independently lists the response fields, ensuring the agent fully understands what to expect.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already covers all parameters with detailed descriptions, so the baseline is 3. The description adds contextual meaning by explaining that shard and query are handed back by wb_categories, that 'blackhole' is a special unlistable value, and that prices/stock are region-specific via dest. This extra provenance and edge-case info justifies a 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'List the products in a catalog category' and immediately references the shard/query selectors from wb_categories. It also distinguishes itself from sibling tools by noting the items come back in the same shape as wb_search and wb_card, making its role in the category-vs-search workflow clear.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly states when to use this tool: after wb_categories provides shard and query selectors, for category-based browsing without inventing search phrases. It also warns that not every category has a feed and blackhole shards raise an explicit error. However, it does not explicitly name alternative tools like wb_search for text-based scenarios, so it falls slightly short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wb_questionsWB Buyer Questions by imt_idA
Read-onlyIdempotent

Fetch buyer questions and seller answers by imt_id (root_id from wb_root_info).

Answers this tool exists for: buyers ask what a listing omits — "does it fit a 60cm opening", "is the cable included", "is this the 10A or the 16A model" — and the seller's reply is often the only public statement of that fact. Reviews describe the experience of owning the product; questions clarify what it actually is.

Keyed by imt_id, exactly like wb_reviews: every colour and size variant shares one question pool. Passing an nmId returns an empty pool with no error, so resolve the root id via wb_root_info first.

Return Format

WbQuestionsResponse: {imt_id, total_available, returned, skip, answered_count, has_more, questions, meta}. Question items carry question_id, text, date, user, answered, answer_text, answer_date, nm_id. An empty pool is NOT an error — it means nobody has asked yet.

Error Format

ToolError: BadRequestError on a bad limit or skip; RateLimitedError on HTTP 429; TransportDownError on network failures, non-200 responses and unexpected internal errors; ParserDriftError when a 200 body loses the count key or the questions shape.

ParametersJSON Schema
NameRequiredDescriptionDefault
skipNoOffset into the question pool, for walking past the first page.
limitNoMax questions to return (1..100). Fetched in pages of 30, which is the upstream cap.
imt_idYesRoot ID (imt_id) from wb_root_info. Questions are pooled per imt_id across every variant, NOT by nmId.
answered_onlyNoReturn only questions the seller has answered. Unanswered questions carry no product information.

Output Schema

ParametersJSON Schema
NameRequiredDescription
metaNo
skipNo
imt_idNo
has_moreNo
returnedNo
questionsNo
answered_countNo
total_availableNo

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false. The description adds substantial behavioral details beyond those: an empty pool is not an error, pagination happens in pages of 30 (upstream cap), and a full error format section covers BadRequestError, RateLimitedError, TransportDownError, and ParserDriftError. It also explains the pooling behavior across variants and the nmId empty-pool consequence.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is longer than average but well-structured with sections for main purpose, context, return format, and error format. It is front-loaded with the essential purpose and keying detail. No sentence is redundant; each adds value, but the error format section could arguably be summarized since the output schema exists. Still, it is appropriately scoped for the tool's complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (imt_id vs nmId, shared pool, pagination, empty pools, error cases), the description covers all necessary context: return format, error format, parameter semantics, and behavioral expectations. The output schema handles return structure details, and the description compensates for the schema's lack of runtime behavior. An agent can confidently invoke this tool correctly without additional lookups.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds meaningful context beyond the schema: imt_id is the root ID from wb_root_info and must not be an nmId; limit is 'Fetched in pages of 30'; answered_only is framed as a filter for product-relevant questions ('Unanswered questions carry no product information'). These clarifications help the agent select and construct correct calls.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description starts with a clear verb and resource: 'Fetch buyer questions and seller answers by imt_id (root_id from wb_root_info).' It explicitly distinguishes this tool from wb_reviews: 'Reviews describe the experience of owning the product; questions clarify what it actually is.' The scoping to imt_id and the relationship to wb_root_info further solidify its unique role among siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit when-to-use context: buyers ask about listing omissions, and seller answers are often the only public statement. It names an alternative (wb_reviews) and contrasts them. It also gives a clear prerequisite: 'resolve the root id via wb_root_info first' because passing an nmId returns an empty pool. The answered_only parameter guidance ('Unanswered questions carry no product information') tells the user when to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wb_reviewsWB Reviews by imt_idA
Read-onlyIdempotent

Fetch reviews by imt_id (root_id from wb_root_info).

All product variants share one review pool, indexed by imt_id NOT nmId.

The WB feedbacks endpoint returns a fixed pool (~1000 most-recent reviews, newest-first) and IGNORES server-side order params (verified Nov 2026), so sort is applied CLIENT-SIDE over that pool. To surface complaints, "worst" reorders the returned pool by lowest rating first.

Return Format

WbReviewsResponse: {imt_id, sort, pool_size, feedback_count, valuation, valuation_distribution, feedbacks, host_used, meta}. Review items carry rating, text, pros, cons, user, date. An empty pool is NOT an error — it returns a healthy response with zero feedbacks.

Error Format

ToolError: BadRequestError on a bad limit or sort; ParserDriftError when a 200 body has no feedbacks list; TransportDownError when every review host fails and on unexpected internal errors.

ParametersJSON Schema
NameRequiredDescriptionDefault
sortNo"recent"/"newest"/"default" (as returned, newest-first), "best"/"highest" (highest rating first), "worst"/"lowest"/"complaints" (LOWEST rating first — finds downsides). Reorders the ~1000-review pool WB returns, not all feedbacks.recent
limitNoMax review texts to return (1..100). Counts always full.
imt_idYesRoot ID (imt_id) from wb_root_info. All product variants share one review pool indexed by imt_id, NOT by nmId.

Output Schema

ParametersJSON Schema
NameRequiredDescription
metaNo
sortNo
imt_idNo
feedbacksNo
host_usedNo
pool_sizeNo
valuationNo
feedback_countNo
valuation_distributionNo

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (readOnlyHint, idempotentHint, etc.), the description reveals important non-obvious behaviors: the fixed ~1000-review pool, that server-side order params are ignored (verified Nov 2026), and that sort is applied client-side. It also discloses that an empty pool is not an error and details error types (BadRequestError, ParserDriftError, TransportDownError). This is substantial added behavioral context beyond what annotations provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with clear sections for main description, return format, and error format. It is dense but every sentence provides useful information: the pool limitation, the sort caveat, the empty-pool behavior, and error handling. It stays within reasonable length and is front-loaded with the core purpose, making it easy to scan.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description does not need to exhaustively list return fields, but it still summarizes the key fields and covers critical edge cases (empty pool not an error). It also explains error semantics and the source of the required id. For a tool with these annotations and schema richness, the description is fully complete for reliable invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3. The description adds value by explaining the 'why' behind sort behavior: the endpoint ignores server-side order params, making the client-side reordering meaningful. It also reinforces the imt_id vs nmId distinction for the required parameter. This deepens understanding beyond the schema descriptions, warranting a 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a clear imperative 'Fetch reviews by imt_id', specifying the resource (reviews), the identifier (imt_id), and explicitly distinguishes from siblings by noting 'All product variants share one review pool, indexed by imt_id NOT nmId.' This disambiguates from wb_card and wb_root_info that use nmId, giving strong purpose clarity with a specific verb+resource+scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context on when to use the tool: it tells users to obtain imt_id from wb_root_info, warns against using nmId, and explains the 'worst' sort for surfacing complaints. However, it does not explicitly name alternative tools (e.g., wb_questions) or state when-not-to-use conditions, stopping short of full exclusionary guidance. The prerequisite and sort usage are clear, so it earns a 4.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wb_root_infoWB Root Info (imt_id)A
Read-onlyIdempotent

Fetch full card metadata from basket CDN. Returns imt_id (root_id) for review pool.

All variants of one product share imt_id. Reviews indexed by imt_id, NOT by nmId.

Return Format

WbRootInfoResponse: {imt_id, subj_name, subj_root_name, colors, compositions, options, host_used, meta}. imt_id is the root product id shared by every variant — wb_reviews is indexed by it, not by nmId.

Error Format

On validation or transport/parse failure, raises ToolError with a JSON message describing the error code and whether it is retryable.

ParametersJSON Schema
NameRequiredDescriptionDefault
nm_idYesnmId (positive integer). The SKU whose basket CDN card.json is fetched for imt_id resolution.

Output Schema

ParametersJSON Schema
NameRequiredDescription
metaNo
colorsNo
imt_idNo
optionsNo
host_usedNo
subj_nameNo
compositionsNo
subj_root_nameNo

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint. The description adds useful behavioral context: error format (ToolError with JSON message and retryable flag), validation/transport failure handling, and details about the response structure. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded and uses clear section headers (Return Format, Error Format), but it repeats the imt_id concept multiple times: 'Returns imt_id', 'All variants of one product share imt_id', and 'imt_id is the root product id shared by every variant'. This redundancy could be trimmed without losing meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter tool with an output schema, the description is complete: it explains the return format (WbRootInfoResponse fields), error format, the relationship to wb_reviews, and the purpose of imt_id. No significant gaps remain.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema provides 100% coverage, describing nm_id as 'nmId (positive integer). The SKU whose basket CDN card.json is fetched for imt_id resolution.' The description does not add additional parameter semantics beyond this, so it meets the baseline but does not exceed it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Fetch full card metadata from basket CDN') and the specific resource/outcome ('Returns imt_id (root_id) for review pool'). It distinguishes from sibling tools by explicitly noting that reviews are indexed by imt_id, not nmId, and referencing wb_reviews.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Clear context is provided: the description explains that reviews are indexed by imt_id rather than nmId, implying this tool should be used to resolve imt_id before querying wb_reviews. However, it does not explicitly name alternative tools or provide when-not-to-use exclusions, so it stops short of full guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wb_sellerWB Seller Legal InfoA
Read-onlyIdempotent

Look up the registered legal entity behind a WB seller.

Answers "who actually ships this?" — the question a marketplace listing is worst at. Returns the registered name, tax ids (INN/KPP/OGRN) and legal address, which is how you tell an official brand store from a reseller trading under a lookalike name, and how you spot several storefronts sharing one entity.

Chain from wb_card: its supplier_id field feeds straight into this tool.

Return Format

WbSellerResponse: {supplier_id, name, full_name, trademark, inn, kpp, ogrn, legal_address, taxpayer_code, foreign_codes, host_used, meta}. foreign_codes carries non-RU registration codes (unp/bin/unn) for EAEU sellers.

Error Format

On validation or transport/parse failure, raises ToolError with a JSON message describing the error code and whether it is retryable.

ParametersJSON Schema
NameRequiredDescriptionDefault
supplier_idYesWB supplier id (positive integer). Get it from wb_card's supplier_id field.

Output Schema

ParametersJSON Schema
NameRequiredDescription
innNo
kppNo
metaNo
nameNo
ogrnNo
full_nameNo
host_usedNo
trademarkNo
supplier_idNo
foreign_codesNo
legal_addressNo
taxpayer_codeNo

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes well beyond the annotations by detailing the return format (WbSellerResponse fields, foreign_codes for EAEU sellers) and error behavior (ToolError with retryable flag). This provides rich context about what the tool returns and how failures are surfaced, which is not inferred from readOnlyHint or idempotentHint.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured: a clear main sentence, a brief rationale, the chain instruction, and then dedicated sections for return and error formats. Each element adds value, and the information is front-loaded with the core purpose. No redundant or irrelevant content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (one parameter), the description is fully complete. It covers the entire workflow: when to use it (chain from wb_card), what the returned data includes, and how errors are reported. The existing annotations and output schema cover safety and structure, leaving no significant gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already provides a full description for supplier_id: 'WB supplier id (positive integer). Get it from wb_card's supplier_id field.' The description's chaining note essentially repeats this, adding no new semantic meaning beyond emphasizing the source. With 100% schema coverage, a baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Look up the registered legal entity behind a WB seller.' It uses a specific verb ('look up') and resource, and distinguishes itself from siblings by focusing on the legal entity rather than product/category/search data. The examples of distinguishing official stores from resellers further clarify the unique value.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context: 'Chain from wb_card: its supplier_id field feeds straight into this tool.' This explains when to use it (after wb_card) and what it's for (identifying the legal entity behind a seller). However, it does not explicitly state when NOT to use it or compare it to alternatives like wb_root_info, so it falls short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

yandex_cardYandex Market Product CardA
Read-onlyIdempotent

Fetch full detail for a Yandex Market product: prices, rating breakdown, reviews.

Two things here are hard to get anywhere else. The star distribution (rating_stars) shows whether a 4.8 average hides a cluster of one-star complaints. And reviews arrive with the card in one request, complete with pros, cons and helpfulness votes.

Reviews are capped at the ~13 Yandex renders server-side; the remainder load through an API this connector deliberately does not touch.

Return Format

YandexCardResponse: {product_id, sku_id, title, brand, seller, description, image, price_rub, price_with_plus, price_before_discount_rub, discount_percent, currency, offers_count, rating, rating_count, review_count, rating_stars, reviews, url, meta}. price_rub is None when the page has no usable price — never 0. Review items carry author, rating, date, pros, cons, comment, votes_up, votes_down, photos.

Error Format

On validation or transport/parse failure, raises ToolError with a JSON message describing the error code and whether it is retryable.

ParametersJSON Schema
NameRequiredDescriptionDefault
product_idYesNumeric Yandex Market product id — take it from yandex_search results.
include_reviewsNoInclude the server-rendered reviews (first ~13).

Output Schema

ParametersJSON Schema
NameRequiredDescription
urlNo
metaNo
brandNo
imageNo
titleNo
ratingNo
sellerNo
sku_idNo
reviewsNo
currencyNo
price_rubNo
product_idNo
descriptionNo
offers_countNo
rating_countNo
rating_starsNo
review_countNo
price_with_plusNo
discount_percentNo
price_before_discount_rubNo

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnly/idempotent annotations, the description discloses valuable behavioral traits: reviews are capped at ~13 server-side, the remainder load via an API deliberately not touched, price_rub is None when unavailable (never 0), and errors raise ToolError with retryability info. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well-structured with clear sections (Return Format, Error Format) and front-loaded purpose. The uniqueness pitch adds a bit of promotional framing and the return field list is lengthy, but each section provides practical value; could be tightened slightly without losing essential details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers purpose, unique value, limitations (review cap), null semantics, error handling, and return format. Combined with rich annotations and an output schema, the agent has all necessary context to select and invoke this tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with both parameters described. The description enriches include_reviews semantics by explaining the ~13 review cap and that the remaining reviews are deliberately not loaded via a secondary API, clarifying what the parameter actually controls.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Fetch full detail for a Yandex Market product: prices, rating breakdown, reviews' – a clear verb+resource+scope. It distinguishes from siblings by highlighting unique data (star distribution, reviews included in one request) and notes these are 'hard to get anywhere else,' making the tool's purpose unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides clear context for when to use (full detail, reviews, star distribution) and implies integration with yandex_search via the product_id parameter description ('take it from yandex_search results'). Does not explicitly name alternatives or exclusions, but the platform-specific name and sibling context make the intended use case obvious.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 2 tool updatesv1.6.0
    • Addedaliexpress_card
    • Addedaliexpress_search
  2. 34 tool updatesv1.5.1
    • First observedavito_card
    • First observedavito_search
    • First observedavito_seller
    • First observedcitilink_card
    • First observedcitilink_search
    • First observedcompare_prices
    • First observedcompare_sources
    • First observeddetmir_card
    • First observeddetmir_categories
    • First observeddetmir_category
    • First observeddns_card
    • First observeddns_search
    • First observedlamoda_card
    • First observedlamoda_search
    • First observedmarketplace_sources
    • First observedmegamarket_card
    • First observedmegamarket_search
    • First observedmpstats_item
    • First observedmpstats_warehouses
    • First observedozon_card
    • First observedozon_reviews
    • First observedozon_search
    • First observedtaobao_card
    • First observedtaobao_search
    • First observedwb_card
    • First observedwb_categories
    • First observedwb_category_products
    • First observedwb_questions
    • First observedwb_reviews
    • First observedwb_root_info
    • First observedwb_search
    • First observedwb_seller
    • First observedyandex_card
    • First observedyandex_search

TDQS

A4/5.0
Disambiguation3/5

Most tools are clearly source-specific (e.g., ozon_search vs wb_search), but several pairs are easy to confuse: detmir_category vs detmir_categories (list products vs browse tree) and marketplace_sources vs compare_sources (both report source availability). wb_root_info and wb_card also overlap in fetching product metadata. The detailed descriptions rescue most ambiguity, but an agent could mis-select under time pressure.

Naming Consistency4/5

The dominant pattern is {source}_{operation} (search, card, seller, categories), with clear prefixes like wb_, ozon_, yandex_. Minor deviations include detmir_category vs detmir_categories (singular/plural confusion) and wb_root_info (a noun phrase not matching the verb-like pattern). Overall, the naming is predictable and readable.

Tool Count3/5

34 tools is above the 25 threshold, but the multi-marketplace scope justifies many symmetric search/card pairs. The toolkit feels intentionally comprehensive rather than bloated, yet the sheer number could overwhelm an agent, especially with near-duplicate patterns across nine sources. It is borderline between 'too many' and 'well-scoped for a broad domain'.

Completeness5/5

For a read-only marketplace data server, the surface is remarkably complete: search, card details, reviews (WB/Ozon/Yandex), seller reputation (Avito), category browsing (WB/Detmir), analytics (MPStats), and cross-marketplace price comparison. The only gaps are niche (e.g., Ozon categories, Taobao seller) and do not create dead ends for common queries.

Maintenance

ActivityMaintained
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Vladimir-Human/ru-marketplace-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server