opensearch-mcp-server 2.0.2__py3-none-any.whl → 2.0.3__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.2.dist-info → opensearch_mcp_server-2.0.3.dist-info}/METADATA +6 -1
- {opensearch_mcp_server-2.0.2.dist-info → opensearch_mcp_server-2.0.3.dist-info}/RECORD +11 -9
- src/clients/base.py +35 -2
- src/clients/common/client.py +2 -1
- src/clients/common/general.py +10 -0
- src/server.py +6 -2
- src/tools/__init__.py +8 -6
- src/tools/general.py +20 -0
- {opensearch_mcp_server-2.0.2.dist-info → opensearch_mcp_server-2.0.3.dist-info}/WHEEL +0 -0
- {opensearch_mcp_server-2.0.2.dist-info → opensearch_mcp_server-2.0.3.dist-info}/entry_points.txt +0 -0
- {opensearch_mcp_server-2.0.2.dist-info → opensearch_mcp_server-2.0.3.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.3
|
4
4
|
Summary: MCP Server for interacting with Elasticsearch and OpenSearch
|
5
5
|
License: Apache License
|
6
6
|
Version 2.0, January 2004
|
@@ -211,6 +211,7 @@ Requires-Dist: fastmcp==0.4.1
|
|
211
211
|
Requires-Dist: mcp==1.6.0
|
212
212
|
Requires-Dist: opensearch-py==2.8.0
|
213
213
|
Requires-Dist: python-dotenv==1.1.0
|
214
|
+
Requires-Dist: toml==0.10.2
|
214
215
|
Requires-Dist: tomli-w==1.2.0
|
215
216
|
Requires-Dist: tomli==2.2.1
|
216
217
|
Description-Content-Type: text/markdown
|
@@ -231,6 +232,10 @@ https://github.com/user-attachments/assets/f7409e31-fac4-4321-9c94-b0ff2ea7ff15
|
|
231
232
|
|
232
233
|
## Features
|
233
234
|
|
235
|
+
### General Operations
|
236
|
+
|
237
|
+
- `general_api_request`: Perform a general HTTP API request. Use this tool for any Elasticsearch/OpenSearch API that does not have a dedicated tool.
|
238
|
+
|
234
239
|
### Index Operations
|
235
240
|
|
236
241
|
- `list_indices`: List all indices.
|
@@ -1,22 +1,24 @@
|
|
1
1
|
src/__init__.py,sha256=aNKcThftSLh9IjOTA-UUpoRzIm4R0WwXKGAzykwecmU,211
|
2
|
-
src/server.py,sha256=
|
2
|
+
src/server.py,sha256=2EyBWtdAIct-L589FXhxTfQswsgo9nusC9ZORVfwXWU,2330
|
3
3
|
src/clients/__init__.py,sha256=3UezAt9422S-7BvMiCo2Y9pmATVutorwsIQXP_g_CkA,1221
|
4
|
-
src/clients/base.py,sha256=
|
4
|
+
src/clients/base.py,sha256=MBAGepXyHPtdbtHhxFB8CamZ2ApWCBuOi_6-ey-MqX8,3298
|
5
5
|
src/clients/exceptions.py,sha256=NYF3KVw-9aAgCViin5OuBI6miMEPS5QsdHx6bcis1wc,2493
|
6
6
|
src/clients/common/__init__.py,sha256=VgvgxFpESn2wAuJmH0XM_Ej2izI7dxK7QJe9wG4fmW0,211
|
7
7
|
src/clients/common/alias.py,sha256=rB53TSld5x2vZyDNAwyEdnh1KWUXMSD7h5fSv_ubR2Q,759
|
8
|
-
src/clients/common/client.py,sha256=
|
8
|
+
src/clients/common/client.py,sha256=khRO3osowTvoXnPscefUSuBYMrhOao2urOnRwqiUMbI,1041
|
9
9
|
src/clients/common/cluster.py,sha256=pd5BVpqqDU6Lck3K704eEdhgFgzt9NstotWQLyG9zFM,401
|
10
10
|
src/clients/common/document.py,sha256=ZzZiXDf_UhlN2FCmqW3drVjIZ07kGYP9yth_sgsJGPc,1623
|
11
|
+
src/clients/common/general.py,sha256=_1eS11Ha-JC1x1YoSu63zUWXKvYkwvN8RQOUM1fx39M,469
|
11
12
|
src/clients/common/index.py,sha256=vyH5iXlJe5JLcDK6fhCCEPN-tgGm6zP5ilwGPdWCXbY,776
|
12
|
-
src/tools/__init__.py,sha256=
|
13
|
+
src/tools/__init__.py,sha256=PGsXXpPubVnUbzXJG4keDhgjr0j6EnMNDs0aLqNIb4A,387
|
13
14
|
src/tools/alias.py,sha256=p9TD4gXkGRGWHTYfvCg7G2hj-Uch9jwDXJNUY1hSD0Y,1376
|
14
15
|
src/tools/cluster.py,sha256=XRAG-uxdfrieYX1ov_cBb66IYXaa8OoSWCUfXvNauy0,587
|
15
16
|
src/tools/document.py,sha256=XZTVuk4di9VEwWMZN7jyDVnzoOiXkb4FBrXF44sVXTs,2052
|
17
|
+
src/tools/general.py,sha256=whj1spjIb8SS75h843X6c3RTsrZcSm-66KVLlY7OEh0,817
|
16
18
|
src/tools/index.py,sha256=7KNPtElTFelkjRSvdMqPBx9nx_9Uk01OnTMeVo7YeCs,1345
|
17
19
|
src/tools/register.py,sha256=wrG2P6-YPW77bTg1j_ELp8omWRYsJjFeOHUy_unHe6Y,1344
|
18
|
-
opensearch_mcp_server-2.0.
|
19
|
-
opensearch_mcp_server-2.0.
|
20
|
-
opensearch_mcp_server-2.0.
|
21
|
-
opensearch_mcp_server-2.0.
|
22
|
-
opensearch_mcp_server-2.0.
|
20
|
+
opensearch_mcp_server-2.0.3.dist-info/METADATA,sha256=OFMMCH1mufu1PkUACANPjp0fzWu3NSTtH6gVccB67r4,18716
|
21
|
+
opensearch_mcp_server-2.0.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
22
|
+
opensearch_mcp_server-2.0.3.dist-info/entry_points.txt,sha256=ImfJnUwMpQUBmu-1MeBG_P0dwamfXKQh82mBKW7tWNY,138
|
23
|
+
opensearch_mcp_server-2.0.3.dist-info/licenses/LICENSE,sha256=DBsjuP5FR51d9kaUdXlVBuBv3cQ_I_adq9gefYQ9FcY,11339
|
24
|
+
opensearch_mcp_server-2.0.3.dist-info/RECORD,,
|
src/clients/base.py
CHANGED
@@ -3,6 +3,10 @@ import logging
|
|
3
3
|
import warnings
|
4
4
|
from typing import Dict
|
5
5
|
|
6
|
+
from elasticsearch import Elasticsearch
|
7
|
+
import httpx
|
8
|
+
from opensearchpy import OpenSearch
|
9
|
+
|
6
10
|
class SearchClientBase(ABC):
|
7
11
|
def __init__(self, config: Dict, engine_type: str):
|
8
12
|
"""
|
@@ -35,7 +39,6 @@ class SearchClientBase(ABC):
|
|
35
39
|
|
36
40
|
# Initialize client based on engine type
|
37
41
|
if engine_type == "elasticsearch":
|
38
|
-
from elasticsearch import Elasticsearch
|
39
42
|
self.client = Elasticsearch(
|
40
43
|
hosts=hosts,
|
41
44
|
basic_auth=(username, password) if username and password else None,
|
@@ -43,7 +46,6 @@ class SearchClientBase(ABC):
|
|
43
46
|
)
|
44
47
|
self.logger.info(f"Elasticsearch client initialized with hosts: {hosts}")
|
45
48
|
elif engine_type == "opensearch":
|
46
|
-
from opensearchpy import OpenSearch
|
47
49
|
self.client = OpenSearch(
|
48
50
|
hosts=hosts,
|
49
51
|
http_auth=(username, password) if username and password else None,
|
@@ -52,3 +54,34 @@ class SearchClientBase(ABC):
|
|
52
54
|
self.logger.info(f"OpenSearch client initialized with hosts: {hosts}")
|
53
55
|
else:
|
54
56
|
raise ValueError(f"Unsupported engine type: {engine_type}")
|
57
|
+
|
58
|
+
# General REST client
|
59
|
+
base_url = hosts[0] if isinstance(hosts, list) else hosts
|
60
|
+
self.general_client = GeneralRestClient(
|
61
|
+
base_url=base_url,
|
62
|
+
username=username,
|
63
|
+
password=password,
|
64
|
+
verify_certs=verify_certs,
|
65
|
+
)
|
66
|
+
|
67
|
+
class GeneralRestClient:
|
68
|
+
def __init__(self, base_url: str, username: str, password: str, verify_certs: bool):
|
69
|
+
self.base_url = base_url.rstrip("/")
|
70
|
+
self.auth = (username, password) if username and password else None
|
71
|
+
self.verify_certs = verify_certs
|
72
|
+
|
73
|
+
def request(self, method, path, params=None, body=None):
|
74
|
+
url = f"{self.base_url}/{path.lstrip('/')}"
|
75
|
+
with httpx.Client(verify=self.verify_certs) as client:
|
76
|
+
resp = client.request(
|
77
|
+
method=method.upper(),
|
78
|
+
url=url,
|
79
|
+
params=params,
|
80
|
+
json=body,
|
81
|
+
auth=self.auth
|
82
|
+
)
|
83
|
+
resp.raise_for_status()
|
84
|
+
ct = resp.headers.get("content-type", "")
|
85
|
+
if ct.startswith("application/json"):
|
86
|
+
return resp.json()
|
87
|
+
return resp.text
|
src/clients/common/client.py
CHANGED
@@ -3,9 +3,10 @@ from typing import Dict
|
|
3
3
|
from src.clients.common.alias import AliasClient
|
4
4
|
from src.clients.common.cluster import ClusterClient
|
5
5
|
from src.clients.common.document import DocumentClient
|
6
|
+
from src.clients.common.general import GeneralClient
|
6
7
|
from src.clients.common.index import IndexClient
|
7
8
|
|
8
|
-
class SearchClient(IndexClient, DocumentClient, ClusterClient, AliasClient):
|
9
|
+
class SearchClient(IndexClient, DocumentClient, ClusterClient, AliasClient, GeneralClient):
|
9
10
|
"""
|
10
11
|
Unified search client that combines all search functionality.
|
11
12
|
|
@@ -0,0 +1,10 @@
|
|
1
|
+
from typing import Dict, Optional
|
2
|
+
|
3
|
+
from src.clients.base import SearchClientBase
|
4
|
+
|
5
|
+
class GeneralClient(SearchClientBase):
|
6
|
+
def general_api_request(self, method: str, path: str, params: Optional[Dict] = None, body: Optional[Dict] = None):
|
7
|
+
"""Perform a general HTTP API request.
|
8
|
+
Use this tool for any Elasticsearch/OpenSearch API that does not have a dedicated tool.
|
9
|
+
"""
|
10
|
+
return self.general_client.request(method, path, params, body)
|
src/server.py
CHANGED
@@ -2,11 +2,13 @@ import logging
|
|
2
2
|
import sys
|
3
3
|
|
4
4
|
from fastmcp import FastMCP
|
5
|
+
import toml
|
5
6
|
|
6
7
|
from src.clients import create_search_client
|
7
8
|
from src.tools.alias import AliasTools
|
8
9
|
from src.tools.cluster import ClusterTools
|
9
10
|
from src.tools.document import DocumentTools
|
11
|
+
from src.tools.general import GeneralTools
|
10
12
|
from src.tools.index import IndexTools
|
11
13
|
from src.tools.register import ToolsRegister
|
12
14
|
|
@@ -17,7 +19,8 @@ class SearchMCPServer:
|
|
17
19
|
self.name = f"{self.engine_type}_mcp_server"
|
18
20
|
self.mcp = FastMCP(self.name)
|
19
21
|
self.logger = logging.getLogger()
|
20
|
-
self.
|
22
|
+
self.version = toml.load("pyproject.toml")["project"]["version"]
|
23
|
+
self.logger.info(f"Initializing {self.name}, Version: {self.version}")
|
21
24
|
|
22
25
|
# Create the corresponding search client
|
23
26
|
self.search_client = create_search_client(self.engine_type)
|
@@ -35,7 +38,8 @@ class SearchMCPServer:
|
|
35
38
|
IndexTools,
|
36
39
|
DocumentTools,
|
37
40
|
ClusterTools,
|
38
|
-
AliasTools
|
41
|
+
AliasTools,
|
42
|
+
GeneralTools,
|
39
43
|
]
|
40
44
|
# Register all tools
|
41
45
|
register.register_all_tools(tool_classes)
|
src/tools/__init__.py
CHANGED
@@ -1,13 +1,15 @@
|
|
1
|
-
from src.tools.index import IndexTools
|
2
|
-
from src.tools.document import DocumentTools
|
3
|
-
from src.tools.cluster import ClusterTools
|
4
1
|
from src.tools.alias import AliasTools
|
2
|
+
from src.tools.cluster import ClusterTools
|
3
|
+
from src.tools.document import DocumentTools
|
4
|
+
from src.tools.general import GeneralTools
|
5
|
+
from src.tools.index import IndexTools
|
5
6
|
from src.tools.register import ToolsRegister
|
6
7
|
|
7
8
|
__all__ = [
|
8
|
-
'IndexTools',
|
9
|
-
'DocumentTools',
|
10
|
-
'ClusterTools',
|
11
9
|
'AliasTools',
|
10
|
+
'ClusterTools',
|
11
|
+
'DocumentTools',
|
12
|
+
'GeneralTools',
|
13
|
+
'IndexTools',
|
12
14
|
'ToolsRegister',
|
13
15
|
]
|
src/tools/general.py
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
from typing import Dict, Optional
|
2
|
+
|
3
|
+
from fastmcp import FastMCP
|
4
|
+
|
5
|
+
class GeneralTools:
|
6
|
+
def __init__(self, search_client):
|
7
|
+
self.search_client = search_client
|
8
|
+
def register_tools(self, mcp: FastMCP):
|
9
|
+
@mcp.tool()
|
10
|
+
def general_api_request(method: str, path: str, params: Optional[Dict] = None, body: Optional[Dict] = None):
|
11
|
+
"""Perform a general HTTP API request.
|
12
|
+
Use this tool for any Elasticsearch/OpenSearch API that does not have a dedicated tool.
|
13
|
+
|
14
|
+
Args:
|
15
|
+
method: HTTP method (GET, POST, PUT, DELETE, etc.)
|
16
|
+
path: API endpoint path
|
17
|
+
params: Query parameters
|
18
|
+
body: Request body
|
19
|
+
"""
|
20
|
+
return self.search_client.general_api_request(method, path, params, body)
|
File without changes
|
{opensearch_mcp_server-2.0.2.dist-info → opensearch_mcp_server-2.0.3.dist-info}/entry_points.txt
RENAMED
File without changes
|
{opensearch_mcp_server-2.0.2.dist-info → opensearch_mcp_server-2.0.3.dist-info}/licenses/LICENSE
RENAMED
File without changes
|