Skip to main content
Glama

chineur

Chiffrage d'un projet entier au meilleur prix livraison comprise, neuf et occasion séparés, avec un plan de commande groupé qui minimise le total réellement payé.

Le moins cher article par article n'est pas la bonne réponse : 10 articles chez 10 marchands, c'est 10 frais de port. Le moteur de panier groupe les achats chez 2 ou 3 marchands, seuils de franco compris, et affiche l'écart avec ce total naïf.

Installation

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

Python 3.11 ou plus. Le projet tourne sans aucune clé : LeDénicheur, AliExpress et Leboncoin ne demandent rien. Les sources à clé (eBay, Mouser) restent simplement éteintes, et list_sources() le dit.

Related MCP server: ingrammicro-mcp

Clés

Aucun secret n'est lu dans un fichier versionné. bin/chineur-mcp.sh charge un .env local s'il existe (ignoré par git), sinon il prend l'environnement tel quel, ce qui permet de les injecter depuis un gestionnaire de secrets par simple substitution, la valeur ne transitant alors que par l'environnement du processus :

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

Variable

Rôle

Sans elle

EBAY_APP_ID / EBAY_CERT_ID

keyset eBay Browse

source eBay éteinte

MOUSER_API_KEY

clé Mouser Search API

source Mouser éteinte

FLARESOLVERR_URL

recours navigateur sur mur anti-bot

recours éteint, le reste fonctionne

CHINEUR_VAR

répertoire d'état (cache, quotas, cookies, journal)

<dépôt>/var

Utilisation

Exposé en MCP stdio (bin/chineur-mcp.sh), trois outils :

Outil

Rôle

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

chiffre une liste complète en un seul appel

best_price(article, …)

le cas à un seul article, en detail="full"

list_sources()

état, quota horaire restant et coupure en cours de chaque source

Chaque article accepte une quantité ou un plafond : "LD2410C x3", "ESP32-S3 <=12€".

En ligne de commande :

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())"

Sources et ce qu'elles valent

Source

Volet

Port

Remarque

LeDénicheur

neuf + occasion

exact

agrégateur : apporte Amazon, Cdiscount, Fnac, Rue du Commerce, Back Market, Rakuten en une requête

AliExpress

neuf

estimé

seule source réaliste pour les modules chinois de niche

Leboncoin

occasion

estimé

10 recherches/heure maximum, non négociable

eBay

neuf + occasion

exact

API Browse officielle, active depuis le 2026-08-06

Mouser

neuf

estimé

distributeur pro, API officielle. Couvre ce qu'AliExpress rate (étain, tresse, résistances, transistors, connectique). Inutile sur les modules chinois : absent, ou 3 à 5x le prix

Limites connues, mesurées le 2026-08-05 et non contournables sans Playwright (V2) :

  • AliExpress ne donne ni le vendeur ni le port sur la page de recherche, et la fiche produit en HTTP simple est vide. Le groupage se fait donc au niveau de la plateforme, avec son seuil de franco. Après plusieurs requêtes rapprochées, AliExpress répond 200 avec une page de 2 Ko : c'est détecté et traité comme un blocage, pas comme une absence d'offre.

  • Le budget AliExpress est d'environ 6 requêtes par IP fraîche, mesuré le 2026-08-10 après 46 h sans aucune sollicitation : 6 articles servis (133 offres), blocage au 7e, FlareSolverr mis au mur lui aussi. Une liste de 17 articles ne peut donc pas être chiffrée en une fois par scraping, quelle que soit l'attente respectée. C'est la limite structurelle qui justifie l'API affiliée officielle (portals.aliexpress.com), et non un réglage de patience à trouver.

  • En occasion, le prix est indicatif. Les annonces Leboncoin sont du texte libre : un résultat peut être un lot, une pièce cassée ou un accessoire. Neuf et occasion ne sont jamais fusionnés en un prix unique.

  • Le port est marqué ~ quand il est estimé (table shipping.py) et ? quand il est inconnu. Un total contenant une estimation est signalé comme tel.

Pertinence : le vrai facteur limitant

Mesuré le 2026-08-08 sur la liste type réelle (17 articles, composants) : les « introuvables » ne venaient pas d'un manque de sources mais du libellé. Deux causes distinctes, séparées en comptant les titres bruts rendus par eBay avant filtrage.

La requête est trop longue. « etain soudure 60/40 flux 0.8mm » fait renvoyer 0 résultat par eBay ; « etain soudure » en renvoie 11. Chaque mot descriptif ajouté rétrécit le résultat jusqu'au vide. D'où reduced_query et la seconde chance de guarded_search : quand une source ne rend rien, on retente une fois sur un libellé réduit aux références et aux deux premiers mots porteurs, les qualifiants jetés. Une requête de plus uniquement en cas d'échec, et jamais sur le dernier crédit du quota.

Le filtre jetait du bon. « cables dupont assortiment » contre « Câble Dupont … Assortiment 5 à 100pcs » tombait à 0.67 pour un seuil de 0.70 : le score ne comparait que par inclusion de chaîne, donc le pluriel cassait tout. _apparie rapproche désormais sur le préfixe commun (60 % du mot), réservé aux mots d'au moins 4 lettres — jamais aux nombres ni aux références courtes, pour que « 2410 » et « 2420 » restent deux capteurs différents.

Résultat sur la même liste : eBay passe de 10 à 14 articles couverts sur 17, articles sans aucune offre de 5 à 3. Restent trois vrais introuvables, à toutes les sources : la plaque pastillée, le Diese 2201M et la Sugon 8620DX.

Le prix à payer, et il est réel. Une recherche élargie répond à une question plus large que celle posée : « ESP32-WROOM-32 DevKit 38 broches » élargi en « esp32 wroom 32 » remonte un modèle 30 broches. Toute offre issue d'un élargissement porte donc la réserve « recherche élargie à « … » », qui doit rester visible jusqu'à l'affichage.

Recours navigateur (FlareSolverr)

Le point faible du projet : AliExpress est la seule source des modules chinois, et elle se fait bloquer au bout de 5 à 9 recherches. Le README annonçait ce trou comme « non contournable sans Playwright (V2) ». Il l'est, sans dépendance supplémentaire côté projet : une instance FlareSolverr pilote un vrai Chrome, exécute le JavaScript et porte une empreinte de navigateur complète. Elle se déclare par FLARESOLVERR_URL ; non renseignée, le recours est simplement éteint.

Mesuré le 2026-08-08, alors que le connecteur direct était bloqué et son disjoncteur ouvert : fr.aliexpress.com/w/wholesale-LD2410C.html rend HTTP 200, 832 Ko, aucun marqueur anti-bot, et le parseur HTML existant y décode 60 articles avec prix en EUR. Aucune modification du parsing n'a été nécessaire.

Branchement dans AliExpress._items : sur mur anti-bot ou page tronquée, on tente le recours avant de lever Blocked. Points de conception :

  • Recours, pas régime. Chaque appel démarre un Chrome : c'est lent et lourd. On n'y passe que sur un blocage avéré.

  • None et pas [] quand le recours ne donne rien. Une liste vide passerait pour « aucun résultat », le disjoncteur ne s'ouvrirait pas, et le connecteur retaperait la source bloquée à l'article suivant en aggravant le bridage.

  • Jamais bloquant. flaresolverr.fetch ne lève pas : une panne du solveur masquerait la vraie cause derrière un incident d'infrastructure. FLARESOLVERR_URL= l'éteint.

  • Abandon après 2 échecs consécutifs. Voir la limite ci-dessous : sans ça, chaque article suivant paierait encore des dizaines de secondes d'attente pour rien.

Sa limite, mesurée le 2026-08-08. Le recours n'est pas un contournement, c'est un second budget. Sur huit recherches AliExpress enchaînées : six servies à 60 articles chacune en 4 à 6 s, la septième en erreur 500 après 101 s d'attente, la huitième renvoyant le mur anti-bot (208 Ko, marqueur RGV587). L'IP de sortie ne change pas, donc le même mur finit par tomber. Deux conséquences dans le code : maxTimeout ramené de 90 à 45 s, et un mur rendu en HTTP 200 compte comme un échec, sinon le compteur d'abandon ne se déclencherait jamais.

En pratique le budget AliExpress passe donc d'environ 9 recherches à environ 15, avec 60 articles par page au lieu de 20. C'est un gain net, ce n'est pas l'illimité.

Garde-fous anti-ban

L'IP de sortie est unique et résidentielle : un ban la coupe entièrement. Tout le module est écrit pour ne jamais en arriver là.

  • Quotas horaires persistés en SQLite (var/chineur.db) : Leboncoin 10/h, LeDénicheur 30/h, AliExpress 20/h, eBay 200/h, Mouser 60/h (quotas API, aucun risque IP).

  • Espacement sérialisé par source, pas un simple sleep : l'orchestrateur lançant tous les articles en parallèle, des délais concurrents s'écouleraient en même temps et les requêtes partiraient quand même en rafale. Chaque départ attend le précédent.

  • Disjoncteur sur 403 / captcha / page tronquée : 1 h, 2 h pour AliExpress, dont la pénalité persiste au-delà de la rafale qui l'a déclenchée.

  • Le blocage AliExpress n'est ni un quota ni une question de cadence. Trois recettes du 2026-08-06, libellés jamais mis en cache :

    espacement

    transport

    servies avant blocage

    6-12 s

    requêtes nues

    5 (blocage à 46 s)

    6-12 s

    session à cookies

    6 (blocage à 56 s)

    45-60 s

    session à cookies

    2 (blocage à 108 s)

    2,5 s

    session à cookies, endpoint JSON

    9 (blocage à 30 s)

    Ralentir dégrade le rendement, donc la cadence n'est pas le levier : le meilleur rendement s'obtient en allant vite. Le blocage dure ~40 min, mesuré deux fois, et se signale par FAIL_SYS_USER_VALIDATE / RGV587_ERROR::SM, l'anti-bot d'Alibaba qui exige une validation.

  • Les articles sont lus sur l'endpoint interne POST www.aliexpress.com/fn/search-pc/index (celui que la page de recherche appelle elle-même), charge utile de forme mods, depuis une session déjà ouverte sur l'accueil. Il rend exactement les mêmes objets article que la page HTML, en .data.result.mods.itemList.content, pour 390 Ko au lieu de 600. Piège : plusieurs blocs de la réponse portent une clé content, celui des filtres de recherche arrive avant itemList. La page HTML reste en repli automatique, mais uniquement si la réponse n'a plus la forme attendue : sur un mur anti-bot, retenter en HTML depuis la même IP ne ferait que gaspiller une requête.

  • Session persistante (transport.Session) conservée pour AliExpress : page d'accueil visitée une fois, cookies rejoués ensuite, pot dans var/cookies/ pour survivre à un redémarrage, jeté dès qu'une page revient tronquée. Aucun gain mesuré sur le blocage, gardée parce qu'elle rapproche le trafic de celui d'un navigateur.

  • Piste non tranchée : si l'endpoint interne se referme un jour, sous-traiter la source à un service hébergé (omkar.cloud, 5 000 requêtes/mois gratuites), au prix d'un tiers qui voit nos recherches.

  • Cache consulté avant le rate limiter : rechiffrer un projet ne retape rien. TTL 1 h par défaut, mais jamais plus court que la coupure du disjoncteur (Connector.effective_ttl, 6 h pour AliExpress). Sans ce plancher, un projet plus large que le budget d'une source ne peut pas se terminer : la relance d'après-coupure retrouve un cache vide, refait les mêmes premières recherches, rebrûle le budget et se fait rebloquer, indéfiniment. Sauf eBay, exclu du cache pour rester conforme à l'exemption (voir plus bas).

  • Un projet dépassant le quota Leboncoin est traité par ordre d'enjeu décroissant, et les articles non traités sont nommés dans la restitution.

Économie de tokens

Le calcul reste en Python, seul le verdict remonte : sortie en texte tabulaire dense, une meilleure offre neuve et une occasion par article, titres tronqués, URL nettoyées, notes regroupées, diagnostics dans var/chineur.log. Mesuré : 10 articles ≈ 650 tokens.

Tests

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

Le moteur de panier est entièrement testable hors ligne, y compris ses cas piégeux (seuil de franco déclenché par le groupage, marchand unique, article sans offre, égalités). La propriété « total optimisé ≤ total naïf » est vérifiée sur 50 jeux d'offres aléatoires.

Mouser

Une seule variable : MOUSER_API_KEY. Clé gratuite en self-service sur mouser.com/api-hub (onglet Search API).

La clé doit être créée depuis mouser.fr. La recherche par mot-clé n'accepte aucun paramètre de devise (vérifié dans le swagger api.mouser.com/api/docs/V1) : la devise est celle du site d'inscription. Une clé créée sur mouser.com renvoie des dollars, que le connecteur écarte plutôt que de les convertir à un taux inventé — la source paraîtrait simplement vide.

Quotas annoncés par Mouser : 50 pièces par appel, 30 appels/minute, 1 000 appels/jour. D'où limit_per_hour = 60 et 2 s d'espacement : ce n'est pas de l'anti-ban, c'est le respect du quota.

Trois choix de fond :

  • mouserPaysCustomsAndDuties: true — Mouser expédie du Texas. Sans ce drapeau, les droits de douane arrivent après coup et un prix « moins cher » sur le papier devient plus cher à la livraison.

  • searchOptions: InStock — une référence à 12 semaines de délai n'a rien à faire dans une comparaison de prix pour un projet en cours.

  • Paliers de prix suivis à la quantité demandée. Retenir le palier 1 surestime tout achat groupé de composants passifs.

Les deux pièges qui fausseraient une comparaison, tous deux signalés en réserve sur l'offre : le minimum de commande (0,10 € l'unité par sachet de 100, soit 10 € réels à la caisse) et le format de prix (« 0,096 € » est un prix à trois décimales, « $1,250 » vaut mille deux cent cinquante — un parseur naïf se trompe d'un facteur mille dans les deux sens).

Port : non vérifié. Le franco de 50 € HT et les ~20 € en dessous sont recoupés sur le web (2026-08-07), pas sur une facture. Ils vivent donc dans shipping.py et ressortent en ESTIMATED, jamais en fait établi. À corriger dès la première commande réelle : sous le franco, le port écrase le gain, et c'est ce seuil qui décide si la source sert à quelque chose.

eBay

EBAY_APP_ID (App ID) et EBAY_CERT_ID (Cert ID), pour un keyset Production — le seul exploitable. Un keyset Sandbox se branche avec EBAY_ENV=sandbox, qui bascule sur api.sandbox.ebay.com. En sandbox le connecteur reste éteint : l'inventaire est factice, les prix entreraient dans le panier sans que rien ne le signale. EBAY_SANDBOX_OK=1 le rallume pour tester la plomberie uniquement.

Vérifié le 2026-08-06 sur un keyset Production : jeton client_credentials obtenu, recherches réelles (29 offres sur « cable hdmi 2.1 2m », port exact lu dans shippingOptions).

L'état de l'article se lit sur conditionId, jamais sur condition : ce dernier est traduit par eBay (« Neuf », « Occasion », « Ouvert (jamais utilisé) » sur EBAY_FR), et la table à clés anglaises d'origine ne matchait rien, donc tout ressortait en occasion. Les articles 7000 (« pour pièces ») sont écartés : à 3 €, un article cassé gagnerait la comparaison sans que rien ne le signale.

Conformité (« Your Keyset is currently disabled »). eBay n'active un keyset Production qu'après abonnement aux notifications de suppression de compte, ou exemption. Le projet prend l'exemption « je ne conserve pas de données eBay », et le code la rend littéralement vraie : EBay.cacheable = False, donc aucune réponse eBay n'est écrite dans var/chineur.db (elles contiennent des pseudos vendeurs). Un test le verrouille. Si un jour on remet eBay en cache, l'exemption devient fausse : il faudra héberger l'endpoint de notification à la place.

Licence

MIT, voir 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