agrica

Elasticsearch 7.x MCP Server

Community agrica
Updated

Elasticsearch 7 MCP server

Elasticsearch 7.x MCP Server

MCP Server for connecting to your Elasticsearch cluster directly from any MCP Client (like Claude Desktop, Cursor).

[!IMPORTANT]This fork targets Elasticsearch 7.x only. It pins the @elastic/elasticsearch 7.17 client,whose product check accepts servers older than 7.14. For an Elasticsearch 8.x cluster, use theupstream project @awesome-ai/elasticsearch-mcp,which this fork is derived from — the 8.x client cannot talk to a 7.x server, and vice versa.

This server connects agents to your Elasticsearch data using the Model Context Protocol. It allows you to interact with your Elasticsearch indices through natural language conversations.

Feature Overview

Tools come in three sets. Only the first is always exposed; the other two areopt-in through an environment variable, so a production deployment can offerdiagnostics without offering deletes. Gating happens at registration: a disabledtool never appears in tools/list, so the model cannot call it and it costsnothing in the agent's context.

Always available — read and write data

Cluster
  • elasticsearch_health: cluster health, optionally down to index level
  • cluster_info: cluster name, Elasticsearch version and build flavour
Index operations
  • list_indices: list indices, filtered by an Elasticsearch wildcard (log-*)
  • create_index: create an index with optional settings and mappings
  • reindex: copy an index, optionally filtered by a query or transformed by a script
  • get_aliases: which aliases point at which indices
Mappings
  • get_mappings: the fields of an index, as dotted paths with their types, then the raw mapping
  • create_mapping: create or update the mapping of an index
Search and data
  • search: run a query DSL search, with highlighting injected over every text field — nested ones included — unless the query brings its own highlight
  • count: how many documents match, without transferring any
  • get_document: fetch one document by id
  • bulk: index many documents at once
Templates
  • create_index_template: create or update a composable index template
  • get_index_template: read index templates
Tasks
  • get_task: progress of a long-running task, such as the one reindex returns

ES_ADMIN_TOOLS=true — diagnostics (read-only)

These only read, so they are safe to enable in production — and are the point ofthis set: an agent can then explain why an index is unhealthy without anyonelogging into the cluster.

  • explain_allocation: why a shard is unassigned, with each allocator's decision
  • list_shards: shard-level state, leading with the copies that are not STARTED
  • list_nodes: heap, CPU, load and disk pressure per node
  • get_index_stats: per-index counters — size, segments, indexing, search, merges
  • get_index_settings: an index's settings (refresh_interval, replicas, read-only blocks)
  • get_cluster_settings: cluster settings that were overridden at runtime
  • list_tasks: what the cluster is currently running

ES_ALLOW_DESTRUCTIVE=true — irreversible

Intended for a staging environment, and off by default so production cannotreach them at all.

  • delete_index: delete an index and its data
  • delete_document: delete one document by id
  • delete_by_query: delete every document matching a query — asynchronous, it returns a task id and the deletion continues in the background
  • delete_index_template: delete an index template

Even with the flag on, these refuse a wildcard, a comma-separated list, * and_all: they act on one named index at a time. A model that mistakes logs-*for a single index gets a refusal instead of an emptied cluster.

How It Works

  1. The MCP Client analyzes your request and determines which Elasticsearch operations are needed.
  2. The MCP server carries out these operations (listing indices, fetching mappings, performing searches).
  3. The MCP Client processes the results and presents them in a user-friendly format.

Getting Started

Prerequisites

  • An Elasticsearch 7.x instance (tested against 7.8; the 7.17 client supports 6.8 through 7.x)
  • Elasticsearch credentials — an API key, or a username and password
  • An MCP client: Claude Code, Claude Desktop, Codex, Cursor, or anything else that speaks MCP over stdio

Authenticate to GitHub Packages, once

[!IMPORTANT]This package is published to GitHub Packages, not npmjs.com, and GitHubPackages requires a token even for public packages. Until you add one, everyinstall below fails with a 401. Put it in your user-level ~/.npmrc:

@agrica:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN

YOUR_GITHUB_TOKEN is a personal access token with the read:packages scope.

Keep it in your own ~/.npmrc rather than a project file — a token committedto a repository is a leaked token, and some package managers refuse to read onefrom there at all.

Connect it to your client

Every example below sets ES_HOST and ES_API_KEY. Swap inES_USERNAME/ES_PASSWORD for basic auth, add ES_ADMIN_TOOLS=true to getthe diagnostic tools, and set ES_INSTANCE_LABEL when more than one instance isdeclared — see Configuration Options.

Claude Codeclaude mcp add
claude mcp add elasticsearch7 \
  --env ES_HOST=https://your-cluster:9200 \
  --env ES_API_KEY=your-api-key \
  --env ES_ADMIN_TOOLS=true \
  -- npx -y @agrica/elasticsearch7-mcp

Then /mcp in a session lists the server and its tools.

Two details that are easy to get wrong:

  • Everything after -- is the command that runs the server; without it, ClaudeCode would try to parse -y as one of its own flags.
  • Do not put the server name straight after --env — the CLI reads it asanother KEY=value pair and rejects it. Above, the name comes first, which iswhy it works.

The server is added at local scope, so it loads in the current project only. Add--scope user to get it everywhere, or --scope project to write it into.mcp.json and share it with your team — mind that a committed .mcp.jsonwould carry your API key, so prefer user scope for credentials.

Claude Desktopclaude_desktop_config.json

Edit claude_desktop_config.jsonSettings > Developer > Edit Config opensit, or find it at %APPDATA%\Claude\ on Windows and~/Library/Application Support/Claude/ on macOS:

{
  "mcpServers": {
    "elasticsearch7": {
      "command": "npx",
      "args": ["-y", "@agrica/elasticsearch7-mcp"],
      "env": {
        "ES_HOST": "https://your-cluster:9200",
        "ES_API_KEY": "your-api-key",
        "ES_ADMIN_TOOLS": "true"
      }
    }
  }
}

Restart Claude Desktop afterwards; it only reads that file at startup.

Codexcodex mcp add or config.toml
codex mcp add elasticsearch7 \
  --env ES_HOST=https://your-cluster:9200 \
  --env ES_API_KEY=your-api-key \
  -- npx -y @agrica/elasticsearch7-mcp

Or write it into ~/.codex/config.toml by hand. Note that Codex spells thetable mcp_servers with an underscore, and that the environment goes in its ownsub-table rather than inline:

[mcp_servers.elasticsearch7]
command = "npx"
args = ["-y", "@agrica/elasticsearch7-mcp"]

[mcp_servers.elasticsearch7.env]
ES_HOST = "https://your-cluster:9200"
ES_API_KEY = "your-api-key"
ES_ADMIN_TOOLS = "true"

/mcp inside Codex confirms the server is loaded.

Any other MCP client — stdio, no port

The server is a plain stdio MCP server, so anything on theMCP client list works. It needs threethings: the command npx, the arguments -y @agrica/elasticsearch7-mcp, and theES_* variables in its environment. It never listens on a port, and writesnothing but MCP protocol to stdout — diagnostics go to stderr.

Configuration Options

The Elasticsearch MCP Server supports configuration options to connect to your Elasticsearch:

[!NOTE]You must provide either an API key or both username and password for authentication.

Environment Variable Description Required
ES_HOST Your Elasticsearch instance URL(s) - supports single URL or comma-separated multiple URLs (also supports legacy HOST) Yes
ES_API_KEY Elasticsearch API key for authentication (also supports legacy API_KEY) No
ES_USERNAME Elasticsearch username for basic authentication (also supports legacy USERNAME) No
ES_PASSWORD Elasticsearch password for basic authentication (also supports legacy PASSWORD) No
ES_CA_CERT Path to custom CA certificate for Elasticsearch SSL/TLS (also supports legacy CA_CERT) No
ES_REQUEST_TIMEOUT Per-request timeout in milliseconds. Default 30000 — raise it if aggregations over many indices time out. No
ES_MAX_RETRIES Retries per request. Default 3; 0 disables them. No
ES_MAX_RESULT_BYTES Ceiling on one tool result. Default 32768. Past it, detail is omitted and the result says so. No
ES_INSTANCE_LABEL Free-text name of this deployment, e.g. production. Shown as the server title, so several instances declared side by side are distinguishable. No
ES_ADMIN_TOOLS true to also expose the read-only diagnostic tools. Default off. No
ES_ALLOW_DESTRUCTIVE true to also expose the irreversible tools. Default off. No

[!WARNING]ES_ADMIN_TOOLS and ES_ALLOW_DESTRUCTIVE have no un-prefixed legacy alias,unlike the connection variables above. That is deliberate: a bare ADMIN_TOOLSor ALLOW_DESTRUCTIVE in an environment is far too easy to set by accident forsomething that decides whether deletes are reachable.

Both accept true or 1; anything else, including an unset variable, means off.

Result size

A tool result is capped at 32 KB (ES_MAX_RESULT_BYTES). This matters on alogging cluster: before the cap, one list_shards call over a year of dailyindices returned 385 KB — around 96 000 tokens — in a single answer, which ismore than most sessions can hold.

When a result is trimmed it says so, says how much went, and says how to ask asmaller question. Three tools shape their answers around it:

  • list_indices and list_shards return a readable summary; the same rows astext are behind verbose.
  • search caps size at 100 per call and tells you the from to page with.
  • get_mappings lists the fields first and the raw mapping second, so athousand-field index still answers the question it was asked.

Four tools — list_indices, list_shards, get_index_settings andget_mappings — also return their answer as typed structured output, so aclient can read the rows instead of parsing the text. It is assembled fromwhatever room the readable answer left, and reports returned against totalso a partial listing is visible as a number.

Run pnpm run measure against the built output to see the current figures foryour own configuration.

Labelling several instances

Most setups declare this server more than once — one entry per cluster. Theentries are otherwise identical, so a client shows two servers with the samename and nothing to tell them apart. ES_INSTANCE_LABEL becomes the server'sdisplay title, and it is the natural place to say which environment an entryreaches:

{
  "mcpServers": {
    "es7-prod": {
      "command": "npx",
      "args": ["-y", "@agrica/elasticsearch7-mcp"],
      "env": {
        "ES_HOST": "https://es-prod:9200",
        "ES_API_KEY": "prod-key",
        "ES_INSTANCE_LABEL": "production",
        "ES_ADMIN_TOOLS": "true"
      }
    },
    "es7-staging": {
      "command": "npx",
      "args": ["-y", "@agrica/elasticsearch7-mcp"],
      "env": {
        "ES_HOST": "https://es-staging:9200",
        "ES_API_KEY": "staging-key",
        "ES_INSTANCE_LABEL": "staging",
        "ES_ADMIN_TOOLS": "true",
        "ES_ALLOW_DESTRUCTIVE": "true"
      }
    }
  }
}

That pair is the intended shape: diagnostics on both, deletes only onstaging. Production keeps the tools that explain an unhealthy index and neverexposes one that can remove data — the model cannot call what was neverregistered.

The label is also printed to stderr at startup, which is where to look when aclient reports a connection but you cannot tell which cluster answered.

Multiple URLs Configuration

You can configure multiple Elasticsearch nodes for high availability and load balancing:

{
  "mcpServers": {
    "elasticsearch7-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@agrica/elasticsearch7-mcp"
      ],
      "env": {
        "ES_HOST": "https://es-node1:9200,https://es-node2:9200,https://es-node3:9200",
        "ES_API_KEY": "your-api-key"
      }
    }
  }
}

The client will automatically handle failover and load balancing between the configured nodes.

Running with Docker

Each release publishes a multi-arch image (linux/amd64, linux/arm64) to theGitHub Container Registry:

docker pull ghcr.io/agrica/elasticsearch7-mcp:latest

The server speaks stdio, so the container needs an interactive stdin and nopublished port. In an MCP client:

{
  "mcpServers": {
    "elasticsearch7-mcp": {
      "command": "docker",
      "args": [
        "run", "--rm", "-i",
        "-e", "ES_HOST",
        "-e", "ES_API_KEY",
        "ghcr.io/agrica/elasticsearch7-mcp:latest"
      ],
      "env": {
        "ES_HOST": "your-elasticsearch-host",
        "ES_API_KEY": "your-api-key"
      }
    }
  }
}

[!NOTE]Like the npm package, the image lives in GitHub Packages: pulling it requires atoken with the read:packages scope, even though the repository is public.

The image needs no port published and no volume: it speaks stdio, and the MCPclient owns its stdin and stdout.

Example Queries

[!TIP]Here are some natural language queries you can try with your MCP Client.

Cluster Management
  • "What is the health status of my Elasticsearch cluster?"
  • "How many active nodes are in my cluster?"
Index Operations
  • "What indices do I have in my Elasticsearch cluster?"
  • "Create a new index called 'users' with 3 shards and 1 replica."
  • "Reindex data from 'old_index' to 'new_index'."
Mapping Management
  • "Show me the field mappings for the 'products' index."
  • "Add a keyword type field called 'tags' to the 'products' index."
Search & Data Operations
  • "Find all orders over $500 from last month."
  • "Which products received the most 5-star reviews?"
  • "Bulk import these customer records into the 'customers' index."
Template Management
  • "Create an index template for logs with pattern 'logs-*'."
  • "Show me all my index templates."
Diagnostics (needs ES_ADMIN_TOOLS=true)
  • "The 'logs-2026' index is yellow — why are its shards unassigned?"
  • "Is any node close to a disk watermark?"
  • "Which of my indices is the largest, and how much of it is deleted documents?"
  • "Has anyone disabled shard allocation on this cluster?"
  • "Is a reindex still running?"
Destructive (needs ES_ALLOW_DESTRUCTIVE=true)
  • "Delete the 'smoke-test-source' index."
  • "Remove every document older than 2024 from 'logs-archive'."

Troubleshooting

Symptom Cause
npm error code E401 on install or npx No GitHub Packages token in your user-level ~/.npmrc. See Authenticate to GitHub Packages.
Server error: ... invalid url at startup ES_HOST is unset or malformed. It is validated at startup on purpose, rather than failing later on the first query.
The client connects, but a diagnostic or delete tool is missing That set is gated. Set ES_ADMIN_TOOLS=true or ES_ALLOW_DESTRUCTIVE=true and restart the client.
Refusing to act on the pattern "logs-*" Working as intended: destructive tools take one concrete index name, never a pattern, even with the flag on.
A connection error mentioning the product check The cluster is 8.x, or unreachable. This build talks to 7.x only.

Found a bug or want a tool that is missing? Open an issue on the GitHubrepository. To work on the code, start fromCONTRIBUTING.md.

MCP Server · Populars

MCP Server · New

    Get-Concord-AI

    Concord MCP

    Live messaging for coding agents

    Community Get-Concord-AI
    alijancb

    Subio MCP

    Open-source MCP server for discovering fast-growing internet conversations with Subio

    Community alijancb
    ruezo

    MCP Video Digest (视频内容提取总结)

    MCP Server for transcribing videos via video links and summarizing video content

    Community ruezo
    LastSearch-HQ

    LastSearch

    Reliable research infrastructure for AI agents. Evidence-backed web search with citations, confidence scores, and Clarity anti-hallucination. MCP server, REST API, Python SDK.

    Community LastSearch-HQ
    gtfodevs

    Autonomo MCP

    Tired of 'it works' lies? Autonomo MCP makes your AI prove it—on real hardware, right in your editor.

    Community gtfodevs