opensearch-mcp-server 2.0.2__tar.gz → 2.0.4__tar.gz

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.
Files changed (53) hide show
  1. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/Makefile +3 -2
  2. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/PKG-INFO +5 -1
  3. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/README.md +4 -0
  4. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/pyproject.toml +1 -1
  5. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/src/clients/base.py +35 -2
  6. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/src/clients/common/client.py +2 -1
  7. opensearch_mcp_server-2.0.4/src/clients/common/general.py +10 -0
  8. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/src/server.py +5 -2
  9. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/src/tools/__init__.py +8 -6
  10. opensearch_mcp_server-2.0.4/src/tools/general.py +20 -0
  11. opensearch_mcp_server-2.0.4/src/version.py +1 -0
  12. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/uv.lock +298 -298
  13. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/.env.example +0 -0
  14. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/.github/workflows/pypi-publish.yaml +0 -0
  15. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/.github/workflows/release.yml +0 -0
  16. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/.gitignore +0 -0
  17. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/.python-version +0 -0
  18. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/CONTRIBUTING.md +0 -0
  19. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/Dockerfile +0 -0
  20. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/LICENSE +0 -0
  21. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/cliff.toml +0 -0
  22. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/docker-compose-elasticsearch.yml +0 -0
  23. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/docker-compose-opensearch.yml +0 -0
  24. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/mcp_client/python-sdk-anthropic/.gitignore +0 -0
  25. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/mcp_client/python-sdk-anthropic/__init__.py +0 -0
  26. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/mcp_client/python-sdk-anthropic/client.py +0 -0
  27. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/mcp_client/python-sdk-anthropic/config.py +0 -0
  28. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/mcp_client/spring-ai/README.md +0 -0
  29. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/mcp_client/spring-ai/build.gradle +0 -0
  30. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/mcp_client/spring-ai/gradle/wrapper/gradle-wrapper.jar +0 -0
  31. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/mcp_client/spring-ai/gradle/wrapper/gradle-wrapper.properties +0 -0
  32. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/mcp_client/spring-ai/gradle.properties +0 -0
  33. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/mcp_client/spring-ai/gradlew +0 -0
  34. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/mcp_client/spring-ai/gradlew.bat +0 -0
  35. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/mcp_client/spring-ai/settings.gradle +0 -0
  36. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/mcp_client/spring-ai/src/main/java/spring/ai/mcp/spring_ai_mcp/Application.java +0 -0
  37. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/mcp_client/spring-ai/src/main/resources/application.yml +0 -0
  38. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/mcp_client/spring-ai/src/main/resources/mcp-servers-config.json +0 -0
  39. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/mcp_client/spring-ai/src/test/java/spring/ai/mcp/spring_ai_mcp/SpringAiMcpApplicationTests.java +0 -0
  40. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/smithery.yaml +0 -0
  41. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/src/__init__.py +0 -0
  42. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/src/clients/__init__.py +0 -0
  43. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/src/clients/common/__init__.py +0 -0
  44. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/src/clients/common/alias.py +0 -0
  45. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/src/clients/common/cluster.py +0 -0
  46. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/src/clients/common/document.py +0 -0
  47. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/src/clients/common/index.py +0 -0
  48. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/src/clients/exceptions.py +0 -0
  49. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/src/tools/alias.py +0 -0
  50. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/src/tools/cluster.py +0 -0
  51. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/src/tools/document.py +0 -0
  52. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/src/tools/index.py +0 -0
  53. {opensearch_mcp_server-2.0.2 → opensearch_mcp_server-2.0.4}/src/tools/register.py +0 -0
@@ -10,9 +10,10 @@ release:
10
10
  data = tomli.load(open("pyproject.toml", "rb")); \
11
11
  data["project"]["version"] = "$(version:v%=%)"; \
12
12
  tomli_w.dump(data, open("pyproject.toml", "wb"))'
13
- @git add pyproject.toml
14
- @git commit -m "release: update version to $(version:v%=%)"
13
+ @python -c 'open("src/version.py", "w").write("__version__ = \"$(version:v%=%)\"\n")'
15
14
  @uv sync
15
+ @git add .
16
+ @git commit -m "release: update version to $(version:v%=%)"
16
17
  @git push origin main
17
18
  @git tag $(version)
18
19
  @git push origin $(version)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opensearch-mcp-server
3
- Version: 2.0.2
3
+ Version: 2.0.4
4
4
  Summary: MCP Server for interacting with Elasticsearch and OpenSearch
5
5
  License: Apache License
6
6
  Version 2.0, January 2004
@@ -231,6 +231,10 @@ https://github.com/user-attachments/assets/f7409e31-fac4-4321-9c94-b0ff2ea7ff15
231
231
 
232
232
  ## Features
233
233
 
234
+ ### General Operations
235
+
236
+ - `general_api_request`: Perform a general HTTP API request. Use this tool for any Elasticsearch/OpenSearch API that does not have a dedicated tool.
237
+
234
238
  ### Index Operations
235
239
 
236
240
  - `list_indices`: List all indices.
@@ -14,6 +14,10 @@ https://github.com/user-attachments/assets/f7409e31-fac4-4321-9c94-b0ff2ea7ff15
14
14
 
15
15
  ## Features
16
16
 
17
+ ### General Operations
18
+
19
+ - `general_api_request`: Perform a general HTTP API request. Use this tool for any Elasticsearch/OpenSearch API that does not have a dedicated tool.
20
+
17
21
  ### Index Operations
18
22
 
19
23
  - `list_indices`: List all indices.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "opensearch-mcp-server"
3
- version = "2.0.2"
3
+ version = "2.0.4"
4
4
  description = "MCP Server for interacting with Elasticsearch and OpenSearch"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -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
@@ -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)
@@ -7,8 +7,10 @@ from src.clients import create_search_client
7
7
  from src.tools.alias import AliasTools
8
8
  from src.tools.cluster import ClusterTools
9
9
  from src.tools.document import DocumentTools
10
+ from src.tools.general import GeneralTools
10
11
  from src.tools.index import IndexTools
11
12
  from src.tools.register import ToolsRegister
13
+ from src.version import __version__ as VERSION
12
14
 
13
15
  class SearchMCPServer:
14
16
  def __init__(self, engine_type):
@@ -17,7 +19,7 @@ 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.logger.info(f"Initializing {self.name}...")
22
+ self.logger.info(f"Initializing {self.name}, Version: {VERSION}")
21
23
 
22
24
  # Create the corresponding search client
23
25
  self.search_client = create_search_client(self.engine_type)
@@ -35,7 +37,8 @@ class SearchMCPServer:
35
37
  IndexTools,
36
38
  DocumentTools,
37
39
  ClusterTools,
38
- AliasTools
40
+ AliasTools,
41
+ GeneralTools,
39
42
  ]
40
43
  # Register all tools
41
44
  register.register_all_tools(tool_classes)
@@ -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
  ]
@@ -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)
@@ -0,0 +1 @@
1
+ __version__ = "2.0.4"