mcp-server-elasticsearch
elastic/mcp-server-elasticsearch
- Type
- MCP server
- Scanned
- Oct 29, 2026
- Version
- 9e64b842f222
- Files read
- 37
This MCP server connects AI agents to an Elasticsearch cluster to list indices, inspect mappings and shards, and run Search DSL and ES|QL queries. The biggest risk is that running the server in HTTP mode exposes the /mcp and /mcp/sse endpoints without authentication while falling back to the server's configured Elasticsearch credentials, and binds to 0.0.0.0 by default in container mode.
What it can reach
- Network
- Connects to the configured Elasticsearch cluster over HTTP/HTTPS, and in HTTP mode listens for incoming connections on TCP port 8080 (or 8000 in Dockerfile-8000).
- Secrets
- Reads Elasticsearch credentials (ES_API_KEY, ES_USERNAME, ES_PASSWORD) and configuration settings from environment variables and .env files.
- Files
- Reads a local .env file if present and an optional JSON5 configuration file specified via the --config flag.
Findings
-
HighUnauthenticated HTTP server falls back to configured Elasticsearch credentials
src/servers/elasticsearch/mod.rs:93
When the server is run in HTTP mode, the
/mcpand/mcp/sseendpoints do not require authentication. If an incoming HTTP request does not include anAuthorizationheader,EsClientProvider::getreturns the default client configured with the server's environment credentials (ES_API_KEYorES_USERNAME/ES_PASSWORD). Any client able to reach the HTTP listener can query the Elasticsearch cluster using the server's credentials without authenticating.Fix: Require an
Authorizationheader on all HTTP requests when running in HTTP mode, or do not fall back to server-side credentials for unauthenticated HTTP requests unless explicitly enabled. -
MediumHTTP server binds to all network interfaces in container mode
When
CONTAINER_MODEis enabled (which is set by default in the provided Dockerfiles), the HTTP server binds to0.0.0.0:8080instead of127.0.0.1:8080. If the container port is published on the host without interface restrictions (such asdocker run -p 8080:8080in the README), the unauthenticated MCP server is exposed to the surrounding network.Fix: Recommend binding published container ports to localhost (
-p 127.0.0.1:8080:8080) in documentation, and require authentication before binding to non-loopback interfaces. -
LowUnpinned Git branch dependency for
elasticsearchcrateThe
elasticsearchcrate dependency points to a mutable Git branch (new-with-creds) rather than a pinned commit hash or a published version on crates.io. Building from source without--lockedcould fetch modified upstream code.Fix: Pin the Git dependency to a specific commit SHA using
revor use an official release version. -
LowUnhandled empty mapping response causes panic in
get_mappingssrc/servers/elasticsearch/base_tools.rs:137
In
get_mappings, the code calls.unwrap()on the first item of the returned mapping map. If a wildcard index pattern matches no indices and Elasticsearch returns an empty JSON object, the handler will panic.Fix: Replace
.unwrap()with proper handling for an empty map, returning a message that no mappings were found for the given index.