Skip to main content
Glama

chineur

Оценка стоимости всего проекта по лучшей цене с учётом доставки, новые и б/у раздельно, с планом группового заказа, минимизирующим реально уплаченную сумму.

Самый дешёвый товар по каждой позиции — неверное решение: 10 позиций у 10 продавцов — это 10 доставок. Движок корзины группирует покупки у 2–3 продавцов, с учётом порогов бесплатной доставки, и показывает разницу с этим наивным итогом.

Установка

python -m venv .venv && ./.venv/bin/pip install -e .
./.venv/bin/pytest          # 74 tests hors ligne, aucun réseau

Нужен Python 3.11 или выше. Проект работает без каких-либо ключей: LeDénicheur, AliExpress и Leboncoin ничего не требуют. Источники с ключами (eBay, Mouser) остаются просто выключенными, и list_sources() сообщает об этом.

Related MCP server: ingrammicro-mcp

Ключи

Никакой секрет не читается из файла под версионным контролем. bin/chineur-web-mcp-server.sh — нет, точнее bin/chineur-mcp.sh — загружает локальный .env, если он существует (игнорируется git), иначе берёт окружение как есть. Это позволяет подставлять их из менеджера секретов простой заменой — значение при этом попадает в процесс только через окружение:

export EBAY_CERT_ID=$(votre-cli-de-coffre get password 'eBay - API Browse')

Variable

Роль

Без неё

EBAY_APP_ID / EBAY_CERT_ID

набор ключей eBay Browse

источник eBay выключен

MOUSER_API_KEY

ключ Mouser Search API

источник Mouser выключен

FLARESOLVERR_URL

браузерный обход при антибот-стене

обход выключен, остальное работает

CHINEUR_VAR

каталог состояния (кэш, квоты, cookie, журнал)

<dépôt>/var

Использование

Доступно через MCP stdio (bin/chineur-mcp.sh), три инструмента:

Инструмент

Роль

price_project(articles, zipcode?, used_threshold?, detail?)

оценивает полный список одним вызовом

best_price(article, …)

случай одного товара, с detail="full"

list_sources()

состояние, оставшийся почасовой бюджет и текущее отключение каждого источника

Каждый товар принимает количество или лимит: "LD2410C x3", "ESP32-S3 <=12ё".

В командной строке:

python -c "
import asyncio; from chineur.models import Project
from chineur.search import Orchestrator; from chineur.report import render
async def m():
    o = Orchestrator(); print(render(await o.run(Project.build(['LD2410C x2','BME280'])), failures=o.failures))
asyncio.run(m())"

Источники и что они стоят

Источник

Категория

Доставка

Примечание

LeDénicheur

новое + б/у

точная

агрегатор: даёт Amazon, Cdiscount, Fnac, Rue du Commerce, Back Market, Rakuten в одном запросе

AliExpress

новое

оценка

единственный реалистичный источник специфических китайских модулей

Leboncoin

б/у

оценка

максимум 10 поисков в час, это не обсуждается

eBay

новое + б/у

точно

официальная API Browse, активна с 2026-08-06

Mouser

новое

оценка

профессиональный дистрибьютор, официальное API. Покрывает то, что у AliExpress отсутствует (олово, плетёнка, пункты, резисторы, транзисторы, коннекторы). Бесполезен на китайских модулях — их нет или они в 3–5 раз дороже

Известные ограничения, измеренные 2026-08-05 и обход которых невозможен без Playwright (V2):

  • AliExpress не даёт ни продавца, ни доставку на странице поиска, а карточка товара в простом HTTP пуста. Группировка поэтому происходит на уровне платформ, с её порогом бесплатной доставки. После нескольких запросов подряд AliExpress отвечает 200 со страницей на 2 КБ: это распознаётся как блокировка, а не как отсутствие предложений.

  • Бюджет AliExpress — примерно 6 запросов с свежего IP, измерено 2026-08-10 после 46 часов без обращений: 6 позиций отданы (133 маршрутов обмена), блокировка на 7-ю, FlareSolverr тоже отправлялся к стене. Поэтому список из 17 позиций не может быть оценён за один подход скрапером, сколько бы ты ни ждал. Это структурный предел, у которого есть официальное партнёрское API (portals.aliexpress.com), а не настройка терпения.

  • На б/у цена индикативная. Объявления Leboncoin — это свободный текст: результат может быть лотом, сломанной деталью или аксессуаром. Новое и б/у никогда не объединяются в одну цену.

  • Доставка помечается ~, когда она оценочная (таблица shipping.py) и ?, когда неизвестна. Итог, содержащий оценку, помечается как таковой.

Релевантность: настоящий ограничивающий фактор

Измерено 2026-08-08 на реальном стандартном списке (17 позиций, компоненты): «не найденное» было не от недостатка источников, а из-за названия. Две отдельные причины — их разделяли, считая сырые заголовки, выданные eBay до фильтрации.

Слишком длинный запрос. «ńberries…» — точнее «brassart…» — «лося»: «живой припой 60/40 с флюсом 0.8мм» выдаёт 0 результат от eBay; «живой припой» даёт 11. Каждое добавленное описательное слово возвращает результат, пока не станет пусто. Отсюда reduced_query и второй шанс в guarded_search: когда источник не даёт ничего, делается ещё одна попытка с заголовком, урезанным до артикулов и первых двух основных слов, а все остальные определения выбрасываются. Дополнительный запрос — только при неудаче и никогда на последнем кредите бюджета.

Фильтр выбрасывал хорошее. «кабели dupont ассортимент» против «Câble Dupont… Ассортимент 5–100 pnc» сказать упало до 0,67 при пороге 0,70: сравнение только по подстроке убивал плюраль. Теперь _apparie ищет по общему префиксу (60 % слова), и только для слов не короче четырёх букв — никогда для чисел или коротких артикулов, так что «2410» и «2420» остаются разными датчиками.

Результат по тому же списку: eBay вырос с 10 до 14 покрытий из 17, позиций вообще без предложений стало с 5 до 3. Остались три настоящих «недосягаемых» на всех источниках: плата-«пастилка», Die and the 2201M и Sugon 8620DX.

За это придётся платить, и плата реальна. Расширенный поиск отвечает на более широкий вопрос, чем заданный: «ESP32-WROOM-32 DevKit 38 контактов» при варианте «esp32 wroom 32» находит модель с 30 контактами. Поэтому любое предложение из расширения снабжается оговоркой «поиск расширен до „…“», которая должна оставаться видимой до отображения.

Браузерный аварийный выход (FlareSolverr)

Слабый диспетчер проекта: AliExpress — единственный источник китайских модулей, и его блокируют после 5–9 поисковых. В README эта дыра объявлялась «не закрывается без Playwright (V2)». Она закрывается, без дополнительной зависимости со стороны проекта: экземпляр FlareSolverr использует настоящий Chrome, выполняет JavaScript и имеет полный браузерный цифровой отпечаток. Он задаётся через FLARESOLVERR_URL; если не задан — аварийный выход просто выключается`.

Измерено 2026-08-08, в момент, когда прямой коннектор был заблокирован, а его брейкер открыт: fr.aliexpress.com/w/wholesale-LD2410C.html отдал HTTP 200, 832 КБ, без принятых анти-бот-маркеров, и существующий HTML-парсер нашёл там 60 позиций с ценами в EUR. Никакой замены в парлинге не понадобилось.

Подключение в AliExpress._items: при анти-бот-стене или усечённой странице сначала пробуем обход, и только потом выбрасываем Blocked. Конструктивные моменты:

  • Авария, а не постоянный режим. Каждый вызов запускает Chrome: это медленно и тяжело. Идём туда только в подтверждённый блок.

  • None — не [], когда обход не дал результата. Пустой список был бы воспринят как «нет результатов», брейкер не разомкнулся бы, и коннектор на следующей позиции снова стучался бы в заблокированный источник, усиливая ограничение.

  • Никогда не блокирует. flaresolverr.fetch не бросает исключение: падение решителя маскировало бы настоящую причину под инцидентом инфраструктуры. FLARESOLVERR_URL= отключает обход.

  • Останавливаемся после двух неудачных . Смотри лимит ниже: без этого каждый следующий элемент ещё оплачивал бы десятки секунд ожидания впустую.

Его лимит, измеренный 2026-08-08. Обход — это не обходка наружу, это второй бюджет. На восемь запросов AliExpress подряд: шесть вернули по 60 позиций за 4–6 секунд, седьмой — ошибку 500 после ожидания 101 с, восьмой — анти-бот-стену (208 КБ, маркер RGV587). Исходящий IP не меняется, поэтому рано илинаблю ту же стену. Два следствия в коде: maxTimeout уменьшено с 90 до 45 секунд, и стена, отданная с HTTP 200, считается провалом; иначе счётчик остановок никогда не сработал бы.

На практике бюджет AliExpress увеличивается примерно с 9 до 15 запросов, по 60 позиций на странице вместо 20. Чистый выигрыш — где-то не бесконечность.

Анти-банные предохранители

Исходящий IP единственный, и он резидентный: бан ресонанс отрубает его весь. Модуль написан так, чтобы никогда этого не допускало.

  • Часовые лимиты сохраняются в SQLite (var/chineur.db): Leboncoin 10/ч, LeDénicheur 30/ч, AliExpress 20/ч, eBay 200/ч, Mouser 60/ч (квоты API, риска для IP нет).

  • Последовательный интервал по источнику, а не просто sleep: поскольку оркестратор запускает все товары параллельно, одновременно задержки завершились бы одновременно, и запросы всё равно уходили бы залпом. Каждый выход ждёт предыдущий.

  • Автоматический предохранитель при 403 / капче / усечённой странице: 1 ч, 2 ч для AliExpress, причём штраф сохраняется и после всплеска запросов, который его вызвал.

  • Блокировка AliExpress — это не квота и не вопрос частоты запросов. Три испытания от 2026-08-06, метки которых никогда не кэшировались:

    интервал

    транспорт

    отдано до блокировки

    6–12 с

    голые запросы

    5 (блокировка на 46 с)

    6–12 с

    cookie-сессия

    6 (блокировка на 56 с)

    45–60 с

    cookie-сессия

    2 (блокировка на 108 с)

    2,5 с

    cookie-сессия, JSON-эндпоинт

    9 (блокировка на 30 с)

    Замедление ухудшает результат, значит, дело не в ритме: лучшая результат достигается при быстрых запросах. Останавливает блокировка на ~40 минут — измерено дважды — и о ней сигнализируют FAIL_SYS_CONNECT / RGV587_ERROR::SM, антибот Alibaba, требующий подтверждения.

  • Товары читаются с внутренней endpoint POST www.aliexpress.com/fn/search-pc/index (того, который вызывает сама страница поиска), полезной нагрузкой вида mods, из уже открытой на главной сессисии. Он возвращает ровно такие же объекты товаров, как HTML-страница, в .data.result.mods.itemList.content, и всего 390 КБ вместо 600. Ловушка: несколько блоков ответа содержат ключ content; тот, что относится к фильтрам поиска, находится до includes. HTML-страница остаётся автоматическим запасным вариантом, но только если ответ больше не соответствует ожидаемой форме: при антибот-стене повторная попытка через HTML с того же IP просто потратила бы запрос.

  • Постоянная сессия (transport.Session) сохраняется для AliExpress: страница главной посещается один раз, файлы cookie впоследствии имеют ходить в cookies/, чтобы пережить перезапуск, и сбрасываются сразу, как только страница возвращается с усечением. Никакого выигрыша в блокировке не измерено; она оставлена, потому что приближает трафик к браузерному.

  • Незавершённая идея: если внутренний эндпоинт когда-нибудь закроется, можно отдать источник стороннему хостингу (omkar.cloud, 5 000 бесплатных запросов/мес), ценой того, что третья сторона будет видеть наши запросы.

  • Кэш проверяется до ограничителя скорости: повторная обработка проекта ничего не загружает. TTL по умолчанию 1 ч, но никогда не короче, чем срабатывает режим разрыва (Connector.effective_ttl, 6 ч для AliExpress). Без этого минимума проект, превышаем бюджет источника, не может завершиться: запуск после паузы находит пустой кэш, снова выполняет те же первые запросы, снова тратит бюджет и снова получает блокировку — бесконечно.

  • Проект, превышающий лимит Leboncoin, обрабатывается в порядке убывающей важности, и необработанные товары называются в отчёте.

Экономия токенов

Расчёт остаётся на Python, вверх поднимается только результат: вывод в плотном табличном тексте, на каждый товар — по одному лучшему новому предложению и одному подморнадному, обрезанные заголовки, очищенные URL, сгруппированные пометки, диагностика в var/chineur.log. Измерено: 10 товаров ≈ 650 токенов.

Тесты

pytest              # 74 tests hors ligne, aucun réseau
pytest -m network   # 5 tests d'intégration réels (consomment du quota)

Движок корзины полностью тестируется офлайн, включая сложные случаи (порог бесплатной доставки, срабатывает из-за размещения заказа, единственный продавец, товар без предложений, равные цены). Свойство «оптимизальный итог ≤ наивный итог» проверяется на 50 случайных наборах предложений.

Mouser

Всего одна переменная: MOUSER_API_KEY. Бесплатный ключ в самообслуживании на mouser.com/api-hub (вкладка Search API).

Ключ должен быть создан из mouser.fr. Поиск по ключевым словам не принимает никаких параметров валюты (проверено в swagger api.mouser.com/api/docs/V1): валюта зависит от сайта, на котором создана ключ. Ключ, созданный на mouser.com, возвращает доллары, и коннектор отбрасывает их, а не конвертируют по выдуманному курсу — источникл бы просто выглядел пустым.

Заявленные лимиты Mouser: 50 позиций за раз, 300 запросов в минуту, 1 000 запросов в день. Отсюда limit_per_hour = 60 и интервал 2 с: это не защита от бана, а соблюдение лимита.

Три принципиальных выбора:

  • mouserPaysCustomsAndDuties: true — Mouser отправляет из Техаса. Без этого флага таможенные пошлины приходят позже, и товар «дешевле» на бумаге становится дороже при доставке.

  • searchOptions: InStock — позиция с срокым 12 недель не нужна в сравнении цен для текущего проекта.

  • Цены уровни отслеживаются по запрашиваемому количеству. Выбор самого первого уровня делает переоценку всей групповой закупки пассивных компонентов.

Две ловушки, которые исказили бы сравнение, и они обель оставляют в примечании к предложению: минимальный заказ (0,10 € за штуку в пак способнаком по 100 штук, т.е. реальные 10 € на кассе) и формат цены («0,096 €» — это цена с трём знакам после запятой, а «$1,250» — это тысяча двести пятьдесят; наивный парсер ошибётся в тысячу раз в обеи направлениях).

Доставка: не проверена. Франко в 50 € без НДС и около 20 € при сумме ниже этой суммы сверены по вебу (2026-08-07), а не по счёту. Поэтому они описаны в shipping.py и возвращаются как ESTIMATED, но не как реальный факт. Это нужно исправить при первом настоящем заказе: если заказ ниже порога, доставка съедает выгоду, и именно этот порог решает, нужна ли данная источник.

eBay

EBAY_APP_ID (App ID) и EBAY_CERT_ID (Cert ID), для набора ключей Production — единственный работающий. Набор Sandbox подключается через EBAY_ENV=sandbox, которая переключает на api.sandbox.ebay.com. В sandbox коннектор остаётся выключенным: инвентарь фиктивный, цены попадали бы в корзину без всякого предупреждения. EBAY_SANDBOX_OK=1 включает его только для проверкой механики.

Проверено 2026-08-06 на наборе Production: получен маркер client_credentials, выполнены реальные искания (29 предложений по запросу «cable hdmi 2.1 2m», стоимость доставки точно прочитана в shippingOptions).

Состояние товара читается из conditionId, никогда не из condition: последний локализован eBay («Neuf», «Occasion», «Ouvert (jamais utilisé)» для EBAY_FR), а исходная англоязычная таблица не совпадали ни с чем, поэтому всё выходило как подержанное. Товар с кодом 7000 («на запчасти») отбрасывается: при цене 3 € повреждённое изделие выиграло бы сравнение, и на это ничто бы не указало.

Соответствие (« Your Must be»). eBay переводит набор ключей Production только после подписки на не уведомления об удалении аккаунта счёта или исключенияnement. Проект выбирает ограничение "не сохраняю данные eBay", и код делает его буквально истинным: EBay.cacheable = False, значит, ни один ответ eBay не записывается в var/chineur.db (в них есть псевдонимы продавцов). Тест это закрепляет. Если однажды его снова включить в кэш, исключение станет ложноëм: тогда придётся разместить у себя endpoint для уведомлений.

Лицензия

MIT, см. LICENSE.

Available Tools

3 tools
best_priceC

Meilleur prix livré pour un seul article, neuf et occasion séparés.

ParametersJSON Schema
NameRequiredDescriptionDefault
detailNofull
articleYes
zipcodeNo
used_thresholdNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.9/5.0
Behavior3/5

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

There are no annotations, so the description must carry behavioral disclosure on its own. It does reveal useful behavior: prices include delivery and new/used results are separated. It does not mention side effects, data sources, or how thresholds affect results, but the core behavior is stated.

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 a single concise sentence with no filler or repetition. The main outcome is front-loaded, though the phrasing is telegraphic.

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

Completeness2/5

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

An output schema exists, so return values need not be described. However, with four parameters and zero parameter documentation, the description is not complete enough for an agent to confidently set 'detail' and 'used_threshold' correctly.

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

Parameters1/5

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

Schema description coverage is 0%, and the description does not explain any of the four parameters. While 'article' and 'zipcode' are somewhat self-evident, 'detail' and 'used_threshold' have no meaning clarified anywhere, making correct invocation unreliable.

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 clearly states the tool's result: the best delivered price for a single article, with new and used items separated. It is understandable on its own, but it lacks an explicit verb and does not differentiate from the sibling tools price_project and list_sources.

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 phrase 'pour un seul article' implies this tool is for single-item price lookups, which contrasts with the project-oriented price_project and list-oriented list_sources siblings. However, there is no explicit instruction about when to use this tool versus those alternatives.

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

list_sourcesB

État de chaque source : activée, quota horaire restant, coupure en cours.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.3/5.0
Behavior3/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. It does state what the tool reports (enabled state, remaining quota, outage status), which conveys a read-only intent, but it never explicitly says the operation is non-mutating or describes side-effect implications. An output schema exists to cover the return shape, but the description adds only the status facets.

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?

A single, front-loaded French sentence conveys the core purpose efficiently with no filler. It could feasibly add usage nuance, but for a parameterless status tool the brevity is reasonable and not wasteful.

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

Completeness3/5

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

An output schema is present, so return-value structure is covered by structured data, and there are no parameters to document. The main gap is the absence of guidance on when to invoke it relative to the pricing siblings; for an agent to use it correctly, that routing context would make it complete.

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 takes zero parameters, so there is nothing for the description to explain; schema coverage is vacuously 100%. Per the baseline for a zero-parameter tool, a 4 is appropriate since the description need not compensate for any undocumented inputs.

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 states a clear verb-plus-resource purpose: report the status of each source, listing the exact status facets it exposes (enabled, remaining hourly quota, active outage). This is specific enough to be useful. It distinguishes from the pricing siblings implicitly, though it never names them.

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 call this tool versus price_project or best_price. An agent must infer from the sibling names (which relate to pricing) that this status tool serves a different purpose. There is no mention of prerequisites, ordering, or situations where this tool should not be used.

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

price_projectA

Chiffre une liste d'articles au meilleur prix livré et rend le plan de commande groupé.

C'est le point d'entrée principal : un seul appel pour tout le projet. Chaque article peut porter une quantité (« LD2410C x3 ») ou un plafond (« ESP32 <=12€ »). Rend le meilleur neuf et le meilleur occasion par article, le plan de commande qui minimise le total port compris, et l'écart avec le total naïf.

ParametersJSON Schema
NameRequiredDescriptionDefault
detailNocompact
zipcodeNo
articlesYes
radius_kmNo
used_thresholdNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior4/5

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

With no annotations, the description carries the full burden of behavioral disclosure. It explicitly reveals what the tool returns (best new/used per article, order plan minimizing shipping, and difference from naive total) and that it only produces a plan, not an actual purchase. This gives a good sense of its side-effect-free nature, though it does not mention potential errors, rate limits, or dependency on external sources.

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 a single, well-structured paragraph that leads with the main purpose and then gives behavior and examples. It is not overly long and efficiently communicates the core function. Minor redundancy in repeating the return list twice, but overall it is concise and front-loaded.

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

Completeness2/5

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

Given the presence of an output schema, return value format is not required, but the description is incomplete for a 5-argument tool with zero schema descriptions. The lack of parameter explanations (especially 'detail' and 'used_threshold') means an agent cannot confidently set non-default values. While the main scope is clear, the missing parameter semantics make it incomplete for full usage.

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

Parameters2/5

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

Schema description coverage is 0%, so the description must clarify all parameters. It does explain the format for the 'articles' parameter (quantity or cap), which is the only required field. However, it leaves 'detail', 'zipcode', 'radius_km', and 'used_threshold' undefined. The defaults exist in the schema, but their meaning is not explained, leaving the agent without guidance for non-default values. The description compensates only for one of five 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 clearly states the tool's purpose: pricing a list of articles at best delivered price and returning a grouped order plan, explicitly calling itself the main entry point. This differentiates it from sibling tools (best_price, list_sources) that are presumably lower-level operations. It also explains the accepted article syntax (quantity or cap), giving concrete examples.

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 states that this is the primary entry point and that a single call handles the entire project, implying it should be used instead of composing multiple calls. However, it does not explicitly say when to prefer best_price or list_sources, nor does it mention exclusions (e.g., for single-item queries). It provides clear context but no explicit alternatives.

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.

  1. 3 tool updatesv0.1.0
    • First observedbest_price
    • First observedlist_sources
    • First observedprice_project

TDQS

A3.6/5.0

Scored across 3 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: price_project handles multi-article project planning, best_price handles a single article, and list_sources provides source status. No overlap or ambiguity between them.

Naming Consistency4/5

All names use lowercase snake_case, which is consistent. However, the structure varies slightly: price_project and list_sources follow verb_noun, while best_price is adjective_noun. This minor deviation is not confusing but prevents a perfect score.

Tool Count5/5

With only 3 tools, the server is tightly scoped. The main tool price_project serves as the primary entry point, while the others handle single-item lookups and system status. This is an appropriate size for the purpose and each tool earns its place.

Completeness5/5

The tool surface covers the core workflow: comprehensive project pricing (price_project), single-article queries (best_price), and source health monitoring (list_sources). No obvious gaps exist, as the domain is price comparison and order planning, which these tools fully address.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    C
    maintenance
    MCP server for finding, comparing, and ranking the cheapest real offers across eBay, Amazon, Craigslist, OfferUp, and Google Shopping, with tax estimation and exact-model filtering.
    6
    1
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables the full Ingram Micro Reseller purchasing lifecycle through a single stateless HTTP MCP service, covering catalog and pricing, quotes, quote-to-order, order placement/modification/cancellation/lookup, invoices, renewals, special deals, returns, and freight estimates with one set of credentials.
    24
    Apache 2.0
  • A
    license
    A
    quality
    C
    maintenance
    Enables eBay-backed product search, authenticated shopping carts, checkout quotes, and order management through MCP tools and resources.
    11
    7 npm
    MIT
  • A
    license
    B
    quality
    B
    maintenance
    Enables product discovery, seller-offer comparison, and bounded, approval-gated cart operations with account-scoped planning and read-back reconciliation.
    40
    MIT