trackmcp
Back to directory
cr7258

elasticsearch-mcp-server

View on GitHub

A Model Context Protocol (MCP) server implementation that provides Elasticsearch and OpenSearch interaction. Python-based implementation.

213 stars PythonSearch & Data Retrieval Updated Oct 17, 2025

Documentation

Elasticsearch/OpenSearch MCP Server

MseeP.ai Security Assessment Badge
Trust Score

Overview

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.

Demo

https://github.com/user-attachments/assets/f7409e31-fac4-4321-9c94-b0ff2ea7ff15

Features

General Operations

  • `general_api_request`: Perform a general HTTP API request. Use this tool for any Elasticsearch/OpenSearch API that does not have a dedicated tool.

Index Operations

  • `list_indices`: List all indices.
  • `get_index`: Returns information (mappings, settings, aliases) about one or more indices.
  • `create_index`: Create a new index.
  • `delete_index`: Delete an index.
  • `create_data_stream`: Create a new data stream (requires matching index template).
  • `get_data_stream`: Get information about one or more data streams.
  • `delete_data_stream`: Delete one or more data streams and their backing indices.

Document Operations

  • `search_documents`: Search for documents.
  • `index_document`: Creates or updates a document in the index.
  • `get_document`: Get a document by ID.
  • `delete_document`: Delete a document by ID.
  • `delete_by_query`: Deletes documents matching the provided query.

Cluster Operations

  • `get_cluster_health`: Returns basic information about the health of the cluster.
  • `get_cluster_stats`: Returns high-level overview of cluster statistics.

Alias Operations

  • `list_aliases`: List all aliases.
  • `get_alias`: Get alias information for a specific index.
  • `put_alias`: Create or update an alias for a specific index.
  • `delete_alias`: Delete an alias for a specific index.

Analyzer Operations

  • `analyze_text`: Analyze text using a specified analyzer or custom analysis chain. Useful for debugging search queries and understanding how text is tokenized.

Configure Environment Variables

The MCP server supports the following environment variables:

Basic Authentication (Username/Password)

  • `ELASTICSEARCH_USERNAME`: Username for basic authentication
  • `ELASTICSEARCH_PASSWORD`: Password for basic authentication
  • `OPENSEARCH_USERNAME`: Username for OpenSearch basic authentication
  • `OPENSEARCH_PASSWORD`: Password for OpenSearch basic authentication

Connection Settings

  • `ELASTICSEARCH_HOSTS` / `OPENSEARCH_HOSTS`: Comma-separated list of hosts (default: `https://localhost:9200`)
  • `ELASTICSEARCH_CLUSTERS` / `OPENSEARCH_CLUSTERS`: Inline JSON object for named cluster configurations. When set, tools can target a specific cluster with the optional `cluster` parameter.
  • `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.
  • `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).
  • `VERIFY_CERTS`: Whether to verify SSL certificates (default: `false`)
  • `REQUEST_TIMEOUT`: Request timeout in seconds (optional, uses client default if not set)

Multiple Cluster Configuration

By 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:

json
{
  "mcpServers": {
    "elasticsearch-mcp-server": {
      "command": "uvx",
      "args": [
        "elasticsearch-mcp-server"
      ],
      "env": {
        "ELASTICSEARCH_CLUSTERS": "{\"prod\": {\"hosts\": [\"https://prod-es:9200\"], \"api_key\": \"\", \"verify_certs\": true}, \"staging\": {\"hosts\": [\"https://staging-es:9200\"], \"username\": \"elastic\", \"password\": \"\"}}",
        "DEFAULT_CLUSTER": "prod"
      }
    }
  }
}

For 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:

json
{
  "mcpServers": {
    "elasticsearch-mcp-server": {
      "command": "uvx",
      "args": [
        "elasticsearch-mcp-server"
      ],
      "env": {
        "ELASTICSEARCH_CLUSTERS_FILE": "/etc/mcp/es-clusters.json",
        "DEFAULT_CLUSTER": "prod"
      }
    }
  }
}

`/etc/mcp/es-clusters.json`:

json
{
  "prod": {
    "hosts": ["https://prod-es:9200"],
    "api_key": "",
    "verify_certs": true
  },
  "staging": {
    "hosts": ["https://staging-es:9200"],
    "username": "elastic",
    "password": ""
  }
}

Every 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:

json
{
  "cluster": "staging",
  "index": "logs-*",
  "body": {
    "query": {
      "match_all": {}
    }
  }
}

MCP Server Authentication (HTTP Transports Only)

When 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.

  • `MCP_API_KEY`: API key for MCP server authentication. Clients must include `Authorization: Bearer ` header.

Important Security Notes:

  • Authentication is only applicable for HTTP transports (`sse`, `streamable-http`). The `stdio` transport uses local process communication and doesn't require authentication.
  • 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.
  • For production deployments with HTTP transports, always set `MCP_API_KEY`.
bash
# Generate a secure API key (example using openssl)
export MCP_API_KEY=$(openssl rand -base64 32)

# Or set a custom API key
export MCP_API_KEY="your-secure-api-key-here"

Disable High-Risk Operations

  • `DISABLE_HIGH_RISK_OPERATIONS`: Set to `true` to disable all write operations (default: `false`)
  • `DISABLE_OPERATIONS`: Comma-separated list of specific operations to disable (optional, uses default write operations list if not set)

When `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.

  • Index Operations:
    • `create_index`
    • `delete_index`
  • Document Operations:
    • `index_document`
    • `delete_document`
    • `delete_by_query`
  • Data Stream Operations:
    • `create_data_stream`
    • `delete_data_stream`
  • Alias Operations:
    • `put_alias`
    • `delete_alias`
  • General API Operations:
    • `general_api_request`

Optionally, you can specify a comma-separated list of operations to disable in the `DISABLE_OPERATIONS` environment variable.

bash
# Disable High-Risk Operations
export DISABLE_HIGH_RISK_OPERATIONS=true
# Disable specific operations only
export DISABLE_OPERATIONS="delete_index,delete_document,delete_by_query"

GCF Response Encoding (optional)

Opt in to serialize tool-result payloads as GCF (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.

bash
export RESPONSE_FORMAT=gcf

`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.

Reproduce the token comparison: `uv run --with tiktoken python benchmarks/gcf_benchmark.py`.

Start Elasticsearch/OpenSearch Cluster

Start the Elasticsearch/OpenSearch cluster using Docker Compose:

bash
# For Elasticsearch
docker-compose -f docker-compose-elasticsearch.yml up -d

# For OpenSearch
docker-compose -f docker-compose-opensearch.yml up -d

The default Elasticsearch username is `elastic` and password is `test123`. The default OpenSearch username is `admin` and password is `admin`.

You can access Kibana/OpenSearch Dashboards from http://localhost:5601.

Stdio

Option 1: Using uvx

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`.

json
// For Elasticsearch with username/password
{
  "mcpServers": {
    "elasticsearch-mcp-server": {
      "command": "uvx",
      "args": [
        "elasticsearch-mcp-server"
      ],
      "env": {
        "ELASTICSEARCH_HOSTS": "https://localhost:9200",
        "ELASTICSEARCH_USERNAME": "elastic",
        "ELASTICSEARCH_PASSWORD": "test123"
      }
    }
  }
}

// For Elasticsearch with API key
{
  "mcpServers": {
    "elasticsearch-mcp-server": {
      "command": "uvx",
      "args": [
        "elasticsearch-mcp-server"
      ],
      "env": {
        "ELASTICSEARCH_HOSTS": "https://localhost:9200",
        "ELASTICSEARCH_API_KEY": ""
      }
    }
  }
}

// For OpenSearch
{
  "mcpServers": {
    "opensearch-mcp-server": {
      "command": "uvx",
      "args": [
        "opensearch-mcp-server"
      ],
      "env": {
        "OPENSEARCH_HOSTS": "https://localhost:9200",
        "OPENSEARCH_USERNAME": "admin",
        "OPENSEARCH_PASSWORD": "admin"
      }
    }
  }
}

Option 2: Using uv with local development

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`.

json
// For Elasticsearch with username/password
{
  "mcpServers": {
    "elasticsearch-mcp-server": {
      "command": "uv",
      "args": [
        "--directory",
        "path/to/elasticsearch-mcp-server",
        "run",
        "elasticsearch-mcp-server"
      ],
      "env": {
        "ELASTICSEARCH_HOSTS": "https://localhost:9200",
        "ELASTICSEARCH_USERNAME": "elastic",
        "ELASTICSEARCH_PASSWORD": "test123"
      }
    }
  }
}

// For Elasticsearch with API key
{
  "mcpServers": {
    "elasticsearch-mcp-server": {
      "command": "uv",
      "args": [
        "--directory",
        "path/to/elasticsearch-mcp-server",
        "run",
        "elasticsearch-mcp-server"
      ],
      "env": {
        "ELASTICSEARCH_HOSTS": "https://localhost:9200",
        "ELASTICSEARCH_API_KEY": ""
      }
    }
  }
}

// For OpenSearch
{
  "mcpServers": {
    "opensearch-mcp-server": {
      "command": "uv",
      "args": [
        "--directory",
        "path/to/elasticsearch-mcp-server",
        "run",
        "opensearch-mcp-server"
      ],
      "env": {
        "OPENSEARCH_HOSTS": "https://localhost:9200",
        "OPENSEARCH_USERNAME": "admin",
        "OPENSEARCH_PASSWORD": "admin"
      }
    }
  }
}

SSE

Option 1: Using uvx

bash
# export environment variables (with username/password)
export ELASTICSEARCH_HOSTS="https://localhost:9200"
export ELASTICSEARCH_USERNAME="elastic"
export ELASTICSEARCH_PASSWORD="test123"

# OR export environment variables (with API key)
export ELASTICSEARCH_HOSTS="https://localhost:9200"
export ELASTICSEARCH_API_KEY=""

# By default, the SSE MCP server will serve on http://127.0.0.1:8000/sse
uvx elasticsearch-mcp-server --transport sse

# The host, port, and path can be specified using the --host, --port, and --path options
uvx elasticsearch-mcp-server --transport sse --host 0.0.0.0 --port 8000 --path /sse

Option 2: Using uv

bash
# By default, the SSE MCP server will serve on http://127.0.0.1:8000/sse
uv run src/server.py elasticsearch-mcp-server --transport sse

# The host, port, and path can be specified using the --host, --port, and --path options
uv run src/server.py elasticsearch-mcp-server --transport sse --host 0.0.0.0 --port 8000 --path /sse

Streamable HTTP

Option 1: Using uvx

bash
# export environment variables (with username/password)
export ELASTICSEARCH_HOSTS="https://localhost:9200"
export ELASTICSEARCH_USERNAME="elastic"
export ELASTICSEARCH_PASSWORD="test123"

# OR export environment variables (with API key)
export ELASTICSEARCH_HOSTS="https://localhost:9200"
export ELASTICSEARCH_API_KEY=""

# By default, the Streamable HTTP MCP server will serve on http://127.0.0.1:8000/mcp
uvx elasticsearch-mcp-server --transport streamable-http

# The host, port, and path can be specified using the --host, --port, and --path options
uvx elasticsearch-mcp-server --transport streamable-http --host 0.0.0.0 --port 8000 --path /mcp

Option 2: Using uv

bash
# By default, the Streamable HTTP MCP server will serve on http://127.0.0.1:8000/mcp
uv run src/server.py elasticsearch-mcp-server --transport streamable-http

# The host, port, and path can be specified using the --host, --port, and --path options
uv run src/server.py elasticsearch-mcp-server --transport streamable-http --host 0.0.0.0 --port 8000 --path /mcp

Compatibility

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).

MCP ServerElasticsearch
elasticsearch-mcp-server-es7Elasticsearch 7.x
elasticsearch-mcp-serverElasticsearch 8.x
elasticsearch-mcp-server-es9Elasticsearch 9.x
opensearch-mcp-serverOpenSearch 1.x, 2.x, 3.x

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:

bash
uvx elasticsearch-mcp-server-es7

If 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:

bash
uv run src/server.py elasticsearch-mcp-server

Kubernetes Deployment

The 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.

For full installation instructions, configuration reference, and usage examples see the **Helm chart README**.

License

This project is licensed under the Apache License Version 2.0 - see the LICENSE file for details.

Frequently asked questions

What is elasticsearch-mcp-server?

elasticsearch-mcp-server is A Model Context Protocol (MCP) server implementation that provides Elasticsearch and OpenSearch interaction. Python-based implementation.

How do I install elasticsearch-mcp-server?

Open the GitHub repository and follow its README. Most MCP servers are added to your client's MCP config, then called by your agent.

Is elasticsearch-mcp-server open source?

Yes — it is hosted on GitHub at https://github.com/cr7258/elasticsearch-mcp-server and has 213 stars.

Related MCP tools

Run your own MCP server? See who uses it and what to fix.

Measure it with TrackMCP