opensearch-mcp-server 2.0.9__py3-none-any.whl → 2.0.11__py3-none-any.whl
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.
- {opensearch_mcp_server-2.0.9.dist-info → opensearch_mcp_server-2.0.11.dist-info}/METADATA +79 -8
- {opensearch_mcp_server-2.0.9.dist-info → opensearch_mcp_server-2.0.11.dist-info}/RECORD +8 -8
- src/clients/__init__.py +2 -0
- src/clients/base.py +23 -8
- src/version.py +1 -1
- {opensearch_mcp_server-2.0.9.dist-info → opensearch_mcp_server-2.0.11.dist-info}/WHEEL +0 -0
- {opensearch_mcp_server-2.0.9.dist-info → opensearch_mcp_server-2.0.11.dist-info}/entry_points.txt +0 -0
- {opensearch_mcp_server-2.0.9.dist-info → opensearch_mcp_server-2.0.11.dist-info}/licenses/LICENSE +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: opensearch-mcp-server
|
3
|
-
Version: 2.0.
|
3
|
+
Version: 2.0.11
|
4
4
|
Summary: MCP Server for interacting with Elasticsearch and OpenSearch
|
5
5
|
License: Apache License
|
6
6
|
Version 2.0, January 2004
|
@@ -218,10 +218,10 @@ Description-Content-Type: text/markdown
|
|
218
218
|
|
219
219
|
# Elasticsearch/OpenSearch MCP Server
|
220
220
|
|
221
|
-
[](https://smithery.ai/server/elasticsearch-mcp-server)
|
222
|
-
|
223
221
|
[](https://mseep.ai/app/cr7258-elasticsearch-mcp-server)
|
224
222
|
|
223
|
+
[](https://archestra.ai/mcp-catalog/cr7258__elasticsearch-mcp-server)
|
224
|
+
|
225
225
|
## Overview
|
226
226
|
|
227
227
|
A Model Context Protocol (MCP) server implementation that provides Elasticsearch and OpenSearch interaction. This server enables searching documents, analyzing indices, and managing cluster through a set of tools.
|
@@ -267,7 +267,20 @@ https://github.com/user-attachments/assets/f7409e31-fac4-4321-9c94-b0ff2ea7ff15
|
|
267
267
|
|
268
268
|
## Configure Environment Variables
|
269
269
|
|
270
|
-
|
270
|
+
The MCP server supports the following environment variables for authentication:
|
271
|
+
|
272
|
+
### Basic Authentication (Username/Password)
|
273
|
+
- `ELASTICSEARCH_USERNAME`: Username for basic authentication
|
274
|
+
- `ELASTICSEARCH_PASSWORD`: Password for basic authentication
|
275
|
+
- `OPENSEARCH_USERNAME`: Username for OpenSearch basic authentication
|
276
|
+
- `OPENSEARCH_PASSWORD`: Password for OpenSearch basic authentication
|
277
|
+
|
278
|
+
### API Key Authentication (Elasticsearch only) - Recommended
|
279
|
+
- `ELASTICSEARCH_API_KEY`: API key for [Elasticsearch](https://www.elastic.co/docs/deploy-manage/api-keys/elasticsearch-api-keys) or [Elastic Cloud](https://www.elastic.co/docs/deploy-manage/api-keys/elastic-cloud-api-keys) Authentication.
|
280
|
+
|
281
|
+
### Other Configuration
|
282
|
+
- `ELASTICSEARCH_HOSTS` / `OPENSEARCH_HOSTS`: Comma-separated list of hosts (default: `https://localhost:9200`)
|
283
|
+
- `ELASTICSEARCH_VERIFY_CERTS` / `OPENSEARCH_VERIFY_CERTS`: Whether to verify SSL certificates (default: `false`)
|
271
284
|
|
272
285
|
## Start Elasticsearch/OpenSearch Cluster
|
273
286
|
|
@@ -292,7 +305,7 @@ You can access Kibana/OpenSearch Dashboards from http://localhost:5601.
|
|
292
305
|
Using `uvx` will automatically install the package from PyPI, no need to clone the repository locally. Add the following configuration to 's config file `claude_desktop_config.json`.
|
293
306
|
|
294
307
|
```json
|
295
|
-
// For Elasticsearch
|
308
|
+
// For Elasticsearch with username/password
|
296
309
|
{
|
297
310
|
"mcpServers": {
|
298
311
|
"elasticsearch-mcp-server": {
|
@@ -309,6 +322,22 @@ Using `uvx` will automatically install the package from PyPI, no need to clone t
|
|
309
322
|
}
|
310
323
|
}
|
311
324
|
|
325
|
+
// For Elasticsearch with API key
|
326
|
+
{
|
327
|
+
"mcpServers": {
|
328
|
+
"elasticsearch-mcp-server": {
|
329
|
+
"command": "uvx",
|
330
|
+
"args": [
|
331
|
+
"elasticsearch-mcp-server"
|
332
|
+
],
|
333
|
+
"env": {
|
334
|
+
"ELASTICSEARCH_HOSTS": "https://localhost:9200",
|
335
|
+
"ELASTICSEARCH_API_KEY": "<YOUR_ELASTICSEARCH_API_KEY>"
|
336
|
+
}
|
337
|
+
}
|
338
|
+
}
|
339
|
+
}
|
340
|
+
|
312
341
|
// For OpenSearch
|
313
342
|
{
|
314
343
|
"mcpServers": {
|
@@ -332,7 +361,7 @@ Using `uvx` will automatically install the package from PyPI, no need to clone t
|
|
332
361
|
Using `uv` requires cloning the repository locally and specifying the path to the source code. Add the following configuration to Claude Desktop's config file `claude_desktop_config.json`.
|
333
362
|
|
334
363
|
```json
|
335
|
-
// For Elasticsearch
|
364
|
+
// For Elasticsearch with username/password
|
336
365
|
{
|
337
366
|
"mcpServers": {
|
338
367
|
"elasticsearch-mcp-server": {
|
@@ -352,6 +381,25 @@ Using `uv` requires cloning the repository locally and specifying the path to th
|
|
352
381
|
}
|
353
382
|
}
|
354
383
|
|
384
|
+
// For Elasticsearch with API key
|
385
|
+
{
|
386
|
+
"mcpServers": {
|
387
|
+
"elasticsearch-mcp-server": {
|
388
|
+
"command": "uv",
|
389
|
+
"args": [
|
390
|
+
"--directory",
|
391
|
+
"path/to/src/elasticsearch_mcp_server",
|
392
|
+
"run",
|
393
|
+
"elasticsearch-mcp-server"
|
394
|
+
],
|
395
|
+
"env": {
|
396
|
+
"ELASTICSEARCH_HOSTS": "https://localhost:9200",
|
397
|
+
"ELASTICSEARCH_API_KEY": "<YOUR_ELASTICSEARCH_API_KEY>"
|
398
|
+
}
|
399
|
+
}
|
400
|
+
}
|
401
|
+
}
|
402
|
+
|
355
403
|
// For OpenSearch
|
356
404
|
{
|
357
405
|
"mcpServers": {
|
@@ -378,11 +426,15 @@ Using `uv` requires cloning the repository locally and specifying the path to th
|
|
378
426
|
### Option 1: Using uvx
|
379
427
|
|
380
428
|
```bash
|
381
|
-
# export environment variables
|
429
|
+
# export environment variables (with username/password)
|
382
430
|
export ELASTICSEARCH_HOSTS="https://localhost:9200"
|
383
431
|
export ELASTICSEARCH_USERNAME="elastic"
|
384
432
|
export ELASTICSEARCH_PASSWORD="test123"
|
385
433
|
|
434
|
+
# OR export environment variables (with API key)
|
435
|
+
export ELASTICSEARCH_HOSTS="https://localhost:9200"
|
436
|
+
export ELASTICSEARCH_API_KEY="<YOUR_ELASTICSEARCH_API_KEY>"
|
437
|
+
|
386
438
|
# By default, the SSE MCP server will serve on http://127.0.0.1:8000/sse
|
387
439
|
uvx elasticsearch-mcp-server --transport sse
|
388
440
|
|
@@ -405,11 +457,15 @@ uv run src/server.py elasticsearch-mcp-server --transport sse --host 0.0.0.0 --p
|
|
405
457
|
### Option 1: Using uvx
|
406
458
|
|
407
459
|
```bash
|
408
|
-
# export environment variables
|
460
|
+
# export environment variables (with username/password)
|
409
461
|
export ELASTICSEARCH_HOSTS="https://localhost:9200"
|
410
462
|
export ELASTICSEARCH_USERNAME="elastic"
|
411
463
|
export ELASTICSEARCH_PASSWORD="test123"
|
412
464
|
|
465
|
+
# OR export environment variables (with API key)
|
466
|
+
export ELASTICSEARCH_HOSTS="https://localhost:9200"
|
467
|
+
export ELASTICSEARCH_API_KEY="<YOUR_ELASTICSEARCH_API_KEY>"
|
468
|
+
|
413
469
|
# By default, the Streamable HTTP MCP server will serve on http://127.0.0.1:8000/mcp
|
414
470
|
uvx elasticsearch-mcp-server --transport streamable-http
|
415
471
|
|
@@ -427,6 +483,21 @@ uv run src/server.py elasticsearch-mcp-server --transport streamable-http
|
|
427
483
|
uv run src/server.py elasticsearch-mcp-server --transport streamable-http --host 0.0.0.0 --port 8000 --path /mcp
|
428
484
|
```
|
429
485
|
|
486
|
+
## Compatibility
|
487
|
+
|
488
|
+
The MCP server is compatible with Elasticsearch 7.x, 8.x, and 9.x. By default, it uses the Elasticsearch 8.x client (without a suffix). To use the Elasticsearch 7.x client, run the `elasticsearch-mcp-server-es7` variant. For Elasticsearch 9.x, use `elasticsearch-mcp-server-es9`. For example:
|
489
|
+
|
490
|
+
```bash
|
491
|
+
uvx elasticsearch-mcp-server-es7
|
492
|
+
```
|
493
|
+
|
494
|
+
| MCP Server | Elasticsearch |
|
495
|
+
| --- | --- |
|
496
|
+
| elasticsearch-mcp-server-es7 | Elasticsearch 7.x |
|
497
|
+
| elasticsearch-mcp-server | Elasticsearch 8.x |
|
498
|
+
| elasticsearch-mcp-server-es9 | Elasticsearch 9.x |
|
499
|
+
| opensearch-mcp-server | OpenSearch 1.x, 2.x, 3.x |
|
500
|
+
|
430
501
|
## License
|
431
502
|
|
432
503
|
This project is licensed under the Apache License Version 2.0 - see the [LICENSE](LICENSE) file for details.
|
@@ -1,8 +1,8 @@
|
|
1
1
|
src/__init__.py,sha256=aNKcThftSLh9IjOTA-UUpoRzIm4R0WwXKGAzykwecmU,211
|
2
2
|
src/server.py,sha256=BfMAgXTFV9C4waCWRro8Sfl6yXEXr2vJ7YoGY7HhMPY,5072
|
3
|
-
src/version.py,sha256=
|
4
|
-
src/clients/__init__.py,sha256=
|
5
|
-
src/clients/base.py,sha256=
|
3
|
+
src/version.py,sha256=T-q0gGRSS4Se3uygy0WDtGhPp5plXECGZSjUouo_yUU,23
|
4
|
+
src/clients/__init__.py,sha256=MUKeCxvAFzzVfQr4x1seB7cRVLtWAk7pb1-5tLG0T8g,1299
|
5
|
+
src/clients/base.py,sha256=tMNdKRsAG1dPHj7famwPvCXCONuT9jML-7FmWV9vXbs,5348
|
6
6
|
src/clients/exceptions.py,sha256=NYF3KVw-9aAgCViin5OuBI6miMEPS5QsdHx6bcis1wc,2493
|
7
7
|
src/clients/common/__init__.py,sha256=VgvgxFpESn2wAuJmH0XM_Ej2izI7dxK7QJe9wG4fmW0,211
|
8
8
|
src/clients/common/alias.py,sha256=rB53TSld5x2vZyDNAwyEdnh1KWUXMSD7h5fSv_ubR2Q,759
|
@@ -18,8 +18,8 @@ src/tools/document.py,sha256=XZTVuk4di9VEwWMZN7jyDVnzoOiXkb4FBrXF44sVXTs,2052
|
|
18
18
|
src/tools/general.py,sha256=whj1spjIb8SS75h843X6c3RTsrZcSm-66KVLlY7OEh0,817
|
19
19
|
src/tools/index.py,sha256=7KNPtElTFelkjRSvdMqPBx9nx_9Uk01OnTMeVo7YeCs,1345
|
20
20
|
src/tools/register.py,sha256=wrG2P6-YPW77bTg1j_ELp8omWRYsJjFeOHUy_unHe6Y,1344
|
21
|
-
opensearch_mcp_server-2.0.
|
22
|
-
opensearch_mcp_server-2.0.
|
23
|
-
opensearch_mcp_server-2.0.
|
24
|
-
opensearch_mcp_server-2.0.
|
25
|
-
opensearch_mcp_server-2.0.
|
21
|
+
opensearch_mcp_server-2.0.11.dist-info/METADATA,sha256=A_35ajQsEfqCYqo5hBp2jYX757DlbYUj4N_CO4utE_s,22552
|
22
|
+
opensearch_mcp_server-2.0.11.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
23
|
+
opensearch_mcp_server-2.0.11.dist-info/entry_points.txt,sha256=ImfJnUwMpQUBmu-1MeBG_P0dwamfXKQh82mBKW7tWNY,138
|
24
|
+
opensearch_mcp_server-2.0.11.dist-info/licenses/LICENSE,sha256=DBsjuP5FR51d9kaUdXlVBuBv3cQ_I_adq9gefYQ9FcY,11339
|
25
|
+
opensearch_mcp_server-2.0.11.dist-info/RECORD,,
|
src/clients/__init__.py
CHANGED
@@ -24,12 +24,14 @@ def create_search_client(engine_type: str) -> SearchClient:
|
|
24
24
|
hosts = [host.strip() for host in hosts_str.split(",")]
|
25
25
|
username = os.environ.get(f"{prefix}_USERNAME")
|
26
26
|
password = os.environ.get(f"{prefix}_PASSWORD")
|
27
|
+
api_key = os.environ.get(f"{prefix}_API_KEY")
|
27
28
|
verify_certs = os.environ.get(f"{prefix}_VERIFY_CERTS", "false").lower() == "true"
|
28
29
|
|
29
30
|
config = {
|
30
31
|
"hosts": hosts,
|
31
32
|
"username": username,
|
32
33
|
"password": password,
|
34
|
+
"api_key": api_key,
|
33
35
|
"verify_certs": verify_certs
|
34
36
|
}
|
35
37
|
|
src/clients/base.py
CHANGED
@@ -24,6 +24,7 @@ class SearchClientBase(ABC):
|
|
24
24
|
hosts = config.get("hosts")
|
25
25
|
username = config.get("username")
|
26
26
|
password = config.get("password")
|
27
|
+
api_key = config.get("api_key")
|
27
28
|
verify_certs = config.get("verify_certs", False)
|
28
29
|
|
29
30
|
# Disable insecure request warnings if verify_certs is False
|
@@ -39,8 +40,8 @@ class SearchClientBase(ABC):
|
|
39
40
|
|
40
41
|
# Initialize client based on engine type
|
41
42
|
if engine_type == "elasticsearch":
|
42
|
-
# Get auth parameters based on elasticsearch package version
|
43
|
-
auth_params = self._get_elasticsearch_auth_params(username, password)
|
43
|
+
# Get auth parameters based on elasticsearch package version and authentication method
|
44
|
+
auth_params = self._get_elasticsearch_auth_params(username, password, api_key)
|
44
45
|
|
45
46
|
self.client = Elasticsearch(
|
46
47
|
hosts=hosts,
|
@@ -64,53 +65,67 @@ class SearchClientBase(ABC):
|
|
64
65
|
base_url=base_url,
|
65
66
|
username=username,
|
66
67
|
password=password,
|
68
|
+
api_key=api_key,
|
67
69
|
verify_certs=verify_certs,
|
68
70
|
)
|
69
71
|
|
70
|
-
def _get_elasticsearch_auth_params(self, username: Optional[str], password: Optional[str]) -> Dict:
|
72
|
+
def _get_elasticsearch_auth_params(self, username: Optional[str], password: Optional[str], api_key: Optional[str]) -> Dict:
|
71
73
|
"""
|
72
74
|
Get authentication parameters for Elasticsearch client based on package version.
|
73
75
|
|
74
76
|
Args:
|
75
77
|
username: Username for authentication
|
76
78
|
password: Password for authentication
|
79
|
+
api_key: API key for authentication
|
77
80
|
|
78
81
|
Returns:
|
79
82
|
Dictionary with appropriate auth parameters for the ES version
|
80
83
|
"""
|
84
|
+
# API key takes precedence over username/password
|
85
|
+
if api_key:
|
86
|
+
return {"api_key": api_key}
|
87
|
+
|
81
88
|
if not username or not password:
|
82
89
|
return {}
|
83
90
|
|
84
91
|
# Check Elasticsearch package version to determine auth parameter name
|
85
92
|
try:
|
86
93
|
from elasticsearch import __version__ as es_version
|
87
|
-
major_version =
|
88
|
-
|
94
|
+
major_version = es_version[0]
|
89
95
|
if major_version >= 8:
|
90
96
|
# ES 8+ uses basic_auth
|
91
97
|
return {"basic_auth": (username, password)}
|
92
98
|
else:
|
93
99
|
# ES 7 and below use http_auth
|
94
100
|
return {"http_auth": (username, password)}
|
95
|
-
except
|
101
|
+
except Exception as e:
|
102
|
+
self.logger.error(f"Failed to detect Elasticsearch version: {e}")
|
96
103
|
# If we can't detect version, try basic_auth first (ES 8+ default)
|
97
104
|
return {"basic_auth": (username, password)}
|
98
105
|
|
99
106
|
class GeneralRestClient:
|
100
|
-
def __init__(self, base_url: Optional[str], username: Optional[str], password: Optional[str], verify_certs: bool):
|
107
|
+
def __init__(self, base_url: Optional[str], username: Optional[str], password: Optional[str], api_key: Optional[str], verify_certs: bool):
|
101
108
|
self.base_url = base_url.rstrip("/") if base_url else ""
|
102
109
|
self.auth = (username, password) if username and password else None
|
110
|
+
self.api_key = api_key
|
103
111
|
self.verify_certs = verify_certs
|
104
112
|
|
105
113
|
def request(self, method, path, params=None, body=None):
|
106
114
|
url = f"{self.base_url}/{path.lstrip('/')}"
|
115
|
+
headers = {}
|
116
|
+
|
117
|
+
# Add API key to Authorization header if provided
|
118
|
+
if self.api_key:
|
119
|
+
headers["Authorization"] = f"ApiKey {self.api_key}"
|
120
|
+
|
107
121
|
with httpx.Client(verify=self.verify_certs) as client:
|
108
122
|
resp = client.request(
|
109
123
|
method=method.upper(),
|
110
124
|
url=url,
|
111
125
|
params=params,
|
112
126
|
json=body,
|
113
|
-
auth=self.auth
|
127
|
+
auth=self.auth if not self.api_key else None, # Use basic auth only if no API key
|
128
|
+
headers=headers
|
114
129
|
)
|
115
130
|
resp.raise_for_status()
|
116
131
|
ct = resp.headers.get("content-type", "")
|
src/version.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "2.0.
|
1
|
+
__version__ = "2.0.11"
|
File without changes
|
{opensearch_mcp_server-2.0.9.dist-info → opensearch_mcp_server-2.0.11.dist-info}/entry_points.txt
RENAMED
File without changes
|
{opensearch_mcp_server-2.0.9.dist-info → opensearch_mcp_server-2.0.11.dist-info}/licenses/LICENSE
RENAMED
File without changes
|