mcpField
E
esmole

esmole

本地服务
github.com数据库14 天前更新

关于 esmole

esmole 是面向 AI Agent 的 stdio MCP 服务,用于管理 Elasticsearch 7.x 和 8.x 集群。它支持运行时修改连接、项目级或全局存储,以及带只读限制的 SSH 隧道。

主要功能

  1. 01运行时管理命名集群
  2. 02支持 Elasticsearch 7.x 和 8.x
  3. 03项目级与全局连接存储
  4. 04SSH 隧道与主机密钥验证
  5. 05只读请求白名单与响应限制

适用场景

  1. 01在 Agent 会话中添加或修改项目集群
  2. 02通过 SSH 堡垒机查询 Elasticsearch
  3. 03将 Agent 连接限制为获准的读取端点

MCP 相关

它向 MCP 客户端提供 Elasticsearch 连接管理和查询工具。每次工具调用都会重新读取连接配置,因此修改无需重启即可生效。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"ed-smartass-esmole": {
"command": "npx",
"args": [
"-y",
"esmole-mcp"
]
}
}
}
启动命令npx -y esmole-mcp

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npmesmole-mcp0.2.0

工具

10

收录的工具列表 · 更新于 3 天前

此工具无需参数。

详细介绍

esmole 吉祥物

esmole-mcp

面向可自行管理连接的 AI Agent,支持 Elasticsearch 7.x 和 8.x:通过 MCP 工具在运行时按项目添加、编辑和移除集群,并通过 SSH 热重载。

npm 版本 npm 下载量 CI MIT 许可证 Glama 评分

esmole-mcp 是一个用于 Elasticsearch 的 stdio MCP 服务。告诉 你的 Agent:“通过 bastion.example.com 连接到日志集群,只读”,它就会调用 add_connection。连接会保存到项目专属的 .esmole.json 或全局存储中, 并且每次调用工具时都会重新读取这两处配置。因此,无论是 Agent、你在编辑器中的修改, 还是其他会话做出的更改,都会在下一次调用时生效。无需修改客户端配置,也无需重启。

  • 支持 Elasticsearch 7.x 和 8.x,可连接任意数量的命名集群,并支持 API 密钥或基本身份验证。
  • 支持通过密码、密钥或 Agent 身份验证建立 SSH 隧道;主机密钥会通过 known_hosts 或 固定指纹进行验证。
  • readonly 连接仅可访问允许列表中的读取端点;请求超时为绝对时限,响应上限为 10 MB,结果限制为 40 KB,避免大型聚合结果淹没上下文。

需要 PostgreSQL 或 MySQL?dbmole-mcp 为 SQL 数据库采用了相同的设计。

演示

Agent 向项目添加只读集群并进行搜索

安装

需要 Node.js 22 或更高版本。服务启动时无需配置;连接可以稍后添加。

Claude Code

claude mcp add esmole -- npx -y esmole-mcp

添加 --scope user,即可在每个项目中启用。也可以将其安装为插件(Claude Code 2.1.275 或更高版本):

/plugin install esmole --marketplace ed-smartass/esmole-mcp

Codex

codex mcp add esmole -- npx -y esmole-mcp

或添加到 ~/.codex/config.toml:

[mcp_servers.esmole]
command = "npx"
args = ["-y", "esmole-mcp"]

Cursor

将 esmole 添加到 Cursor

VS Code

在 VS Code 中安装

Claude Desktop

从最新版本下载 esmole-mcp-<version>.mcpb 并打开,或者将下面的 JSON 添加到 claude_desktop_config.json。Claude Desktop 不会在项目内启动服务,因此请将连接保存在全局存储中(默认作用域)。

其他 MCP 客户端

{
    "mcpServers": {
        "esmole": { "command": "npx", "args": ["-y", "esmole-mcp"] }
    }
}

Docker

镜像由源代码构建:

git clone https://github.com/ed-smartass/esmole-mcp.git && cd esmole-mcp
docker build -t esmole-mcp .
{
    "mcpServers": {
        "esmole": {
            "command": "docker",
            "args": [
                "run", "-i", "--rm",
                "-v", "esmole-store:/home/node/.config/esmole",
                "-v", "/abs/path/to/project:/work",
                "-v", "/home/me/.ssh/known_hosts:/home/node/.ssh/known_hosts:ro",
                "esmole-mcp"
            ]
        }
    }
}

容器以 node 用户运行,工作目录为 /work:将项目挂载到该目录,即可使用项目中的 .esmole.json;命名卷则会保留全局存储。对于 SSH 连接,请挂载 known_hosts(或固定 ssh.hostKey),并将通过 privateKeyPath 引用的任何私钥挂载到连接指定的路径;若设置 ssh.agent: true,请转发 Agent 套接字(-v "$SSH_AUTH_SOCK:/ssh-agent" -e SSH_AUTH_SOCK=/ssh-agent)。若要访问只有本机才能连接的主机,请添加 --add-host=host.docker.internal:host-gateway(Linux),并使用 host.docker.internal。镜像中没有 git,因此“未被 git 忽略”检查总会发出警告。

即使仍设置了 ESMOLE_CONNECTIONS、ESMOLE_CONFIG 或 --config,0.1 版的配置也能正常启动:服务会在 stderr 输出一行提示,说明这些配置已被忽略。请参阅变更日志。

快速开始

例如,可以向 Agent 提出请求:

在此项目中添加一个名为 logs 的只读 elasticsearch 连接:通过 ssh,以 [email protected] 身份和我的 ssh agent 连接到 10.0.0.20 上的 https 服务,使用 API 密钥 VnVhQ2ZH…。然后显示最大的五个索引。

它会调用 add_connection,并传入:

{
    "name": "logs",
    "host": "10.0.0.20",
    "apiKey": "VnVhQ2ZH…",
    "readonly": true,
    "ssh": { "host": "bastion.example.com", "user": "deploy", "agent": true },
    "scope": "project"
}

然后调用 test_connection 和 es_list_indices。你在聊天中输入的凭据会经过模型的上下文;对于生产环境的密钥,请自行将条目写入文件。

连接

两层配置
层级文件结构
project.esmole.json,从服务的工作目录开始查找{ "connections": [ ... ] }
global~/.config/esmole/connections.json,或 ESMOLE_STORE 中指定的路径[ ... ]
  • 两层中名称相同:项目条目优先。 list_connections 会报告每个连接的 source(project 或 global);当一个条目遮蔽了另一层中同名的条目时,还会报告 shadows。
  • 热重载。 每次调用工具时都会重新读取这两个文件。在会话期间编辑文件后,下次调用就会使用新设置;发生变化的连接会创建新的客户端,并关闭旧客户端。
  • 项目文件发现。 esmole 从服务的工作目录开始(Claude Code 和 Codex 会在项目目录中启动服务),向上遍历至文件系统根目录,并使用找到的第一个 .esmole.json。如果链接的 git worktree 中没有自己的文件,则会回退到主检出目录中的 .esmole.json,因此同一仓库的所有 worktree 共用一个文件。
  • 两个文件都是权限模式为 0600 的普通 JSON 文件,并以原子方式写入。写入时会原样保留无法解析的条目,并拒绝覆盖无效 JSON 文件。
使用工具管理连接
  • add_connection 接受连接字段以及 scope:"global"(默认值)或 "project"。选择 project 且尚无文件时,文件会创建在主检出目录的根目录 (或 git 根目录;如果不在 git 仓库中,则创建在工作目录)。如果 git 未忽略该文件, 响应会发出警告;请将 .esmole.json 添加到 .gitignore,以免提交凭据。
  • 如果目标层中已存在同名连接,add_connection 会失败。另一层中存在同名连接是允许的; 响应会说明现在由哪个条目覆盖哪个条目。
  • update_connection 会更新连接所在的层(优先层)。将可选字段设为 null 可移除该字段。 ssh 对象会逐字段合并到已存储的对象中,因此 { "ssh": { "hostKey": "SHA256:..." } } 会保留已存储的 SSH 密钥。
  • remove_connection 会从该层删除连接,并告知删除后是否会显露另一层中的同名条目。
  • 凭据绝不会回显:list_connections 会显示 scheme、host、port、认证类型、 verifyTls、readonly、source 以及是否使用 SSH。
损坏和无效条目
  • 未通过验证的条目不会悄然消失:其名称会解析为错误 (connection 'x' in <file> is invalid: ...),而不会回退到全局存储中的同名条目; list_connections 会将其列为无效条目。在同一文件中定义两个同名条目也会报错。 remove_connection 可以删除无效条目。
  • 如果文件存在但无法读取、不是 JSON 格式或结构不正确,list_connections 会在 brokenLayers 中报告。损坏的项目文件会阻止所有连接;损坏的全局存储只会阻止 项目文件中未定义的名称。文件缺失时则视为空。
连接字段

不接受未知字段。必须提供身份验证信息:apiKey,或同时提供 user 和 password。

字段类型说明
namestring[a-zA-Z0-9_-]+
typeelasticsearch默认值为 elasticsearch
hoststring设置 ssh 时,从 SSH 堡垒机看到的主机
portnumber默认值为 9200
schemehttp | https默认值为 https
verifyTlsboolean默认值为 true;false 会跳过证书验证
apiKeystringAPI 密钥(base64 格式的 id:key)
user, passwordstring基本身份验证
readonlyboolean默认值为 false,参见 只读
queryTimeoutMsinteger毫秒数,默认值为 60000,最大为 2147483647;参见 限制和超时
sshobject参见 SSH 隧道

.esmole.json 示例:

{
    "connections": [
        { "name": "local", "host": "localhost", "scheme": "http", "user": "elastic", "password": "changeme" },
        {
            "name": "logs",
            "host": "10.0.0.20",
            "apiKey": "VnVhQ2ZHY0JDZGJrUW0t...",
            "readonly": true,
            "ssh": { "host": "bastion.example.com", "user": "deploy", "agent": true }
        }
    ]
}

SSH 隧道

ssh 字段说明
host、port堡垒机;port 默认为 22
userSSH 用户
password密码身份验证
privateKey / privateKeyPath密钥内容或路径(会展开 ~)
passphrase用于加密密钥
agent设为 true 可使用 SSH_AUTH_SOCK 中的 Agent
hostKey固定的主机密钥指纹,SHA256:...(OpenSSH 格式)
{ "host": "bastion.example.com", "user": "deploy", "privateKeyPath": "~/.ssh/id_ed25519" }
{ "host": "bastion.example.com", "user": "deploy", "password": "…" }
{ "host": "bastion.example.com", "port": 2222, "user": "deploy", "agent": true }
{ "host": "bastion.example.com", "user": "deploy", "agent": true, "hostKey": "SHA256:EXAMPLEexampleEXAMPLEexampleEXAMPLEexample1" }

主机密钥会经过验证。 设置 hostKey 后,堡垒机的密钥必须与其匹配(接受末尾带有 = 填充的情况),并且不会查询 known_hosts。否则,密钥必须与 ~/.ssh/known_hosts 中该主机对应的条目匹配(端口为 22 时使用 host,否则使用 [host]:port):

  • 普通和哈希主机名均可匹配。通配符模式永不匹配,带有否定通配符(!*.example.com)的行会被忽略。
  • 对于任何主机,凡是在 @revoked 下列出的密钥都会被拒绝,无论该行的主机模式是什么。@cert-authority 行和未知标记会被跳过。

不支持首次使用时自动信任:遇到未知密钥时,连接会失败并显示该密钥的指纹。请通过可信来源核验该指纹,然后将主机添加到 known_hosts,或固定该密钥:

ssh-keyscan -p 22 bastion.example.com 2>/dev/null | ssh-keygen -lf -
# 256 SHA256:EXAMPLEexampleEXAMPLEexampleEXAMPLEexample1 bastion.example.com (ED25519)

并让 Agent 使用该 SHA256:... 值设置 ssh.hostKey,调用 update_connection。

隧道每隔 15 s 发送一次保活信号,连续 3 次未收到回复后会重建。不支持:ProxyJump 和 ~/.ssh/config、SSH 证书。通过隧道使用 scheme: "https" 时,证书会针对 host 而非隧道的本地地址进行验证。

只读

readonly: true 可防止意外写入。每个工具(包括 es_request)都会先根据允许列表检查方法和路径,再发送任何内容:

  • GET 和 HEAD:允许。
  • POST:仅允许 _search、_msearch、_count、_field_caps 和 _pit(可选地位于一个索引或模式下,例如 /logs-*/_search),以及 /_search/scroll。
  • DELETE:仅允许 /_search/scroll 和 /_pit(关闭读取会话)。
  • 其他所有请求都会被拒绝,路径中包含 ..、%2e、%2f、%5c、\ 或 # 的请求也会被拒绝,无论使用什么方法。因此,在只读连接上,es_request 无法使用带 / 取整的日期数学索引名称,例如 <logs-{now/d}>;可写连接不受影响。
  • 辅助工具的索引和模式参数也会经过验证(不能包含 /、\、?、#、%、空白字符或 ..);支持逗号分隔列表、通配符、-exclusions 和 cluster:index。日期数学名称需要经过 % 编码,因此只能通过 es_request 使用。
  • 由于所有 GET 请求都会通过,仅用于 GET 的维护端点(例如 GET /_flush)也会通过。它们不会更改任何文档,但并非读取操作。

这不是安全边界:Agent 可以通过 update_connection 将其关闭,这是有意如此设计的。如需强制保证,请使用仅具有读取权限的 Elasticsearch 角色或 API 密钥。

工具

工具功能
list_connections列出连接及其 source、被覆盖的名称、无效条目和损坏的文件
add_connection将连接添加到 project 文件或 global 存储
update_connection修改连接所在位置的连接;null 会移除字段
remove_connection移除连接;报告因此显露的同名条目
test_connection端到端连接(包括隧道),并报告集群版本和延迟
es_request支持任意方法、路径、请求体和查询参数;受只读保护;用于 NDJSON(_bulk、_msearch)的字符串请求体
es_search在索引或模式上支持 query、aggs、size、source(作为 _source 发送)、sort、from、search_after、track_total_hits、highlight、script_fields;整个请求体若嵌套在 query 中,会被提取出来,并附带一条 note
es_list_indices列出与模式匹配的索引(默认 *),并显示健康状态、文档数和存储大小
es_get_mapping将映射扁平化为 field: type;设置 raw: true 可获取原始映射
es_cluster_health集群健康状态

es_search 的 size 默认值为 10,上限为 1000,嵌套请求体中的 size 也不例外;如果有 aggs 但没有 query,则为 0。工具参数会严格检查:错误的键会被拒绝并给出提示,例如 unknown key '_source' — did you mean 'source'?。

集群返回的 4xx 或 5xx 错误(包括 es_request 的响应)会作为工具错误返回:第一行显示 HTTP <status> <root_cause[0].type>: <reason>,后面附上经过修剪的响应体。test_connection 遇到任何非 2xx 响应都会失败(例如,受到保护的集群返回 401)。

这十个工具定义约占用 2.1k 个上下文 token(tools/list 约 8,200 个字符;使用 npm run smoke 测量,按每个 token 约 4 个字符计算)。

限制和超时

  • 每个结果最多为 40 KB 的 JSON。超过 2 KB 的字符串会被截断并标记为 …[+N bytes];如果请求体仍然过大,则会将最长的数组(hits、buckets)减半,直到符合限制。结果会在 truncated 中说明,并保持为有效 JSON。可通过在 es_search 中设置 size 和 source,或在 es_request 中设置 filter_path,来减少结果。
  • 超过 10 MB 的响应会被中止并报错(“narrow it with size/_source”),不会返回部分内容。
  • queryTimeoutMs(默认 60 s)是每个请求的绝对截止时间,从连接开始到读取完响应体最后一个字节为止。

对比

esmole-mcpelastic/mcp-server-elasticsearchcr7258/elasticsearch-mcp-server
状态维护中已弃用;Elastic 指向 Agent Builder MCP 端点(Elasticsearch 9.2+)维护中
Elasticsearch 7.x✓—✓
Elasticsearch 8.x✓✓✓
OpenSearch—✗✓
内置 SSH 隧道✓✗✗
Agent 通过 MCP 工具添加和编辑连接✓✗✗

✓ 有文档说明,✗ 不提供,— 未提及或未测试。信息核对时间:2026 年 10 月;欢迎指正。

安全性

连接文件以明文形式保存凭据(权限模式为 0600)。请勿将 .esmole.json 提交到 git。 集群错误会原样传递给客户端。

任何能够通过 update_connection 或编辑连接文件来更改连接的人,都可以重定向该连接的凭据。 更改 host 会保留已存储的密码或 API 密钥,更改 ssh.host 会保留已存储的 SSH 密码或密钥,因此下一次调用会将它们发送到新主机。请将连接工具和文件的写入权限视同凭据的访问权限。

项目的 .esmole.json 会被直接信任:在克隆的或不受信任的代码库中,它可以添加连接,或覆盖同名的全局连接,并将你的查询发送到另一台主机。发现过程会一路向上遍历到 /,因此父目录(例如 ~)中的文件会应用于其下的所有项目。在不熟悉的代码库中工作前,请检查 list_connections。

每个打开的 SSH 隧道都会在 127.0.0.1 上使用随机端口监听,且不需要身份验证:隧道打开期间,任何本地进程(包括共享主机上的其他用户)都可以通过它连接到目标主机。集群仍会要求提供其自身的凭据。

有关威胁模型以及如何报告漏洞,请参阅 SECURITY.md。

开发

npm ci
npm run lint        # Biome
npm run typecheck   # tsc
npm run test:unit   # unit tests, mocked IO
npm run test:int    # integration tests against Elasticsearch 7.17 and 8.x (needs Docker)
npm run smoke       # build, npm pack, install the tarball in a temp dir, boot, tools/list

共享的连接核心是 @dbmole/core, 该核心在 dbmole-mcp 仓库中开发,并在构建时打包到此软件包中。请参阅 CONTRIBUTING.md。

许可证

MIT

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。