Lorsque vous travaillez avec de grandes bases de connaissances dans Elasticsearch, trouver des informations n’est que la moitié du travail. Les ingénieurs ont souvent besoin de synthétiser des résultats issus de plusieurs documents, de générer des résumés et de faire remonter les réponses à leur source. Model Context Protocol (MCP) fournit un moyen standardisé de connecter Elasticsearch à des applications alimentées par des grands modèles de langage (LLM) afin d’y parvenir. Bien qu’Elastic propose des solutions officielles, comme Elastic Agent Builder (qui inclut un point de terminaison MCP parmi ses fonctionnalités), la création d’un serveur MCP personnalisé vous offre un contrôle total sur la logique de recherche, la mise en forme des résultats et la manière dont le contenu récupéré est transmis à un LLM pour la synthèse, les résumés et les citations.
Dans cet article, nous examinerons les avantages de la création d’un serveur MCP Elasticsearch personnalisé et expliquerons comment en créer un en TypeScript pour connecter Elasticsearch aux applications alimentées par des modèles LLM.
Pourquoi créer un serveur Elasticsearch MCP personnalisé ?
Elastic propose quelques alternatives pour les serveurs MCP :
- Serveur MCP Elastic Agent Builder pour Elasticsearch 9.2+
- Serveur MCP Elasticsearch pour les anciennes versions (Python)
Si vous avez besoin de plus de contrôle sur la façon dont votre serveur MCP interagit avec Elasticsearch, la création de votre propre serveur personnalisé vous donne la flexibilité de l'adapter exactement à vos besoins. Par exemple, le point de terminaison MCP d'Agent Builder est limité aux requêtes du langage de requête Elasticsearch (ES|QL), tandis qu'un serveur personnalisé vous permet d'utiliser le langage de requête DSL complet. Vous gagnez également le contrôle sur la façon dont les résultats sont formatés avant d'être transmis au LLM et pouvez intégrer des étapes de traitement supplémentaires, comme la summarisation alimentée par OpenAI que nous mettrons en œuvre dans ce tutoriel.
À la fin de cet article, vous aurez un serveur MCP dans TypeScript qui recherche les informations stockées dans un index Elasticsearch, les résume et fournit des citations. Nous utiliserons Elasticsearch pour la récupération, le modèle gpt-4o-mini d'OpenAI pour résumer et générer des citations, et Claude Desktop comme client MCP et interface utilisateur pour recevoir les requêtes des utilisateurs et fournir des réponses. Le résultat final est un assistant de connaissances interne qui aide les ingénieurs à découvrir et à synthétiser les bonnes pratiques dans l'ensemble de la documentation technique de leur organisation.

Produits requis
- Node.js 20 +
- Elasticsearch
- Clé API OpenAI
- Claude Desktop
Qu'est-ce que le MCP ?
MCP est une norme ouverte, créée par Anthropic, qui fournit des connexions bidirectionnelles sécurisées entre les LLM et les systèmes externes, comme Elasticsearch. Vous pouvez en savoir plus sur l'état actuel du MCP dans cet article.
Le paysage des MCP évolue chaque jour, avec des serveurs disponibles pour un large éventail de cas d'utilisation. De plus, il est facile de créer votre propre serveur MCP personnalisé, comme nous le montrerons dans cet article.
Clients MCP
Il existe une longue liste de clients MCP disponibles, chacun ayant ses propres caractéristiques et limitations. Par souci de simplicité et de popularité, nous utiliserons Claude Desktop comme client MCP. Il servira d'interface de chat où les utilisateurs pourront poser des questions en langage naturel, et il invoquera automatiquement les outils exposés par notre serveur MCP pour rechercher des documents et générer des résumés.

Créer un serveur Elasticsearch MCP
Grâce au SDK TypeScript, nous pouvons facilement créer un serveur qui comprend comment interroger nos données Elasticsearch à partir d'une requête utilisateur.
Voici les étapes dans cet article pour intégrer le serveur Elasticsearch MCP avec le client Claude Desktop :
Configurez le serveur MCP pour Elasticsearch
Pour commencer, initialisons une application Node :
Cela créera un fichier package.json, et avec lui, nous pourrons commencer à installer les dépendances nécessaires pour cette application.
- @elastic/elasticsearch nous donnera accès à la bibliothèque de Node.js Elasticsearch.
- @modelcontextprotocol/sdk fournit les outils du noyau pour créer et gérer un serveur MCP, enregistrer les outils et gérer la communication avec les clients MCP.
- OpenAI permet d'interagir avec les modèles OpenAI pour générer des résumés ou des réponses en langage naturel.
- ZOD aide à définir et valider des schémas structurés pour les données d’entrée et de sortie dans chaque outil.
ts-node, @types/node et typescript seront utilisés pendant le développement pour écrire le code et compiler les scripts.
Configurer l’ensemble de données
Pour fournir les données que Claude Desktop peut interroger via notre serveur MCP, nous utiliserons un ensemble de données simulé de base de connaissances interne. Voici à quoi ressemblera un document issu de cet ensemble de données :
Pour ingérer les données, nous avons préparé un script qui crée un index dans Elasticsearch et y charge l’ensemble de données. Vous pouvez le trouver ici.
Serveur MCP
Créez un fichier nommé index.ts et ajoutez le code suivant pour importer les dépendances et gérer les variables d’environnement :
Aussi, initialisons les clients pour gérer les appels Elasticsearch et OpenAI :
Pour rendre notre implémentation plus robuste et garantir des entrées et des sorties structurées, nous définirons des schémas en utilisant zod. Cela nous permet de valider les données au moment de l'exécution, de détecter les erreurs tôt et de rendre les réponses des outils plus faciles à traiter de manière programmatique :
Pour en savoir plus sur les sorties structurées, cliquez ici.
Maintenant, initialisons le serveur MCP :
Définition des outils MCP
Une fois que tout est configuré, nous pouvons commencer à écrire les outils qui seront exposés par notre serveur MCP. Ce serveur expose deux outils :
search_docs: Recherche des documents dans Elasticsearch à l'aide de la recherche full-text.summarize_and_cite: Résume et synthétise les informations provenant de documents précédemment récupérés pour répondre à la question d'un utilisateur. Cet outil ajoute également des citations faisant référence aux documents sources.
Ensemble, ces outils forment un workflow simple de « récupération puis synthèse », où un outil extrait les documents pertinents et l'autre utilise ces documents pour générer une réponse synthétisée et citée.
Format de réponse de l'outil
Chaque outil peut accepter des paramètres d'entrée arbitraires, mais il doit répondre avec la structure suivante :
- Contenu : il s'agit de la réponse de l'outil dans un format non structuré. Ce champ est généralement utilisé pour renvoyer du texte, des images, de l’audio, des liens ou des plongements. Pour cette application, il sera utilisé pour renvoyer un texte formaté contenant les informations générées par les outils.
- structuredContent : il s'agit d'un retour facultatif utilisé pour fournir les résultats de chaque outil dans un format structuré. Ceci est utile à des fins de programmation. Bien qu'il ne soit pas utilisé dans ce serveur MCP, il peut être utile si vous souhaitez développer d'autres outils ou traiter les résultats de manière programmée.
En gardant cette structure à l’esprit, entrons dans le vif du sujet en examinant chaque outil en détail.
Outil de recherche
Cet outil effectue une recherche full-text dans l’index Elasticsearch pour récupérer les documents les plus pertinents selon la requête de l’utilisateur. Il met en évidence les correspondances clés et offre un aperçu rapide avec des scores de pertinence.
Nous configurons fuzziness: “AUTO” pour que la tolérance aux fautes de frappe soit variable en fonction de la longueur du jeton analysé. Nous configurons également title^2 pour qu'il augmente le score des documents dont la correspondance se fait sur le champ du titre.
outil summarize_and_cite
Cet outil génère un résumé basé sur les documents récupérés lors de la recherche précédente. Il utilise le modèle gpt-4o-mini d’OpenAI pour synthétiser les informations les plus pertinentes afin de répondre à la question de l’utilisateur, en fournissant des réponses dérivées directement des résultats de recherche. Outre le résumé, il renvoie également les métadonnées de citation des documents sources utilisés.
Enfin, il faut démarrer le serveur avec stdio. Cela signifie que le client MCP communiquera avec notre serveur en lisant et en écrivant dans ses flux d'entrée et de sortie standard. StDIO est l’option de transport la plus simple et fonctionne bien pour les serveurs MCP locaux lancés en sous-processus par le client. Ajoutez le code suivant à la fin du fichier :
Compilez le projet en utilisant la commande suivante :
Cela créera un dossier dist, dans lequel se trouvera un fichier index.js.
Chargez le serveur MCP dans Claude Desktop.
Suivez ce guide pour configurer le serveur MCP avec Claude Desktop. Dans le fichier de configuration Claude, nous devons définir les valeurs suivantes :
La valeur args doit pointer vers le fichier compilé dans le dossier dist . Vous devez également définir les variables d'environnement dans le fichier de configuration avec les noms exacts définis dans le code.
Testez-le
Avant d’exécuter chaque outil, cliquez sur Recherche et Outils pour vous assurer que les outils sont activés. Vous pouvez également activer ou désactiver chaque option ici :

Enfin, testons le serveur MCP depuis le chat Claude Desktop et commençons à poser des questions :

Pour la question « Recherche de documents sur les méthodes d’authentification et le contrôle d’accès basé sur les rôles », l’outil search_docs est exécuté et renvoie les résultats suivants :
La réponse est : « Super ! J'ai trouvé 5 documents pertinents sur les méthodes d'authentification et le contrôle d'accès basé sur les rôles. Voici ce qui a été découvert : »
L'appel d'outil renvoie les documents sources dans le cadre de sa charge utile de réponse, qui sont ensuite utilisés pour générer des citations.

Il est également possible d'enchaîner plusieurs outils dans une même interaction. Dans ce cas, Claude Desktop analyse la question de l’utilisateur et détermine qu’il doit d’abord appeler search_docs pour récupérer les documents pertinents, puis transmettre ces résultats à summarize_and_cite pour générer la réponse finale, le tout sans nécessiter d’invites séparées de la part de l’utilisateur :

Dans ce cas, pour la requête « Quelles sont les principales recommandations pour améliorer l’authentification et le contrôle d’accès dans l’ensemble de nos systèmes ? Veuillez inclure des références. », Nous avons obtenu les résultats suivants :
Comme à l’étape précédente, nous pouvons voir la réponse de chaque outil à cette question :

Note : Si un sous-menu apparaît demandant si vous approuvez l’utilisation de chaque outil, sélectionnez Toujours autoriser ou Permettre une fois.

Conclusion
Les serveurs MCP représentent une étape importante vers la standardisation des outils LLM pour les applications locales et distantes. Bien que la compatibilité totale soit encore en cours de développement, nous avançons rapidement dans cette direction.
Dans cet article, nous avons appris à créer un serveur MCP personnalisé en TypeScript qui connecte Elasticsearch aux applications basées sur LLM. Notre serveur propose deux outils : search_docs pour récupérer les documents pertinents à l'aide de Query DSL ; et summarize_and_cite pour générer des résumés avec des citations via des modèles OpenAI et Claude Desktop comme interface utilisateur client.
L'avenir de la compatibilité entre les différents fournisseurs côté client et côté serveur semble prometteur. Les prochaines étapes consistent à ajouter davantage de fonctionnalités et de flexibilité à votre agent. Vous trouverez un article pratique expliquant comment paramétrer vos requêtes à l'aide de modèles de rechercher pour gagner en précision et en flexibilité.




