一、准备ElasticSearch环境

服务器:Rocky9 2C4G

1、配置yum仓库

# 导入GPG key
rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch

# 编辑repo配置文件
vi /etc/yum.repos.d/elasticsearch.repo  ##内容如下
[elasticsearch]
name=Elasticsearch repository for 8.x packages
baseurl=https://mirrors.aliyun.com/elasticstack/8.x/yum/
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/elasticstack/GPG-KEY-elasticsearch
enabled=0
autorefresh=1
type=rpm-md

2、dnf安装es

dnf install --enablerepo=elasticsearch elasticsearch -y

3、修改配置

vi /etc/elasticsearch/elasticsearch.yml  ## 修改为如下内容
cluster.name: my-es
node.name: es-1
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 0.0.0.0
http.port: 9200
discovery.type: single-node

xpack.security.enabled: true

xpack.security.enrollment.enabled: true

xpack.security.http.ssl:
  enabled: true
  keystore.path: certs/http.p12

xpack.security.transport.ssl:
  enabled: true
  verification_mode: certificate
  keystore.path: certs/transport.p12
  truststore.path: certs/transport.p12

http.host: 0.0.0.0

4、设置主机名

hostnamectl set-hostname es-1

5、启动服务

systemctl enable --now elasticsearch.service

6、设置elastic用户密码

/usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic

82f08193-27e8-4593-b87b-d3ae8c932a57.png

访问

curl -k -u elastic:evoK1z68zgO5I*8Ipdy1 https://localhost:9200

7、基础操作

创建索引

假设我们要创建一个名为 products 的索引,包含商品名称、价格和描述。

curl -k -u elastic:evoK1z68zgO5I*8Ipdy1 -X PUT 'https://localhost:9200/products?pretty' -H 'Content-Type: application/json' -d'
{
  "mappings": {
    "properties": {
      "name": { "type": "text" },
      "price": { "type": "double" }
    }
  }
}
'

在索引里增加数据

curl -k -u elastic:evoK1z68zgO5I*8Ipdy1 -X PUT 'https://localhost:9200/products/_doc/1?pretty' -H 'Content-Type: application/json' -d'
{
  "name": "iPhone 15",
  "price": 7999,
  "category": "phone"
}
'

创建第二个索引user,并插入5条测试数据

# 创建索引user
curl -k -u elastic:evoK1z68zgO5I*8Ipdy1 -X PUT 'https://localhost:9200/users?pretty' -H 'Content-Type: application/json' -d'
{
  "mappings": {
    "properties": {
      "name": { "type": "text" },
      "age":  { "type": "integer" },
      "email": { "type": "keyword" },
      "address": { "type": "text" }
    }
  }
}
'
# 插入第一条数据
curl -k -u elastic:evoK1z68zgO5I*8Ipdy1 -X PUT 'https://localhost:9200/users/_doc/101?pretty' -H 'Content-Type: application/json' -d'
{
  "name": "Zhang San",
  "age": 25,
  "email": "zhangsan@example.com",
  "address": "Beijing Haidian District"
}
'

# 第二条
curl -k -u elastic:evoK1z68zgO5I*8Ipdy1 -X PUT 'https://localhost:9200/users/_doc/102?pretty' -H 'Content-Type: application/json' -d'
{
  "name": "Li Si",
  "age": 30,
  "email": "lisi@test.com",
  "address": "Shanghai Pudong New Area"
}
'

# 第三条
curl -k -u elastic:evoK1z68zgO5I*8Ipdy1 -X PUT 'https://localhost:9200/users/_doc/103?pretty' -H 'Content-Type: application/json' -d'
{
  "name": "Wang Wu",
  "age": 28,
  "email": "wangwu@example.com",
  "address": "Guangzhou Tianhe District"
}
'

# 第四条
curl -k -u elastic:evoK1z68zgO5I*8Ipdy1 -X PUT 'https://localhost:9200/users/_doc/104?pretty' -H 'Content-Type: application/json' -d'
{
  "name": "Zhao Liu",
  "age": 22,
  "email": "zhaoliu@test.com",
  "address": "Shenzhen Nanshan District"
}
'
# 第五条
curl -k -u elastic:evoK1z68zgO5I*8Ipdy1 -X PUT 'https://localhost:9200/users/_doc/105?pretty' -H 'Content-Type: application/json' -d'
{
  "name": "Sun Qi",
  "age": 35,
  "email": "sunqi@work.com",
  "address": "Hangzhou Binjiang District"
}
'

查询单个文档,通过ID

curl -k -u elastic:evoK1z68zgO5I*8Ipdy1  -X GET 'https://localhost:9200/products/_doc/1?pretty'

另外一个

curl -k -u elastic:evoK1z68zgO5I*8Ipdy1  -X GET 'https://localhost:9200/users/_doc/101?pretty'

查询所有数据

curl -k -u elastic:evoK1z68zgO5I*8Ipdy1  -X GET 'https://localhost:9200/products/_search?pretty' -H 'Content-Type: application/json' -d'
{
  "query": {
    "match_all": {}
  }
}
'

按条件查询,比如搜索名字包含'iphone'

curl -k -u elastic:evoK1z68zgO5I*8Ipdy1  -X GET 'https://localhost:9200/products/_search?pretty' -H 'Content-Type: application/json' -d'
{
  "query": {
    "match": {
      "name": "iPhone"
    }
  }
}
'

搜索年龄为35

curl -k -u elastic:evoK1z68zgO5I*8Ipdy1  -X GET 'https://localhost:9200/users/_search?pretty' -H 'Content-Type: application/json' -d'
{
  "query": {
    "match": {"age":"35"}
  }
}
'

11.2 部署es mcp

就在es那台机器上部署,系统版本:Rocky9

项目地址:https://github.com/cr7258/elasticsearch-mcp-server

1、安装uv

我们通过pip安装uv,首先安装pip3

dnf install -y python3.12 python3.12-pip

然后用pip3安装uv

pip3.12 install uv -i https://mirrors.aliyun.com/pypi/simple/

2、用uvx启动mcp服务

export ELASTICSEARCH_HOSTS="https://localhost:9200"
export ELASTICSEARCH_USERNAME="elastic"
export ELASTICSEARCH_PASSWORD="evoK1z68zgO5I*8Ipdy1"
uvx --python 3.12 elasticsearch-mcp-server --transport sse --host 0.0.0.0 --port 8000 --path /sse > /tmp/es-mcp.log 2> /tmp/es-mcp.log &

11.3 到Dify配置MCP工具

1、到dify服务器上测试连通性

curl http://<your-server-ip>:8000/sse

如果不通,可能是firewalld开着,需要到es服务器上将其关闭

 systemctl disable --now firewalld

2、增加MCP工具

登录Dify控制台,点击工具 --> MCP --> 添加MCP服务

11.4 在Dify中创建Agent应用

提示词:

你是一个企业级 AIOps 运维 Agent,通过 MCP 工具操作 Elasticsearch / OpenSearch 集群。
你的目标是用自然语言帮助用户完成日志分析、故障排查、索引检查、集群巡检等任务。========================【可用工具】========================你可以调用的工具包括:
索引:
- list_indices
- get_index
- create_index
- delete_index
- create_data_stream
- get_data_stream
- delete_data_stream

文档:
- search_documents
- get_document
- index_document
- delete_document
- delete_by_query

别名:
- list_aliases
- get_alias
- put_alias
- delete_alias

集群:
- get_cluster_health
- get_cluster_stats

通用:
- general_api_request========================【行为规则】========================1. 查询类操作(list / get / search / health / stats)可以直接调用工具。

2. 以下高风险操作必须先让用户确认:
- delete_index
- delete_document
- delete_by_query
- delete_data_stream
- put_alias / delete_alias
- create_index
- general_api_request涉及 PUT / DELETE

除非用户明确回复“确认执行”,否则禁止调用。

3. 优先使用专用工具;只有没有对应工具时才使用 general_api_request。

4. 如果用户描述不清楚,必须先询问:
- 索引名称
- 时间范围
- 环境(如 prod / staging)

5. 不允许凭空猜测索引名或字段。========================【工作流程】========================- 判断用户意图:
查询 / 写入 / 删除 / 结构变更
- 选择最小权限工具
- 调用工具
- 总结结果并给出建议========================【输出要求】========================你的回复必须包含:
【执行的操作】
【关键结果】
【风险提示(如有)】
【建议下一步】
默认假设运行在生产环境,行为应保守、安全。

添加工具:

示例1:

查询索引都有哪些

示例2:

帮我新建一个索引,名字nginx_log,这个索引用来记录nginx的访问日志

示例3:

给nginx_log索引插入两条测试的数据

示例4:

查看nginx_log索引中的所有数据,以表格形式列出来

示例5

删除products索引