Elasticsearch MCP Server
by gpremo-re
README.md
# Elasticsearch MCP Server
An MCP (Model Context Protocol) server that gives AI assistants like Claude direct access to Elasticsearch. Search, aggregate, and retrieve documents from any index — all exposed as MCP tools over a Streamable HTTP transport.
## Quickstart
### With Docker (recommended)
```bash
docker build -t elasticsearch-mcp .
docker run -e ES_URL=http://host.docker.internal:9200 -p 3100:3100 elasticsearch-mcp
```
### Without Docker
Requires Node.js 22+.
```bash
npm install
npm run build
ES_URL=http://localhost:9200 npm start
```
### Connect to Claude Code
Add to your `.mcp.json`:
```json
{
"mcpServers": {
"elasticsearch": {
"type": "streamable-http",
"url": "http://localhost:3100/mcp"
}
}
}
```
### Sample prompts
Once connected, try asking Claude things like:
- "What indices do I have? Pick the most interesting one and tell me what fields are available."
- "Search the `logs` index for timeout errors in the last 24 hours and summarize what's going wrong."
- "Which users have the most failed login attempts? Break it down by country."
- "Find all documents mentioning 'rate limit' and show me the top 5 with highlights."
- "How many orders were placed each month this year? Plot the trend."
- "Compare how often these product names appear across the catalog: 'widget', 'gadget', 'gizmo', 'doohickey'."
- "Pull up document `abc-123` and give me a plain-English summary."
- "What are the most common values in the `status` field? Are any of them suspicious?"
## Tools
### `list_indices`
List all Elasticsearch indices with doc counts, storage size, health, and status. Accepts an optional glob pattern to filter index names.
### `get_mapping`
Get field names and types for an index.
### `search`
Full-text search with query modes: `match`, `match_phrase`, `multi_match`, `query_string`. Supports filters, sorting, pagination, highlighting, field selection, and minimum score thresholds.
### `count`
Count documents matching a query with optional filters.
### `multi_count`
Count multiple phrases in one call using msearch. Useful for co-occurrence analysis — can require an additional term to co-occur with each phrase.
### `get_document`
Retrieve a single document by `_id` or `document_id` field value. Long text fields are truncated by default.
### `aggregate`
Run aggregations on an index:
- **terms** — Top values by frequency
- **stats** — min/max/avg/sum/count for numeric fields
- **date_histogram** — Monthly bucketing for date fields
- **top_hits** — Sample documents per bucket
- **cardinality** — Distinct value count
- **filter** — Filtered document count
Supports sub-aggregations for nested analysis (e.g., terms + stats).
## Configuration
| Variable | Default | Description |
|---|---|---|
| `ES_URL` | `http://localhost:9200` | Elasticsearch URL |
| `ES_API_KEY` | — | API key for Elasticsearch authentication (optional) |
| `PORT` | `3100` | HTTP port the server listens on |
## Endpoints
| Path | Method | Description |
|---|---|---|
| `/mcp` | `POST` | MCP protocol (Streamable HTTP transport) |
| `/health` | `GET` | Health check (returns `ok`) |
## Semantic & Hybrid Search
The `search` tool also supports two additional modes for indices with `dense_vector` fields:
- **semantic** — kNN vector search using a built-in [all-MiniLM-L6-v2](https://huggingface.co/Xenova/all-MiniLM-L6-v2) embedding model (384 dimensions). No external embedding API needed.
- **hybrid** — Runs keyword + semantic in parallel and fuses results with Reciprocal Rank Fusion (k=60).
Set `search_mode` to `semantic` or `hybrid` and specify the `embedding_field` (defaults to `text_embedding`).
The embedding model is downloaded on first use and cached locally. The Docker image pre-downloads it at build time. Use `TRANSFORMERS_CACHE` to control where the model is stored.
| Variable | Default | Description |
|---|---|---|
| `TRANSFORMERS_CACHE` | (system default) | Directory to cache the embedding model |
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues