Doramagic 项目包 · 项目说明书
mcp-server-elasticsearch 项目
生成时间:2026-05-31 01:03:00 UTC
项目介绍
Elasticsearch MCP Server 是由 Elastic 公司开发的 Model Context Protocol (MCP) 服务器实现,专门用于将 Elasticsearch 集群与 AI 助手(如 Claude、Cursor 等)进行集成。该项目允许 AI 代理通过标准化接口执行 Elasticsearch 操作,包括索引查询、映射获取、分片状态检查等高...
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
Elasticsearch MCP Server 是由 Elastic 公司开发的 Model Context Protocol (MCP) 服务器实现,专门用于将 Elasticsearch 集群与 AI 助手(如 Claude、Cursor 等)进行集成。该项目允许 AI 代理通过标准化接口执行 Elasticsearch 操作,包括索引查询、映射获取、分片状态检查等高级功能。
资料来源:catalog-info.yaml:4
项目定位
| 属性 | 值 |
|---|---|
| 类型 | 库 (library) |
| 所属团队 | devtools-team |
| 生命周期 | beta (测试阶段) |
| 版权 | Elasticsearch B.V. 2025 |
核心架构
整体架构图
graph TD
A["MCP Client<br/>(Claude/Cursor)"] --> B["Elasticsearch MCP Server"]
B --> C["Elasticsearch Cluster"]
B --> D["base_tools<br/>基础工具集"]
B --> E["custom_tools<br/>自定义工具"]
D --> D1["list_indices"]
D --> D2["get_mappings"]
D --> D3["search"]
D --> D4["get_shards"]
D --> D5["esql"]
E --> E1["ESQL 查询"]
E --> E2["搜索模板"]
C --> F["REST API"]组件层次结构
graph TD
A["ElasticsearchMcp"] --> B["EsBaseTools"]
B --> C["EsClientProvider"]
C --> D["Elasticsearch<br/>HTTP Client"]
B --> E["ToolRouter<br/>工具路由器"]
E --> F["工具处理器"]
A --> G["Configuration<br/>配置管理"]
G --> H["环境变量解析"]
G --> I["配置文件加载"]资料来源:src/servers/elasticsearch/mod.rs:77-93
工具集详解
基础工具 (Base Tools)
项目提供五个核心工具用于日常 Elasticsearch 操作:
| 工具名称 | 功能描述 | 只读 | |
|---|---|---|---|
list_indices | 列出所有符合条件的 Elasticsearch 索引 | 是 | |
get_mappings | 获取指定索引的字段映射信息 | 是 | |
search | 使用 Query DSL 执行搜索查询 | 是 | |
get_shards | 获取索引分片分配状态信息 | 是 | |
esql | 执行 ES | QL 查询语句 | 是 |
资料来源:src/servers/elasticsearch/base_tools.rs:1-100
搜索功能增强
search 工具支持以下高级特性:
- 字段选择:通过
fields参数指定返回字段,减少上下文大小 - 聚合支持:自动返回聚合结果,支持复杂分析查询
- Query DSL 完整支持:支持 query、size、from、sort 等完整查询语法
// 搜索结果数据结构
pub struct SearchResult {
pub hits: Hits,
#[serde(default)]
pub aggregations: IndexMap<String, Value>, // 聚合结果
}
#[derive(Serialize, Deserialize)]
pub struct Hits {
pub total: Option<TotalHits>,
pub hits: Vec<Hit>,
}
资料来源:src/servers/elasticsearch/base_tools.rs:100-130
自定义工具 (Custom Tools)
支持扩展的工具类型:
#[derive(Debug, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum CustomTool {
Esql(EsqlTool),
SearchTemplate(SearchTemplateTool),
}
pub enum EsqlResultFormat {
Json, // 默认,输出 JSON 数组或对象
Value, // 单属性时仅输出值
}
资料来源:src/servers/elasticsearch/mod.rs:20-35
配置系统
配置结构
{
"elasticsearch": {
"url": "https://localhost:9200",
"api_key": "${ES_API_KEY:}",
"username": "${ES_USERNAME:}",
"password": "${ES_PASSWORD:}",
"ssl_skip_verify": "${ES_SSL_SKIP_VERIFY:false}"
}
}
环境变量配置
| 变量名 | 必填 | 说明 |
|---|---|---|
ES_URL | 是 | Elasticsearch 集群 URL |
ES_API_KEY | 否 | API Key 认证 |
ES_USERNAME | 否 | 用户名(需配合密码使用) |
ES_PASSWORD | 否 | 密码 |
ES_SSL_SKIP_VERIFY | 否 | 跳过 SSL 证书验证 |
资料来源:src/lib.rs:1-30
配置加载流程
sequenceDiagram
participant CLI as 命令行
participant Config as 配置解析器
participant Interpolator as 变量插值器
participant ES as ElasticsearchMcp
CLI->>Config: 加载配置文件
Config->>Interpolator: 解析 ${VAR:default} 语法
Interpolator-->>Config: 返回展开后的配置
Config->>ES: new_with_config(config)
ES->>ES: 创建连接池和认证
ES-->>CLI: 返回处理器实例通信协议
支持的传输模式
| 模式 | 说明 | 使用场景 |
|---|---|---|
stdio | 标准输入/输出 | 本地 Claude Desktop 集成 |
http | Streamable HTTP | Web 集成、远程访问 |
资料来源:src/cli.rs:30-50
HTTP 服务配置
pub struct HttpCommand {
/// 配置文件路径
pub config: Option<PathBuf>,
/// 监听地址 [default: 127.0.0.1:8080]
pub address: Option<std::net::SocketAddr>,
/// 启用 SSE 服务于 '/sse'
pub sse: bool,
}
| 参数 | 默认值 | 环境变量 |
|---|---|---|
--address | 127.0.0.1:8080 | HTTP_ADDRESS |
--config | 无 | 无 |
--sse | false | 无 |
资料来源:src/cli.rs:35-48
认证机制
认证流程
graph LR
A["请求上下文"] --> B{"授权头存在?"}
B -->|是| C["使用请求头认证"]
B -->|否| D{"配置中有凭证?"}
D -->|API Key| E["EncodedApiKey"]
D -->|用户名密码| F["Basic Auth"]
D -->|无| G["匿名访问"]凭证优先级
- HTTP 请求头中的
Authorization - 配置中的
api_key - 配置中的
username+password
资料来源:src/servers/elasticsearch/mod.rs:80-95
部署方式
Docker 部署
# Stdio 模式
docker run --rm \
-e ES_URL \
-e ES_API_KEY \
docker.elastic.co/mcp/elasticsearch \
stdio
# HTTP 模式
docker run --rm \
-e ES_URL \
-e ES_API_KEY \
-p 8080:8080 \
docker.elastic.co/mcp/elasticsearch \
http
Claude Desktop 配置 (Stdio)
{
"mcpServers": {
"elasticsearch-mcp-server": {
"command": "docker",
"args": [
"run", "--rm",
"-e", "ES_URL",
"-e", "ES_API_KEY",
"docker.elastic.co/mcp/elasticsearch",
"stdio"
]
}
}
}
HTTP 模式配置
通过 mcp-proxy 桥接到 Claude Desktop:
uv tool install mcp-proxy
{
"mcpServers": {
"elasticsearch-mcp-server": {
"command": "/path/to/mcp-proxy",
"args": [
"--transport=streamablehttp",
"--header", "Authorization", "ApiKey <key>",
"http://host:8080/mcp"
]
}
}
}
已知问题与限制
社区反馈的问题
| 问题编号 | 描述 | 状态 |
|---|---|---|
| #185 | get_mappings 工具在嵌套类型未显式声明时解码失败 | 待修复 |
| #170 | Basic 认证失败 (401 Unauthorized) | 社区讨论中 |
| #191 | 缺少 Linux ARM64 二进制发布 | 功能请求 |
健康检查
HTTP 模式提供健康检查端点:
curl http://<host>:8080/ping
# 返回: pong
版本历史
| 版本 | 主要变更 |
|---|---|
| v0.4.6 | 添加弃用通知 |
| v0.4.5 | 修复用户名环境变量名称 |
| v0.4.4 | 添加 CA 证书支持 |
| v0.4.3 | 默认端口改回 8080 |
| v0.4.2 | 默认端口改为 8000 |
| v0.4.1 | 添加 CLI_ARGS 环境变量支持 |
| v0.3.1 | 修复 npx 执行缺少 hashbang |
| v0.3.0 | 添加 OpenTelemetry 支持、Smithery 配置 |
技术栈
| 组件 | 技术 |
|---|---|
| 语言 | Rust |
| HTTP 客户端 | elasticsearch-rs |
| MCP 框架 | rmcp |
| 序列化 | serde_json, serde_json5 |
| 宏处理 | rmcp_macros |
| CLI | clap |
依赖管理
项目使用 Renovate 进行自动化依赖更新:
- 计划:每周一 1:00 后执行
- 配置:继承自
elastic/renovate-config
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["local>elastic/renovate-config"],
"schedule": ["after 1am on monday"]
}
资料来源:renovate.json:1-8
持续集成
项目使用 Buildkite 进行 CI/CD:
| 流水线 | 触发条件 | 说明 |
|---|---|---|
| mcp-server-elasticsearch | PR、推送 | 执行检查 |
| mcp-server-elasticsearch-docker | Tags | 构建并发布 Docker 镜像 |
资料来源:catalog-info.yaml:4
版本历史与更新
Elasticsearch MCP Server 是由 Elasticsearch B.V. 开发维护的 Model Context Protocol (MCP) 服务器实现,旨在为 AI 代理提供与 Elasticsearch 集群交互的能力。本页面记录该项目的完整版本历史、功能演进以及重要更新信息。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
版本发布时间线
timeline
title Elasticsearch MCP Server 版本发布历史
v0.2.0 : 新增 get_shards 工具
灵活认证验证
索引模式参数
v0.3.0 : Smithery 配置支持
OpenTelemetry 支持
聚合结果返回
profile 和 explain
v0.3.1 : 修复 npx hashbang 问题
v0.4.1 : Dockerfile EXPOSE
CLI_ARGS 环境变量
v0.4.2 : 默认端口 8000
v0.4.3 : 默认端口恢复 8080
v0.4.4 : 添加 CA 证书
v0.4.5 : 用户名 ENV 名称更新
v0.4.6 : 添加弃用通知各版本详细说明
v0.4.6(最新版本)
发布状态:当前稳定版本
主要变更:添加了项目弃用通知(Deprecation Notice),提示用户项目已进入维护模式。
资料来源:社区发布说明
资料来源:社区发布说明
系统架构
Elasticsearch MCP Server 是一个基于 Model Context Protocol (MCP) 的中间件服务,用于将 Elasticsearch 集群与 AI 代理进行连接。它充当协议转换层,将 MCP 协议请求转换为 Elasticsearch HTTP API 调用,并返回结构化结果。
继续阅读本节完整说明和来源证据。
概述
Elasticsearch MCP Server 是一个基于 Model Context Protocol (MCP) 的中间件服务,用于将 Elasticsearch 集群与 AI 代理进行连接。它充当协议转换层,将 MCP 协议请求转换为 Elasticsearch HTTP API 调用,并返回结构化结果。
核心职责:
- 接收来自 MCP 客户端(如 Claude Desktop、Cursor 等)的标准化工具调用请求
- 验证认证信息并建立与 Elasticsearch 集群的连接
- 将请求路由至相应的工具处理器并执行查询
- 将 Elasticsearch 响应转换回 MCP 协议格式返回
技术栈:
- 语言:Rust
- MCP 协议:rmcp (Rust MCP 实现)
- Elasticsearch 客户端:elasticsearch crate
资料来源:src/lib.rs:1-50
资料来源:src/lib.rs:1-50
通信协议配置
Elasticsearch MCP Server 支持两种通信协议模式,用于与 MCP 客户端建立连接并传输数据。协议配置是整个服务架构的核心组成部分,决定了客户端如何与服务器通信、认证方式如何处理,以及请求如何在 MCP 协议层进行路由。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
Elasticsearch MCP Server 支持两种通信协议模式,用于与 MCP 客户端建立连接并传输数据。协议配置是整个服务架构的核心组成部分,决定了客户端如何与服务器通信、认证方式如何处理,以及请求如何在 MCP 协议层进行路由。
本项目实现了 Stdio(标准输入/输出) 和 HTTP/SSE(服务器发送事件) 两种传输模式,分别适用于不同的部署场景和客户端类型。
协议架构
graph TD
A[MCP 客户端] --> B{传输模式选择}
B -->|Stdio| C[Stdio 协议层]
B -->|HTTP/SSE| D[HTTP 协议层]
C --> E[rmcp 框架]
D --> E
E --> F[工具路由器 ToolRouter]
F --> G[Elasticsearch 工具集]
G --> H[Elasticsearch 集群]
style C fill:#e1f5fe
style D fill:#fff3e0传输模式
Stdio 模式
Stdio 模式是最基础的通信方式,通过标准输入(stdin)和标准输出(stdout)进行 JSON-RPC 消息的传输。这种模式适用于本地进程调用和命令行工具集成。
配置参数:
| 参数 | 标志 | 说明 |
|---|---|---|
| 配置文件 | -c, --config | 可选配置文件路径 |
| 传输类型 | stdio | 通过 stdin/stdout 通信 |
Stdio 模式的启动命令:
mcp-server-elasticsearch stdio --config /path/to/config.json
HTTP/SSE 模式
HTTP 模式提供了远程访问能力,支持通过 HTTP 请求与 MCP 服务器交互。该模式使用 Axum 框架构建异步 HTTP 服务器,并可选地启用 SSE(Server-Sent Events)端点实现服务端推送。
核心配置参数:
| 参数 | 环境变量 | 默认值 | 说明 |
|---|---|---|---|
| 监听地址 | HTTP_ADDRESS | 127.0.0.1:8080 | 服务器监听的网络地址 |
| SSE 启用 | --sse | 关闭 | 是否启用 SSE 端点 |
| 配置文件 | -c, --config | 无 | 配置文件路径 |
HTTP 模式的启动命令:
mcp-server-elasticsearch http --address 0.0.0.0:8080 --config /path/to/config.json
启用 SSE 模式:
mcp-server-elasticsearch http --address 0.0.0.0:8080 --sse
服务端点:
| 端点 | 方法 | 功能 |
|---|---|---|
/ | GET | 服务器信息 |
/ping | GET | 健康检查 |
/mcp/sse | SSE | SSE 传输端点 |
/mcp | MCP | MCP 协议处理 |
/_health/ready | GET | 就绪探针 |
/_health/live | GET | 存活探针 |
sequenceDiagram
participant C as MCP 客户端
participant H as HTTP 服务器
participant M as MCP 处理层
participant ES as Elasticsearch
C->>H: HTTP POST /mcp (JSON-RPC)
H->>M: 转发请求
M->>ES: 执行查询
ES-->>M: 返回结果
M-->>H: JSON-RPC 响应
H-->>C: HTTP Response
Note over C,H: SSE 模式可选用于服务端推送
C->>H: GET /mcp/sse
H-->>C: SSE Stream命令行接口结构
源码位置:src/cli.rs:1-100
Command 枚举
#[derive(Debug, Subcommand)]
pub enum Command {
Stdio(StdioCommand),
Http(HttpCommand),
}
服务器支持两个顶层命令,分别对应不同的协议模式:
Stdio- 启动标准输入/输出服务器Http- 启动 HTTP 服务器(可选 SSE)
HttpCommand 配置
#[derive(Debug, Args)]
pub struct HttpCommand {
/// Config file
#[clap(short, long)]
pub config: Option<PathBuf>,
/// Address to listen to [default: 127.0.0.1:8080]
#[clap(long, value_name = "IP_ADDRESS:PORT", env = "HTTP_ADDRESS")]
pub address: Option<std::net::SocketAddr>,
/// Also start an SSE server on '/sse'
#[clap(long)]
pub sse: bool,
}
HTTP 协议实现
源码位置:src/protocol/http.rs
健康检查路由
服务器实现了标准的 Kubernetes 就绪/存活探针接口:
let health_router = {
Router::new()
.route("/ready", get(async || (StatusCode::OK, "Ready\n")))
.route("/live", get(async || "Alive\n"))
};
路由聚合
let main_router = Router::new()
.route("/", get(hello))
.route("/ping", get(async || (StatusCode::OK, "Ready\n")))
.nest("/mcp/sse", sse_router)
.nest("/mcp", sh_router)
.nest("/_health", health_router)
.with_state(());
服务器启动
let listener = tokio::net::TcpListener::bind(config.bind).await?;
let server = axum::serve(listener, main_router).with_graceful_shutdown({
let ct = ct.clone();
async move {
ct.cancelled().await;
tracing::info!("http server cancelled");
}
});
认证与客户端上下文
源码位置:src/servers/elasticsearch/mod.rs:100-150
Credentials 配置
pub struct ElasticsearchMcpConfig {
/// Cluster URL
pub url: String,
/// API key
#[serde(default, deserialize_with = "none_if_empty_string")]
pub api_key: Option<String>,
/// Username
#[serde(default, deserialize_with = "none_if_empty_string")]
pub username: Option<String>,
/// Password
#[serde(default, deserialize_with = "none_if_empty_string")]
pub password: Option<String>,
/// Should we skip SSL certificate verification?
#[serde(default, deserialize_with = "deserialize_bool_from_anything")]
pub ssl_skip_verify: bool,
}
认证凭证构建
let creds = if let Some(api_key) = config.api_key.clone() {
Some(Credentials::EncodedApiKey(api_key))
} else if let Some(username) = config.username.clone() {
let pwd = config.password.clone().ok_or(anyhow::Error::msg("missing password"))?;
Some(Credentials::Basic(username, pwd))
} else {
None
};
EsClientProvider 客户端提供者
pub struct EsClientProvider(Elasticsearch);
impl EsClientProvider {
pub fn new(client: Elasticsearch) -> Self {
EsClientProvider(client)
}
/// If the incoming request is a http request and has an `Authorization` header, use it
/// to authenticate to the remote ES instance.
pub fn get(&self, context: RequestContext<RoleServer>) -> Elasticsearch {
// 根据请求上下文获取客户端实例
}
}
配置加载流程
源码位置:src/lib.rs
flowchart LR
A[启动应用] --> B[解析命令行参数]
B --> C{协议模式}
C -->|stdio| D[启动 Stdio 服务器]
C -->|http| E[启动 HTTP 服务器]
E --> F[加载配置文件]
F --> G[环境变量插值]
G --> H[解析 JSON5 配置]
H --> I[构建 Elasticsearch 客户端]
I --> J[初始化工具路由]
J --> K[等待客户端连接]环境变量插值
配置支持 ${VAR_NAME} 和 ${VAR_NAME:default_value} 语法:
let config = interpolator::interpolate_from_env(config)?;
默认配置模板
{
"elasticsearch": {
"url": "${ES_URL}",
"api_key": "${ES_API_KEY:}",
"username": "${ES_USERNAME:}",
"password": "${ES_PASSWORD:}",
"ssl_skip_verify": "${ES_SSL_SKIP_VERIFY:false}"
}
}
协议选择指南
| 场景 | 推荐模式 | 原因 |
|---|---|---|
| 本地开发调试 | Stdio | 简单直接,无需网络配置 |
| Claude Desktop / Cursor | Stdio | 原生支持 MCP stdio 协议 |
| 远程服务部署 | HTTP | 支持网络访问和负载均衡 |
| n8n 集成 | HTTP/SSE | 适合工作流自动化 |
| 容器化部署 | 两者皆可 | 根据客户端类型选择 |
常见问题
HTTP 401 认证失败
社区 Issue #170 报告了在使用 Docker 部署时配置了正确的环境变量但仍出现认证失败的问题。解决方案:
- 确认环境变量
ES_USERNAME、ES_PASSWORD或ES_API_KEY正确设置 - 使用
docker exec进入容器验证凭证配置 - 测试与 Elasticsearch 集群的连接:
# 使用用户名密码
docker exec <container-id> curl -k -u <username>:<password> <ES_URL>
# 使用 API Key
docker exec <container-id> curl -k -H "Authorization: ApiKey <api-key>" <ES_URL>
SSE 与 Streamable HTTP
由于 SSE 已被废弃,项目正在迁移到新的 Streamable HTTP 传输模式。详见社区 Issue #17。
最佳实践
- 安全建议
- 生产环境优先使用 API Key 认证
- 通过 HTTPS 连接到 Elasticsearch
- 使用 AWS Secrets Manager 管理敏感凭证
- 性能优化
- HTTP 模式默认监听本地地址,如需远程访问改为
0.0.0.0 - 使用健康检查端点进行负载均衡器配置
- 配置管理
- 使用配置文件集中管理复杂配置
- 利用环境变量插值实现环境差异化配置
来源:https://github.com/elastic/mcp-server-elasticsearch / 项目说明书
MCP 工具详解
MCP Server Elasticsearch 提供了多个 MCP 工具,使 AI Agent 能够与 Elasticsearch 集群进行交互。这些工具通过 Model Context Protocol (MCP) 暴露,允许 LLM 通过自然语言执行索引管理、搜索查询、数据分析等操作。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
MCP Server Elasticsearch 提供了多个 MCP 工具,使 AI Agent 能够与 Elasticsearch 集群进行交互。这些工具通过 Model Context Protocol (MCP) 暴露,允许 LLM 通过自然语言执行索引管理、搜索查询、数据分析等操作。
核心工具定义位于 EsBaseTools 结构体中,通过 #[tool_router] 宏注册每个工具的处理程序。工具支持通过请求上下文动态获取 Elasticsearch 客户端实例,实现基于请求的认证凭证传递。
工具架构
工具注册机制
工具通过 Rust 宏 #[tool] 和 #[tool_handler] 进行声明和实现:
#[tool_router]
impl EsBaseTools {
#[tool(
description = "工具描述",
annotations(title = "显示标题", read_only_hint = true)
)]
async fn tool_name(
&self,
req_ctx: RequestContext<RoleServer>,
Parameters(Params): Parameters<Params>,
) -> Result<CallToolResult, rmcp::Error> {
// 工具实现
}
}
客户端提供机制
工具通过 EsClientProvider 获取 Elasticsearch 客户端,该提供者支持基于 HTTP 请求 Authorization 头的动态认证:
#[derive(Clone)]
pub struct EsClientProvider(Elasticsearch);
impl EsClientProvider {
pub fn get(&self, context: RequestContext<RoleServer>) -> Elasticsearch {
// 从请求上下文中提取认证信息
}
}
核心工具列表
1. list_indices - 列出索引
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
| index_pattern | String | 是 | 索引名称或通配符模式 |
实现位置: src/servers/elasticsearch/base_tools.rs:73-95
该工具调用 Elasticsearch Cat API,返回匹配的索引列表:
async fn list_indices(
&self,
req_ctx: RequestContext<RoleServer>,
Parameters(ListIndicesParams { index_pattern }): Parameters<ListIndicesParams>,
) -> Result<CallToolResult, rmcp::Error> {
let es_client = self.es_client.get(req_ctx);
let response = es_client
.cat()
.indices(CatIndicesParts::Index(&[&index_pattern]))
.h(&["index", "status", "docs.count"])
.format("json")
.send()
.await;
let response: Vec<CatIndexResponse> = read_json(response).await?;
Ok(CallToolResult::success(vec![
Content::text(format!("Found {} indices:", response.len())),
Content::json(response)?,
]))
}
2. get_mappings - 获取索引映射
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
| index | String | 是 | 索引名称 |
实现位置: src/servers/elasticsearch/base_tools.rs:97-120
[!NOTE]
已知问题: 当嵌套属性未显式指定"type": "nested"时,get_mappings工具会返回"error decoding response body"错误。这是 Issue #185 报告的问题,尽管 Elasticsearch 规范允许省略显式类型声明。
3. search - 执行搜索
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
| index | String | 是 | 索引名称 |
| query_body | Map<String, Value> | 是 | 完整的 Elasticsearch Query DSL 对象 |
| fields | Option<Vec<String>> | 否 | 指定返回的字段列表 |
实现位置: src/servers/elasticsearch/base_tools.rs:130-180
search 工具支持完整的 Elasticsearch Query DSL,包括 query、size、from、sort、aggregations 等参数。
struct SearchParams {
index: String,
fields: Option<Vec<String>>,
query_body: Map<String, Value>,
}
返回结果包含:
hits.total- 匹配文档总数hits.hits- 文档数组aggregations- 聚合结果(如果有)
4. esql - ES|QL 查询
| 参数 | 类型 | 必需 | 说明 | |
|---|---|---|---|---|
| query | String | 是 | 完整的 ES | QL 查询语句 |
实现位置: src/servers/elasticsearch/mod.rs:46-50
pub enum EsqlResultFormat {
#[default]
Json, // 输出为 JSON 对象数组或单个对象
Value, // 如果是单个属性,输出其值
}
5. get_shards - 获取分片信息
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
| index | Option<String> | 否 | 可选的索引名称 |
实现位置: src/servers/elasticsearch/base_tools.rs:41-69
该工具返回分片的详细信息:
pub struct CatShardsResponse {
pub index: String,
pub shard: usize,
pub prirep: String, // primary 或 replica
pub state: String, // STARTED, INITIALIZING, etc.
pub docs: Option<u64>,
pub store: Option<u64>,
pub node: String,
}
自定义工具扩展
Tools 配置结构
用户可以通过配置文件定义自定义工具:
pub struct Tools {
#[serde(flatten)]
pub incl_excl: Option<IncludeExclude>,
pub custom: HashMap<String, CustomTool>,
}
pub enum CustomTool {
Esql(EsqlTool),
SearchTemplate(SearchTemplateTool),
}
SearchTemplateTool
支持两种搜索模板定义方式:
pub enum SearchTemplate {
TemplateId(String), // 通过模板 ID 引用
Template(serde_json::Value), // 内联模板定义
}
工具响应格式
所有工具通过 CallToolResult 返回结果:
pub struct SearchResult {
pub hits: Hits,
#[serde(default)]
pub aggregations: IndexMap<String, Value>,
}
pub struct Hits {
pub total: Option<TotalHits>,
pub hits: Vec<Hit>,
}
pub struct Hit {
#[serde(rename = "_source")]
pub source: Value,
}
配置选项
ElasticsearchMcpConfig
| 配置项 | 环境变量 | 类型 | 默认值 | 说明 |
|---|---|---|---|---|
| url | ES_URL | String | - | Elasticsearch 集群地址 |
| api_key | ES_API_KEY | Option<String> | None | API Key 认证 |
| username | ES_USERNAME | Option<String> | None | 用户名 |
| password | ES_PASSWORD | Option<String> | None | 密码 |
| ssl_skip_verify | ES_SSL_SKIP_VERIFY | bool | false | 跳过 SSL 验证 |
| tools | - | Tools | empty | 自定义工具配置 |
实现位置: src/servers/elasticsearch/mod.rs:24-52
数据流图
graph TD
A[MCP Client 请求] --> B[RequestContext 解析]
B --> C{认证方式}
C -->|API Key| D[Credentials::EncodedApiKey]
C -->|用户名密码| E[Credentials::Basic]
C -->|无认证| F[None]
D --> G[TransportBuilder 配置]
E --> G
F --> G
G --> H[Elasticsearch 客户端]
H --> I{请求类型}
I -->|list_indices| J[Cat Indices API]
I -->|get_mappings| K[Get Mapping API]
I -->|search| L[Search API]
I -->|esql| M[ES|QL API]
I -->|get_shards| N[Cat Shards API]
J --> O[CatIndexResponse]
K --> P[Mapping JSON]
L --> Q[SearchResult]
M --> R[ES|QL Result]
N --> S[CatShardsResponse]
O --> T[CallToolResult]
P --> T
Q --> T
R --> T
S --> THTTP 协议支持
MCP Server 支持通过 HTTP 进行远程访问:
HttpServerConfig
| 配置项 | 类型 | 说明 |
|---|---|---|
| bind | SocketAddr | TCP 监听地址 |
| ct | CancellationToken | 取消令牌 |
| keep_alive | Option<Duration> | SSE 保活时间 |
| stateful_mode | bool | 启用状态会话 |
| session_manager | Arc<M> | 会话管理器 |
实现位置: src/protocol/http.rs:13-30
命令行配置
pub struct HttpCommand {
pub config: Option<PathBuf>, // 配置文件路径
pub address: Option<SocketAddr>, // 监听地址 [default: 127.0.0.1:8080]
pub sse: bool, // 启用 SSE 端点
}
已知问题
| Issue | 描述 | 影响 |
|---|---|---|
| #185 | get_mappings 工具在嵌套属性未显式指定 type: nested 时失败 | get_mappings 功能受限 |
| #170 | Basic 认证失败 401 Unauthorized | 认证配置问题 |
| #173 | 通过 HTTP/SSE 访问时部分功能返回错误 | HTTP 模式稳定性 |
相关文档
来源:https://github.com/elastic/mcp-server-elasticsearch / 项目说明书
配置与工具过滤
Elasticsearch MCP Server 的配置与工具过滤系统提供了灵活的运行时自定义能力,允许管理员通过配置文件和环境变量来控制服务器行为、认证方式以及可用工具集。该系统支持两种传输模式(stdio 和 streamable-HTTP),配置通过 JSON5 格式加载,并支持 ${ENVVAR} 或 ${ENVVAR:default} 语法的环境变量插值。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
Elasticsearch MCP Server 的配置与工具过滤系统提供了灵活的运行时自定义能力,允许管理员通过配置文件和环境变量来控制服务器行为、认证方式以及可用工具集。该系统支持两种传输模式(stdio 和 streamable-HTTP),配置通过 JSON5 格式加载,并支持 ${ENV_VAR} 或 ${ENV_VAR:default} 语法的环境变量插值。
配置架构
配置加载流程
graph TD
A[CLI 启动命令] --> B[加载配置文件]
B --> C[读取 JSON5 内容]
C --> D[环境变量插值]
D --> E[解析为 Configuration]
E --> F[创建 ElasticsearchMcp]
G[环境变量] -.->|${VAR}| D配置加载逻辑位于 src/lib.rs 中,服务器启动时首先读取配置文件,然后通过插值器处理环境变量引用,最后解析为强类型配置结构体。
核心配置结构体
#### ElasticsearchMcpConfig
ElasticsearchMcpConfig 是服务器的核心配置单元,定义了所有可配置的运行时参数:
| 字段 | 类型 | 说明 | 环境变量 |
|---|---|---|---|
url | String | Elasticsearch 集群 URL | ES_URL |
api_key | Option<String> | API Key 认证 | ES_API_KEY |
username | Option<String> | 用户名 | ES_USERNAME |
password | Option<String> | 密码 | ES_PASSWORD |
ssl_skip_verify | bool | 跳过 SSL 证书验证 | ES_SSL_SKIP_VERIFY |
tools | Tools | 工具配置 | - |
prompts | Vec<String> | Prompt 模板列表 | - |
资料来源:src/servers/elasticsearch/mod.rs:55-78
配置示例
服务器提供了默认配置模板,位于 src/lib.rs:
{
"elasticsearch": {
"url": "${ES_URL}",
"api_key": "${ES_API_KEY:}",
"username": "${ES_USERNAME:}",
"password": "${ES_PASSWORD:}",
"ssl_skip_verify": "${ES_SSL_SKIP_VERIFY:false}"
}
}
该模板展示了配置文件的推荐格式,支持:
- JSON5 语法(注释和多行字符串)
- 环境变量插值
- 默认值指定
认证配置
认证凭证优先级
系统支持三种认证方式,但同一时间只能使用一种:
- API Key 认证(优先)
- 用户名/密码认证
- 无认证(适用于信任网络)
认证逻辑在 ElasticsearchMcp::new_with_config 方法中实现:
let creds = if let Some(api_key) = config.api_key.clone() {
Some(Credentials::EncodedApiKey(api_key))
} else if let Some(username) = config.username.clone() {
let pwd = config.password.clone().ok_or(anyhow::Error::msg("missing password"))?;
Some(Credentials::Basic(username, pwd))
} else {
None
};
资料来源:src/servers/elasticsearch/mod.rs:88-96
HTTP 请求转发认证
EsClientProvider 提供了一个重要的功能:支持将 HTTP 请求中的 Authorization 头转发到远程 Elasticsearch 实例。这在 MCP 服务器代理认证时尤为重要。
环境变量插值系统
插值语法
插值器支持两种语法格式:
| 语法 | 说明 | 示例 |
|---|---|---|
${VAR} | 必填变量,不存在则报错 | ${ES_URL} |
${VAR:default} | 可选变量,默认值为 default | ${ES_SSL_SKIP_VERIFY:false} |
插值实现
插值逻辑位于 src/utils/interpolator.rs,核心函数签名:
pub fn interpolate(
input: String,
lookup: impl Fn(&str) -> Option<String>,
) -> Result<String, InterpolationError>
工作原理:
- 扫描输入字符串中的
${...}模式 - 对每个模式调用
lookup函数获取值 - 支持默认值语法
name:default - 返回插值后的字符串
资料来源:src/utils/interpolator.rs
单元测试示例
#[test]
fn good_extrapolation() -> anyhow::Result<()> {
assert_eq!("foo_value01234", expand("${foo}01234")?);
assert_eq!("foo_value01234\n1234bar_value", expand("${foo}01234\n1234${bar}")?);
Ok(())
}
资料来源:src/utils/interpolator.rs:47-51
工具配置与过滤
工具注册架构
graph TD
A[Tools 配置] --> B[IncludeExclude 包含/排除规则]
A --> C[CustomTool 自定义工具]
C --> D[EsqlTool ES|QL 查询工具]
C --> E[SearchTemplateTool 搜索模板工具]
F[基础工具集] --> G[EsBaseTools]
F -->|list_indices| G
F -->|get_mappings| G
F -->|search| G
F -->|get_shards| G
F -->|esql| G工具结构定义
#### Tools 结构体
#[derive(Debug, Serialize, Deserialize)]
pub struct Tools {
#[serde(flatten)]
pub incl_excl: Option<IncludeExclude>,
pub custom: HashMap<String, CustomTool>,
}
| 字段 | 类型 | 说明 |
|---|---|---|
incl_excl | Option<IncludeExclude> | 包含/排除过滤规则 |
custom | HashMap<String, CustomTool> | 自定义工具集合 |
资料来源:src/servers/elasticsearch/mod.rs:27-32
#### 自定义工具类型
#[derive(Debug, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum CustomTool {
Esql(EsqlTool),
SearchTemplate(SearchTemplateTool),
}
| 工具类型 | 说明 | 配置字段 | |
|---|---|---|---|
Esql | ES | QL 查询工具 | query, format |
SearchTemplate | 搜索模板工具 | template_id 或 template |
资料来源:src/servers/elasticsearch/mod.rs:34-48
基础工具集 (EsBaseTools)
EsBaseTools 是 MCP 服务器的核心工具提供者,定义了所有内置工具:
| 工具名称 | 功能 | 参数 | |
|---|---|---|---|
list_indices | 列出 Elasticsearch 索引 | index_pattern | |
get_mappings | 获取索引映射 | index | |
search | 执行搜索查询 | index, fields, query_body | |
get_shards | 获取分片信息 | index(可选) | |
esql | 执行 ES | QL 查询 | query |
#### 工具参数定义示例
#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]
struct ListIndicesParams {
/// Index pattern of Elasticsearch indices to list
pub index_pattern: String,
}
#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]
struct SearchParams {
/// Name of the Elasticsearch index to search
index: String,
/// Name of the fields that need to be returned (optional)
fields: Option<Vec<String>>,
/// Complete Elasticsearch query DSL object
query_body: Map<String, Value>,
}
资料来源:src/servers/elasticsearch/base_tools.rs:112-137
工具注解系统
每个工具都可以通过 annotations 属性添加元数据:
#[tool(
description = "List all available Elasticsearch indices",
annotations(title = "List ES indices", read_only_hint = true)
)]
| 注解字段 | 说明 |
|---|---|
title | 工具显示标题 |
read_only_hint | 仅读提示(优化 LLM 决策) |
CLI 启动配置
命令行结构
#[derive(Debug, Subcommand)]
pub enum Command {
Stdio(StdioCommand),
Http(HttpCommand),
}
| 命令 | 说明 | 默认端口 |
|---|---|---|
stdio | 标准输入/输出模式 | - |
http | Streamable-HTTP 模式 | 8080 |
HTTP 模式配置
#[derive(Debug, Args)]
pub struct HttpCommand {
/// Config file
#[clap(short, long)]
pub config: Option<PathBuf>,
/// Address to listen to [default: 127.0.0.1:8080]
#[clap(long, value_name = "IP_ADDRESS:PORT", env = "HTTP_ADDRESS")]
pub address: Option<std::net::SocketAddr>,
/// Also start an SSE server on '/sse'
#[clap(long)]
pub sse: bool,
}
资料来源:src/cli.rs
Stdio 模式配置
#[derive(Debug, Args)]
pub struct StdioCommand {
/// Config file
#[clap(short, long)]
pub config: Option<PathBuf>,
}
客户端提供器
EsClientProvider 实现
EsClientProvider 是对 Elasticsearch 客户端的包装,提供基于请求上下文的客户端实例:
#[derive(Clone)]
pub struct EsClientProvider(Elasticsearch);
impl EsClientProvider {
pub fn new(client: Elasticsearch) -> Self {
EsClientProvider(client)
}
/// If the incoming request is a http request and has an `Authorization` header, use it
/// to authenticate to the remote ES instance.
pub fn get(&self, context: RequestContext<RoleServer>) -> Elasticsearch {
// 返回配置好的客户端实例
}
}
资料来源:src/servers/elasticsearch/mod.rs:106-119
错误处理
pub fn handle_error(result: Result<Response, elasticsearch::Error>) -> Result<Response, rmcp::Error> {
match result {
Ok(resp) => resp.error_for_status_code(),
Err(e) => {
tracing::error!("Error: {:?}", &e);
Err(e)
}
}
.map_err(internal_error)
}
资料来源:src/servers/elasticsearch/mod.rs:121-130
配置最佳实践
生产环境配置
- 使用环境变量存储敏感信息
- API Key 或用户名/密码不应硬编码在配置文件中
- 推荐使用
${ES_API_KEY}或${ES_PASSWORD}语法
- SSL 证书验证
- 生产环境应保持
ssl_skip_verify: false - 如需跳过验证,明确设置
${ES_SSL_SKIP_VERIFY:true}
- 工具限制
- 通过配置文件的
incl_excl规则限制可用工具 - 使用
custom字段添加预定义的 ES|QL 查询或搜索模板
容器化部署
docker run --rm \
-e ES_URL=https://elasticsearch:9200 \
-e ES_API_KEY=your-api-key \
-e ES_SSL_SKIP_VERIFY=false \
-p 8080:8080 \
docker.elastic.co/mcp/elasticsearch \
http
已知问题
社区反馈的认证相关问题(#170)表明,在 Docker 容器部署时需要确保:
- 环境变量名称正确(区分大小写)
ES_USERNAME和ES_PASSWORD同时设置或使用 API Key- 检查容器日志中的认证错误信息
Docker 部署指南
本文档介绍如何通过 Docker 容器方式部署 Elasticsearch MCP Server。Elasticsearch MCP Server 是基于 Model Context Protocol (MCP) 的 Elasticsearch 集成服务,允许 AI 代理通过标准化接口与 Elasticsearch 集群进行交互。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
核心概念
架构概览
MCP Server 以 Docker 容器的形式运行,提供两种协议支持:
graph TD
A[AI Agent / MCP Client] -->|Stdio| B[MCP Server 容器<br/>stdio 模式]
A -->|Streamable HTTP| C[MCP Server 容器<br/>HTTP 模式]
B -->|HTTPS| D[Elasticsearch 集群]
C -->|HTTPS| D容器模式识别
MCP Server 支持自动检测运行环境的容器模式。当检测到容器运行时,服务器会自动将 localhost 替换为容器网络别名,以确保容器内的网络请求能正确路由到宿主机服务(如本地 Elasticsearch 集群)。
资料来源:src/lib.rs:89-101
容器模式通过以下逻辑实现:
graph LR
A[检测运行环境] --> B{是否容器模式?}
B -->|是| C[替换 localhost]
B -->|否| D[保持 localhost]
C --> E[host.containers.internal<br/>Podman<br/>其他别名]支持的宿主机别名包括:
host.containers.internal(Podman 及部分 Docker 环境)- 其他平台特定别名
资料来源:src/servers/elasticsearch/mod.rs:89-95
环境变量配置
必需变量
| 变量名 | 说明 | 示例值 |
|---|---|---|
ES_URL | Elasticsearch 集群地址 | https://localhost:9200 |
ES_API_KEY | API Key 认证密钥 | base64EncodedApiKey... |
ES_USERNAME | 基本认证用户名 | elastic |
ES_PASSWORD | 基本认证密码 | password123 |
ES_SSL_SKIP_VERIFY | 跳过 SSL 证书验证 | true / false |
配置优先级
环境变量支持默认值语法,格式为 ${VAR_NAME:default_value}。当变量未定义时使用默认值。
资料来源:src/lib.rs:67-77
# .env 文件示例
ES_URL=https://elasticsearch:9200
ES_API_KEY=your_api_key_here
ES_SSL_SKIP_VERIFY=false
认证方式
MCP Server 支持三种认证方式:
- API Key 认证(推荐):通过
ES_API_KEY环境变量设置 - 用户名密码认证:通过
ES_USERNAME和ES_PASSWORD环境变量设置 - SSL 跳过验证:仅在开发环境中使用
ES_SSL_SKIP_VERIFY=true
[!IMPORTANT]
认证凭证仅存储在环境变量中,不会持久化到磁盘或写入日志。
资料来源:.env-example
Docker 镜像
镜像信息
官方镜像托管在 Elastic 的 Docker Registry:
docker.elastic.co/mcp/elasticsearch
镜像版本
| 标签 | 说明 |
|---|---|
latest | 最新稳定版本 |
v0.4.6 | 特定版本号(当前最新) |
端口配置
| Dockerfile | 默认端口 | 用途 |
|---|---|---|
Dockerfile | 8080 | HTTP 模式监听端口 |
Dockerfile-8000 | 8000 | 备用端口配置 |
v0.4.3 之前的版本默认端口为 8000,之后统一改为 8080。
资料来源:README.md
Stdio 模式部署
Stdio 模式适用于直接与 MCP Client 进程通信的场景。
启动命令
docker run --rm \
-e ES_URL="https://your-cluster.es.region.amazonaws.com:9200" \
-e ES_API_KEY="your_api_key" \
docker.elastic.co/mcp/elasticsearch \
stdio
Claude Desktop 配置
{
"mcpServers": {
"elasticsearch-mcp-server": {
"command": "docker",
"args": [
"run",
"--rm",
"-e", "ES_URL",
"-e", "ES_API_KEY",
"docker.elastic.co/mcp/elasticsearch",
"stdio"
],
"env": {
"ES_URL": "<elasticsearch-cluster-url>",
"ES_API_KEY": "<elasticsearch-API-key>"
}
}
}
}
资料来源:README.md
HTTP 模式部署
HTTP 模式适用于需要远程访问、多客户端并发连接或通过代理桥接的场景。
启动命令
docker run --rm \
-e ES_URL="https://your-cluster.es.region.amazonaws.com:9200" \
-e ES_API_KEY="your_api_key" \
-p 8080:8080 \
docker.elastic.co/mcp/elasticsearch \
http
端点说明
| 端点 | 方法 | 说明 |
|---|---|---|
/mcp | POST | Streamable HTTP MCP 端点 |
/ping | GET | 健康检查端点 |
健康检查
curl http://<host>:8080/ping
成功响应返回 pong。
资料来源:README.md
Claude Desktop 代理配置
由于 Claude Desktop 免费版仅支持 stdio 协议,需要使用 mcp-proxy 进行协议桥接:
- 安装 mcp-proxy:
uv tool install mcp-proxy
- 配置 Claude Desktop:
{
"mcpServers": {
"elasticsearch-mcp-server": {
"command": "/<home-directory>/.local/bin/mcp-proxy",
"args": [
"--transport=streamablehttp",
"--header", "Authorization", "ApiKey <elasticsearch-API-key>",
"http://<mcp-server-host>:<mcp-server-port>/mcp"
]
}
}
}
资料来源:README.md
故障排查
常见问题
#### 认证失败 (401 Unauthorized)
Issue #170 中用户反馈使用 Docker 部署时环境变量配置正确但仍出现认证失败:
- 确认
ES_USERNAME、ES_PASSWORD环境变量名称拼写正确(区分大小写) - v0.4.5 版本修复了用户名环境变量名称问题,确保使用正确的变量名
- 验证 Elasticsearch 集群的认证配置
#### 连接超时
如果容器无法连接到 Elasticsearch 集群:
# 从容器内部测试连接
docker exec <container-id> curl -k -u <username>:<password> <ES_URL>
#### 容器模式 localhost 问题
如果容器内访问宿主机 Elasticsearch 失败,检查容器是否正确识别容器模式。MCP Server 会自动将 localhost 替换为网络别名。
资料来源:src/servers/elasticsearch/mod.rs:89-95
日志查看
# 查看容器日志
docker logs <container-id>
# 实时跟踪日志
docker logs -f <container-id>
日志中可能出现的错误类型:
- Elasticsearch 连接失败
- 认证错误
- 网络连接问题
验证连接
- 检查容器状态:
docker ps | grep elasticsearch-mcp-server
- 测试健康端点:
curl http://<host>:8080/ping
- 通过 MCP Client 测试功能(如
list_indices、get_shards)
安全最佳实践
凭证管理
| 安全措施 | 说明 |
|---|---|
| 环境变量存储 | 凭证仅存储在环境变量中 |
| 定期轮换 | 生产环境建议 30-90 天轮换 API Key |
| 最小权限 | 使用仅读权限的 API Key |
| 不提交凭证 | 禁止将凭证提交到版本控制 |
网络安全
- 使用 HTTPS 协议 (
ES_URL以https://开头) - 配置正确的安全组和网络 ACL
- 生产环境避免使用
ES_SSL_SKIP_VERIFY=true
AWS 部署建议
在 AWS 环境中部署时:
- 使用 AWS Secrets Manager 管理凭证
- 通过 IAM 角色控制 EKS/EC2 访问权限
- 配置 VPC 安全组规则
资料来源:README.md
CLI_ARGS 环境变量
v0.4.1 版本新增 CLI_ARGS 环境变量支持,可作为传递命令行参数的替代方式:
docker run --rm \
-e ES_URL="https://elasticsearch:9200" \
-e ES_API_KEY="your_key" \
-e CLI_ARGS="--config /path/to/config.json" \
docker.elastic.co/mcp/elasticsearch \
stdio
资料来源:README.md
资料来源:src/lib.rs:89-101
认证配置
Elasticsearch MCP Server 支持两种主要的认证方式与 Elasticsearch 集群建立安全连接。本页详细说明认证配置的工作原理、配置参数以及常见问题的排查方法。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
Elasticsearch MCP Server 支持两种主要的认证方式与 Elasticsearch 集群建立安全连接。本页详细说明认证配置的工作原理、配置参数以及常见问题的排查方法。
认证配置在 MCP Server 启动时通过环境变量或配置文件加载,用于建立与 Elasticsearch 集群的信任连接。所有认证凭证仅在运行时内存中处理,不会持久化到磁盘或日志中。
认证方式
MCP Server 支持两种认证方式:
| 认证方式 | 配置参数 | 说明 |
|---|---|---|
| API Key 认证 | ES_API_KEY | 使用 Elasticsearch API 密钥进行认证 |
| 用户名密码认证 | ES_USERNAME + ES_PASSWORD | 使用用户名和密码进行 Basic 认证 |
[!NOTE]
API Key 认证优先于用户名密码认证。如果同时配置了 API Key 和用户名密码,系统将使用 API Key。
认证凭证优先级
graph TD
A[启动 MCP Server] --> B{是否配置 ES_API_KEY?}
B -->|是| C[使用 API Key 认证]
B -->|否| D{是否配置 ES_USERNAME?}
D -->|是| E{是否配置 ES_PASSWORD?}
E -->|是| F[使用 Basic 认证]
E -->|否| G[无认证]
D -->|否| G
C --> H[连接 Elasticsearch]
F --> H
G --> H配置参数详解
环境变量配置
| 环境变量 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
ES_URL | String | 是 | - | Elasticsearch 集群地址,如 https://localhost:9200 |
ES_API_KEY | String | 否 | 空 | API Key 认证凭证 |
ES_USERNAME | String | 否 | 空 | Basic 认证用户名 |
ES_PASSWORD | String | 否 | 空 | Basic 认证密码 |
ES_SSL_SKIP_VERIFY | Boolean | 否 | false | 是否跳过 SSL 证书验证 |
[!CAUTION]
ES_SSL_SKIP_VERIFY=true 会绕过 SSL 证书验证,仅在测试环境中使用。生产环境应配置正确的 CA 证书。
配置文件格式
除了环境变量,还可以通过配置文件指定认证信息。配置文件支持 JSON5 格式(允许注释和多行字符串):
{
"elasticsearch": {
"url": "${ES_URL}",
"api_key": "${ES_API_KEY:}",
"username": "${ES_USERNAME:}",
"password": "${ES_PASSWORD:}",
"ssl_skip_verify": "${ES_SSL_SKIP_VERIFY:false}"
}
}
配置文件中的 ${VAR:default} 语法表示环境变量插值,如果环境变量未设置则使用默认值。
认证实现架构
核心组件
classDiagram
class ElasticsearchMcpConfig {
+String url
+Option~String~ api_key
+Option~String~ username
+Option~String~ password
+bool ssl_skip_verify
}
class ElasticsearchMcp {
+new_with_config(config, container_mode) EsBaseTools
}
class EsClientProvider {
+Elasticsearch client
+get(context) Elasticsearch
}
class Credentials {
<<enumeration>>
EncodedApiKey(String)
Basic(String, String)
}
ElasticsearchMcpConfig --> ElasticsearchMcp : 配置输入
ElasticsearchMcp --> EsClientProvider : 创建客户端
ElasticsearchMcpConfig --> Credentials : 生成凭证
Credentials --> EsClientProvider : 注入传输层凭证生成逻辑
凭证生成在 ElasticsearchMcp::new_with_config 方法中完成:
let creds = if let Some(api_key) = config.api_key.clone() {
Some(Credentials::EncodedApiKey(api_key))
} else if let Some(username) = config.username.clone() {
let pwd = config.password.clone().ok_or(anyhow::Error::msg("missing password"))?;
Some(Credentials::Basic(username, pwd))
} else {
None
};
资料来源:src/servers/elasticsearch/mod.rs:57-64
传输层配置
凭证创建后,通过 Elasticsearch Rust 客户端的 TransportBuilder 注入到传输层:
let mut transport = elasticsearch::http::transport::TransportBuilder::new(pool);
if let Some(creds) = creds {
transport = transport.auth(creds);
}
// ... 继续配置 SSL 等选项
资料来源:src/servers/elasticsearch/mod.rs:66-70
运行时认证
HTTP 请求上下文认证
EsClientProvider 支持从传入的 HTTP 请求中提取 Authorization 头,用于对远程 ES 实例进行认证:
pub fn get(&self, context: RequestContext<RoleServer>) -> Elasticsearch {
// 从请求上下文中获取 Authorization 头
}
资料来源:src/servers/elasticsearch/mod.rs:97-101
容器模式下的 localhost 重写
当 MCP Server 在 Docker 容器中运行时,rewrite_localhost 函数会将 localhost URL 重写为 host.docker.internal,以便容器可以正确访问宿主机上的 Elasticsearch 服务:
if container_mode {
rewrite_localhost(&mut url)?;
}
资料来源:src/servers/elasticsearch/mod.rs:51-53
配置示例
使用 API Key 认证
# 环境变量方式
export ES_URL=https://elasticsearch.example.com:9200
export ES_API_KEY=your_api_key_here
# 运行 MCP Server
docker run -e ES_URL -e ES_API_KEY elastic/mcp-server-elasticsearch
使用用户名密码认证
# 环境变量方式
export ES_URL=https://elasticsearch.example.com:9200
export ES_USERNAME=elastic
export ES_PASSWORD=your_password
# 运行 MCP Server
docker run -e ES_URL -e ES_USERNAME -e ES_PASSWORD elastic/mcp-server-elasticsearch
使用 .env 文件
# 创建 .env 文件
cat > .env << 'EOF'
ES_URL=https://elasticsearch.example.com:9200
ES_USERNAME=elastic
ES_PASSWORD=your_password
ES_SSL_SKIP_VERIFY=false
EOF
# 运行 MCP Server
docker run --env-file .env elastic/mcp-server-elasticsearch
常见问题排查
401 Unauthorized 错误
问题描述:认证失败,返回 401 Unauthorized 错误。
可能原因:
- 凭证配置错误(用户名/密码不匹配)
- API Key 格式不正确或已过期
- Elasticsearch 安全策略阻止了该凭证
排查步骤:
- 验证环境变量是否正确设置:
docker exec <container-id> env | grep ES_
- 直接测试 Elasticsearch 连接:
# 使用 Basic 认证
docker exec <container-id> curl -k -u <username>:<password> <ES_URL>
# 使用 API Key
docker exec <container-id> curl -k -H "Authorization: ApiKey <api-key>" <ES_URL>
- 检查凭证是否有正确的索引访问权限
认证凭证优先级问题
问题描述:同时配置了 API Key 和用户名密码,但使用了错误的认证方式。
根据代码逻辑,API Key 具有最高优先级。如果希望使用 Basic 认证,请确保不设置 ES_API_KEY 环境变量。
容器内连接问题
问题描述:在 Docker 容器中运行时报连接错误。
当 ES_URL 使用 localhost 时,容器内的进程无法访问宿主机的 Elasticsearch。需要使用 rewrite_localhost 功能或修改 ES_URL 为宿主机的实际 IP 地址。
安全最佳实践
| 安全措施 | 说明 |
|---|---|
| 使用 AWS Secrets Manager | 生产环境应使用 AWS Secrets Manager 或类似服务管理凭证 |
| 定期轮换 API Key | 建议每 30-90 天轮换一次生产环境的 API Key |
| 最小权限原则 | 为 MCP Server 创建只读用户,仅授予必要的索引访问权限 |
| 启用 SSL/TLS | 生产环境必须使用 HTTPS 协议 |
| 避免 SSL 跳过验证 | 生产环境不应设置 ES_SSL_SKIP_VERIFY=true |
[!WARNING]
切勿将凭证直接写入配置文件并提交到版本控制系统。所有凭证都应通过环境变量或密钥管理服务注入。
相关文档
故障排除指南
本页面提供 Elasticsearch MCP Server 部署和运行过程中常见问题的诊断和解决方案。
继续阅读本节完整说明和来源证据。
故障排除指南
本页面提供 Elasticsearch MCP Server 部署和运行过程中常见问题的诊断和解决方案。
来源:https://github.com/elastic/mcp-server-elasticsearch / 项目说明书
安全最佳实践
本文档介绍 Elasticsearch MCP Server 的安全最佳实践,涵盖身份认证、凭证管理、传输加密、网络配置等关键安全领域。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
身份认证配置
Elasticsearch MCP Server 支持两种身份认证方式:API Key 认证 和 基本认证(用户名/密码)。
认证方式对比
| 认证方式 | 环境变量 | 说明 |
|---|---|---|
| API Key | ES_API_KEY | 推荐用于生产环境,安全性更高 |
| 基本认证 | ES_USERNAME + ES_PASSWORD | 适用于传统用户名密码场景 |
| SSL 跳过验证 | ES_SSL_SKIP_VERIFY | 仅在开发/测试环境使用 |
配置认证参数
认证配置通过 ElasticsearchMcpConfig 结构体管理:
// 资料来源:src/servers/elasticsearch/mod.rs:88-102
pub struct ElasticsearchMcpConfig {
/// 集群 URL
pub url: String,
/// API 密钥
#[serde(default, deserialize_with = "none_if_empty_string")]
pub api_key: Option<String>,
/// 用户名
#[serde(default, deserialize_with = "none_if_empty_string")]
pub username: Option<String>,
/// 密码
#[serde(default, deserialize_with = "none_if_empty_string")]
pub password: Option<String>,
/// 是否跳过 SSL 证书验证
#[serde(default, deserialize_with = "deserialize_bool_from_anything")]
pub ssl_skip_verify: bool,
}
API Key 认证配置
docker run --rm \
-e ES_URL="https://your-elasticsearch:9200" \
-e ES_API_KEY="your-api-key-here" \
-p 8080:8080 \
docker.elastic.co/mcp/elasticsearch \
http
基本认证配置
docker run --rm \
-e ES_URL="https://your-elasticsearch:9200" \
-e ES_USERNAME="elastic" \
-e ES_PASSWORD="your-password" \
-p 8080:8080 \
docker.elastic.co/mcp/elasticsearch \
http
凭证安全管理
凭证存储原则
Elasticsearch MCP Server 遵循严格的凭证安全管理原则:
- API 密钥和密码:仅存储在传递给容器的环境变量中
- 不持久化到磁盘:凭证不会写入文件系统
- 不记录到日志:敏感信息不会出现在日志输出中
// 资料来源:src/servers/elasticsearch/mod.rs:72-79
let creds = if let Some(api_key) = config.api_key.clone() {
Some(Credentials::EncodedApiKey(api_key))
} else if let Some(username) = config.username.clone() {
let pwd = config.password.clone().ok_or(anyhow::Error::msg("missing password"))?;
Some(Credentials::Basic(username, pwd))
} else {
None
};
环境变量插值
配置文件支持环境变量插值,使用 ${VAR_NAME} 或 ${VAR_NAME:default} 语法:
{
"elasticsearch": {
"url": "${ES_URL}",
"api_key": "${ES_API_KEY:}",
"username": "${ES_USERNAME:}",
"password": "${ES_PASSWORD:}",
"ssl_skip_verify": "${ES_SSL_SKIP_VERIFY:false}"
}
}
// 资料来源:src/lib.rs:48-52
let config = interpolator::interpolate_from_env(config)?;
生产环境凭证管理建议
| 推荐做法 | 说明 |
|---|---|
| AWS Secrets Manager | 使用 AWS Secrets Manager 存储和轮换凭证 |
| AWS Systems Manager Parameter Store | 使用 Parameter Store 管理敏感参数 |
| 定期轮换 | API 密钥建议每 30-90 天轮换一次 |
| 最小权限 | 使用只读访问特定索引的 API 密钥 |
传输加密
HTTPS 通信
MCP Server 与 Elasticsearch 集群之间的通信采用 HTTPS 加密:
graph LR
A[MCP Server] -->|HTTPS/TLS| B[Elasticsearch Cluster]
B -->|加密响应| A当 ES_URL 使用 https:// 协议时,通信自动加密:
# 正确的 HTTPS 配置
ES_URL="https://your-elasticsearch:9200"
SSL 证书验证
#### 生产环境配置
生产环境应保持 SSL 证书验证启用:
# 默认情况下 ssl_skip_verify 为 false,保持验证
docker run --rm \
-e ES_URL="https://your-elasticsearch:9200" \
-e ES_API_KEY="your-api-key" \
docker.elastic.co/mcp/elasticsearch \
stdio
#### 开发/测试环境配置
仅在本地开发或使用自签名证书时禁用验证:
docker run --rm \
-e ES_URL="https://localhost:9200" \
-e ES_API_KEY="your-api-key" \
-e ES_SSL_SKIP_VERIFY=true \
docker.elastic.co/mcp/elasticsearch \
stdio
⚠️ 警告:禁用 SSL 验证会使通信暴露于中间人攻击风险,仅限于受信任的内部网络。
网络安全配置
HTTP 服务监听地址
HTTP 模式下,默认监听地址为 127.0.0.1:8080:
// 资料来源:src/cli.rs:28-32
pub struct HttpCommand {
/// 监听地址 [默认: 127.0.0.1:8080]
#[clap(long, value_name = "IP_ADDRESS:PORT", env = "HTTP_ADDRESS")]
pub address: Option<std::net::SocketAddr>,
/// 同时启动 SSE 服务器在 '/sse'
#[clap(long)]
pub sse: bool,
}
安全监听建议
| 场景 | 推荐配置 | 说明 |
|---|---|---|
| 本地开发 | 127.0.0.1:8080 | 仅本地访问 |
| Docker 网络 | 0.0.0.0:8080 | 容器间通信 |
| 公网部署 | 使用反向代理 + TLS | 添加额外安全层 |
Docker 网络安全
容器模式下,自动重写 localhost 引用:
// 资料来源:src/servers/elasticsearch/mod.rs:67-68
if container_mode {
rewrite_localhost(&mut url)?;
}
常见安全问题排查
401 Unauthorized 错误
社区反馈:Issue #170 中许多用户遇到基本认证失败的问题。
#### 排查步骤
``bash docker exec <container-id> env | grep ES_ ``
- 验证环境变量配置:
```bash # 使用 API Key docker exec <container-id> curl -k -H "Authorization: ApiKey <api-key>" <ES_URL>
- 测试 Elasticsearch 连接:
# 使用用户名密码 docker exec <container-id> curl -k -u <username>:<password> <ES_URL> ```
- 检查凭证是否正确传递:
- 确认
ES_USERNAME和ES_PASSWORD同时设置 - 确认 API Key 格式正确(不带 "ApiKey" 前缀)
SSL 证书错误
# 检查 Elasticsearch SSL 配置
docker exec <container-id> curl -v <ES_URL>
容器日志分析
docker logs <container-id>
查看日志中的错误信息:
- Elasticsearch 连接失败
- 身份认证错误
- 网络连接问题
数据安全
数据存储
| 层面 | 说明 |
|---|---|
| 传输中数据 | MCP Server 与 Elasticsearch 之间的通信加密 |
| 静态数据 | 容器不本地存储数据,所有数据保留在 Elasticsearch 集群 |
| 临时数据 | 容器重启后清除所有临时数据 |
数据访问控制
建议在 Elasticsearch 层面配置:
- 基于角色的访问控制 (RBAC)
- 字段级安全
- 索引级权限
{
"roles": [
{
"name": "mcp_readonly",
"indices": [
{
"names": ["allowed-index-*"],
"privileges": ["read", "view_index_metadata"]
}
]
}
]
}
审计与监控
健康检查端点
HTTP 模式提供健康检查端点:
curl http://<host>:8080/ping
成功响应返回 pong。
MCP 端点
# MCP 协议端点
http://<host>:8080/mcp
最佳实践清单
部署前检查
- [ ] 使用 HTTPS 连接到 Elasticsearch
- [ ] 配置有效的 API Key 或用户名密码
- [ ] 不在生产环境设置
ES_SSL_SKIP_VERIFY=true - [ ] 使用只读权限的 API 密钥
容器配置检查
- [ ] 凭证通过环境变量传递,不写入配置文件
- [ ] 容器日志不包含敏感信息
- [ ] 网络访问限制在必要范围
运维检查
- [ ] 定期轮换 API 密钥(30-90 天)
- [ ] 监控认证失败日志
- [ ] 审计 Elasticsearch 访问日志
相关资源
来源:https://github.com/elastic/mcp-server-elasticsearch / 项目说明书
失败模式与踩坑日记
保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。
非工程用户可能没有 Docker,启动成本明显增加。
可能阻塞安装或首次运行。
安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。
假设不成立时,用户拿不到承诺的能力。
Pitfall Log / 踩坑日志
项目:elastic/mcp-server-elasticsearch
摘要:发现 10 个潜在踩坑项,其中 0 个为 high/blocking;最高优先级:安装坑 - 依赖 Docker 环境。
1. 安装坑 · 依赖 Docker 环境
- 严重度:medium
- 证据强度:runtime_trace
- 发现:安装/运行入口包含 Docker 命令:docker run -i --rm -e ES_URL -e ES_API_KEY docker.elastic.co/mcp/elasticsearch stdio
- 对用户的影响:非工程用户可能没有 Docker,启动成本明显增加。
- 建议检查:标注 Docker 前置条件,并提供非 Docker 路径或失败提示。
- 复现命令:
docker run -i --rm -e ES_URL -e ES_API_KEY docker.elastic.co/mcp/elasticsearch stdio - 防护动作:Docker 前置条件未说明时,不把项目标成普通用户低门槛。
- 证据:identity.distribution | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | docker run -i --rm -e ES_URL -e ES_API_KEY docker.elastic.co/mcp/elasticsearch stdio
2. 安装坑 · 来源证据:Dependency Dashboard
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:Dependency Dashboard
- 对用户的影响:可能阻塞安装或首次运行。
- 建议检查:来源问题仍为 open,Pack Agent 需要复核是否仍影响当前版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_5573c160ecdd4e34be6dbf6549fe2529 | https://github.com/elastic/mcp-server-elasticsearch/issues/6 | 来源讨论提到 docker 相关条件,需在安装/试用前复核。
3. 配置坑 · 可能修改宿主 AI 配置
- 严重度:medium
- 证据强度:source_linked
- 发现:项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主,或安装命令涉及用户配置目录。
- 对用户的影响:安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。
- 建议检查:列出会写入的配置文件、目录和卸载/回滚步骤。
- 防护动作:涉及宿主配置目录时必须给回滚路径,不能只给安装命令。
- 证据:capability.host_targets | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | host_targets=mcp_host, claude, cursor
4. 能力坑 · 能力判断依赖假设
- 严重度:medium
- 证据强度:source_linked
- 发现:README/documentation is current enough for a first validation pass.
- 对用户的影响:假设不成立时,用户拿不到承诺的能力。
- 建议检查:将假设转成下游验证清单。
- 防护动作:假设必须转成验证项;没有验证结果前不能写成事实。
- 证据:capability.assumptions | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | README/documentation is current enough for a first validation pass.
5. 维护坑 · 维护活跃度未知
- 严重度:medium
- 证据强度:source_linked
- 发现:未记录 last_activity_observed。
- 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
- 建议检查:补 GitHub 最近 commit、release、issue/PR 响应信号。
- 防护动作:维护活跃度未知时,推荐强度不能标为高信任。
- 证据:evidence.maintainer_signals | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | last_activity_observed missing
6. 安全/权限坑 · 下游验证发现风险项
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 对用户的影响:下游已经要求复核,不能在页面中弱化。
- 建议检查:进入安全/权限治理复核队列。
- 防护动作:下游风险存在时必须保持 review/recommendation 降级。
- 证据:downstream_validation.risk_items | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | no_demo; severity=medium
7. 安全/权限坑 · 存在评分风险
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 对用户的影响:风险会影响是否适合普通用户安装。
- 建议检查:把风险写入边界卡,并确认是否需要人工复核。
- 防护动作:评分风险必须进入边界卡,不能只作为内部分数。
- 证据:risks.scoring_risks | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | no_demo; severity=medium
8. 安全/权限坑 · 来源证据:get_mappings tool fails with "error decoding response body" when nested type is omitted in properties
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题:get_mappings tool fails with "error decoding response body" when nested type is omitted in properties
- 对用户的影响:可能影响授权、密钥配置或安全边界。
- 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_f8732a2deab341d6b739b122459d1243 | https://github.com/elastic/mcp-server-elasticsearch/issues/185 | 来源讨论提到 api key 相关条件,需在安装/试用前复核。
9. 维护坑 · issue/PR 响应质量未知
- 严重度:low
- 证据强度:source_linked
- 发现:issue_or_pr_quality=unknown。
- 对用户的影响:用户无法判断遇到问题后是否有人维护。
- 建议检查:抽样最近 issue/PR,判断是否长期无人处理。
- 防护动作:issue/PR 响应未知时,必须提示维护风险。
- 证据:evidence.maintainer_signals | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | issue_or_pr_quality=unknown
10. 维护坑 · 发布节奏不明确
- 严重度:low
- 证据强度:source_linked
- 发现:release_recency=unknown。
- 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
- 建议检查:确认最近 release/tag 和 README 安装命令是否一致。
- 防护动作:发布节奏未知或过期时,安装说明必须标注可能漂移。
- 证据:evidence.maintainer_signals | github_repo:953992846 | https://github.com/elastic/mcp-server-elasticsearch | release_recency=unknown
来源:Doramagic 发现、验证与编译记录