Intégrer un serveur MCP à un agent Semantic Kernel pour Claude Desktop

Vous êtes développeur et vous avez créé un agent intelligent avec Semantic Kernel pour interroger une base de données en langage naturel. Tout fonctionne bien dans vos tests, mais comment l’utiliser dans votre application de chat préférée ? Par exemple, faire dialoguer Anthropic Claude avec votre base SQL locale. Récemment, je me suis retrouvé face à cette frustration : Claude (ou tout LLM généraliste) n’a pas naturellement accès à ma base de données, et mes premières tentatives ont échoué. Un Large Language Model seul n’est en effet pas un expert SQL fiable, car il peut inventer des tables ou produire des requêtes incorrectes sans contexte ni contrôle (Créer un agent NL2SQL avec Semantic Kernel – Kevin BEAUGRAND). Il lui manque une connexion directe aux données et un garde-fou pour éviter les erreurs. C’est exactement ce que je voulais résoudre.

Comment permettre à Claude d’utiliser mon “agent base de données” en toute sécurité ? Dans cet article, je vais raconter comment l’intégration du protocole MCP (Model Context Protocol) m’a permis d’exposer mon agent Semantic Kernel à Claude Desktop. Nous verrons comment j’ai procédé pour créer un serveur MCP autour de l’agent, configurer Claude Desktop pour s’y connecter, et obtenir enfin des réponses fiables issues de ma base de données. Embarquez dans ce récit technique et pédagogique, où l’on combine la puissance des LLM avec la flexibilité de Semantic Kernel !

Contexte : Un agent NL2SQL avec Semantic Kernel

Avant d’entrer dans MCP, posons le décor. J’avais développé un agent “NL2SQL” (Natural Language to SQL) avec Microsoft Semantic Kernel (SK). Son rôle : prendre une question en français et renvoyer la réponse en s’appuyant sur une base de données. Pour cela, il convertit la question en requête SQL, exécute cette requête sur la base, puis formate le résultat pour l’utilisateur. Cet agent s’appuie sur plusieurs briques internes : une mémoire sémantique du schéma de base de données, un LLM pour générer le SQL approprié, et des fonctions natives pour exécuter les requêtes et renvoyer les données. Concrètement, j’ai utilisé Semantic Kernel pour orchestrer tout cela : le Kernel Memory me sert à mémoriser le schéma et les relations de la base afin de donner du contexte au modèle (GitHub – kbeaugrand/SemanticKernel.Agents.DatabaseAgent: Database agent for Semantic Kernel), et un ensemble plugin/agent gère la génération et l’exécution de la requête.

Bien sûr, permettre à une IA de formuler et exécuter du SQL pose des enjeux de fiabilité et sécurité. J’ai donc intégré un module de Quality Assurance à mon agent. Par exemple, un filtre de pertinence de requête s’assure que l’agent n’exécute que des requêtes cohérentes avec la question posée, en comparant sémantiquement la requête générée avec la demande initiale (GitHub – kbeaugrand/SemanticKernel.Agents.DatabaseAgent: Database agent for Semantic Kernel). Si la similarité est trop faible, l’agent rejette la requête. Cela évite qu’une question innocente ne déclenche une requête farfelue ou hors sujet. D’autres garde-fous sont en place (restriction aux requêtes en lecture seule, etc.), car on ne brancherait pas une IA sur une base de prod sans ces précautions ! Avec ces mesures, mon agent NL2SQL est prêt à répondre de manière pertinente tout en évitant les dérapages.

Jusqu’ici, j’interrogeais cet agent via du code C# ou une interface console. L’agent est instancié et on peut lui envoyer une question comme n’importe quel autre service. Par exemple, on peut créer le kernel SK, configurer la connexion à la base SQLite, créer l’agent et l’interroger :

// Configuration de la connexion DB dans le Kernel
kernelBuilder.Services.AddSingleton<DbConnection>(
    _ => new SqliteConnection("Data Source=./northwind.db;Mode=ReadOnly")
);
var kernel = kernelBuilder.Build();
// Création de l'agent NL2SQL Semantic Kernel
var agent = await DBMSAgentFactory.CreateAgentAsync(kernel, memory);
// Envoi d'une question à l'agent (historique de chat avec rôle Utilisateur)
var chatHistory = new ChatHistory("Quel client a passé le plus de commandes ?", AuthorRole.User);
var responses = await agent.InvokeAsync(chatHistory);

(Code simplifié inspiré de la documentation du projet) (GitHub – kbeaugrand/SemanticKernel.Agents.DatabaseAgent: Database agent for Semantic Kernel). Ici DBMSAgentFactory.CreateAgentAsync initialise tout l’enchaînement nécessaire. L’agent va analyser la question, générer la requête SQL adéquate, l’exécuter sur la base Northwind (notre exemple), et renvoyer la réponse sous forme textuelle. Le tout est rendu possible par Semantic Kernel, qui combine fonctions semantics (pour le LLM) et fonctions native (pour exécuter le SQL) au sein de l’agent.

MCP : brancher Claude sur des outils externes

Maintenant, comment brancher cet agent dans Claude Desktop ? C’est là qu’intervient le Model Context Protocol (MCP). Annoncé fin 2024 par Anthropic, MCP est un protocole ouvert conçu pour connecter des assistants IA à des sources de données ou des outils externes de manière standardisée (Introducing the Model Context Protocol \ Anthropic). En d’autres termes, MCP est comme un port USB-C de la data pour les IA : un standard universel pour que nos modèles puissent interagir avec notre environnement logiciel. Le principe est simple : on peut exposer un outil via un petit serveur MCP local, et n’importe quelle application IA compatible (client MCP) peut s’y connecter (Introducing the Model Context Protocol \ Anthropic). Claude Desktop prend justement en charge les serveurs MCP locaux depuis fin 2024, ce qui ouvre la voie à des intégrations personnalisées.

Concrètement, Claude Desktop peut lancer et dialoguer avec un processus serveur MCP sur votre machine. Dès lors, si ce serveur MCP encapsule mon agent Semantic Kernel, Claude pourra lui déléguer certaines questions. Plutôt que d’halluciner des réponses SQL, Claude passera la main à l’agent spécialisé qui, lui, saura réellement interroger la base et renvoyer la bonne réponse. On combine ainsi le meilleur des deux mondes : la compréhension en langage naturel de Claude et la précision d’un outil sur mesure connecté à vos données.

Mise en œuvre : un serveur MCP pour l’agent Semantic Kernel

Pour que Claude puisse utiliser l’agent NL2SQL, il faut emballer notre agent dans un serveur MCP. J’aurais pu coder cela from scratch en respectant la spec MCP (disponible en open-source), mais bonne nouvelle : je n’ai pas eu à tout réinventer. J’ai créé (et publié) un petit serveur prêt à l’emploi sous forme d’un outil .NET, disponible via le package NuGet SemanticKernel.Agents.DatabaseAgent.MCPServer. Ce serveur MCP fait office d’interface entre Claude et l’agent : il écoute les messages entrants de Claude et exécute les actions appropriées en appelant l’agent SK en interne ( NuGet Gallery | SemanticKernel.Agents.DatabaseAgent.MCPServer 0.0.3 ).

Installation du serveur MCP

Le serveur est fourni comme un outil .NET pour plus de simplicité. Il suffit de disposer du SDK .NET 8 sur la machine, puis d’exécuter la commande suivante :

dotnet tool install --global SemanticKernel.Agents.DatabaseAgent.MCPServer --version 0.0.3

Cette commande installe l’outil modelcontextprotocol-database-agent sur votre système ( NuGet Gallery | SemanticKernel.Agents.DatabaseAgent.MCPServer 0.0.3 ). Une fois cela fait, nous avons accès à un nouvel exécutable.

Lancer le serveur MCP de l’agent

Pour démarrer notre serveur MCP, on utilisera justement la commande installée. Le binaire s’appelle **modelcontextprotocol-database-agent** – nom explicite s’il en est. On doit le lancer avec un certain nombre d’options de configuration pour qu’il sache comment accéder à notre base de données et quel modèle d’IA utiliser. Les principales options à fournir sont :

  • Provider de base de données : le type de SGBD (ex : SQLite, SqlServer, MySQL…).
  • ConnectionString : la chaîne de connexion à la base de données.
  • Modèle de langage : quelle API de LLM utiliser pour l’agent (OpenAI, Azure OpenAI, etc.), avec les clés ou endpoints nécessaires.
  • (Optionnel) Paramètres de qualité : activer/désactiver les filtres de sécurité, seuils de pertinence, etc. (par défaut, le filtre de pertinence est actif à 0.8).

On peut passer ces options en ligne de commande. Par exemple, pour une petite base SQLite locale et l’API OpenAI :

modelcontextprotocol-database-agent \
  --database:Provider=sqlite \
  --database:ConnectionString="Data Source=C:\\Data\\Northwind.sqlite;Mode=ReadOnly" \
  --services:openai:Type=OpenAI \
  --services:openai:APIKey="sk-XXXXXXXXXXXXXXXXXXXXXX" \
  --services:openai:Deployment="gpt-3.5-turbo"

Ici, on indique au serveur MCP d’utiliser SQLite comme base (avec le fichier Northwind), et d’appeler l’API OpenAI avec la clé fournie pour générer du texte (modèle GPT-3.5 Turbo dans cet exemple). Le serveur va alors démarrer en initialisant en interne le Kernel Semantic Kernel avec ces paramètres (il créera par exemple la connexion DB et chargera le schéma en mémoire sémantique comme vu plus haut). Ensuite, il se mettra en attente des requêtes MCP.

Note : Vous pouvez bien sûr utiliser un service Azure OpenAI ou autre en ajustant les options (--services:xxx:Type=AzureOpenAI, --services:xxx:Endpoint=..., --services:xxx:Deployment=...). Le choix du modèle et de l’endpoint dépend de votre contexte. Assurez-vous simplement que le modèle choisi a assez de contexte pour gérer le schéma si celui-ci est volumineux (GPT-4 peut être recommandé pour des grosses bases, GPT-3.5 peut suffire pour des schémas plus petits).

Configuration de Claude Desktop

Il reste à informer Claude Desktop de l’existence de notre serveur MCP. Claude Desktop utilise un fichier de configuration (JSON) pour savoir quels serveurs MCP lancer au démarrage. Sous Windows, ce fichier se trouve dans %%APPDATA%%\\Claude\\claude_desktop_config.json (sous macOS : ~/Library/Application Support/Claude/claude_desktop_config.json). Vous pouvez l’éditer via l’onglet Developer des paramètres de Claude Desktop (bouton Edit Config).

Dans ce fichier JSON, nous allons ajouter une nouvelle entrée dans la section "mcpServers". Par exemple :

Exemple de configuration (claude_desktop_config.json) ajoutant un serveur MCP personnalisé.

Dans cet exemple, nous avons ajouté un serveur nommé "databaseAgent" (vous pouvez choisir un autre identifiant). La clé command indique le programme à exécuter (ici notre outil .NET installé, modelcontextprotocol-database-agent), et args fournit la liste des arguments à passer. On y retrouve exactement les options discutées précédemment : le provider sqlite, la connexion vers le fichier de base de données, et les paramètres du service AzureOpenAI (type et clé API, le nom du modèle déployé).

Une fois cette configuration en place, Claude Desktop lancera automatiquement notre serveur MCP à son démarrage. Pour vérifier, vous pouvez relancer Claude Desktop et observer dans les logs (ou le moniteur de ressources) que le processus modelcontextprotocol-database-agent tourne bien en arrière-plan.

Démonstration : Claude interroge la base via l’agent

Passons à la pratique ! Maintenant que tout est en place, ouvrons Claude Desktop et posons-lui une question qui nécessite de consulter la base de données. Par exemple : « Quel est le produit le plus vendu, et combien d’unités en ont été écoulées ? ». Sans l’agent, Claude serait incapable de répondre précisément à partir de ses seules connaissances. Mais grâce à MCP, voici ce qu’il se passe en coulisses :

  1. Analyse de la question – Claude comprend qu’il doit faire appel à un outil externe (notre serveur MCP) pour obtenir la réponse.
  2. Appel du serveur MCP – Claude envoie la requête au serveur databaseAgent via MCP. La première fois, Claude Desktop affiche une demande d’autorisation pour utiliser cet outil (par sécurité).

Claude Desktop demande l’autorisation d’exécuter l’action via le serveur MCP databaseAgent.

  1. Exécution par l’agent SK – Une fois autorisé, le serveur MCP reçoit la question. Il la transmet à l’agent Semantic Kernel en interne. L’agent génère la requête SQL correspondante, par exemple SELECT ProductName, SUM(Quantity) FROM Orders... etc., l’exécute sur la base, et obtient le résultat (disons « le plus vendu est le Louisiana Hot Spiced Okra, avec un total de 206,213 unités vendues »).
  2. Réponse à Claude – Le serveur renvoie cette réponse à Claude au format MCP. Claude intègre alors cette donnée dans sa réponse finale à l’utilisateur.
{
  `message`: `Quel est le produit le plus vendu et combien d'unités ont été vendues pour ce produit?`
}

Le produit le plus vendu est le **Louisiana Hot Spiced Okra**, avec un total de **206,213 unit�s** vendues.

Réponse du serveur MCP à Claude.

Réponse de Claude après utilisation de l’agent : le modèle a récupéré la donnée exacte via le serveur MCP (indiqué par l’icône de puzzle autorisé dans l’interface).

Et voilà ! 🎉 Claude répond en donnant le nom du produit et le nombre d’unités vendues, avec une exactitude qu’il n’aurait jamais eue sans l’outil. L’interface de Claude Desktop indique que l’outil databaseAgent a été utilisé (icône puzzle ✅ ou message d’autorisation visible), témoignant que la réponse provient bien d’une action MCP. Pour l’utilisateur final, l’expérience est fluide : il a posé une question en langage naturel et obtenu une réponse précise, sans se soucier qu’en coulisse un agent C# et une base SQL ont travaillé ensemble pour lui fournir.

Sous le capot du serveur MCP

Intéressons-nous rapidement à l’implémentation technique du serveur MCP (pour les plus curieux). Le code du serveur est disponible sur le dépôt GitHub du projet. En résumé, ce serveur utilise le SDK MCP et la bibliothèque Semantic Kernel pour faire le lien. Lorsque le serveur démarre, il initialise en mémoire l’agent NL2SQL comme nous l’avons fait plus haut (kernel SK, connexion DB, etc.). Puis il attend des messages entrants – typiquement des messages de type “UserQuery” contenant la question à traiter.

Le cœur du traitement est simple : à la réception d’une question, le serveur la passe à l’agent Semantic Kernel et récupère sa réponse. Ensuite, il renvoie cette réponse sous forme d’un message MCP à Claude Desktop. Voici un extrait pseudo-code illustrant le mécanisme :

// Boucle principale du serveur MCP (simplifiée)
while (true) {
    var request = AwaitNextRequest();        // Attend un message entrant de Claude
    if (request.Type == MessageType.Input) { // Claude pose une question
        string question = request.Content;
        var chatHistory = new ChatHistory(question, AuthorRole.User);
        var result = await agent.InvokeAsync(chatHistory);
        SendResponse(result);                // Renvoie la réponse à Claude
    }
    // ... (gère d’autres types de messages éventuels)
}

Le serveur gère éventuellement d’autres types de messages MCP (par ex. arrêt, pings, etc.), mais l’important est ce traitement de la requête utilisateur. Grâce à Semantic Kernel, l’agent renvoie non seulement les données brutes, mais peut aussi formater une réponse textuelle compréhensible. On pourrait par exemple intégrer dans l’agent un prompt template pour rédiger une phrase du style « le plus vendu est le Louisiana Hot Spiced Okra, avec un total de 206,213 unités vendues. ». Dans tous les cas, Claude présentera le contenu retourné comme s’il l’avait produit lui-même, sans hallucination puisque l’information vient directement de votre base.

Enfin, notez que le serveur MCP tourne localement : vos données restent chez vous. Seules la question et la réponse transitent via Claude (et potentiellement une API LLM si vous utilisez un service cloud pour le modèle), mais la base de données, elle, n’est jamais exposée directement à l’IA. L’agent fait office de courtier sécurisé.

Conclusion

Grâce au Model Context Protocol, j’ai pu combiner la flexibilité de mon agent Semantic Kernel avec la puissance conversationnelle de Claude. Là où ChatGPT ou Claude seuls auraient été « incapables » d’interroger une base de données, l’ajout d’un outil spécialisé change la donne. On a désormais un Claude augmenté, capable de puiser dans une base SQL en temps réel pour fournir des réponses fiables, le tout sans compromettre la sécurité grâce aux filtres intégrés et au contrôle de l’utilisateur (qui valide chaque action MCP).

Cette expérience illustre la formidable modularité apportée par Semantic Kernel et MCP. On peut imaginer brancher bien d’autres outils : fichiers locaux, services métier, API internes… Anthropic a ouvert la voie avec MCP, et en tant que développeurs nous avons maintenant un cadre pour y brancher nos propres assistants maison. Pour ma part, avoir un Claude DB-aware est un vrai confort : fini les « Désolé, je ne peux pas accéder à vos données » – place à « Voici la réponse précise que j’ai trouvée ». 🚀

En combinant un orchestrateur d’IA open-source (Semantic Kernel) avec un assistant grand public (Claude) via un protocole standard, on entrevoit ce que pourrait être l’avenir des agents IA : collaboratifs, extensibles, et hautement spécialisés tout en restant faciles d’accès. À vous d’expérimenter : et si vous connectiez Claude à votre donnée, quelle nouvelle super-pouvoir pourriez-vous lui donner ? 🙌

Sources :

Package NuGet SemanticKernel.Agents.DatabaseAgent.MCPServer ( NuGet Gallery | SemanticKernel.Agents.DatabaseAgent.MCPServer 0.0.3 )

Documentation Semantic Kernel & DatabaseAgent (GitHub – kbeaugrand/SemanticKernel.Agents.DatabaseAgent: Database agent for Semantic Kernel)

Mon article précédent sur l’agent NL2SQL (Créer un agent NL2SQL avec Semantic Kernel – Kevin BEAUGRAND)

Annonce du Model Context Protocol (Introducing the Model Context Protocol \ Anthropic)

Laisser un commentaire