ServicesÀ proposNotesContact Me contacter →
EN FR
Note

Schéma de serveur MCP pour la qualité des données

Un schéma pratique de serveur MCP pour la qualité des données — exécuter des contrôles de validation, récupérer des scores de qualité et identifier les tables nécessitant une attention.

Planté
mcpdata engineeringdata quality

Un serveur MCP de qualité des données expose des scores de qualité et des résultats de validation comme outils accessibles par l’IA. Cela permet d’interroger l’état de qualité en conversation — « quel est le score de qualité pour sales.orders ? » — plutôt que de naviguer dans un tableau de bord.

Le schéma s’applique aux équipes utilisant Great Expectations, Elementary, Soda ou des frameworks de qualité internes. Le serveur MCP encapsule l’API de la plateforme qualité, exposant les contrôles, scores et problèmes comme outils.

Le serveur

from mcp.server.fastmcp import FastMCP, Context
from pydantic import BaseModel, Field
from enum import Enum
import json
mcp = FastMCP("DataQualityMCP")
class CheckType(str, Enum):
COMPLETENESS = "completeness"
UNIQUENESS = "uniqueness"
FRESHNESS = "freshness"
VALIDITY = "validity"
CONSISTENCY = "consistency"
class QualityCheckResult(BaseModel):
"""Result of a single quality check."""
check_name: str
check_type: CheckType
table_name: str
passed: bool
score: float = Field(ge=0, le=1, description="Score between 0 and 1")
rows_checked: int
issues_found: int
details: str | None = None

L’enum CheckType contraint les dimensions de qualité que l’IA peut vérifier. Le modèle QualityCheckResult garantit une sortie cohérente sur tous les contrôles — l’IA reçoit toujours les mêmes champs, rendant la comparaison et l’agrégation fiables. Voir MCP Tool Design Patterns pour la justification de la sortie structurée.

Outils essentiels

Exécuter un contrôle de qualité

L’outil ciblé — exécuter un type de contrôle spécifique sur une table spécifique :

@mcp.tool()
async def run_quality_check(
table_name: str,
check_type: CheckType,
ctx: Context
) -> QualityCheckResult:
"""Run a specific data quality check on a table.
Args:
table_name: Table to validate
check_type: Type of quality check to run
ctx: Context for progress reporting
Returns:
Detailed check results
"""
await ctx.info(f"Running {check_type.value} check on {table_name}")
await ctx.report_progress(progress=0.5, total=1.0, message="Scanning table...")
# In real implementation, call your quality framework
score = QUALITY_SCORES.get(table_name, {}).get(check_type.value, 0.5)
passed = score >= 0.9
await ctx.report_progress(progress=1.0, total=1.0, message="Check complete")
return QualityCheckResult(
check_name=f"{check_type.value}_{table_name.replace('.', '_')}",
check_type=check_type,
table_name=table_name,
passed=passed,
score=score,
rows_checked=100000,
issues_found=int((1 - score) * 100000),
details=f"{'Passed' if passed else 'Failed'}: {score:.1%} of rows meet {check_type.value} criteria"
)

Le reporting de progression via l’objet Context est important ici. Les contrôles de qualité sur des tables volumineuses peuvent prendre des minutes. Sans reporting de progression, l’utilisateur ne sait pas si l’outil fonctionne ou est bloqué.

Vue d’ensemble du score de qualité

L’outil de consultation rapide — état de santé global d’une table :

@mcp.tool()
def get_quality_score(table_name: str) -> str:
"""Get the overall data quality score for a table.
Args:
table_name: Table to get scores for
Returns:
Quality scores across all dimensions
"""
if table_name not in QUALITY_SCORES:
return json.dumps({
"error": f"No quality scores found for '{table_name}'",
"available_tables": list(QUALITY_SCORES.keys())
}, indent=2)
scores = QUALITY_SCORES[table_name]
return json.dumps({
"table": table_name,
"overall_score": scores["overall"],
"dimensions": {
"completeness": scores["completeness"],
"uniqueness": scores["uniqueness"],
"freshness": scores["freshness"],
"validity": scores.get("validity", "not measured")
},
"status": "healthy" if scores["overall"] >= 0.9 else "needs attention"
}, indent=2)

Retourner available_tables dans le cas d’erreur est un schéma à souligner. Quand l’IA demande une table qui n’existe pas dans le système qualité, elle obtient la liste de ce qui existe — et peut soit suggérer des alternatives, soit demander à l’utilisateur de clarifier. Bien mieux qu’une simple erreur « introuvable ».

Résumé des problèmes de qualité

L’outil de triage — « quoi nécessite mon attention ? »

@mcp.tool()
def list_quality_issues(min_severity: str = "warning") -> str:
"""List tables with data quality issues.
Args:
min_severity: Minimum severity to include ('warning' or 'critical')
Returns:
Tables that need attention
"""
issues = []
threshold = 0.8 if min_severity == "critical" else 0.9
for table_name, scores in QUALITY_SCORES.items():
if scores["overall"] < threshold:
dimensions = {k: v for k, v in scores.items() if k != "overall"}
worst_dim = min(dimensions, key=dimensions.get)
issues.append({
"table": table_name,
"overall_score": scores["overall"],
"severity": "critical" if scores["overall"] < 0.8 else "warning",
"primary_issue": worst_dim,
"issue_score": dimensions[worst_dim]
})
return json.dumps(sorted(issues, key=lambda x: x["overall_score"]), indent=2)

Identifier le primary_issue — la dimension avec le score le plus bas — donne à l’IA quelque chose d’actionnable à rapporter. « La table customers a un problème de fraîcheur (0,75) » est plus utile que « la table customers a obtenu 0,87 ».

Validation complète

L’outil exhaustif — tout exécuter :

@mcp.tool()
async def run_full_validation(table_name: str, ctx: Context) -> str:
"""Run all quality checks on a table.
Args:
table_name: Table to validate
ctx: Context for progress reporting
Returns:
Complete validation report
"""
await ctx.info(f"Starting full validation of {table_name}")
results = []
checks = list(CheckType)
for i, check_type in enumerate(checks):
await ctx.report_progress(
progress=(i + 1) / len(checks),
total=1.0,
message=f"Running {check_type.value} check..."
)
result = await run_quality_check(table_name, check_type, ctx)
results.append({
"check": result.check_type.value,
"passed": result.passed,
"score": result.score
})
overall_passed = all(r["passed"] for r in results)
return json.dumps({
"table": table_name,
"validation_passed": overall_passed,
"checks": results,
"summary": f"{'All checks passed' if overall_passed else 'Some checks failed'}"
}, indent=2)
if __name__ == "__main__":
mcp.run(transport="stdio")

Ce que vous pouvez demander

Avec ce serveur connecté :

  • « Quel est le score de qualité des données pour la table orders ? »
  • « Effectuez un contrôle de complétude sur sales.customers »
  • « Quelles tables présentent des problèmes de qualité à investiguer ? »
  • « Exécutez une validation complète sur la table revenue_daily »
  • « Quel est le score de fraîcheur de nos données clients ? »

Considérations pour la production

Exécution des contrôles vs scores mis en cache. L’exemple confond l’exécution des contrôles avec la récupération de scores stockés. En production, séparez ces deux aspects — get_quality_score lit depuis la base de données de votre plateforme qualité (rapide, peu coûteux), tandis que run_quality_check déclenche un scan réel (lent, potentiellement coûteux). Rendez la distinction claire dans les descriptions des outils afin que l’IA utilise par défaut les scores mis en cache et n’exécute de nouveaux contrôles que sur demande explicite.

Configuration des seuils. Les seuils 0,9/0,8 pour warning/critical sont codés en dur dans l’exemple. En production, rendez-les configurables par table ou par type de contrôle. Certaines tables peuvent tolérer des scores de fraîcheur plus bas ; d’autres nécessitent une complétude à 100 %.

Tendances historiques. Un outil get_quality_trend montrant l’historique des scores sur les N derniers jours révèle des patterns de dégradation. « La fraîcheur se détériore depuis une semaine » est le type d’insight qui n’apparaît qu’avec un contexte historique.

Implémentations de référence. L’intégration MCP Elementary démontre des patterns de production pour l’observabilité des données, incluant l’historique des résultats de tests, la détection d’anomalies et la gestion des alertes. Étudiez-la avant de construire votre propre serveur de qualité.