Consommer vs exposer le MCP — les deux sens du fil

Recycler la documentation du projet LivresAgités (en sommeil) vers le dépôt pédagogique. Ce notebook rend exécutable la leçon du Parcours 0 du dossier AI-Engine-WordPress : AI-Engine est un des rares produits à jouer les deux rôles du protocole MCP — il expose* WordPress comme serveur MCP (un agent externe appelle ses outils), et il consomme des serveurs MCP externes (module Orchestration). La confusion entre les deux est le piège le plus fréquent du dossier.*

Thèse. Les deux sens du protocole ne se configurent pas au même endroit, ne servent pas le même public, et — c’est ce que ce notebook mesure — ne devraient pas se chevaucher fonctionnellement. Quand un outil exposé et un outil consommé font la même chose, l’agent qui les a tous les deux doit choisir, et le double-écrit devient un risque.

Ce notebook ne dépend d’aucun service : pas de réseau, pas de modèle, pas de clé. Un mini-serveur MCP et un mini-client MCP sont construits en mémoire, sur le même fixture synthétique « Maison Valmont ». Ce qui est enseigné est la structure du chevauchement, pas une mesure sur une instance réelle.

1. Le protocole MCP en une phrase

Model Context Protocol est un protocole client-serveur par lequel un agent (LLM) découvre et appelle des outils exposés par une application. Le serveur publie un catalogue (liste d’outils avec leur schéma) ; le client (appelé host ou agent) choisit un outil, fournit des arguments, reçoit un résultat. Le modèle ne « sait » rien faire lui-même : tout passe par les outils qu’on lui expose.

Deux rôles, donc : serveur (j’expose mes outils) et client (j’appelle les outils des autres). Une même application peut jouer les deux. AI-Engine le fait ; c’est rare. La plupart des produits ne jouent qu’un rôle.

Les deux sens, operationnellement

Le titre du notebook oppose deux verbes que le protocole MCP rend concrets. Exposer, c’est inscrire ses propres outils dans un catalogue qu’un agent externe viendra appeler : la machine locale devient serveur, l’initiative du dialogue vient du dehors. Consommer, c’est prendre l’initiative d’appeler des outils hébergés ailleurs : la machine locale devient cliente, et le catalogue consulté décrit ce que l’autre sait faire. Dans le vocabulaire du protocole, ces deux positions ont chacune un nom — hôte et client MCP — mais le point pédagogique est ailleurs : rien n’empêche un même site d’occuper les deux positions à la fois, sur le même fil, avec des catalogues différents.

Les deux sens coexistent sans contradiction parce qu’ils répondent à deux questions différentes. La question du sens exposé est : « que sait-on faire faire à ce site ? ». La question du sens consommé est : « de quelles capacités extérieures ce site dépend-il pour ses propres traitements ? ». Un site qui expose sans consommer vit en autarcie servie — on l’appelle, on ne l’appelle pas. Un site qui consomme sans exposer est un consommateur muet — il dépend sans offrir. Le cas pédagogique de ce notebook, la Maison Valmont, qui expose sept outils et en consomme sept ailleurs, est le cas général d’une application intégrée : elle offre au monde ce qu’elle sait faire, et elle s’appuie sur le monde pour ce qu’elle ne sait pas faire seule.

Ce double statut a une conséquence directe sur la manière de raisonner : quand on évalue « les outils MCP d’un site », la phrase est incomplète tant qu’on n’a pas dit de quel côté du fil on se place. Les deux catalogues qui suivent portent le même format, mais ils n’ont pas le même statut contractuel — l’un est une offre publique, que le site s’engage à servir ; l’autre est une dépendance déclarée, que le site subit autant qu’il la choisit. Toute la question du chevauchement, au cœur de la suite, vient de ce que ces deux statuts différents décrivent parfois la même capacité fonctionnelle : savoir lire une fiche de livre, que ce soit en la servant soi-même ou en l’appelant chez un autre.

Enfin, les deux sens ne vieillissent pas de la même manière, et c’est une raison de plus de les distinguer soigneusement. Une offre exposée est un contrat : la retirer casse des appelants inconnus, donc elle bouge lentement et avec versionnement. Une dépendance consommée est un risque accepté : l’externe peut changer ses tarifs, ses formats, sa disponibilité, et chaque évolution est subie. Les mesures qui suivent donnent les critères pour décider laquelle des deux positions mérite de porter une capacité donnée. Un dernier repère de vocabulaire, pour la suite de la série : les catalogues de ce notebook sont déclarés en mémoire, côté code, mais ils jouent le rôle exact des documents que le protocole rend consultables — la liste des outils qu’un hôte publie et décrit, et que le client découvre avant de pouvoir appeler quoi que ce soit. La découverte précède l’appel ; l’inventaire précède la décision. Quand les sections suivantes comparent les deux listes, elles font donc le travail que toute intégration MCP réelle devrait faire avant de signer : lire les deux catalogues, les projeter dans un vocabulaire commun, et mesurer — pas seulement parcourir.

2. Deux catalogues synthétiques — un exposé, un consommé

On monte la « Maison Valmont » avec son catalogue d’outils exposés (valmont_*, ceux qu’un agent externe peut appeler sur le site), et un catalogue d’outils consommés depuis un serveur MCP externe hypothétique (un service d’enrichissement de fiches livre, bookgraph_*). Les deux sont des dicts en mémoire — aucun réseau.

Ce que le format (verbe, cible) achète ici

Chaque entrée des deux catalogues associe un nom d’outil à une spécification minimale : un verbe d’action (lire, soumettre, modifier…) et une cible (manuscrit, livre, lecteur…). Ce format est volontairement plus pauvre qu’une vraie fiche d’outil MCP, qui décrirait un schéma d’arguments JSON, des types de retour, des effets de bord, des conditions d’erreur. La pauvreté est le choix pédagogique : en réduisant chaque outil à ce qu’il fait (le verbe) et à quoi (la cible), on rend deux catalogues comparables ligne à ligne, ce qu’une description riche rendrait incomparable — deux schémas d’arguments jamais identiques feraient de chaque comparaison un cas d’espèce.

C’est cette réduction qui rend possibles les trois mesures du notebook, dans l’ordre où elles arrivent : l’intersection des signatures (que sait-on déjà faire de ce que l’externe propose ?), l’indice de Jaccard (ce recouvrement vaut-il le branchement ?), et la différence ensembliste (qu’apporte réellement l’externe une fois ôté ce qu’on possède déjà ?). Aucune de ces trois mesures n’exigerait de connaître les arguments d’un appel — elles classent des capacités, pas des interfaces. Le notebook peut ainsi enseigner la démarche de décision sans dépendre d’aucun service réel : la décision est transportable, les schémas ne le sont pas.

Il faut toutefois garder en tête ce que le format ne voit pas, parce que la conclusion finale en dépend. Deux outils de même signature ne sont pas interchangeables pour autant : un lire livre interne qui sert le texte déjà publié dans le site et un lire livre externe qui interroge une base bibliographique font bien « la même chose » au sens de la signature, mais diffèrent par la fraîcheur des données, le coût de l’appel, la latence, la disponibilité. La signature est l’unité de mesure du recouvrement, pas du remplacement — elle dit « vous possédez déjà cette capacité », jamais « inutile d’appeler l’externe pour cela ». C’est une distinction que la règle de canonical de l’exercice 3 sera chargée d’opérationnaliser.

# Aucune dependance externe. Tout est en memoire.

# --- Catalogue EXPOSE par la Maison Valmont (serveur MCP) ---
# Un agent externe (Claude Code, ChatGPT...) appelle ces outils sur Valmont.
catalogue_expose = {
    "valmont_get_manuscripts":      {"verbe": "lire",       "cible": "manuscrit"},
    "valmont_submit_manuscript":    {"verbe": "soumettre",  "cible": "manuscrit"},
    "valmont_assign_reviewer":      {"verbe": "assigner",   "cible": "lecteur"},
    "valmont_get_book":             {"verbe": "lire",       "cible": "livre"},
    "valmont_search_catalog":       {"verbe": "chercher",   "cible": "livre"},
    "valmont_update_book_meta":     {"verbe": "modifier",   "cible": "livre"},
    "valmont_get_review":           {"verbe": "lire",       "cible": "compte-rendu"},
}

# --- Catalogue CONSOMME depuis un serveur MCP externe (bookgraph) ---
# Valmont, via son module Orchestration, appelle ces outils chez bookgraph.
catalogue_consomme = {
    "bookgraph_get_book_info":      {"verbe": "lire",       "cible": "livre"},
    "bookgraph_search_books":       {"verbe": "chercher",   "cible": "livre"},
    "bookgraph_update_book":        {"verbe": "modifier",   "cible": "livre"},
    "bookgraph_enrich_book":        {"verbe": "enrichir",   "cible": "livre"},
    "bookgraph_get_author":         {"verbe": "lire",       "cible": "auteur"},
    "bookgraph_link_similar":       {"verbe": "lier",       "cible": "livre"},
    "bookgraph_submit_review":      {"verbe": "soumettre",  "cible": "compte-rendu"},
}

print("Catalogue EXPOSE (Valmont sert)  : " + str(len(catalogue_expose)) + " outils")
print("Catalogue CONSOMME (Valmont appelle) : " + str(len(catalogue_consomme)) + " outils")
Catalogue EXPOSE (Valmont sert)  : 7 outils
Catalogue CONSOMME (Valmont appelle) : 7 outils

Les deux rôles, sur le même site

Exposé par Valmont Consommé par Valmont
Sens agent externe → Valmont Valmont → serveur externe
Préfixe valmont_* bookgraph_*
Public Claude Code, ChatGPT, OpenClaw… Le chatbot interne de Valmont
Configuré dans AI-Engine : serveur MCP (Bearer token) AI-Engine : module Orchestration

La confusion fréquente : un administrateur qui veut « connecter un outil MCP » ne sait pas s’il doit l’ajouter côté serveur (exposer un nouvel outil Valmont aux agents externes) ou côté client (consommer un outil externe depuis Valmont). La réponse dépend du sens du fil : qui appelle qui ?

Lecture de la sortie : la symétrie 7 / 7 et le vocabulaire partagé

La sortie ne montre que deux compteurs — 7 outils servis, 7 outils appelés — mais cette symétrie apparente est déjà une information : le site n’est ni dominé par sa consommation ni réduit à son offre. Le déséquilibre serait en soi un signal architectural. Un site qui expose dix fois ce qu’il consomme est surtout un serveur, dont la valeur est dans ce que le monde peut en tirer. Un site qui consomme dix fois ce qu’il expose est surtout un client, dont la valeur est dans ce qu’il saucissonne derrière ses appels. Le rapport un-pour-un de Valmont dessine un profil d’intégration équilibrée : le site s’appuie autant qu’il sert — ce qui ne préjuge en rien de la qualité de chaque côté, seulement de sa physionomie.

Plus significatif encore : les deux catalogues, écrits l’un pour l’offre et l’autre pour la dépendance, partagent une grande partie de leur vocabulaire de verbes — lire, chercher, modifier, soumettre apparaissent des deux côtés, comme les cellules suivantes vont le mesurer explicitement. Ce partage n’est pas une négligence de modélisation : c’est la trace du fait que les deux côtés parlent du même métier — les livres, leurs comptes-rendus, leurs fiches — chacun avec sa perspective. Et c’est précisément ce vocabulaire commun qui rendra le chevauchement de la section 4 possible : si les verbes étaient disjoints entre les deux catalogues, la question du recouvrement ne se poserait même pas, et l’indice de la section 5 vaudrait zéro par construction.

Retenir le geste de lecture, car il est réutilisable partout : deux compteurs égaux ne disent pas « deux catalogues équivalents ». Ils disent « deux ensembles de même taille » — rien sur le contenu. Une égalité de cardinalité est compatible avec l’identité parfaite comme avec l’intersection vide. La comparaison de contenu exige l’outillage ensembliste que le notebook construit dans les sections suivantes ; c’est exactement la distance entre compter et comparer. Une précision d’ordre de grandeur, pour fixer les idées sur ce que ces compteurs pèsent : sept outils de chaque côté, c’est la taille d’un catalogue pédagogique, lisible en une screen. Les mesures qui suivent seraient exactement les mêmes sur des catalogues de soixante dix outils — mais la lecture à l’œil, elle, ne survivrait pas : c’est la raison pour laquelle le notebook s’outille dès maintenant (signatures, indice, différence) au lieu de compter sur l’inspection directe. La taille présente rend chaque étape vérifiable à la main ; la méthode restera la seule viable quand la taille ne le permettra plus.

3. Le mini-serveur et le mini-client

Deux fonctions simulent les deux rôles, en mémoire. Le serveur répond à un appel d’outil ; le client appelle un outil chez un serveur externe. Le comportement réel (réseau, JSON-RPC, authentification) est remplacé par des dicts — la structure du protocole est ce qui compte ici.

def servir(catalogue_serveur, nom_outil, arguments):
    """Cote SERVEUR : un agent externe appelle un outil expose par Valmont."""
    if nom_outil not in catalogue_serveur:
        return {"erreur": "outil inconnu: " + nom_outil}
    spec = catalogue_serveur[nom_outil]
    return {"ok": True, "outil": nom_outil, "spec": spec, "args_recus": arguments}


def appeler(catalogue_externe, nom_outil, arguments):
    """Cote CLIENT : Valmont appelle un outil chez un serveur MCP externe."""
    if nom_outil not in catalogue_externe:
        return {"erreur": "outil inconnu chez l'externe: " + nom_outil}
    spec = catalogue_externe[nom_outil]
    return {"ok": True, "outil": nom_outil, "spec": spec, "args_envoyes": arguments}


# Demonstration : un agent externe lit un manuscrit cote Valmont (sens expose)
r1 = servir(catalogue_expose, "valmont_get_manuscripts", {"status": "pending"})
print("SERVEUR (agent -> Valmont) : valmont_get_manuscripts")
print("  -> " + str(r1["spec"]))

# Demonstration : Valmont enrichit une fiche livre cote bookgraph (sens consomme)
r2 = appeler(catalogue_consomme, "bookgraph_enrich_book", {"book_id": 4892})
print()
print("CLIENT (Valmont -> bookgraph) : bookgraph_enrich_book")
print("  -> " + str(r2["spec"]))
SERVEUR (agent -> Valmont) : valmont_get_manuscripts
  -> {'verbe': 'lire', 'cible': 'manuscrit'}

CLIENT (Valmont -> bookgraph) : bookgraph_enrich_book
  -> {'verbe': 'enrichir', 'cible': 'livre'}

Deux appels, deux sens, deux configurations. Rien ne dit à l’agent que ces deux mondes existent — c’est la conception du catalogue qui décide ce qu’un agent peut atteindre. C’est pour ça que les deux sens se configurent séparément : ils répondent à deux questions différentes (que peut-on faire de puis l’extérieur ? vs de quoi le site a-t-il besoin depuis l’extérieur ?).

4. Le piège — le chevauchement fonctionnel

Voilà le cœur du problème. Valmont expose valmont_get_book (lire un livre) et consomme bookgraph_get_book_info (lire un livre). Les deux font la même chose, vue du modèle. Si un chatbot interne de Valmont a accès aux deux catalogues (le consommé par construction, l’exposé s’il est branché en boucle), comment choisit-il ?

Pour mesurer le chevauchement, on normalise chaque outil en une signature (verbe, cible) et on calcule le recouvrement entre les deux catalogues.

def signature(spec):
    """Normalise un outil en (verbe, cible) -- la signature fonctionnelle."""
    return (spec["verbe"], spec["cible"])


def signatures_catalogue(catalogue):
    """Ensemble des signatures presentes dans un catalogue."""
    return {signature(spec) for spec in catalogue.values()}


sig_expose = signatures_catalogue(catalogue_expose)
sig_consomme = signatures_catalogue(catalogue_consomme)

print("Signatures EXPOSE   : " + str(sorted(sig_expose)))
print()
print("Signatures CONSOMME : " + str(sorted(sig_consomme)))
print()
commun = sig_expose & sig_consomme
print("Chevauchement (present des deux cotes) : " + str(sorted(commun)))
print("  -> " + str(len(commun)) + " signature(s) commune(s)")
Signatures EXPOSE   : [('assigner', 'lecteur'), ('chercher', 'livre'), ('lire', 'compte-rendu'), ('lire', 'livre'), ('lire', 'manuscrit'), ('modifier', 'livre'), ('soumettre', 'manuscrit')]

Signatures CONSOMME : [('chercher', 'livre'), ('enrichir', 'livre'), ('lier', 'livre'), ('lire', 'auteur'), ('lire', 'livre'), ('modifier', 'livre'), ('soumettre', 'compte-rendu')]

Chevauchement (present des deux cotes) : [('chercher', 'livre'), ('lire', 'livre'), ('modifier', 'livre')]
  -> 3 signature(s) commune(s)

Lecture du chevauchement

Les signatures (lire, livre) et (chercher, livre) sont présentes des deux côtés. Concrètement : un chatbot Valmont qui veut lire une fiche livre a deux chemins — valmont_get_book (interne) ou bookgraph_get_book_info (externe). Lequel choisir ? S’ils divergent (données différentes, fraîcheur différente), l’agent peut donner une réponse incohérente selon le chemin. S’ils convergent, l’un des deux est redondant.

Ce que la concentration du chevauchement révèle

La sortie classe les faits mieux qu’un discours : les trois signatures communes — chercher livre, lire livre, modifier livre — sont toutes trois centrées sur la même entité, le livre. Ce n’est pas un hasard d’échantillonnage, c’est la structure du métier : le livre est l’objet que les deux sites manipulent nécessairement, celui autour duquel l’offre interne et la dépendance externe se rencontrent. Le recouvrement se concentre là où les deux univers d’action se superposent — et il serait resté concentré sur d’autres entités communes si le métier en avait : c’est une loi de lecture, pas une particularité du jeu de données.

La lecture duale est tout aussi instructive : ce que chaque côté garde en propre dessine sa spécialisation. Côté exposé, les signatures exclusives sont éditoriales — lire manuscrit, soumettre manuscrit, assigner lecteur, lire compte-rendu : le flux de fabrication d’un texte, de la soumission brute jusqu’au compte-rendu publié, ce que Valmont sait faire de bout en bout. Côté consommé, les exclusives sont bibliographiques — enrichir livre, lier livre, lire auteur, soumettre compte-rendu : la fiche du livre relâchée dans un graphe de connaissances, ce que bookgraph sait faire de ce que Valmont fabrique. L’interne gère la fabrication, l’externe enrichit la connaissance du produit fabriqué — et les quatre exclusives de chaque côté, en nombre égal, disent une dépendance mutuelle plutôt qu’une subordination.

Cette lecture prépare la suite de deux manières. D’abord, le chevauchement n’est pas uniformément distribué sur les catalogues : il a une géographie. Quantifier son ampleur globale (section 5) ne dispensera jamais de regarder où il se situe — car un recouvrement sur les verbes de lecture se juge différemment d’un recouvrement sur les verbes d’écriture : lire deux fois coûte une requête, écrire deux fois coûte une incohérence. C’est cette distinction que l’exercice 2 fera travailler sur le sous-ensemble des verbes d’écriture. Ensuite, la spécialisation des exclusives annonce la valeur du branchement (section 6) : l’apport réel de l’externe se lira dans ses signatures exclusives, pas dans ses doublons.

5. Mesurer — indice de Jaccard et redondance

L’indice de Jaccard entre les deux ensembles de signatures mesure à quel point les catalogues se recouvrent : |intersection| / |union|. Un indice élevé signifie que brancher le serveur externe ajoute peu de capacité nouvelle — la plupart de ses outils dupliquent l’interne.

def jaccard(a, b):
    """Indice de Jaccard entre deux ensembles : |A n B| / |A u B|."""
    inter = len(a & b)
    union = len(a | b)
    return inter / union if union else 0.0


j = jaccard(sig_expose, sig_consomme)
print("Indice de Jaccard (expose vs consomme) : " + format(j, ".2f"))
print("  |intersection| = " + str(len(sig_expose & sig_consomme)))
print("  |union|        = " + str(len(sig_expose | sig_consomme)))
print()
if j >= 0.4:
    print(">>> CHEVAUCHEMENT ELEVE : brancher ce serveur externe ajoute peu")
    print("    de capacite nouvelle. Plus de la moitie des signatures sont")
    print("    deja couvertes par le catalogue interne.")
else:
    print(">>> chevauchement faible : le serveur externe apporte majoritairement")
    print("    des signatures que le catalogue interne n'a pas.")
Indice de Jaccard (expose vs consomme) : 0.27
  |intersection| = 3
  |union|        = 11

>>> chevauchement faible : le serveur externe apporte majoritairement
    des signatures que le catalogue interne n'a pas.

Interprétation

Un Jaccard élevé n’est pas forcément un défaut : il peut traduire une redondance volontaire (un backup, une source de validation croisée). Mais il pose la question opérationnelle : pour chaque signature commune, quel est l’outil canonique ? Sans règle explicite, l’agent choisit au hasard — et la cohérence des réponses s’en ressent.

La règle pratique : un seul chemin par verbe métier. Si deux outils font (lire, livre), l’un doit être marqué comme canonique et l’autre comme dégénérescence (ou supprimé du catalogue branché).

Ce que l’indice ne voit pas : signatures contre outils

Le 0,27 porte sur des signatures, pas sur des outils — et l’écart entre les deux niveaux n’est pas un abus de langage mais une distinction de mesure, invisible ici par coïncidence. Le catalogue exposé compte sept outils pour sept signatures : chaque outil interne vise une cible distincte, donc la projection outils-vers-signatures est ici une bijection. Le côté consommé présente la même coïncidence. Mais rien ne garantit cette identité en général : trois outils internes ciblant le livre avec le même verbe lire — par recherche, par identifiant, par collection — compteraient pour une seule signature dans l’indice. L’indice mesure le recouvrement des capacités, pas la redondance des implémentations.

Cette distinction devient opérationnelle dans l’exercice 1, qui redescend précisément au niveau des outils : parmi les outils consommés, lesquels sont redondants au sens des signatures ? La mesure par signatures peut rester faible pendant qu’une masse d’outils individuels duplique l’offre interne — si l’externe expose cinq variantes de recherche de livre, elles ne pèsent qu’une signature dans l’union, mais cinq dépendances dans la maintenance : cinq schémas d’arguments à suivre en version, cinq points de panne possibles, cinq entrées de catalogue à auditer. Le coût réel d’une intégration se paie en outils, pas en signatures ; la décision de brancher se prend en signatures, l’inventaire de ce qu’on retire se fait en outils.

Règle de lecture en deux temps, que le reste du notebook applique et que l’exercice 1 demandera de refaire : les signatures pour décider si le recouvrement est significatif — comparaison en espace commun, ratio borné, seuil écrit ; les outils pour décider quoi retirer ou garder une fois la décision prise — inventaire nommé, entrée par entrée, avec les noms d’outils réels du catalogue consommé. Les deux niveaux répondent à des questions différentes et aucun ne se déduit mécaniquement de l’autre : c’est la raison pour laquelle le notebook mesure aux deux, au lieu de choisir. On peut le voir sur les données du notebook elles-mêmes, sans hypothèse externe : la sortie de la section 4 imprime sept signatures pour le catalogue exposé, et l’inventaire des sources en compte sept outils — mais rien dans la construction n’imposait l’égalité, et le jour où Valmont ajoute valmont_list_books_by_collection à côté de valmont_search_catalog et valmont_get_book (trois outils, la même signature chercher livre au sens large), le compte de signatures ne bougera pas d’une unité alors que le catalogue aura grandi d’un tiers. Toute lecture de l’indice devrait donc être accompagnée, dans un audit réel, du ratio outils/signatures de chaque côté — un catalogue dont le ratio grimpe est un catalogue qui s’étoffe en profondeur sur ses capacités existantes, pas un catalogue qui s’élargit.

6. Les outils externes non couverts — la vraie valeur du branchement

Le miroir du chevauchement : les signatures du catalogue consommé absentes du catalogue interne. Ce sont elles que le branchement apporte de neuf.

apporte_neuf = sig_consomme - sig_expose
print("Signatures APPORTEES par le serveur externe (absentes de l'interne) :")
for s in sorted(apporte_neuf):
    # Retrouver le nom d'outil concret cote consomme pour cette signature
    noms = [n for n, spec in catalogue_consomme.items() if signature(spec) == s]
    print("  " + str(s) + "  via " + ", ".join(noms))
print()
print(">>> " + str(len(apporte_neuf)) + " signature(s) reellement nouvelle(s).")
print("    C'est la valeur reelle du branchement, derriere le bruit du chevauchement.")
Signatures APPORTEES par le serveur externe (absentes de l'interne) :
  ('enrichir', 'livre')  via bookgraph_enrich_book
  ('lier', 'livre')  via bookgraph_link_similar
  ('lire', 'auteur')  via bookgraph_get_author
  ('soumettre', 'compte-rendu')  via bookgraph_submit_review

>>> 4 signature(s) reellement nouvelle(s).
    C'est la valeur reelle du branchement, derriere le bruit du chevauchement.

Lecture

Le verdict est en deux temps. Au niveau global, le chevauchement est faible (Jaccard ~0,27) : sur 7 outils consommés, 4 apportent une signature que l’interne n’a pas ((enrichir, livre), (lier, livre), (lire, auteur), (soumettre, compte-rendu)). Le branchement est donc justifié — il élargit vraiment le champ fonctionnel.

Mais un chevauchement global faible ne dispense pas d’examiner le sous-ensemble écriture. Parmi les 3 signatures communes, l’une est (modifier, livre) — présente côté exposé (valmont_update_book_meta) et côté consommé (bookgraph_update_book). C’est un double-écrit : si l’agent met à jour la même fiche par les deux chemins, les deux sources divergent. Un seul point de chevauchement sur un verbe d’écriture suffit à créer un risque, même noyé dans un catalogue par ailleurs peu redondant. C’est l’objet de l’exercice 2.

C’est la question que ce notebook formalise : faut-il brancher ce serveur MCP externe ? se répond en deux dénombrements — global (le chevauchement total dit si le branchement vaut le coup) et fin (le chevauchement sur les verbes d’écriture dit où est le risque résiduel).

Quatre signatures neuves : la dépendance jugée sur ce qu’elle apporte

La mesure finale inverse la perspective des précédentes : au lieu de compter ce qui se recouvre, elle isole ce que le branchement apporte. La sortie en dresse la liste exacte — enrichir livre, lier livre, lire auteur, soumettre compte-rendu — et chacune se lit comme une capacité que Valmont ne possède pas dans son offre : enrichir une fiche de relations bibliographiques, relier deux livres entre eux, consulter la fiche d’un auteur, publier un avis vers l’extérieur. Quatre dépendances nouvelles, mais surtout quatre capacités nouvelles — la nuance est tout le sujet de la mesure.

La lecture la plus utile n’est pas la liste mais sa cohérence. Les quatre signatures neuves sont précisément les capacités d’un graphe de connaissances — enrichir les nœuds, créer les arêtes, consulter les voisins (lier relie des livres, lire auteur consulte le nœud adjacent, enrichir complète l’attributage). La dépendance externe n’apporte pas quatre outils disparates, elle apporte une fonctionnalité cohérente : l’inscription du catalogue Valmont dans un graphe plus large que lui. C’est cette cohérence qui fonde la valeur du branchement bien davantage que le compte de quatre — un apport de quatre signatures sans lien mutuel vaudrait moins qu’un apport d’une seule signature qui ouvre une dimension. La décision d’intégration juge des dimensions ouvertes, pas des lignes ajoutées.

Noter enfin la rigueur du geste de mesure, car c’est lui qui établit la preuve. Le compte brut des outils consommés (sept) laissait la valeur croire acquise ; l’indice de Jaccard (0,27) la laissait deviner favorable ; seule la différence consommé − exposé la démontre, entrée par entrée, avec le nom de l’outil porteur pour chaque signature. Trois mesures, trois certitudes croissantes — et la progression n’est pas décorative : chaque mesure répond à une question que la précédente ne pouvait pas fermer. C’est la démarche, plus encore que les chiffres, que les exercices suivants demandent de savoir refaire.

7. Exercices

Les trois exercices suivants manipulent les deux catalogues synthétiques. Les stub sont à compléter — return None ou pass.

Exercice 1 — la redondance par outil

Écrire une fonction qui, pour chaque outil du catalogue consommé, indique s’il est redondant (sa signature existe déjà dans le catalogue exposé) ou nouveau. Renvoie deux listes : les noms d’outils redondants et les noms d’outils nouveaux.

def partitionner_redondance(expose, consomme):
    """Renvoie (redondants, nouveaux) -- listes de noms d'outils du consomme.

    Un outil consomme est redondant si sa signature existe deja cote expose.
    """
    # TODO : utiliser signature() et signatures_catalogue().
    return None, None

Exercice 2 — le coût d’un double-écrit

Un outil redondant peut causer un double-écrit : si l’agent met à jour une fiche livre via valmont_update_book_meta (interne) puis via un outil externe équivalent, les deux sources divergent. Écrire une fonction detecter_double_ecrit qui renvoie les signatures (verbe, cible) présentes des deux côtés avec un verbe d’écriture (modifier, soumettre, enrichir, lier…), c’est-à-dire le sous-ensemble du chevauchement qui est dangereux (lecture redondante = tolérable, écriture redondante = risque).

VERBES_ECRITURE = {"modifier", "soumettre", "enrichir", "lier", "assigner", "creer", "supprimer"}

def detecter_double_ecrit(expose, consomme):
    """Renvoie les signatures (verbe, cible) presentes des deux cotes
    ET dont le verbe est un verbe d'ecriture -- le sous-ensemble dangereux
    du chevauchement.
    """
    # TODO : croiser signatures et VERBES_ECRITURE.
    return None

Exercice 3 — choisir le canonical

Pour chaque signature commune, il faut désigner un canonical (l’outil à utiliser par défaut). Écrire une fonction choisir_canonical qui, étant donné les deux catalogues et une signature commune, renvoie le nom d’outil canonique selon une règle simple : préférer l’outil interne (préfixe valmont_) sauf si l’externe est le seul à offrir la signature.

def choisir_canonical(expose, consomme, sig_commune):
    """Pour une signature commune, renvoie le nom d'outil canonique.

    Regle : preferer l'outil interne (valmont_*); si aucun interne n'offre
    cette signature, prendre l'externe.
    """
    # TODO : parcourir expose puis consomme pour trouver l'outil de signature donnee.
    return None

Ce que les trois exercices font des mesures qui les précèdent

Les trois exercices ne sont pas des applications décoratives : chacun reprend une mesure du corps du notebook et la retourne en décision, en changeant à chaque fois le niveau de granularité. L’exercice 1 redescend des signatures vers les outils : le recouvrement de trois signatures, mesuré en section 4, cache quels outils consommés précisément seraient jetables — c’est l’inventaire dont l’indice a décidé qu’il valait la peine, et il exige de relier chaque signature au nom d’outil qui la porte, comme la sortie de la section 6 sait le faire pour les apports neufs.

L’exercice 2 isole le sous-ensemble dangereux du recouvrement : parmi les signatures communes, celles dont le verbe est un verbe d’écriture. La sortie de la section 4 donne la réponse d’avance à qui la lit bien : modifier livre est commune aux deux catalogues et porte un verbe que la constante VERBES_ECRITURE de l’énoncé range parmi les écritures — le risque de double-écrit n’est donc pas hypothétique dans ce jeu de données, il est déjà présent, installé dans le chevauchement mesuré. Lire deux fois la même fiche coûte une requête ; l’écrire deux fois, par deux chemins indépendants, coûte une incohérence — c’est toute la différence entre un recouvrement bénin et un recouvrement qui appelle une politique.

L’exercice 3 tranche la gouvernance du recouvrement : pour une signature commune, quel côté est canonique — l’outil interne ou l’outil externe ? La règle proposée par l’énoncé, préférer l’interne, est une politique de souveraineté : ce que le site sait faire seul, il ne doit pas en dépendre ; la dépendance externe se réserve à ce qu’elle apporte, mesuré en section 6. Lus ensemble, les trois exercices parcourent le cycle complet d’une décision d’intégration MCP : que peut-on retirer (redondance), quoi surveiller (double-écrit), qui fait autorité (canonical). Le notebook a construit les mesures ; les exercices demandent de les transformer en politique — ce qui est, en fin de compte, la seule chose qu’une mesure vise.

8. Provenance et limites

Ce que ce notebook mesure. La structure d’un chevauchement cross-catalogue : étant donné un catalogue exposé et un catalogue consommé, combien d’outils se dupliquent, combien apportent du neuf, et quel sous-ensemble du chevauchement est dangereux (écriture). Tout est déterministe sur fixture synthétique.

Ce qu’il ne mesure pas. La qualité réelle des outils (un outil externe peut avoir la même signature qu’un interne et renvoyer des données radicalement différentes), la latence, le coût. La signature (verbe, cible) est une proxy : elle dit que deux outils font la même chose au niveau taxonomique, pas qu’ils renvoient le même résultat.

La limite de la proxy. Deux outils (lire, livre) peuvent l’un lire dans la base WordPress et l’autre chez un agrégateur distant — même verbe, même cible, données différentes. Le chevauchement mesuré ici est donc un signal d’alarme, pas un verdict : il désigne les paires à examiner, pas les paires à supprimer.

Pour aller plus loin. - auditer-un-serveur-mcp.ipynb — l’autre moitié : classifier les outils d’un seul catalogue en CRUD générique vs verbe métier (ce notebook compare deux catalogues). - livresagites-parcours.md Parcours 0 — la confusion fréquente entre les deux sens du protocole, dont ce notebook est l’illustration exécutable.

Retour au sommet