{
  "markdown": "# Elasticsearch/OpenSearch MCP Server\n\n[![MseeP.ai Security Assessment Badge](https://mseep.net/pr/cr7258-elasticsearch-mcp-server-badge.png)](https://mseep.ai/app/cr7258-elasticsearch-mcp-server)\n\n[![Trust Score](https://archestra.ai/mcp-catalog/api/badge/quality/cr7258/elasticsearch-mcp-server)](https://archestra.ai/mcp-catalog/cr7258__elasticsearch-mcp-server)\n\n## Overview\n\nA 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.\n\n<a href=\"https://glama.ai/mcp/servers/b3po3delex\"><img width=\"380\" height=\"200\" src=\"https://glama.ai/mcp/servers/b3po3delex/badge\" alt=\"Elasticsearch MCP Server\" /></a>\n\n## Demo\n\nhttps://github.com/user-attachments/assets/f7409e31-fac4-4321-9c94-b0ff2ea7ff15\n\n## Features\n\n### General Operations\n\n- `general_api_request`: Perform a general HTTP API request. Use this tool for any Elasticsearch/OpenSearch API that does not have a dedicated tool.\n\n### Index Operations\n\n- `list_indices`: List all indices.\n- `get_index`: Returns information (mappings, settings, aliases) about one or more indices.\n- `create_index`: Create a new index.\n- `delete_index`: Delete an index.\n- `create_data_stream`: Create a new data stream (requires matching index template).\n- `get_data_stream`: Get information about one or more data streams.\n- `delete_data_stream`: Delete one or more data streams and their backing indices.\n\n### Document Operations\n\n- `search_documents`: Search for documents.\n- `index_document`: Creates or updates a document in the index.\n- `get_document`: Get a document by ID.\n- `delete_document`: Delete a document by ID.\n- `delete_by_query`: Deletes documents matching the provided query.\n\n### Cluster Operations\n\n- `get_cluster_health`: Returns basic information about the health of the cluster.\n- `get_cluster_stats`: Returns high-level overview of cluster statistics.\n\n### Alias Operations\n\n- `list_aliases`: List all aliases.\n- `get_alias`: Get alias information for a specific index.\n- `put_alias`: Create or update an alias for a specific index.\n- `delete_alias`: Delete an alias for a specific index.\n\n### Analyzer Operations\n\n- `analyze_text`: Analyze text using a specified analyzer or custom analysis chain. Useful for debugging search queries and understanding how text is tokenized.\n\n## Configure Environment Variables\n\nThe MCP server supports the following environment variables:\n\n### Basic Authentication (Username/Password)\n- `ELASTICSEARCH_USERNAME`: Username for basic authentication\n- `ELASTICSEARCH_PASSWORD`: Password for basic authentication\n- `OPENSEARCH_USERNAME`: Username for OpenSearch basic authentication\n- `OPENSEARCH_PASSWORD`: Password for OpenSearch basic authentication\n\n### API Key Authentication (Elasticsearch only) - Recommended\n- `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.\n\n### Connection Settings\n- `ELASTICSEARCH_HOSTS` / `OPENSEARCH_HOSTS`: Comma-separated list of hosts (default: `https://localhost:9200`)\n- `ELASTICSEARCH_CLUSTERS` / `OPENSEARCH_CLUSTERS`: Inline JSON object for named cluster configurations. When set, tools can target a specific cluster with the optional `cluster` parameter.\n- `ELASTICSEARCH_CLUSTERS_FILE` / `OPENSEARCH_CLUSTERS_FILE`: Path to a JSON file with the clusters object. Recommended when the configuration is embedded inside another JSON file (e.g. the MCP client config) because it avoids JSON-in-JSON escaping. Takes precedence over the inline variable when both are set.\n- `DEFAULT_CLUSTER`: Default cluster name to use when multi-cluster configuration is set and a tool call omits `cluster` (defaults to the first configured cluster).\n- `VERIFY_CERTS`: Whether to verify SSL certificates (default: `false`)\n- `REQUEST_TIMEOUT`: Request timeout in seconds (optional, uses client default if not set)\n\n### Multiple Cluster Configuration\n\nBy default, the server uses a single Elasticsearch cluster from `ELASTICSEARCH_HOSTS`, `ELASTICSEARCH_USERNAME`, `ELASTICSEARCH_PASSWORD`, and `ELASTICSEARCH_API_KEY`, or a single OpenSearch cluster from `OPENSEARCH_HOSTS`, `OPENSEARCH_USERNAME`, and `OPENSEARCH_PASSWORD`. To configure multiple named clusters, set `ELASTICSEARCH_CLUSTERS` (or `OPENSEARCH_CLUSTERS`) to a JSON object inside the MCP server configuration. Because the value is a JSON string embedded in another JSON file, the inner quotes need to be escaped:\n\n```json\n{\n  \"mcpServers\": {\n    \"elasticsearch-mcp-server\": {\n      \"command\": \"uvx\",\n      \"args\": [\n        \"elasticsearch-mcp-server\"\n      ],\n      \"env\": {\n        \"ELASTICSEARCH_CLUSTERS\": \"{\\\"prod\\\": {\\\"hosts\\\": [\\\"https://prod-es:9200\\\"], \\\"api_key\\\": \\\"<PROD_API_KEY>\\\", \\\"verify_certs\\\": true}, \\\"staging\\\": {\\\"hosts\\\": [\\\"https://staging-es:9200\\\"], \\\"username\\\": \\\"elastic\\\", \\\"password\\\": \\\"<STAGING_PASSWORD>\\\"}}\",\n        \"DEFAULT_CLUSTER\": \"prod\"\n      }\n    }\n  }\n}\n```\n\nFor better readability, point `ELASTICSEARCH_CLUSTERS_FILE` (or `OPENSEARCH_CLUSTERS_FILE`) at a standalone JSON file instead. The value is just a path so it avoids the JSON-in-JSON escaping:\n\n```json\n{\n  \"mcpServers\": {\n    \"elasticsearch-mcp-server\": {\n      \"command\": \"uvx\",\n      \"args\": [\n        \"elasticsearch-mcp-server\"\n      ],\n      \"env\": {\n        \"ELASTICSEARCH_CLUSTERS_FILE\": \"/etc/mcp/es-clusters.json\",\n        \"DEFAULT_CLUSTER\": \"prod\"\n      }\n    }\n  }\n}\n```\n\n`/etc/mcp/es-clusters.json`:\n\n```json\n{\n  \"prod\": {\n    \"hosts\": [\"https://prod-es:9200\"],\n    \"api_key\": \"<PROD_API_KEY>\",\n    \"verify_certs\": true\n  },\n  \"staging\": {\n    \"hosts\": [\"https://staging-es:9200\"],\n    \"username\": \"elastic\",\n    \"password\": \"<STAGING_PASSWORD>\"\n  }\n}\n```\n\nEvery tool accepts an optional `cluster` parameter. If omitted, the server uses `DEFAULT_CLUSTER`. When `DEFAULT_CLUSTER` is not set, the first cluster in the JSON object is used as the default. A tool call targeting a specific cluster looks like:\n\n```json\n{\n  \"cluster\": \"staging\",\n  \"index\": \"logs-*\",\n  \"body\": {\n    \"query\": {\n      \"match_all\": {}\n    }\n  }\n}\n```\n\n### MCP Server Authentication (HTTP Transports Only)\n\nWhen running the MCP server with HTTP-based transports (SSE or Streamable HTTP), you can enable Bearer token authentication to protect the server from unauthorized access.\n\n- `MCP_API_KEY`: API key for MCP server authentication. Clients must include `Authorization: Bearer <MCP_API_KEY>` header.\n\n**Important Security Notes:**\n- Authentication is **only applicable** for HTTP transports (`sse`, `streamable-http`). The `stdio` transport uses local process communication and doesn't require authentication.\n- If `MCP_API_KEY` is **not set**, the MCP server will be accessible **without authentication**. This is a security risk when exposing the server over a network.\n- For production deployments with HTTP transports, **always set `MCP_API_KEY`**.\n\n```bash\n# Generate a secure API key (example using openssl)\nexport MCP_API_KEY=$(openssl rand -base64 32)\n\n# Or set a custom API key\nexport MCP_API_KEY=\"your-secure-api-key-here\"\n```\n\n### Disable High-Risk Operations\n\n- `DISABLE_HIGH_RISK_OPERATIONS`: Set to `true` to disable all write operations (default: `false`)\n- `DISABLE_OPERATIONS`: Comma-separated list of specific operations to disable (optional, uses default write operations list if not set)\n\nWhen `DISABLE_HIGH_RISK_OPERATIONS` is set to true, all MCP tools that perform write operations are completely hidden from the MCP client. In this mode, the following MCP tools are disabled by default.\n\n- **Index Operations:**\n  - `create_index`\n  - `delete_index`\n  \n- **Document Operations:**\n  - `index_document`\n  - `delete_document`\n  - `delete_by_query`\n  \n- **Data Stream Operations:**\n  - `create_data_stream`\n  - `delete_data_stream`\n  \n- **Alias Operations:**\n  - `put_alias`\n  - `delete_alias`\n  \n- **General API Operations:**\n  - `general_api_request`\n\nOptionally, you can specify a comma-separated list of operations to disable in the `DISABLE_OPERATIONS` environment variable.\n\n```bash\n# Disable High-Risk Operations\nexport DISABLE_HIGH_RISK_OPERATIONS=true\n# Disable specific operations only\nexport DISABLE_OPERATIONS=\"delete_index,delete_document,delete_by_query\"\n```\n\n### GCF Response Encoding (optional)\n\nOpt in to serialize tool-result payloads as [GCF](https://gcformat.com/) (Graph Compact Format), a token-optimized wire format, in the content block the model reads. Elasticsearch returns large, uniform record sets (search hits, aggregation buckets, mappings), the shape GCF compacts best: on representative responses it is **~39% fewer tokens than compact JSON** (40% on search hits), losslessly.\n\n```bash\nexport RESPONSE_FORMAT=gcf\n```\n\n`structuredContent` is preserved unchanged, so a tool's declared output schema still validates and any non-model client keeps receiving JSON; only the model-facing text block is re-encoded. Encoding is fail-safe: any error, including a value outside GCF's canonical `int64` numeric domain (which GCF rejects rather than silently approximating), leaves the original JSON result untouched, so a tool call is never dropped over encoding. Default behavior is unchanged when `RESPONSE_FORMAT` is unset.\n\nReproduce the token comparison: `uv run --with tiktoken python benchmarks/gcf_benchmark.py`.\n\n## Start Elasticsearch/OpenSearch Cluster\n\nStart the Elasticsearch/OpenSearch cluster using Docker Compose:\n\n```bash\n# For Elasticsearch\ndocker-compose -f docker-compose-elasticsearch.yml up -d\n\n# For OpenSearch\ndocker-compose -f docker-compose-opensearch.yml up -d\n```\n\nThe default Elasticsearch username is `elastic` and password is `test123`. The default OpenSearch username is `admin` and password is `admin`.\n\nYou can access Kibana/OpenSearch Dashboards from http://localhost:5601.\n\n## Stdio\n\n### Option 1: Using uvx\n\nUsing `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`.\n\n```json\n// For Elasticsearch with username/password\n{\n  \"mcpServers\": {\n    \"elasticsearch-mcp-server\": {\n      \"command\": \"uvx\",\n      \"args\": [\n        \"elasticsearch-mcp-server\"\n      ],\n      \"env\": {\n        \"ELASTICSEARCH_HOSTS\": \"https://localhost:9200\",\n        \"ELASTICSEARCH_USERNAME\": \"elastic\",\n        \"ELASTICSEARCH_PASSWORD\": \"test123\"\n      }\n    }\n  }\n}\n\n// For Elasticsearch with API key\n{\n  \"mcpServers\": {\n    \"elasticsearch-mcp-server\": {\n      \"command\": \"uvx\",\n      \"args\": [\n        \"elasticsearch-mcp-server\"\n      ],\n      \"env\": {\n        \"ELASTICSEARCH_HOSTS\": \"https://localhost:9200\",\n        \"ELASTICSEARCH_API_KEY\": \"<YOUR_ELASTICSEARCH_API_KEY>\"\n      }\n    }\n  }\n}\n\n// For OpenSearch\n{\n  \"mcpServers\": {\n    \"opensearch-mcp-server\": {\n      \"command\": \"uvx\",\n      \"args\": [\n        \"opensearch-mcp-server\"\n      ],\n      \"env\": {\n        \"OPENSEARCH_HOSTS\": \"https://localhost:9200\",\n        \"OPENSEARCH_USERNAME\": \"admin\",\n        \"OPENSEARCH_PASSWORD\": \"admin\"\n      }\n    }\n  }\n}\n```\n\n### Option 2: Using uv with local development\n\nUsing `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`.\n\n```json\n// For Elasticsearch with username/password\n{\n  \"mcpServers\": {\n    \"elasticsearch-mcp-server\": {\n      \"command\": \"uv\",\n      \"args\": [\n        \"--directory\",\n        \"path/to/elasticsearch-mcp-server\",\n        \"run\",\n        \"elasticsearch-mcp-server\"\n      ],\n      \"env\": {\n        \"ELASTICSEARCH_HOSTS\": \"https://localhost:9200\",\n        \"ELASTICSEARCH_USERNAME\": \"elastic\",\n        \"ELASTICSEARCH_PASSWORD\": \"test123\"\n      }\n    }\n  }\n}\n\n// For Elasticsearch with API key\n{\n  \"mcpServers\": {\n    \"elasticsearch-mcp-server\": {\n      \"command\": \"uv\",\n      \"args\": [\n        \"--directory\",\n        \"path/to/elasticsearch-mcp-server\",\n        \"run\",\n        \"elasticsearch-mcp-server\"\n      ],\n      \"env\": {\n        \"ELASTICSEARCH_HOSTS\": \"https://localhost:9200\",\n        \"ELASTICSEARCH_API_KEY\": \"<YOUR_ELASTICSEARCH_API_KEY>\"\n      }\n    }\n  }\n}\n\n// For OpenSearch\n{\n  \"mcpServers\": {\n    \"opensearch-mcp-server\": {\n      \"command\": \"uv\",\n      \"args\": [\n        \"--directory\",\n        \"path/to/elasticsearch-mcp-server\",\n        \"run\",\n        \"opensearch-mcp-server\"\n      ],\n      \"env\": {\n        \"OPENSEARCH_HOSTS\": \"https://localhost:9200\",\n        \"OPENSEARCH_USERNAME\": \"admin\",\n        \"OPENSEARCH_PASSWORD\": \"admin\"\n      }\n    }\n  }\n}\n```\n\n## SSE\n\n### Option 1: Using uvx\n\n```bash\n# export environment variables (with username/password)\nexport ELASTICSEARCH_HOSTS=\"https://localhost:9200\"\nexport ELASTICSEARCH_USERNAME=\"elastic\"\nexport ELASTICSEARCH_PASSWORD=\"test123\"\n\n# OR export environment variables (with API key)\nexport ELASTICSEARCH_HOSTS=\"https://localhost:9200\"\nexport ELASTICSEARCH_API_KEY=\"<YOUR_ELASTICSEARCH_API_KEY>\"\n\n# By default, the SSE MCP server will serve on http://127.0.0.1:8000/sse\nuvx elasticsearch-mcp-server --transport sse\n\n# The host, port, and path can be specified using the --host, --port, and --path options\nuvx elasticsearch-mcp-server --transport sse --host 0.0.0.0 --port 8000 --path /sse\n```\n\n### Option 2: Using uv\n\n```bash\n# By default, the SSE MCP server will serve on http://127.0.0.1:8000/sse\nuv run src/server.py elasticsearch-mcp-server --transport sse\n\n# The host, port, and path can be specified using the --host, --port, and --path options\nuv run src/server.py elasticsearch-mcp-server --transport sse --host 0.0.0.0 --port 8000 --path /sse\n```\n\n## Streamable HTTP\n\n### Option 1: Using uvx\n\n```bash\n# export environment variables (with username/password)\nexport ELASTICSEARCH_HOSTS=\"https://localhost:9200\"\nexport ELASTICSEARCH_USERNAME=\"elastic\"\nexport ELASTICSEARCH_PASSWORD=\"test123\"\n\n# OR export environment variables (with API key)\nexport ELASTICSEARCH_HOSTS=\"https://localhost:9200\"\nexport ELASTICSEARCH_API_KEY=\"<YOUR_ELASTICSEARCH_API_KEY>\"\n\n# By default, the Streamable HTTP MCP server will serve on http://127.0.0.1:8000/mcp\nuvx elasticsearch-mcp-server --transport streamable-http\n\n# The host, port, and path can be specified using the --host, --port, and --path options\nuvx elasticsearch-mcp-server --transport streamable-http --host 0.0.0.0 --port 8000 --path /mcp\n```\n\n### Option 2: Using uv\n\n```bash\n# By default, the Streamable HTTP MCP server will serve on http://127.0.0.1:8000/mcp\nuv run src/server.py elasticsearch-mcp-server --transport streamable-http\n\n# The host, port, and path can be specified using the --host, --port, and --path options\nuv run src/server.py elasticsearch-mcp-server --transport streamable-http --host 0.0.0.0 --port 8000 --path /mcp\n```\n\n## Compatibility\n\nThe 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).\n\n| MCP Server | Elasticsearch |\n| --- | --- |\n| elasticsearch-mcp-server-es7 | Elasticsearch 7.x |\n| elasticsearch-mcp-server | Elasticsearch 8.x |\n| elasticsearch-mcp-server-es9 | Elasticsearch 9.x |\n| opensearch-mcp-server | OpenSearch 1.x, 2.x, 3.x |\n\n 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:\n\n```bash\nuvx elasticsearch-mcp-server-es7\n```\n\nIf you want to run different Elasticsearch variants (e.g., 7.x or 9.x) locally, simply update the `elasticsearch` dependency version in `pyproject.toml`, then start the server with:\n\n```bash\nuv run src/server.py elasticsearch-mcp-server\n```\n\n## Kubernetes Deployment\n\nThe Docker image is published to `ghcr.io/cr7258/elasticsearch-mcp-server` and the Helm chart is available as an OCI artifact at `oci://ghcr.io/cr7258/charts/elasticsearch-mcp-server` repository.\n\nFor full installation instructions, configuration reference, and usage examples see the **[Helm chart README](helm/elasticsearch-mcp-server/README.md)**.\n\n## License\n\nThis project is licensed under the Apache License Version 2.0 - see the [LICENSE](LICENSE) file for details.\n",
  "bytes": 16254,
  "sha": "79973d651de221e466d1207cb2847ffce2e3901d0c2c81e3a1b28f98a1355ffc",
  "repo_slug": "cr7258/elasticsearch-mcp-server",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_cr7258_elasticsearch_mcp_serve_1df0ace2/readme"
}