MCP Server 开发实战:无缝对接 LLM 和 Elasticsearch

在一文带你入门 MCP(模型上下文协议)文章中,我们快速介绍了 MCP 的基本概念,并且通过一个示例让读者初步感受到了 MCP 的强大能力。本文将进一步深入,带领读者一步步学习如何开发一个完整的 MCP Server。本文的完整代码可以在这里找到:https://github.com/cr7258/hands-on-lab/tree/main/ai/claude/mcp/server/elasticsearch-mcp-server-example

MCP Server 核心原语

Model Context Protocol (MCP) 是一个专门为 LLM(大语言模型)应用设计的协议,它允许你构建服务器以安全、标准化的方式向 LLM 应用程序公开数据和功能。MCP Server 提供了 3 种核心原语,每种原语都有其特定的用途和特点:

  1. Tool(工具)
  • Tool 允许服务器公开可执行的函数,这些函数可由客户端调用并由 LLM 使用来执行操作。Tool 不仅人让 LLM 能从外部获取信息,还能执行写入或操作,为 LLM 提供真正的行动力。
  • 模型控制:Tool 直接暴露给 LLM 可执行函数,让模型可以主动调用。
  1. Resource(资源)
  • Resource 表示服务器希望提供给客户端的任何类型的只读数据。这可能包括:文件内容、数据库记录、图片、日志等等。
  • 应用控制:Resource 由客户端或应用管理,用于为 LLM 提供上下文内容。
  1. Prompt(提示模板)
  • Prompt 是由服务器定义的可重用的模板,用户可以选择这些模板来引导或标准化与 LLM 的交互过程。例如,Git MCP server 可以提供一个“生成提交信息”的提示模板,用户可以用它来创建标准化的提交消息。
  • 用户控制:Prompt 通常由用户自行选择。

Elasticsearch MCP Server 示例

接下来,我们将通过构建一个 Elasticsearch MCP Server,分别演示 Tool、Prompt 和 Resource 的具体用法。

使用 Docker Compose 启动 Elasticsearch 集群

执行 docker-compose up -d 命令在后台启动一个 3 节点的 Elasticsearch 集群,并且提供了 Kibana 用于管理和可视化 Elasticsearch。

浏览器输入 http://localhost:5601 访问 Kibana 界面,用户名 elastic,密码 test123

准备测试数据

在 Kibana 中打开 Management -> Dev Tools 页面, 执行以下代码创建两个索引 studentteacher,分别插入几条数据:

POST /student/_doc
{
  "name": "Alice",
  "age": 20,
  "major": "Computer Science"
}

POST /student/_doc
{
  "name": "Bob",
  "age": 22,
  "major": "Mathematics"
}

POST /student/_doc
{
  "name": "Carol",
  "age": 21,
  "major": "Physics"
}

POST /teacher/_doc
{
  "name": "Tom",
  "subject": "English",
  "yearsOfExperience": 10
}

POST /teacher/_doc
{
  "name": "John",
  "subject": "History",
  "yearsOfExperience": 7
}

POST /teacher/_doc
{
  "name": "Lily",
  "subject": "Mathematics",
  "yearsOfExperience": 5
}

初始化项目

在本教程中,我们将使用 MCP Python SDK 来编写项目,使用 uv 来管理 Python 项目依赖。

安装 uv 可以参考 Installing uv。MacOS 用户可以使用 brew 进行安装:

brew install uv

执行以下命令初始化项目:

uv init elasticsearch-mcp-server-example
cd elasticsearch-mcp-server-example

添加依赖:

uv add "mcp[cli]" elasticsearch python-dotenv

创建 server.py 文件,接下来将会在该文件中编写代码:

touch server.py

在 Claude Desktop 中安装 MCP Server

.env 文件中设置好 Elasticsearch 的连接信息。

ELASTIC_HOST=https://localhost:9200
ELASTIC_USERNAME=elastic
ELASTIC_PASSWORD=test123

可以执行以下命令将 MCP Server 安装到 Claude Desktop 中:

  • --env-file 参数指定了 .env 文件的路径,用于加载环境变量。
  • --with-editable 参数指定了 uv 依赖管理文件 pyproject.toml 所在的目录,用于安装项目的依赖。
mcp install server.py --env-file .env --with-editable ./

该命令会自动帮助你在 cluade_desktop_config.json 文件中添加 MCP Server 的配置。

{
  "mcpServers": {
    "elasticsearch-mcp-server": {
      "command": "uv",
      "args": [
        "run",
        "--with",
        "mcp[cli]",
        "--with-editable",
        "/your/project/path/elasticsearch-mcp-server-example",
        "mcp",
        "run",
        "/your/project/path/elasticsearch-mcp-server-example/server.py"
      ],
      "env": {
        "ELASTIC_HOST": "https://localhost:9200",
        "ELASTIC_USERNAME": "elastic",
        "ELASTIC_PASSWORD": "test123"
      }
    }
  }
}

接下来我们开始编写 Elasticsearch MCP Server 的相关代码。

Elasticsearch 客户端配置

首先创建 Elasticsearch 客户端,用于和 Elasticsearch 服务器进行交互。

def create_elasticsearch_client() -> Elasticsearch:
    # Load environment variables from .env file
    load_dotenv()

    url = os.getenv("ELASTIC_HOST")
    username = os.getenv("ELASTIC_USERNAME")
    password = os.getenv("ELASTIC_PASSWORD")

    # Disable SSL warnings
    warnings.filterwarnings("ignore", message=".*TLS with verify_certs=False is insecure.*",)
    
    if username and password:
        return Elasticsearch(url, basic_auth=(username, password), verify_certs=False)
    return Elasticsearch(url)

初始化 FastMCP Server

MCP Python SDK 现在提供了全新的 FastMCP 类,它通过利用 Python 的类型注解(Type Hints)和文档字符串(Docstrings)特性,能够自动生成工具定义。这种方式让开发者可以更加便捷地创建和管理 MCP 的 Tool、Resource 以及 Prompt 等功能组件。

以下代码创建一个名为 mcp 的 FastMCP 对象。

from mcp.server.fastmcp import FastMCP

MCP_SERVER_NAME = "elasticsearch-mcp-server"
mcp = FastMCP(MCP_SERVER_NAME)
添加 Tool

Tool 定义了允许 LLM 可以调用 MCP Server 执行的操作,除了查询以外,还可以执行写入操作。接下来定义了两个 Tool:

  • list_indices: 列出所有可用的索引。
  • get_index: 获取指定索引的详细信息。

使用 @mcp.tool() 装饰器将这两个函数标记为 MCP 的 Tool。

@mcp.tool()
def list_indices() -> List[str]:
    """列出所有 Elasticsearch 索引"""
    return [index["index"] for index in es.cat.indices(format="json")]

@mcp.tool()
def get_index(index: str) -> dict:
    """获取特定 Elasticsearch 索引的详细信息"""
    return es.indices.get(index=index)

然后重启 Claude Desktop,一切正常的话,你应该能在输入框的右下角看到一个锤子图标。点击锤子图标,可以看到 Elasticsearch MCP Server 提供的工具信息。

我们可以针对 Elasticsearch 的数据进行提问,比如:

Elasticsearch 中有哪些索引? 可以看到 Claude 调用了 list_indices 来列出所有索引。

student 索引中有哪些字段? 可以看到 Claude 调用了 get_index 来获取 student 索引信息。

添加 Resource

Resource 定义了 LLM 可以访问只读的数据源,可以用于为 LLM 提供上下文内容。在这个示例中,我们定义了两个资源:

  • es://logs:允许 LLM 访问 Elasticsearch 容器的日志信息,通过 Docker 命令获取日志内容。
  • file://docker-compose.yaml:允许 LLM 访问项目的 docker-compose.yaml 文件内容。
@mcp.resource("es://logs")
def get_logs() -> str:
    """Get Elasticsearch container logs"""
    result = subprocess.run(["docker", "logs", "elasticsearch-mcp-server-example-es01-1"], capture_output=True, text=True, check=True)
    return result.stdout

@mcp.resource("file://docker-compose.yaml")
def get_file() -> str:
    """Return the contents of docker-compose.yaml file"""
    with open("docker-compose.yaml", "r") as f:
        return f.read()

使用 @mcp.resource() 装饰器将这些函数标记为 MCP 的 Resource,装饰器参数指定了 Resource 的 URI。

Resource 建议遵循以下格式的 URI 标识:

[protocol]://[host]/[path]

URI 的协议和路径结构由 MCP Server 自定实现定义。

重启 Claude,点击插头图标,可以看到 Elasticsearch MCP Server 提供的 Resource。

接下来我们可以选择 Resource 作为提问的上下文,让 LLM 进行回答。

  • 选择 es://logs,然后提问:分析一下日志。

  • 选择 file://docker-compose.yaml,然后提问:文件中定义了哪几个容器?

添加 Prompt

Prompt 用于定义可重用的提示模板,帮助用户更好地引导 LLM 以标准化的方式完成任务。在这个示例中,我们定义了一个名为 es_prompt 的提示模板,引导 LLM 从多个维度(如索引设置、搜索优化、数据建模和扩展性等)对索引进行分析。

@mcp.prompt()
def es_prompt(index: str) -> str:
    """Create a prompt for index analysis"""
    return f"""You are an elite Elasticsearch expert with deep knowledge of search engine architecture, data indexing strategies, and performance optimization. Please analyze the index '{index}' considering:
- Index settings and mappings
- Search optimization opportunities
- Data modeling improvements
- Potential scaling considerations
"""

重启 Claude Desktop,点击插头图标,选择 es_prompt,并输入待分析的索引 student

Claude 会调用 get_index Tool 来获取 student 索引的信息,并根据我们提供的 Prompt 给出多个维度的建议。

使用 MCP Inspector 调试 MCP Server

MCP Inspector 是一个交互式的开发者工具,专门用于测试和调试 MCP 服务器。它提供了一个图形化界面,让开发者能够直观地检查和验证 MCP 服务器的功能。

执行以下命令可以启动 MCP Inspector:

mcp dev server.py 

启动成功后,浏览数输入 http://localhost:5173 打开 MCP Inspector 界面。点击 Connect 连接 MCP Server。

将 Elasticsearch 的连接信息添加到环境变量中。

在 MCP Inspector 中可以列出和执行 Resource、Tool 和 Prompt。

组合示例

现在假设我们有这样一个需求,读取 movies.csv 文件,将文档写入 Elasticsearch 的 movies 索引中,如果电影票房超过 1 亿美元,则在文档中设置一个额外的字段 isPopular: true,否则设置为 isPopular: false

在过去,我们可能会考虑使用 Elasticsearch Ingest Pipeline 的 Script processor 来实现这一需求。

现在我们可以通过 Resource 向 LLM 提供要读取的 movies.csv 文件,LLM 会对电影票房进行计算,然后设置文档的 isPopular 字段值,最后调用 write_documents Tool 来将文档写入 Elasticsearch 的 movies 索引中。实现的代码如下:

@mcp.resource("file://movies.csv")
def get_movies() -> str:
    """Return the contents of movies.csv file"""
    with open("movies.csv", "r") as f:
        return f.read()

@mcp.tool()
def write_documents(index: str, documents: List[Dict]) -> dict:
    """Write multiple documents to an Elasticsearch index using bulk API
    
    Args:
        index: Name of the index to write to
        documents: List of documents to write
        
    Returns:
        Bulk operation response from Elasticsearch
    """
    operations = []
    for doc in documents:
        # Add index operation
        operations.append({"index": {"_index": index}})
        # Add document
        operations.append(doc)
    
    return es.bulk(operations=operations, refresh=True)

重启 Claude,选择 file://movies.csv/ Resource,然后向 Claude 发送以下指令:将文件中的电影写入 Elasticserach 中的 movies 索引,如果电影票房超过 1 亿美元,那么在该文档中设置一个额外的字段 isPopular: true,否则设置为 false。

可以看到 Claude 顺利地完成了我们指定的任务。

在 Kibana 中查询 movies 索引,可以看到我们的数据已经成功写入,并且 isPopular 字段也已经被正确设置了。

总结

本教程通过构建一个 Elasticsearch MCP Server 的实例,展示了如何利用 MCP 协议的三个核心原语(Tool、Resource 和 Prompt)来增强 LLM 的能力。通过 Tool 实现了索引操作和文档写入,通过 Resource 提供数据的访问能力,而 Prompt 则帮助 LLM 以标准化的方式完成任务。最后通过一个实际的组合示例,演示了如何让 LLM 利用这些组件完成更复杂的数据处理任务,充分体现了 MCP 在提升 LLM 应用开发效率方面的优势。

欢迎关注

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/958269.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Kubernetes v1.28.0安装dashboard v2.6.1(k8s图形化操作界面)

准备工作 Kubernetes v1.28.0搭建教程请参考:Kubernetes v1.28.0集群快速搭建教程-CSDN博客 查看当前集群nodes都是ready状态 查看当前pods都是running状态 下载并修改配置文件 下载 recommended.yaml ,下载好之后,进入文件编辑 下载地址…

设计模式的艺术-职责链模式

行为型模式的名称、定义、学习难度和使用频率如下表所示: 1.如何理解职责链模式 最常见的职责链是直线型,即沿着一条单向的链来传递请求。链上的每一个对象都是请求处理者,职责链模式可以将请求的处理者组织成一条链,并让请求沿着…

通过脚本申请免费SSL证书(泛解析SSL证书)

参考来源 1.https://github.com/acmesh-official/acme.sh/wiki/%E8%AF%B4%E6%98%8E 2.https://github.com/acmesh-official/acme.sh/wiki/dns-manual-mode 3.https://github.com/acmesh-official/acme.sh/wiki/dnsapi 安装 acme.sh 配置账号 配置默认CA 安装依赖 # Cento…

CrypTen项目实践

CrypTen是一个用于安全多方计算(MPC)的python库,基于PyTorch构建。 CrypTen facebookresearch/CrypTen: A framework for Privacy Preserving Machine Learning 目录 一、实践准备 二、实践操作 1.下载WSL 2.下载代码 3.创建虚拟环境&…

【CS61A 2024秋】Python入门课,全过程记录P3(Week5 Sequences开始,更新于2025/1/23)

文章目录 关于基本介绍👋新的问题Week5Mon Sequences阅读材料 关于 个人博客,里面偶尔更新,最近比较忙。发一些总结的帖子和思考。 江湖有缘相见🤝。如果读者想和我交个朋友可以加我好友(见主页or个人博客&#xff0…

Jenkins-基于Role的鉴权机制

jenkins自带了一些全局性的安全配置。 但无法通过job等相对细粒度的来控制使用者的权限。但它可以借助相关的插件实现细颗粒的权限控制。 插件: Role-based Authorization Strategy 需要在configure global security中配置授权策略如下: 保存后&#x…

SSM开发(一)JAVA,javaEE,spring,springmvc,springboot,SSM,SSH等几个概念区别

目录 JAVA 框架 javaEE spring springmvc springboot SSM SSH maven JAVA 一种面向对象、高级编程语言,Python也是高级编程语言;不是框架(框架:一般用于大型复杂需求项目,用于快速开发)具有三大特性,所谓Jav…

Linux——入门基本指令汇总

目录 1. ls指令2. pwd3. whoami指令4. cd指令5. clear指令6. touch指令7. mkdir指令8. rm指令9. man指令10. cp指令11. mv指令12. cat指令13. tac指令14. more指令15. less指令16. head指令17. tail指令18. date指令19. cal指令20. find指令21. which指令22. alias指令23. grep…

基于SpringBoot+Vue的旅游管理系统【源码+文档+部署讲解】

系统介绍 基于SpringBootVue实现的旅游管理系统采用前后端分离架构方式,系统设计了管理员、用户两种角色,系统实现了用户登录与注册、个人中心、用户管理、景点信息管理、订票信息管理、用户评价管理、景点咨询、轮播图管理等功能。 技术选型 开发工具…

光学遥感显著性目标检测2023-2024论文学习

GRSL 2023: Attention-Aware Three-Branch Network for Salient Object Detection in Remote Sensing Images 基于encoder-decoder框架,提出了一系列缝合模块,GCA,FDUC,MSDC,RA。 GRSL 2023:OR…

接口 V2 完善:基于责任链模式、Canal 监听 Binlog 实现数据库、缓存的库存最终一致性

🎯 本文介绍了一种使用Canal监听MySQL Binlog实现数据库与缓存最终一致性的方案。文章首先讲解了如何修改Canal配置以适应订单表和时间段表的变化,然后详细描述了通过责任链模式优化消息处理逻辑的方法,确保能够灵活应对不同数据表的更新需求…

graylog~认识一下-日志管理平台

1、介绍 Graylog 是一个开源的日志管理和分析平台,旨在帮助企业集中收集、存储、搜索和分析来自各种来源的日志数据。它提供了强大的实时日志处理能力,适用于大规模分布式系统和复杂的生产环境。 主要功能 集中化日志管理: 收集来自不同来源…

Android程序中使用FFmpeg库

目录 前言 一、环境 二、创建APP 三. 添加FFmpeg库文件到app中 1. 复制ffmpeg头文件和so库到app中 2. 修改CMakeLists.txt文件内容. 3. 修改ffmpeglib.cpp 文件内容 4. 修改NativeLib.kt 文件添加方法和加载库 5. 调用 四. 增加解析视频文件信息功能 总结 前言 前面…

AI 编程工具—Cursor进阶使用 Rules for AI

AI 编程工具—Cursor进阶使用 Rules for AI 这里配置是给所有的会话和内嵌模式的,你可以理解为是一个全局的配置 下面的代码是之前Cursor 给我们生成的,下面我们开始配置Rules ,来让Cursor生成的代码更加符合我们的编程习惯 def quick_sort(arr):"""使用快…

【系统环境丢失恢复】如何恢复和重建 Ubuntu 中的 .bashrc 文件

r如果你遇到这种情况,说明系统环境的.bashrc 文件丢失恢复: 要恢复 ~/.bashrc 文件,可以按照以下几种方式操作: 恢复默认的 ~/.bashrc 文件 如果 ~/.bashrc 文件被删除或修改,你可以恢复到默认的版本。可以参考以下…

PyTorch使用教程(8)-一文了解torchvision

一、什么是torchvision torchvision提供了丰富的功能,主要包括数据集、模型、转换工具和实用方法四大模块。数据集模块内置了多种广泛使用的图像和视频数据集,如ImageNet、CIFAR-10、MNIST等,方便开发者进行训练和评估。模型模块封装了大量经…

实战演示:利用ChatGPT高效撰写论文

在当今学术界,撰写论文是一项必不可少的技能。然而,许多研究人员和学生在写作过程中常常感到困惑和压力。幸运的是,人工智能的快速发展为我们提供了新的工具,其中ChatGPT便是一个优秀的选择。本文将通过易创AI创作平台&#xff0c…

群晖部署-Calibreweb

最近家里搞了台群晖,准备部署个Calibreweb看看电子书,看了好多部署的教程老是不太成功,要么报错要么有问题的,很难搞。下面将部署流程分享一下,给大家参考,少走点弯路 镜像的选择 我们使用johngong/calibr…

WordPress果果对象存储插件

将网站上的图片等静态资源文件上传至七牛云对象存储,可以减轻服务器文件存储压力,提升静态文件访问速度,从而加速网站访问速度。 支持:阿里云对象存储、华为云对象存储、百度云对象存储、腾讯云对象存储、七牛云对象存储。 下载…

电路研究9.1.1——合宙 Air780EP 模组外围线路

本来要继续研究AT指令来着,结果发现后面还有之前用到的电路设计资料,所以就贴过来了。 5.3.2 工作模式: 注意:  当模块进入休眠模式或深度休眠模式后, VDD_EXT 电源会掉电,相应电压域的 GPIO 以及串口…