
Connects Claude directly to Elasticsearch clusters running versions 5.x through 9.x with automatic version detection and client selection. Exposes the full Elasticsearch API surface including search, indexing, data streams, ILM policies, and ES|QL queries (8.11+). The server disables unsupported features based on your cluster version, so Data Streams won't appear on 7.8 and earlier. Supports both stdio for Claude Desktop and HTTP transport for remote access. Built with security operations in mind, offering tools for threat detection, anomaly analysis, and audit workflows, though these require a valid Elasticsearch license (trial, platinum, or enterprise). Configure with API key or username/password auth, and set NODE_TLS_REJECT_UNAUTHORIZED=0 for self-signed certificates in development.
Enhanced Elasticsearch MCP Server Solution - Security & Threat Analysis Focused
This is a professional security-focused solution maintained by TocharianOU. It enables comprehensive interaction with all Elasticsearch APIs, specifically optimized for security analysis, threat detection, and incident investigation. Features include advanced security monitoring, anomaly detection, threat hunting, root cause analysis, and comprehensive audit capabilities.
Key Security Features:
Note: This solution is designed for security professionals, SOC teams, and threat analysts.
Connect to your Elasticsearch data directly from any MCP Client (such as Claude Desktop) using the Model Context Protocol (MCP). Interact with your Elasticsearch security data through natural language queries for advanced threat analysis and incident response.
Automatically supports Elasticsearch 5.x - 9.x with intelligent version detection:
| Version | Status | Client | Notes |
|---|---|---|---|
| ES 5.x | ✅ | 5.6.22 | EOL - Basic tools only |
| ES 6.x | ✅ | 6.8.8 | EOL - ILM available (6.6+) |
| ES 7.x | ✅ | 7.17.14 | LTS - Full features |
| ES 8.x | ✅ | 8.19.1 | Recommended - Latest features, ES|QL (8.11+) |
| ES 9.x+ | ✅ | Auto-fallback | Future-ready |
Key Features:
What happens:
Connect → Detect ES version → Load matching client → Register compatible tools
Since v0.9.0 the server ships a query harness: a deterministic layer between the AI model and your cluster. The design philosophy is simple:
The model steers; the harness knows. Intent ("find failed logins by user") belongs to the model. Correctness (real field names, aggregatability, version quirks) belongs to the harness.
What this means in practice — at the level of principles, not internals:
.keyword suffix on modern ECS mappings is
auto-corrected (and the correction is reported); an unknown field blocks the
doomed query and returns the nearest real fields instead of a provider error.lookup_fields.text + .keyword subfield vs. modern
bare keyword) are absorbed entirely by the harness. The same model behaves
identically against ES 5.6 and ES 9.x — verified by a version test matrix
covering nine watershed releases (5.6 → 9.0).skip_lint) when the model knows better — e.g. runtime fields defined
outside the query. The harness assists; it never imprisons.To connect to Elasticsearch with a self-signed certificate or in a test environment, you can set the following environment variable:
NODE_TLS_REJECT_UNAUTHORIZED=0
⚠️ This disables Node.js SSL certificate validation. Use only in development or testing environments. For production, always use a trusted CA certificate.
Install (or run) the server, point it at your cluster via environment variables, register it in your MCP client, then just start a conversation — the server connects and registers the tools your ES version supports.
The Elasticsearch MCP Server supports the following configuration options:
| Environment Variable | Description | Required |
|---|---|---|
ES_URL | Your Elasticsearch instance URL | Yes |
ES_API_KEY | Elasticsearch API key for authentication | No |
ES_USERNAME | Elasticsearch username for basic authentication | No |
ES_PASSWORD | Elasticsearch password for basic authentication | No |
ES_CA_CERT | Path to custom CA certificate for Elasticsearch SSL/TLS | No |
NODE_TLS_REJECT_UNAUTHORIZED | Set to 0 to disable SSL certificate validation | No |
| Environment Variable | Description | Default | Values |
|---|---|---|---|
MCP_TRANSPORT | Transport mode selection | stdio | stdio, http |
MCP_HTTP_PORT | HTTP server port (when using HTTP transport) | 3000 | 1-65535 |
MCP_HTTP_HOST | HTTP server host (when using HTTP transport) | localhost | Any valid host |
Transport Mode Details:
Install globally via NPM
npm install -g @tocharianou/elasticsearch-mcp
Run directly
npx @tocharianou/elasticsearch-mcp
Download release package
.tar.gz file and its checksum files (.sha256 and .sha512)Verify package integrity
shasum -a 256 -c elasticsearch-mcp-v*.tar.gz.sha256
# Should output: elasticsearch-mcp-v*.tar.gz: OK
Extract and use
mkdir elasticsearch-mcp && cd elasticsearch-mcp
tar -xzf ../elasticsearch-mcp-v*.tar.gz
# Run with your Elasticsearch credentials
ES_URL=https://localhost:9200 ES_API_KEY=your-key node dist/index.js
Clone the repository
git clone https://github.com/TocharianOU/elasticsearch-mcp.git
cd elasticsearch-mcp
Install Dependencies
npm install
Build the Project
npm run build
Configure Claude Desktop App
Edit Config and add a new MCP Server with the following configuration:For NPM Installation:
{
"mcpServers": {
"elasticsearch-mcp-server": {
"command": "npx",
"args": [
"@tocharianou/elasticsearch-mcp"
],
"env": {
"ES_URL": "your-elasticsearch-url",
"ES_USERNAME": "elastic",
"ES_PASSWORD": "your_pass",
"NODE_TLS_REJECT_UNAUTHORIZED": "0"
}
}
}
}
For Source Installation:
{
"mcpServers": {
"elasticsearch-mcp-server-local": {
"command": "node",
"args": [
"/path/to/your/elasticsearch-mcp/dist/index.js"
],
"env": {
"ES_URL": "your-elasticsearch-url",
"ES_USERNAME": "elastic",
"ES_PASSWORD": "your_pass",
"NODE_TLS_REJECT_UNAUTHORIZED": "0"
}
}
}
}
Debugging with MCP Inspector (optional)
ES_URL=your-elasticsearch-url ES_USERNAME=elastic ES_PASSWORD=your_pass npm run inspector
If npm install -g misbehaves:
EACCES) on global install — don't sudo. Either skip
the global install entirely and let your MCP client run npx @tocharianou/elasticsearch-mcp
(npx fetches on demand), or set a user-level prefix:
npm config set prefix ~/.npm-global and add it to your PATH.npm install -g @tocharianou/elasticsearch-mcp --registry=https://registry.npmmirror.com.node --version). Older Node fails
at startup with ESM/fetch errors, not at install time.npx cold start — the first npx run downloads the package; if your MCP
client times out on first connect, run npx @tocharianou/elasticsearch-mcp
once in a terminal to warm the cache, then reconnect.node /path/to/dist/index.js; nothing is fetched at runtime.Claude Desktop — Settings → Developer → MCP Servers → Edit Config, then add the JSON block shown above. Restart the app after editing; the server appears in the tools list of a new conversation.
Claude Code (CLI) — register the server per-project or globally:
claude mcp add elasticsearch \
-e ES_URL=https://your-es:9200 -e ES_API_KEY=your-key \
-- npx @tocharianou/elasticsearch-mcp
Any other MCP client / platform integration — run in HTTP mode
(MCP_TRANSPORT=http, see below) and point the client at http://host:port/mcp;
this is the recommended shape for containerized platforms, one server instance
per cluster connection.
Credentials hygiene — the env vars end up in your client's config file in plain text. Prefer a scoped, read-only API key (see Elasticsearch Access Control below) over superuser credentials.
Run the server as a standalone HTTP service for remote access and API integration:
# Start HTTP server (default port 3000)
MCP_TRANSPORT=http \
ES_URL=your-elasticsearch-url \
ES_USERNAME=elastic \
ES_PASSWORD=your_pass \
npx @tocharianou/elasticsearch-mcp
# Or with custom port and host
MCP_TRANSPORT=http \
MCP_HTTP_PORT=9000 \
MCP_HTTP_HOST=0.0.0.0 \
ES_URL=your-elasticsearch-url \
ES_USERNAME=elastic \
ES_PASSWORD=your_pass \
npx @tocharianou/elasticsearch-mcp
HTTP Streamable Mode Features:
http://host:port/mcp endpointhttp://host:port/healthAny MCP-capable client (or plain JSON-RPC over HTTP) can talk to the /mcp
endpoint: initialize once, keep the returned mcp-session-id header on
subsequent tools/list / tools/call requests. Use /health for liveness
checks.
| Tool | Description | Min Version |
|---|---|---|
list_indices | List indices with pattern filter, health filter, sorting and token-aware summary | ES 5.x+ |
get_mappings | Get field mappings with flat/tree/raw modes, field filtering and multi-index compare | ES 5.x+ |
es_search | Full Query DSL search with auto-highlight, plus harness field validation / auto-fix | ES 5.x+ |
lookup_fields | Find the right field names: ECS vocabulary intersected with the index's real fields | ES 5.x+ |
execute_es_api | Execute any ES REST endpoint directly (GET/POST/PUT/DELETE/HEAD) | ES 5.x+ |
get_shards | Shard info with health analysis, problem detection and recommendations | ES 5.x+ |
list_data_streams | List and analyze Data Streams with ILM info and backing index details | ES 7.9+ |
esql_query | Execute ES|QL pipe-based queries with harness field validation and tabular output | ES 8.11+ |
Tools not supported by your cluster version are automatically skipped at startup.
es_searchandesql_queryacceptskip_lint: trueto bypass the harness validation for edge cases (e.g. runtime fields defined outside the query).
esql_query)ES|QL is Elasticsearch's modern pipe-based query language, ideal for analytics and data exploration without complex JSON DSL.
Example queries:
FROM logs-* | WHERE level == "error" | STATS count = COUNT(*) BY service | SORT count DESC | LIMIT 20
FROM metrics-* | WHERE @timestamp > NOW() - 1 hour | STATS avg_cpu = AVG(cpu.usage) BY host.name
FROM auditbeat-* | WHERE event.action == "user_login" AND event.outcome == "failure" | LIMIT 50
Parameters:
query — the ES|QL string (required)params — positional parameters replacing ? placeholders (optional)include_types — include column type info in output (optional, default false)break_token_rule — bypass token limit for large results (optional, default false)skip_lint — bypass harness field validation (optional, default false)Automatically registered only on ES 8.11+ clusters.
We welcome contributions from the community! For details on how to contribute, please see Contributing Guidelines.
[!TIP] Here are security-focused queries you can try with your MCP Client.
Threat Detection:
Root Cause Analysis:
Threat Intelligence:
Real-time Monitoring:
[!WARNING] Avoid using cluster-admin privileges. Create dedicated API keys with limited scope and apply fine-grained access control at the index level to prevent unauthorized data access.
When downloading release packages, always verify checksums to ensure integrity:
# Verify SHA256 checksum
shasum -a 256 -c elasticsearch-mcp-vX.Y.Z.tar.gz.sha256
# Verify SHA512 checksum
shasum -a 512 -c elasticsearch-mcp-vX.Y.Z.tar.gz.sha512
This protects against:
You can create a dedicated Elasticsearch API key with minimal permissions to control access to your data:
{
"name": "es-mcp-server-access",
"role_descriptors": {
"mcp_server_role": {
"cluster": [
"monitor"
],
"indices": [
{
"names": [
"index-1",
"index-2",
"index-pattern-*"
],
"privileges": [
"read",
"view_index_metadata"
]
}
]
}
}
}
This project is licensed under the Apache License 2.0.
If you encounter issues, feel free to open an issue on the GitHub repository.
ES_URL*Your Elasticsearch instance URL (e.g., https://localhost:9200)
ES_API_KEYsecretElasticsearch API key for authentication
ES_USERNAMEElasticsearch username for basic authentication
ES_PASSWORDsecretElasticsearch password for basic authentication
ES_CA_CERTPath to custom CA certificate for Elasticsearch SSL/TLS
NODE_TLS_REJECT_UNAUTHORIZEDdefault: 1Set to '0' to disable SSL certificate validation (development only)
MAX_TOKEN_CALLdefault: 20000Maximum tokens per API call
MCP_TRANSPORT*default: httpTransport mode selection
MCP_HTTP_PORTdefault: 3000HTTP server port (when using HTTP transport)
MCP_HTTP_HOSTdefault: localhostHTTP server host (when using HTTP transport)