MCP pour la data : cas d'usage concrets
Le meilleur usage de MCP en data n'est pas de laisser l'IA ecrire du SQL libre. C'est de lui donner acces a des metriques deja validees.
Temps de lecture : 15 min | Niveau : Intermediaire
Ce que tu sauras faire apres
- Interroger un entrepot de donnees en langage naturel sans copier de schema.
- Expliquer pourquoi une couche semantique bat le texte-vers-SQL libre.
- Brancher le serveur MCP de dbt et savoir quels outils il expose.
- Automatiser un reporting recurrent avec des metriques certifiees.
- Concevoir ton propre serveur de metriques pour ton equipe.
1️⃣ Interroger un entrepot en langage naturel
C'est le premier usage, le plus evident, et celui qui donne le declic.
AVANT : le copier-coller de schema
Voici mes tables :
commandes(id, client_id, montant_ht, tva, date_commande, statut, canal)
clients(id, nom, segment, date_creation, pays)
Ecris-moi le CA par segment client sur le dernier trimestre.Trois problemes que tu connais deja :
- Tu as passe cinq minutes a reconstituer ce schema de memoire, et tu as oublie la table
remises. - L'IA ne connait pas les valeurs de
statut. Elle va ecrirestatut = 'annulee'alors que la vraie valeur est'CANCELLED'. - Elle ne sait pas que le CA se calcule sur
montant_htapres jointure avecremises. Ta regle metier n'est nulle part.
APRES : avec un serveur MCP branche
Sur le serveur MCP entrepot :
1. liste les tables du schema ventes
2. decris les tables commandes, clients et remises
3. donne-moi les valeurs distinctes de commandes.statut
4. ecris ensuite le CA par segment client sur le dernier trimestre
Avant d'executer, montre-moi la requete et explique quelles lignes tu exclus.Pourquoi c'est mieux : les etapes 1 a 3 sont des lectures. L'IA construit sa comprehension a partir de la vraie base. L'etape 4 s'appuie sur du reel. Et la derniere phrase te garde dans la boucle avant l'execution.
Le garde-fou a mettre tout de suite
Trois regles, non negociables, avant de brancher un entrepot :
- Un compte technique en lecture seule. Pas ton compte a toi.
GRANT SELECTet rien d'autre. - Un perimetre limite. Ne donne acces qu'aux schemas necessaires. Surtout pas aux tables qui contiennent des donnees personnelles.
- Une limite de lignes dans le serveur lui-meme. Rappel du fichier 03 : la sortie MCP est limitee par defaut a 25 000 tokens dans Claude Code, avec un avertissement des 10 000. Un
SELECT *sur une table de faits va saturer ta fenetre de contexte pour rien. Si un outil precis doit vraiment renvoyer un gros document, comme un schema complet, releve sa limite avec_meta["anthropic/maxResultSizeChars"]plutot que la limite globale.
2️⃣ Exposer une couche semantique plutot que du SQL brut
C'est le point le plus important de ce fichier. Lis-le deux fois.
Le probleme du texte-vers-SQL libre
Quand tu laisses une IA ecrire du SQL librement sur ton entrepot, tu obtiens des requetes syntaxiquement correctes et metier fausses. Et c'est le pire cas possible, parce que rien ne plante.
Exemple vecu par toutes les equipes data :
-- Ce que l'IA ecrit, parce qu'elle ne peut pas deviner mieux
SELECT sum(montant_ht) AS ca
FROM commandes
WHERE date_commande >= '2026-01-01';-- Ce que ton entreprise appelle vraiment "le CA"
SELECT sum(c.montant_ht - coalesce(r.montant_remise, 0)) AS ca
FROM commandes c
LEFT JOIN remises r ON r.commande_id = c.id
WHERE c.statut NOT IN ('CANCELLED', 'DRAFT', 'TEST')
AND c.canal <> 'INTERNE'
AND c.date_commande >= '2026-01-01';Les deux requetes tournent. Les deux renvoient un nombre. L'ecart est de 12 %. Et ce nombre part dans une presentation au comite de direction.
Le probleme n'est pas l'IA. Le probleme est que la definition du CA n'existe nulle part sous forme lisible par une machine. Elle vit dans la tete de trois personnes et dans un vieux fichier Excel.
La solution : exposer des metriques, pas des tables
Une couche semantique, c'est l'endroit ou tu ecris une fois la definition de chaque metrique. Les outils qui l'implementent, comme le Semantic Layer de dbt, permettent ensuite d'interroger ces metriques plutot que les tables brutes.
Compare les deux approches :
| SQL brut expose via MCP | Metriques certifiees exposees via MCP | |
|---|---|---|
| Ce que l'IA appelle | run_select("SELECT ...") | query_metrics(metrics=["ca"], group_by=["segment"]) |
| Qui definit la regle metier | Le modele, a chaque appel | Toi, une fois, dans le depot |
| Reproductibilite | Deux appels peuvent donner deux resultats | Meme metrique, meme definition, toujours |
| Verifiabilite | Il faut relire chaque requete | Il faut relire la definition, une fois |
| Surface d'erreur | Enorme | Reduite aux dimensions et aux filtres |
| Ce qui casse quand le modele se trompe | Un chiffre faux et credible | Un appel en erreur, ou une dimension inexistante |
La derniere ligne est la plus importante. Avec du SQL libre, une erreur du modele produit un chiffre faux qui a l'air juste. Avec une couche semantique, une erreur du modele produit une erreur visible.
AVANT / APRES sur le prompt
AVANT
Combien on a fait de CA le mois dernier par region ?
Le serveur MCP entrepot est branche, ecris la requete SQL.APRES
Sur le serveur MCP dbt :
1. appelle list_metrics et montre-moi les metriques disponibles
2. si une metrique de chiffre d'affaires existe, appelle get_dimensions dessus
pour verifier qu'une dimension de region existe
3. interroge la metrique avec query_metrics, groupee par region, sur le mois dernier
4. affiche aussi le SQL compile via get_metrics_compiled_sql, que je verifie la definition
Si aucune metrique de CA n'existe, dis-le-moi et n'invente pas de SQL.Pourquoi c'est mieux : tu forces l'IA a decouvrir ce qui existe avant de calculer. La derniere phrase lui interdit explicitement le repli sur du SQL improvise. Et l'etape 4 te laisse auditer la definition.
3️⃣ Le serveur MCP de dbt, concretement
dbt publie un serveur MCP qui donne acces a ses ressources. C'est l'exemple le plus complet que je connaisse d'une couche semantique exposee a l'IA.
Deux formes existent, et le choix n'est pas anodin.
| Auto-heberge | Distant (heberge par dbt) | |
|---|---|---|
| Ou ca tourne | Sur ta machine, via uvx dbt-mcp | Chez dbt, en HTTP, rien a installer |
| Pour quoi faire | Developpement : ecrire des modeles, des tests, de la documentation | Consommation : interroger des metriques, explorer les metadonnees, lire le lineage |
Commandes dbt (run, build, test) | Oui | Non |
| Projet dbt local | Oui, avec ou sans compte sur la plateforme dbt | Non |
| Limites | Limites publiques des API Administrative et Discovery | Limite globale par defaut de 5 000 requetes par minute et par IP |
Le serveur auto-heberge se lance avec :
uvx dbt-mcpSa configuration, y compris la desactivation d'outils precis, passe par des variables d'environnement.
Ma recommandation pour toi : commence par le distant si tu veux juste poser des questions aux donnees, et passe a l'auto-heberge le jour ou tu veux que l'IA t'aide a ecrire des modeles.
Les outils de couche semantique
Ce sont ceux qui t'interessent en priorite :
| Outil | Ce qu'il fait |
|---|---|
list_metrics | Recupere toutes les metriques definies |
get_dimensions | Donne les dimensions disponibles pour des metriques donnees |
get_entities | Donne les entites liees a des metriques |
get_dimension_values | Donne les valeurs distinctes d'une dimension |
query_metrics | Execute une requete de metriques, avec filtres et groupements |
get_metrics_compiled_sql | Renvoie le SQL compile sans executer la requete |
list_saved_queries | Liste les requetes sauvegardees |
Regarde bien get_metrics_compiled_sql. C'est l'outil d'audit : il te montre ce qui serait execute, sans rien executer. Utilise-le systematiquement la premiere fois que tu valides un chiffre.
Les outils de decouverte (lineage et qualite)
| Outil | Usage data engineering |
|---|---|
get_all_models | Nom et description de tous les modeles |
get_all_sources | Toutes les sources avec leur statut de fraicheur |
get_lineage | Un graphe de lineage borne, filtrable par type, profondeur et direction |
get_model_health | Signaux de sante : statut des runs, resultats des tests, fraicheur des sources amont |
get_model_performance | Historique d'execution d'un modele |
get_exposures | Les expositions aval : dashboards, applications, analyses |
get_node_details | Details complets d'une ressource dbt |
get_related_models | Modeles similaires, par recherche semantique |
get_mart_models | Les modeles de la couche mart |
get_all_macros | Tous les macros du projet |
search | Recherche dans les ressources dbt |
get_exposures merite une mention speciale : il te dit qui casse si tu modifies un modele. C'est l'outil que tu veux avant chaque refactoring.
Attention si tu lis un vieil article : toute une serie d'outils de decouverte sont marques deprecies dans la documentation, notamment
get_model_details,get_model_parents,get_model_children,get_source_details,get_exposure_detailsetget_test_details. Leurs successeurs sontget_node_detailsetget_lineage. Verifie toujours la page officielle avant d'ecrire un prompt qui nomme un outil.
Les outils SQL et CLI
Le serveur expose aussi execute_sql et text_to_sql, ainsi que les commandes dbt classiques : build, run, test, compile, parse, list, show, docs, clone.
Attention : run, build et clone modifient ton entrepot. Ces outils-la exigent une validation humaine. Voir le fichier 06.
4️⃣ Analyse d'impact avant un refactoring
Un cas d'usage que j'utilise tous les jours et qui fait gagner un temps fou.
Je veux renommer la colonne montant_ht en montant_hors_taxes
dans le modele stg_commandes.
Avec le serveur MCP dbt :
1. appelle get_lineage sur stg_commandes, direction aval, profondeur 3
2. appelle get_exposures pour savoir quels dashboards en dependent
3. appelle get_model_health sur chaque modele aval direct
Puis, avec le serveur MCP filesystem :
4. cherche toutes les occurrences de montant_ht dans le dossier models/
Rends-moi :
- la liste des fichiers a modifier, par ordre de dependance
- la liste des dashboards a prevenir, avec leur proprietaire
- les modeles aval dont les tests sont deja en echec aujourd'hui
Ne modifie aucun fichier pour l'instant.Pourquoi ca marche : tu croises deux serveurs MCP, le lineage cote dbt et le code cote fichiers. Aucune des deux sources seule ne donne la reponse complete. Et la derniere ligne t'evite un refactoring sauvage.
5️⃣ Automatiser un reporting recurrent
Le piege du reporting automatise, c'est de laisser l'IA recalculer les chiffres a chaque fois. Ne fais pas ca. Fais-lui lire des chiffres deja calcules, et lui demander de commenter.
Prepare le point hebdo de l'equipe data.
Chiffres (via le serveur MCP dbt, metriques certifiees uniquement) :
- query_metrics sur [LISTE_DES_METRIQUES], groupe par semaine, 8 dernieres semaines
- pour chaque metrique, calcule la variation par rapport a la semaine precedente
Sante des pipelines (via le meme serveur) :
- get_all_sources : liste les sources dont la fraicheur est en alerte
- get_model_health sur les modeles du dossier marts
Redige ensuite :
- 5 puces maximum, une par fait marquant
- pour chaque variation superieure a 10 %, dis si elle est expliquee par
un probleme de pipeline identifie plus haut, ou si elle est inexpliquee
- une section "a verifier manuellement" pour tout ce dont tu n'es pas sur
N'invente aucun chiffre. Si une metrique n'est pas disponible, ecris "non disponible".La phrase finale n'est pas decorative. Elle transforme les trous en trous visibles au lieu de trous combles par invention.
🏗️ Concevoir ton propre serveur de metriques
Tu n'as pas de couche semantique ? Tu peux en construire une minimale avec ce que tu as appris au fichier 04. Le principe : une metrique = un outil, ou un parametre d'enumeration, jamais du SQL libre.
# Les definitions vivent dans le code, versionnees, relues en pull request.
METRIQUES = {
"ca_net": {
"description": "Chiffre d'affaires HT apres remises, hors commandes "
"annulees, brouillons, tests et canal interne.",
"sql": """
SELECT {dimension} AS dimension,
sum(c.montant_ht - coalesce(r.montant_remise, 0)) AS valeur
FROM commandes c
LEFT JOIN remises r ON r.commande_id = c.id
WHERE c.statut NOT IN ('CANCELLED', 'DRAFT', 'TEST')
AND c.canal <> 'INTERNE'
AND c.date_commande BETWEEN :debut AND :fin
GROUP BY 1
ORDER BY 2 DESC
""",
"dimensions_autorisees": ["segment", "pays", "canal", "mois"],
},
}
@mcp.tool()
def list_metrics() -> str:
"""Liste les metriques certifiees disponibles et leur definition metier.
Appelle cet outil EN PREMIER. N'ecris jamais de SQL toi-meme pour
calculer une metrique metier : utilise query_metric a la place.
"""
...
@mcp.tool()
def query_metric(metrique: str, dimension: str, debut: str, fin: str) -> str:
"""Calcule une metrique certifiee, groupee par une dimension autorisee.
Args:
metrique: Nom exact d'une metrique renvoyee par list_metrics.
dimension: Dimension de regroupement, parmi dimensions_autorisees.
debut: Date de debut incluse, au format AAAA-MM-JJ.
fin: Date de fin incluse, au format AAAA-MM-JJ.
"""
...Ce que tu gagnes : le modele ne peut appeler que des metriques que tu as validees, avec des dimensions que tu as autorisees. Sa marge d'invention tombe a zero sur la partie la plus risquee.
📋 Templates prets a copier
Template A : explorer une base inconnue
Le serveur MCP [NOM_DU_SERVEUR] est branche sur [NOM_DE_LA_BASE].
Etape 1 : liste les tables et leur volumetrie.
Etape 2 : pour les tables [TABLE_1] et [TABLE_2], donne-moi les colonnes,
les types et 3 lignes d'exemple.
Etape 3 : identifie les cles de jointure probables entre ces tables.
Etape 4 : donne-moi les valeurs distinctes des colonnes de statut ou de type.
Ne fais aucune hypothese sur le contenu : appuie-toi uniquement sur ce que
les outils te renvoient. Si une information manque, dis-le.Template B : calculer un chiffre fiable
Question metier : [QUESTION_EN_FRANCAIS]
Periode : [DATE_DEBUT] a [DATE_FIN]
Granularite : [PAR_JOUR / PAR_SEMAINE / PAR_MOIS]
Decoupage : [DIMENSION_1], [DIMENSION_2]
Contraintes :
- Utilise en priorite les metriques certifiees du serveur MCP [NOM_DU_SERVEUR].
- Si la metrique [NOM_DE_LA_METRIQUE] existe, utilise-la. Sinon, dis-le-moi
avant d'ecrire du SQL.
- Montre-moi le SQL compile ou la requete avant execution.
- Exclus explicitement : [LISTE_DES_EXCLUSIONS_METIER].
- Limite le resultat a [NOMBRE] lignes.
Rends-moi : le chiffre, la requete, et la liste des hypotheses que tu as faites.Template C : audit de fraicheur avant une livraison
Avant que je livre [NOM_DU_LIVRABLE], verifie la chaine amont.
Avec le serveur MCP [NOM_DU_SERVEUR_DBT] :
1. get_all_sources : quelles sources sont en alerte de fraicheur ?
2. get_lineage sur [NOM_DU_MODELE], direction amont, profondeur [N]
3. get_model_health sur chaque modele de cette chaine
Rends-moi un tableau : modele | dernier run | tests en echec | fraicheur amont.
Conclus par : livrable fiable OUI / NON, et pourquoi en une phrase.A retenir
- Le gain numero un en data, c'est que l'IA lit le vrai schema au lieu de le deviner.
- Le SQL libre genere par IA produit des requetes correctes et metier fausses. C'est le pire cas : rien ne plante.
- Expose des metriques certifiees plutot que des tables. Une erreur du modele devient alors visible au lieu d'etre credible.
- Le serveur MCP de dbt expose
list_metrics,get_dimensions,query_metricsetget_metrics_compiled_sqlpour ca. get_metrics_compiled_sqlmontre le SQL sans l'executer : c'est ton outil d'audit.get_exposureste dit qui casse avant un refactoring.- Pour un reporting : fais lire des chiffres deja calcules, pas recalculer.
Sources
- Le serveur MCP de dbt : presentation
- Liste complete des outils du serveur MCP dbt
- Concepts serveur MCP : tools, resources, prompts
- Limites de sortie et delais des outils MCP dans Claude Code
- Specification des tools : outputSchema et gestion des erreurs
- dbt-labs/dbt-mcp - le code du serveur MCP dbt decrit ici, dans
src/dbt_mcp/ - googleapis/mcp-toolbox - code d'exemple sur l'acces a un entrepot depuis un serveur MCP : BigQuery, Postgres, Snowflake, voir
docs/BIGQUERY_README.md