使用 TypeScript 构建 Elasticsearch MCP 服务器

学习如何使用 TypeScript 和 Claude Desktop 创建 Elasticsearch MCP 服务器。

Elasticsearch 中处理大型知识库时,找到信息只是成功的一半。工程师通常还需要综合多个文档的结果,生成摘要,并追溯答案的来源。模型上下文协议 (MCP) 提供了一种标准化的方式,可将 Elasticsearch 与大语言模型 (LLM) 驱动的应用程序连接起来,以实现上述目标。虽然 Elastic 提供官方解决方案,例如 Elastic Agent Builder(其功能包括 MCP 终端),但构建自定义 MCP 服务器可让您完全掌控搜索逻辑、结果格式,以及如何将检索到的内容传递给 LLM,以用于综合分析、生成摘要和提供引用。

本文将探讨构建自定义 Elasticsearch MCP 服务器的优势,并展示如何使用 TypeScript 创建该服务器,以将 Elasticsearch 连接到 LLM 驱动的应用程序。

为什么要构建自定义 Elasticsearch MCP 服务器?

Elastic 为 MCP 服务器提供了一些替代方案:

如果您需要更好地控制 MCP 服务器与 Elasticsearch 的交互,构建自己的自定义服务器可以让您灵活地根据自身需求进行定制。例如,Agent Builder 的 MCP 终端仅限于 Elasticsearch 查询语言 (ES|QL) 查询,而自定义服务器允许您使用完整的查询 DSL。在将结果传递给 LLM 之前,您还可以控制结果的格式,并可以集成其他处理步骤,例如我们将在本教程中实现的由 OpenAI 驱动的摘要功能。

通过阅读本文,您将学会使用 TypeScript 创建 MCP 服务器,该服务器可搜索存储在 Elasticsearch 索引中的信息,对其进行总结并提供引用。我们将使用 Elasticsearch 进行检索,使用 OpenAI 的 gpt-4o-mini 模型提炼摘要并生成引用,并使用 Claude Desktop 作为 MCP 客户端和 UI 来接收用户查询并提供回复。最终我们将得到一个内部知识助手,帮助工程师在整个组织的技术文档中发现并综合最佳实践。

准备工作:

  • Node.js 20 +
  • Elasticsearch
  • OpenAI API 密钥
  • Claude Desktop

什么是 MCP?

MCP 是由 Anthropic 创建的开放标准,提供大型语言模型与外部系统(如 Elasticsearch)之间的安全双向连接。您可以在这篇文章中了解更多关于 MCP 现状的信息。

MCP 的发展每天都在变化,服务器的使用范围越来越广。此外,构建自定义 MCP 服务器也非常简单,我们将在本文中进行演示。

MCP 客户端

可用的 MCP 客户端由很多,每个客户端都有自己的特点和局限性。为了简化和普及,我们将使用 Claude Desktop 作为演示中的 MCP 客户端。它将作为聊天界面,用户可以用自然语言提问,它还将自动调用我们的 MCP 服务器提供的工具来搜索文档和生成摘要。

创建 Elasticsearch MCP 服务器

通过使用 TypeScript 软件开发工具包,我们可以轻松创建一个能够根据用户查询输入来查询 Elasticsearch 数据的服务器。

本文将介绍将 Elasticsearch MCP 服务器与 Claude Desktop 客户端集成的步骤:

  1. 为 Elasticsearch 配置 MCP 服务器。
  2. 将 MCP 服务器加载到 Claude Desktop。
  3. 测试一下。

为 Elasticsearch 配置 MCP 服务器。

首先,我们来初始化一个 Node 应用程序:

这将会创建一个 package.json 文件,有了它,我们就可以开始安装该应用程序所需的依赖项。

  • @elastic/elasticsearch 将使我们能够访问 Elasticsearch Node.js 库。
  • @modelcontextprotocol/sdk 提供核心工具来创建和管理 MCP 服务器、注册工具以及处理与 MCP 客户端的通信。
  • openai 允许与 OpenAI 模型进行交互以生成摘要或自然语言响应。
  • zod 帮助定义和验证每个工具中输入和输出数据的结构化模式。

ts-node@types/nodetypescript 将在开发过程中用于键入代码和编译脚本。

配置数据集

为了提供 Claude Desktop 可以使用我们的 MCP 服务器进行查询的数据,我们将使用模拟的内部知识库数据集。来自该数据集的文档是这样子的:

为了摄取数据,我们准备了一个脚本,该脚本在 Elasticsearch 中创建一个索引并将数据集加载到其中。您可以在这里找到它。

MCP 服务器

创建一个名为 index.ts 的文件,并添加以下代码来导入依赖项并处理环境变量:

此外,让我们初始化客户端以处理 Elasticsearch 和 OpenAI 的调用:

为了使我们的实现更加稳健,并确保输入和输出结构化,我们将使用 zod 定义模式。这使我们能够在运行时验证数据,及早发现错误,并使工具响应更容易以编程方式进行处理:

请在此处了解更多关于结构化输出的信息。

现在让我们初始化 MCP 服务器:

定义 MCP 工具

完成所有配置后,我们就可以开始编写将由 MCP 服务器公开的工具了。此服务器公开两种工具:

  • search_docs使用全文本搜索在 Elasticsearch 中搜索文档。
  • summarize_and_cite汇总和综合先前检索到的文档中的信息,以回答用户的问题。该工具还可添加引用源文档的引文。

这两个工具共同构成了一个简单的“检索后总结”工作流,其中一个工具获取相关文档,另一个工具使用这些文档生成汇总的引用回复。

工具响应格式

每个工具都可以接受任意输入参数,但必须以以下结构作出响应:

  • 内容:这是工具以非结构化格式做出的响应。该字段通常用于返回文本、图像、音频、链接或嵌入内容。在本应用程序中,它将用于返回包含工具生成的信息的格式化文本。
  • 结构化内容: 这是一个可选返回,用于以结构化格式提供每个工具的结果。这对程序化用途非常有用。虽然本 MCP 服务器没有使用它,但如果您想开发其他工具或以编程方式处理结果,它可能会很有用。

基于这个结构,让我们详细探讨每个工具。

Search_docs 工具

此工具在 Elasticsearch 索引中执行 全文本搜索,以根据用户查询检索最相关的文档。它突出显示关键匹配项,并快速提供相关性评分概述。

我们将 fuzziness : “AUTO” 配置为根据被分析的词元的长度具有可变的拼写错误容忍度。我们还设置了 title^2 来提高标题字段匹配的文档的分数。

摘要和引用工具

该工具根据上一次搜索中检索到的文档生成摘要。它使用 OpenAI 的 gpt-4o-mini 模型来综合最相关的信息,提供直接来自搜索结果的响应,以回答用户的问题。除了摘要之外,它还返回所使用源文档的引用元数据。

最后,我们需要用 stdio 启动服务器。这意味着 MCP 客户端将通过读取和写入其标准输入和输出流与我们的服务器进行通信。stdio 是最简单的传输选项,适用于客户端作为子进程启动的本地 MCP 服务器。在文件末尾添加以下代码:

现在请您使用以下命令编译该项目:

这将创建一个 dist 文件夹,并在其中创建一个 index.js 文件。

将 MCP 服务器加载到 Claude Desktop。

请按照本指南配置 MCP 服务器和 Claude Desktop。在 Claude 配置文件中,我们需要设置以下值:

args 的值应指向 dist 文件夹中的编译后文件。您还需要在配置文件中设置环境变量,使其名称与代码中定义的名称完全一致。

测试一下

在执行每个工具前,点击搜索和工具,确保这些工具已启用。您还可以在这里启用或禁用每个工具:

最后,让我们从 Claude Desktop 聊天中测试 MCP 服务器,并开始提问:

针对问题“搜索有关身份验证方法和基于角色的访问控制的文档”,已执行 search_docs 工具并返回以下结果:

回复是:“太好了!我找到了 5 份关于身份验证方法和基于角色的访问控制的相关文档。以下是找到的内容:”

该工具调用会将源文档作为其响应有效负载的一部分返回,这些文档随后用于生成引用。

您也可以在一次交互中串联使用多个工具。在这种情况下,Claude Desktop 会分析用户的问题,并确定首先需要调用 search_docs 来检索相关文档,然后将这些结果传递给 summarize_and_cite 以生成最终回答,所有这些都无需用户单独提示:

在这种情况下,对于“在我们的系统中改进身份验证和访问控制的主要建议是什么?附上参考文献”,我们得到了以下结果:

与上一步一样,我们可以看到每个工具对该问题的响应:

注意:如果出现子菜单询问是否批准使用每个工具,请选择“始终允许”“允许一次”

结论

MCP 服务器代表了本地和远程应用中 LLM 工具标准化的重要一步。虽然完全兼容仍在开发中,但我们正朝这个方向快速推进。

在本文中,我们学习了如何用 TypeScript 构建一个自定义 MCP 服务器,将 Elasticsearch 连接到基于 LLM 的应用。我们的服务器公开了两个工具:search_docs 用于使用查询 DSL 检索相关文档;summarize_and_cite 用于通过 OpenAI 模型和 Claude Desktop 作为客户端 UI 生成带引用的摘要。

不同客户端和服务器提供商之间的兼容性前景看起来一片光明。下一步包括为您的智能体添加更多功能和灵活性。这里有一篇实用的文章介绍了如何使用搜索模板参数化查询,以获得精确性和灵活性。

这些内容对您有多大帮助?

没有帮助

有点帮助

非常有帮助

相关内容

准备好打造最先进的搜索体验了吗?

足够先进的搜索不是一个人的努力就能实现的。Elasticsearch 由数据科学家、ML 操作员、工程师以及更多和您一样对搜索充满热情的人提供支持。让我们联系起来,共同打造神奇的搜索体验,让您获得想要的结果。

亲自试用