es-mcp-server 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +182 -0
- package/bin/cli.js +10 -0
- package/index.js +435 -0
- package/package.json +32 -0
package/README.md
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# Elasticsearch MCP Server
|
|
2
|
+
|
|
3
|
+
这是一个为 Elasticsearch 设计的 MCP (Model Context Protocol) 服务器,允许通过 Claude Code 直接管理和查询 Elasticsearch 集群。
|
|
4
|
+
|
|
5
|
+
## 功能特性
|
|
6
|
+
|
|
7
|
+
- ✅ 集群健康检查
|
|
8
|
+
- ✅ 索引管理(创建、删除、查看)
|
|
9
|
+
- ✅ 文档操作(增删改查)
|
|
10
|
+
- ✅ 搜索和查询
|
|
11
|
+
- ✅ 集群信息获取
|
|
12
|
+
- ✅ 支持认证(用户名/密码 或 API Key)
|
|
13
|
+
|
|
14
|
+
## 安装
|
|
15
|
+
|
|
16
|
+
### 方式一:npm 全局安装(推荐)
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install -g es-mcp-server
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### 方式二:从本地安装
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
cd <path-to-es-mcp-server>
|
|
26
|
+
npm install -g .
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### 方式三:开发模式
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
cd <path-to-es-mcp-server>
|
|
33
|
+
npm install
|
|
34
|
+
npm start
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## 配置
|
|
38
|
+
|
|
39
|
+
### 环境变量(可选)
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
export ES_HOST="localhost:9200"
|
|
43
|
+
export ES_USERNAME="your_username" # 如果需要认证
|
|
44
|
+
export ES_PASSWORD="your_password" # 如果需要认证
|
|
45
|
+
export ES_API_KEY="your_api_key" # 如果使用 API Key 认证
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## 使用方法
|
|
49
|
+
|
|
50
|
+
### 集成到 Claude Code
|
|
51
|
+
|
|
52
|
+
将以下配置添加到你的 Claude Code MCP 配置中:
|
|
53
|
+
|
|
54
|
+
**使用 npm 全局安装的命令:**
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"mcpServers": {
|
|
59
|
+
"elasticsearch": {
|
|
60
|
+
"command": "es-mcp-server",
|
|
61
|
+
"env": {
|
|
62
|
+
"ES_HOST": "localhost:9200"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**开发模式(从源码运行):**
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"mcpServers": {
|
|
74
|
+
"elasticsearch": {
|
|
75
|
+
"command": "node",
|
|
76
|
+
"args": ["<path-to-es-mcp-server>/index.js"],
|
|
77
|
+
"env": {
|
|
78
|
+
"ES_HOST": "localhost:9200"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## 可用工具
|
|
86
|
+
|
|
87
|
+
| 工具名称 | 描述 | 参数 |
|
|
88
|
+
|---------|------|------|
|
|
89
|
+
| `es_health_check` | 检查集群健康状态 | 无 |
|
|
90
|
+
| `es_list_indices` | 列出所有索引 | `pattern` (可选) - 索引模式 |
|
|
91
|
+
| `es_create_index` | 创建新索引 | `index` (必需) - 索引名<br>`mappings` (可选) - 映射<br>`settings` (可选) - 设置 |
|
|
92
|
+
| `es_delete_index` | 删除索引 | `index` (必需) - 索引名 |
|
|
93
|
+
| `es_index_document` | 索引文档 | `index` (必需) - 索引名<br>`document` (必需) - 文档内容<br>`id` (可选) - 文档ID |
|
|
94
|
+
| `es_get_document` | 获取文档 | `index` (必需) - 索引名<br>`id` (必需) - 文档ID |
|
|
95
|
+
| `es_search` | 搜索文档 | `index` (必需) - 索引名<br>`query` (可选) - 查询DSL<br>`size` (可选) - 返回数量<br>`from` (可选) - 偏移量 |
|
|
96
|
+
| `es_update_document` | 更新文档 | `index` (必需) - 索引名<br>`id` (必需) - 文档ID<br>`document` (必需) - 更新内容 |
|
|
97
|
+
| `es_delete_document` | 删除文档 | `index` (必需) - 索引名<br>`id` (必需) - 文档ID |
|
|
98
|
+
| `es_cluster_info` | 获取集群信息 | 无 |
|
|
99
|
+
|
|
100
|
+
## 使用示例
|
|
101
|
+
|
|
102
|
+
### 检查集群健康
|
|
103
|
+
```javascript
|
|
104
|
+
// 使用 MCP 工具
|
|
105
|
+
await mcpCall("es_health_check", {});
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### 创建索引
|
|
109
|
+
```javascript
|
|
110
|
+
await mcpCall("es_create_index", {
|
|
111
|
+
index: "products",
|
|
112
|
+
mappings: {
|
|
113
|
+
properties: {
|
|
114
|
+
name: { type: "text" },
|
|
115
|
+
price: { type: "float" },
|
|
116
|
+
category: { type: "keyword" }
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### 索引文档
|
|
123
|
+
```javascript
|
|
124
|
+
await mcpCall("es_index_document", {
|
|
125
|
+
index: "products",
|
|
126
|
+
document: {
|
|
127
|
+
name: "iPhone 15",
|
|
128
|
+
price: 999.99,
|
|
129
|
+
category: "Electronics"
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### 搜索文档
|
|
135
|
+
```javascript
|
|
136
|
+
await mcpCall("es_search", {
|
|
137
|
+
index: "products",
|
|
138
|
+
query: {
|
|
139
|
+
query: {
|
|
140
|
+
match: {
|
|
141
|
+
name: "iPhone"
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
size: 10
|
|
146
|
+
});
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## 认证配置
|
|
150
|
+
|
|
151
|
+
### 用户名/密码认证
|
|
152
|
+
```bash
|
|
153
|
+
export ES_USERNAME="elastic"
|
|
154
|
+
export ES_PASSWORD="your_password"
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### API Key 认证
|
|
158
|
+
```bash
|
|
159
|
+
export ES_API_KEY="your_base64_encoded_api_key"
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## 故障排除
|
|
163
|
+
|
|
164
|
+
1. **连接失败**:确保 Elasticsearch 服务正在运行且可访问
|
|
165
|
+
2. **认证错误**:检查用户名/密码或 API Key 是否正确
|
|
166
|
+
3. **权限错误**:确保用户有足够的权限执行请求的操作
|
|
167
|
+
|
|
168
|
+
## 开发
|
|
169
|
+
|
|
170
|
+
### 开发模式运行
|
|
171
|
+
```bash
|
|
172
|
+
npm run dev
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### 添加新工具
|
|
176
|
+
1. 在 `index.js` 的 `ListToolsRequestSchema` 处理程序中添加工具定义
|
|
177
|
+
2. 在 `CallToolRequestSchema` 处理程序中添加相应的 case
|
|
178
|
+
3. 测试新功能
|
|
179
|
+
|
|
180
|
+
## 许可证
|
|
181
|
+
|
|
182
|
+
MIT License
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import { dirname, join } from 'path';
|
|
5
|
+
|
|
6
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
+
const __dirname = dirname(__filename);
|
|
8
|
+
|
|
9
|
+
// Import and run the main server
|
|
10
|
+
import(join(__dirname, '../index.js'));
|
package/index.js
ADDED
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
4
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
|
+
import {
|
|
6
|
+
CallToolRequestSchema,
|
|
7
|
+
ListToolsRequestSchema,
|
|
8
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
9
|
+
import { Client } from "@elastic/elasticsearch";
|
|
10
|
+
|
|
11
|
+
// Elasticsearch client
|
|
12
|
+
let esClient;
|
|
13
|
+
|
|
14
|
+
// MCP Server
|
|
15
|
+
const server = new Server(
|
|
16
|
+
{
|
|
17
|
+
name: "elasticsearch-mcp",
|
|
18
|
+
version: "1.0.0",
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
capabilities: {
|
|
22
|
+
tools: {},
|
|
23
|
+
},
|
|
24
|
+
}
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
// Initialize Elasticsearch client
|
|
28
|
+
function initESClient() {
|
|
29
|
+
const esHost = process.env.ES_HOST || "localhost:9200";
|
|
30
|
+
const esUsername = process.env.ES_USERNAME;
|
|
31
|
+
const esPassword = process.env.ES_PASSWORD;
|
|
32
|
+
const esApiKey = process.env.ES_API_KEY;
|
|
33
|
+
|
|
34
|
+
const clientConfig = {
|
|
35
|
+
node: `http://${esHost}`,
|
|
36
|
+
requestTimeout: 30000,
|
|
37
|
+
sniffOnStart: true,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
if (esApiKey) {
|
|
41
|
+
clientConfig.auth = {
|
|
42
|
+
apiKey: esApiKey,
|
|
43
|
+
};
|
|
44
|
+
} else if (esUsername && esPassword) {
|
|
45
|
+
clientConfig.auth = {
|
|
46
|
+
username: esUsername,
|
|
47
|
+
password: esPassword,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
esClient = new Client(clientConfig);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// List available tools
|
|
55
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
56
|
+
return {
|
|
57
|
+
tools: [
|
|
58
|
+
{
|
|
59
|
+
name: "es_health_check",
|
|
60
|
+
description: "Check Elasticsearch cluster health",
|
|
61
|
+
inputSchema: {
|
|
62
|
+
type: "object",
|
|
63
|
+
properties: {},
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: "es_list_indices",
|
|
68
|
+
description: "List all indices in the cluster",
|
|
69
|
+
inputSchema: {
|
|
70
|
+
type: "object",
|
|
71
|
+
properties: {
|
|
72
|
+
pattern: {
|
|
73
|
+
type: "string",
|
|
74
|
+
description: "Index pattern (default: '*')",
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
name: "es_create_index",
|
|
81
|
+
description: "Create a new index",
|
|
82
|
+
inputSchema: {
|
|
83
|
+
type: "object",
|
|
84
|
+
properties: {
|
|
85
|
+
index: {
|
|
86
|
+
type: "string",
|
|
87
|
+
description: "Index name",
|
|
88
|
+
},
|
|
89
|
+
mappings: {
|
|
90
|
+
type: "object",
|
|
91
|
+
description: "Index mappings (optional)",
|
|
92
|
+
},
|
|
93
|
+
settings: {
|
|
94
|
+
type: "object",
|
|
95
|
+
description: "Index settings (optional)",
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
required: ["index"],
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
name: "es_delete_index",
|
|
103
|
+
description: "Delete an index",
|
|
104
|
+
inputSchema: {
|
|
105
|
+
type: "object",
|
|
106
|
+
properties: {
|
|
107
|
+
index: {
|
|
108
|
+
type: "string",
|
|
109
|
+
description: "Index name",
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
required: ["index"],
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
name: "es_index_document",
|
|
117
|
+
description: "Index a document",
|
|
118
|
+
inputSchema: {
|
|
119
|
+
type: "object",
|
|
120
|
+
properties: {
|
|
121
|
+
index: {
|
|
122
|
+
type: "string",
|
|
123
|
+
description: "Index name",
|
|
124
|
+
},
|
|
125
|
+
id: {
|
|
126
|
+
type: "string",
|
|
127
|
+
description: "Document ID (optional, will be auto-generated if not provided)",
|
|
128
|
+
},
|
|
129
|
+
document: {
|
|
130
|
+
type: "object",
|
|
131
|
+
description: "Document content",
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
required: ["index", "document"],
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
name: "es_get_document",
|
|
139
|
+
description: "Get a document by ID",
|
|
140
|
+
inputSchema: {
|
|
141
|
+
type: "object",
|
|
142
|
+
properties: {
|
|
143
|
+
index: {
|
|
144
|
+
type: "string",
|
|
145
|
+
description: "Index name",
|
|
146
|
+
},
|
|
147
|
+
id: {
|
|
148
|
+
type: "string",
|
|
149
|
+
description: "Document ID",
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
required: ["index", "id"],
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
name: "es_search",
|
|
157
|
+
description: "Search documents",
|
|
158
|
+
inputSchema: {
|
|
159
|
+
type: "object",
|
|
160
|
+
properties: {
|
|
161
|
+
index: {
|
|
162
|
+
type: "string",
|
|
163
|
+
description: "Index name or pattern",
|
|
164
|
+
},
|
|
165
|
+
query: {
|
|
166
|
+
type: "object",
|
|
167
|
+
description: "Search query DSL",
|
|
168
|
+
},
|
|
169
|
+
size: {
|
|
170
|
+
type: "number",
|
|
171
|
+
description: "Number of results to return (default: 10)",
|
|
172
|
+
},
|
|
173
|
+
from: {
|
|
174
|
+
type: "number",
|
|
175
|
+
description: "Starting offset (default: 0)",
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
required: ["index"],
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
name: "es_update_document",
|
|
183
|
+
description: "Update a document",
|
|
184
|
+
inputSchema: {
|
|
185
|
+
type: "object",
|
|
186
|
+
properties: {
|
|
187
|
+
index: {
|
|
188
|
+
type: "string",
|
|
189
|
+
description: "Index name",
|
|
190
|
+
},
|
|
191
|
+
id: {
|
|
192
|
+
type: "string",
|
|
193
|
+
description: "Document ID",
|
|
194
|
+
},
|
|
195
|
+
document: {
|
|
196
|
+
type: "object",
|
|
197
|
+
description: "Partial document to update",
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
required: ["index", "id", "document"],
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
name: "es_delete_document",
|
|
205
|
+
description: "Delete a document",
|
|
206
|
+
inputSchema: {
|
|
207
|
+
type: "object",
|
|
208
|
+
properties: {
|
|
209
|
+
index: {
|
|
210
|
+
type: "string",
|
|
211
|
+
description: "Index name",
|
|
212
|
+
},
|
|
213
|
+
id: {
|
|
214
|
+
type: "string",
|
|
215
|
+
description: "Document ID",
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
required: ["index", "id"],
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
name: "es_cluster_info",
|
|
223
|
+
description: "Get cluster information",
|
|
224
|
+
inputSchema: {
|
|
225
|
+
type: "object",
|
|
226
|
+
properties: {},
|
|
227
|
+
},
|
|
228
|
+
},
|
|
229
|
+
],
|
|
230
|
+
};
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
// Handle tool calls
|
|
234
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
235
|
+
const { name, arguments: args } = request.params;
|
|
236
|
+
|
|
237
|
+
try {
|
|
238
|
+
if (!esClient) {
|
|
239
|
+
initESClient();
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
switch (name) {
|
|
243
|
+
case "es_health_check":
|
|
244
|
+
const health = await esClient.cluster.health();
|
|
245
|
+
return {
|
|
246
|
+
content: [
|
|
247
|
+
{
|
|
248
|
+
type: "text",
|
|
249
|
+
text: JSON.stringify(health, null, 2),
|
|
250
|
+
},
|
|
251
|
+
],
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
case "es_list_indices":
|
|
255
|
+
const indices = await esClient.cat.indices({
|
|
256
|
+
format: "json",
|
|
257
|
+
index: args.pattern || "*",
|
|
258
|
+
});
|
|
259
|
+
return {
|
|
260
|
+
content: [
|
|
261
|
+
{
|
|
262
|
+
type: "text",
|
|
263
|
+
text: JSON.stringify(indices, null, 2),
|
|
264
|
+
},
|
|
265
|
+
],
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
case "es_create_index":
|
|
269
|
+
const createParams = {
|
|
270
|
+
index: args.index,
|
|
271
|
+
};
|
|
272
|
+
if (args.mappings) {
|
|
273
|
+
createParams.mappings = args.mappings;
|
|
274
|
+
}
|
|
275
|
+
if (args.settings) {
|
|
276
|
+
createParams.settings = args.settings;
|
|
277
|
+
}
|
|
278
|
+
const createResult = await esClient.indices.create(createParams);
|
|
279
|
+
return {
|
|
280
|
+
content: [
|
|
281
|
+
{
|
|
282
|
+
type: "text",
|
|
283
|
+
text: JSON.stringify(createResult, null, 2),
|
|
284
|
+
},
|
|
285
|
+
],
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
case "es_delete_index":
|
|
289
|
+
const deleteResult = await esClient.indices.delete({
|
|
290
|
+
index: args.index,
|
|
291
|
+
});
|
|
292
|
+
return {
|
|
293
|
+
content: [
|
|
294
|
+
{
|
|
295
|
+
type: "text",
|
|
296
|
+
text: JSON.stringify(deleteResult, null, 2),
|
|
297
|
+
},
|
|
298
|
+
],
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
case "es_index_document":
|
|
302
|
+
const indexParams = {
|
|
303
|
+
index: args.index,
|
|
304
|
+
body: args.document,
|
|
305
|
+
};
|
|
306
|
+
if (args.id) {
|
|
307
|
+
indexParams.id = args.id;
|
|
308
|
+
}
|
|
309
|
+
const indexResult = await esClient.index(indexParams);
|
|
310
|
+
return {
|
|
311
|
+
content: [
|
|
312
|
+
{
|
|
313
|
+
type: "text",
|
|
314
|
+
text: JSON.stringify(indexResult, null, 2),
|
|
315
|
+
},
|
|
316
|
+
],
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
case "es_get_document":
|
|
320
|
+
const doc = await esClient.get({
|
|
321
|
+
index: args.index,
|
|
322
|
+
id: args.id,
|
|
323
|
+
});
|
|
324
|
+
return {
|
|
325
|
+
content: [
|
|
326
|
+
{
|
|
327
|
+
type: "text",
|
|
328
|
+
text: JSON.stringify(doc, null, 2),
|
|
329
|
+
},
|
|
330
|
+
],
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
case "es_search":
|
|
334
|
+
const searchParams = {
|
|
335
|
+
index: args.index,
|
|
336
|
+
body: args.query || { query: { match_all: {} } },
|
|
337
|
+
};
|
|
338
|
+
if (args.size) {
|
|
339
|
+
searchParams.size = args.size;
|
|
340
|
+
}
|
|
341
|
+
if (args.from) {
|
|
342
|
+
searchParams.from = args.from;
|
|
343
|
+
}
|
|
344
|
+
const searchResult = await esClient.search(searchParams);
|
|
345
|
+
return {
|
|
346
|
+
content: [
|
|
347
|
+
{
|
|
348
|
+
type: "text",
|
|
349
|
+
text: JSON.stringify(searchResult, null, 2),
|
|
350
|
+
},
|
|
351
|
+
],
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
case "es_update_document":
|
|
355
|
+
const updateResult = await esClient.update({
|
|
356
|
+
index: args.index,
|
|
357
|
+
id: args.id,
|
|
358
|
+
body: { doc: args.document },
|
|
359
|
+
});
|
|
360
|
+
return {
|
|
361
|
+
content: [
|
|
362
|
+
{
|
|
363
|
+
type: "text",
|
|
364
|
+
text: JSON.stringify(updateResult, null, 2),
|
|
365
|
+
},
|
|
366
|
+
],
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
case "es_delete_document":
|
|
370
|
+
const deleteDocResult = await esClient.delete({
|
|
371
|
+
index: args.index,
|
|
372
|
+
id: args.id,
|
|
373
|
+
});
|
|
374
|
+
return {
|
|
375
|
+
content: [
|
|
376
|
+
{
|
|
377
|
+
type: "text",
|
|
378
|
+
text: JSON.stringify(deleteDocResult, null, 2),
|
|
379
|
+
},
|
|
380
|
+
],
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
case "es_cluster_info":
|
|
384
|
+
const info = await esClient.info();
|
|
385
|
+
const nodes = await esClient.nodes.stats();
|
|
386
|
+
return {
|
|
387
|
+
content: [
|
|
388
|
+
{
|
|
389
|
+
type: "text",
|
|
390
|
+
text: JSON.stringify(
|
|
391
|
+
{
|
|
392
|
+
cluster_info: info,
|
|
393
|
+
nodes_stats: nodes,
|
|
394
|
+
},
|
|
395
|
+
null,
|
|
396
|
+
2
|
|
397
|
+
),
|
|
398
|
+
},
|
|
399
|
+
],
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
default:
|
|
403
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
404
|
+
}
|
|
405
|
+
} catch (error) {
|
|
406
|
+
return {
|
|
407
|
+
content: [
|
|
408
|
+
{
|
|
409
|
+
type: "text",
|
|
410
|
+
text: JSON.stringify(
|
|
411
|
+
{
|
|
412
|
+
error: error.message,
|
|
413
|
+
details: error.meta?.body || error.stack,
|
|
414
|
+
},
|
|
415
|
+
null,
|
|
416
|
+
2
|
|
417
|
+
),
|
|
418
|
+
},
|
|
419
|
+
],
|
|
420
|
+
isError: true,
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
// Start the server
|
|
426
|
+
async function main() {
|
|
427
|
+
const transport = new StdioServerTransport();
|
|
428
|
+
await server.connect(transport);
|
|
429
|
+
console.error("Elasticsearch MCP Server running on stdio");
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
main().catch((error) => {
|
|
433
|
+
console.error("Server error:", error);
|
|
434
|
+
process.exit(1);
|
|
435
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "es-mcp-server",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Elasticsearch MCP Server for Claude Code",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"es-mcp-server": "bin/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"start": "node index.js",
|
|
12
|
+
"dev": "node --watch index.js"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"mcp",
|
|
16
|
+
"elasticsearch",
|
|
17
|
+
"claude-code"
|
|
18
|
+
],
|
|
19
|
+
"author": "",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@modelcontextprotocol/sdk": "^0.6.0",
|
|
23
|
+
"@elastic/elasticsearch": "^8.12.0"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/node": "^20.0.0"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"index.js",
|
|
30
|
+
"bin/"
|
|
31
|
+
]
|
|
32
|
+
}
|