Elasticsearch MCP Server: Search and Logs From an Agent

Elastic’s first-party MCP server is the Agent Builder endpoint in Kibana, and the older standalone Elasticsearch MCP server is deprecated. Which one to use, the tools it exposes, how to create a read-only API key limited to your log indices, and how to connect Claude, Cursor and VS Code.

7 min read

Elastic’s first-party MCP server is built into Kibana as part of Elastic Agent Builder. It lives at {KIBANA_URL}/api/agent_builder/mcp, and any MCP client that can send an authorization header can use it to list indices, read mappings, run ES|QL queries, search in natural language and, on Observability deployments, pull logs, traces and alerts. It is generally available on Elastic Stack 9.3 and later (a preview in 9.2) and on Serverless projects. The older standalone server, elastic/mcp-server-elasticsearch, still exists as a Docker image but is deprecated. For an agent that searches data and reads logs, the setup that matters is an API key with read privileges on only the indices it needs, and an expiry.

Two Elasticsearch MCP servers, one current

  • Agent Builder MCP endpoint: part of Kibana, nothing to deploy. Elastic’s Agent Builder MCP server docs (opens in a new tab) list it as a preview in 9.2, generally available from 9.3, and generally available on Serverless Elasticsearch, Observability and Security projects. In a custom Kibana space the path becomes {KIBANA_URL}/s/{SPACE_NAME}/api/agent_builder/mcp, and the Tools page has a button that copies the URL.
  • The standalone Elasticsearch MCP server: a container image at docker.elastic.co/mcp/elasticsearch that talks to Elasticsearch 8.x or 9.x directly. Its repository README (opens in a new tab) opens with a caution: the server “is deprecated and will only receive critical security updates going forward,” superseded by the Agent Builder endpoint.

So the choice is mostly made by your version. On 9.3 or later, or on Serverless, use Agent Builder. On an 8.x cluster the Agent Builder endpoint is not available, and the deprecated container is the Elastic-made option until you upgrade.

What the tools cover

The MCP endpoint serves Agent Builder’s tools: the built-in ones and any custom tools you create in Kibana. Elastic’s built-in tools reference (opens in a new tab) groups them by namespace. The platform core tools are the ones an agent uses for search:

  • platform.core.list_indices lists the indices, aliases and data streams the caller can access, and platform.core.get_index_mapping reads their mappings.
  • platform.core.index_explorer finds relevant indices from a plain-language description.
  • platform.core.search searches in natural language, choosing between query DSL and ES|QL.
  • platform.core.generate_esql writes an ES|QL query from a question, and platform.core.execute_esql runs one and returns a table.
  • platform.core.get_document_by_id fetches a whole document by index and ID.

On Observability, observability.* tools add log and trace work: get_logs returns a histogram, a count, samples and message patterns in one call; get_log_groups groups exceptions from logs and spans; get_log_change_points flags significant shifts in log volume; get_alerts, get_services, get_traces and get_trace_metrics cover alerts and APM. Several of these arrived in 9.4, and some older ones were removed in 9.4, so check the reference against your version.

One wording trap: the reference says “built-in tools are read-only,” meaning you cannot edit or delete the tool definitions. It does not mean every tool only reads. The reference also lists tools that create and update cases, run workflows or act on saved Kibana connectors, several of them in technical preview. What the agent can change is decided by the credentials it connects with, which is the next section.

A read-only API key for the agent

On Elastic Stack deployments the MCP endpoint authenticates with an API key. Elastic’s API key guide for the MCP server (opens in a new tab) says tools execute with the scope assigned to the key, and shows a key limited to log and metric indices. In Kibana Dev Tools, send POST /_security/api_key with this body:

Request body for POST /_security/api_key
{
  "name": "agent-logs-readonly",
  "expiration": "30d",
  "role_descriptors": {
    "mcp-access": {
      "cluster": ["monitor_inference"],
      "indices": [
        {
          "names": ["logs-*", "metrics-*"],
          "privileges": ["read", "view_index_metadata"]
        }
      ],
      "applications": [
        {
          "application": "kibana-.kibana",
          "privileges": ["feature_agentBuilder.read", "feature_actions.read"],
          "resources": ["space:default"]
        }
      ]
    }
  }
}
  • read and view_index_metadata on named index patterns let the agent query and see mappings, and nothing else. Elastic’s note on the example: read-only privileges prevent the agent from modifying data.
  • monitor_inference is the cluster privilege Elastic says is required to use Elasticsearch inference endpoints.
  • The application must be exactly kibana-.kibana. Without feature_agentBuilder.read the endpoint answers 403 Forbidden.
  • Set an expiry. Elastic suggests 1 to 7 days for development and 30 to 90 days for production, with regular rotation.
  • Keep sensitive indices out of the pattern. An index the key can read is an index the model can read, and whatever a tool returns goes to your AI client’s model provider.

Give each agent or job its own key, so revoking one leaves the rest working. The general habits are in MCP security best practices.

Connecting Claude, Cursor and VS Code

Elastic’s documented client configuration runs mcp-remote, a small npm bridge, with the endpoint and an Authorization: ApiKey ... header. The same block goes in Claude Desktop’s config file, Cursor’s mcp.json or VS Code’s MCP configuration:

MCP client configuration, as Elastic documents it
{
  "mcpServers": {
    "elastic-agent-builder": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "${KIBANA_URL}/api/agent_builder/mcp",
        "--header",
        "Authorization:${AUTH_HEADER}"
      ],
      "env": {
        "KIBANA_URL": "${KIBANA_URL}",
        "AUTH_HEADER": "ApiKey ${API_KEY}"
      }
    }
  }
}

The Kibana API reference for the endpoint (opens in a new tab) shows it accepting MCP requests over HTTP with an ApiKey header, and notes it is meant for MCP clients rather than direct REST calls. A client that sends headers itself can therefore skip the bridge. In Claude Code:

Terminal
claude mcp add --transport http elastic \
  "https://<your-kibana-host>/api/agent_builder/mcp" \
  --header "Authorization: ApiKey <your-api-key>"

Run /mcp to confirm the tools are listed. Either way, that config holds a live key; keep it out of anything you commit. If a server shows but will not connect, Claude Code MCP not working covers the usual causes.

OAuth on Serverless

Serverless projects can also use OAuth 2.1 through an application connection. Elastic’s comparison is useful: an API key is one shared identity with the key’s fixed permissions, suited to automation; OAuth gives each person their own connection, acting with their own live permissions, revocable one at a time, with short-lived tokens that need a new connection after 30 days unused. For people using Claude or Cursor interactively on Serverless, OAuth is the better fit. How the browser flow works is in how MCP sign-in works.

Elasticsearch MCP with Docker

If you are on 8.x, or already run the standalone server, its README gives two modes. Over stdio, the client starts the container:

Terminal, deprecated standalone server
docker run -i --rm -e ES_URL -e ES_API_KEY \
  docker.elastic.co/mcp/elasticsearch stdio

# or Streamable HTTP on port 8080, endpoint /mcp
docker run --rm -e ES_URL -e ES_API_KEY -p 8080:8080 \
  docker.elastic.co/mcp/elasticsearch http

Its tools are list_indices, get_mappings, search, esql and get_shards. The same key discipline applies: create the key with read on the indices the agent needs, not a superuser login in ES_USERNAME and ES_PASSWORD, and leave ES_SSL_SKIP_VERIFY off outside a test cluster. Plan the move to Agent Builder when you upgrade, since the container gets security fixes only.

Searching logs from an agent

The pattern that works is narrow questions, a time window and a service name: “Using logs from the last hour for service checkout-api, group the errors by message pattern and show the three most common with one sample each.” Ask the agent to show the ES|QL it ran, so you can rerun it in Discover and check the numbers. Two cautions. Large result sets fill the context window quickly, so prefer counts, patterns and samples to raw documents; MCP token usage explains the cost. And log lines are written by whoever can reach your services, which makes them untrusted input to the model; see indirect prompt injection.

From a log search to a task

Once the agent has found the error pattern and the service, the next step is a record that someone will fix it. With fenbs connected as a second MCP server at https://fenbs.ai/api/mcp, the assistant can search the board for an existing task, and if there is none, file a bug in To Do with the pattern, the ES|QL query and a sample in the note, and a priority from 1 to 10. When the fix ships, it records a test status and test notes from a fresh query and moves the task to Completed; History keeps each step under the assistant’s name. fenbs does not read Elasticsearch or receive alerts itself; the agent carries the finding across. The same flow with other tools is in Datadog MCP server and Grafana MCP server.

Related

Querying databases directly: database MCP server. When the error is an outage: AI agent incident response. Errors rather than logs: Sentry MCP. Connecting the board: Claude Code, Cursor and the MCP docs.

Questions people ask.

Does Elasticsearch have a first-party MCP server?

Yes. Elastic Agent Builder exposes an MCP endpoint in Kibana at /api/agent_builder/mcp. It is generally available on Elastic Stack 9.3 and later and on Serverless projects, and was a preview in 9.2.

Is the elastic/mcp-server-elasticsearch project still supported?

It is deprecated. Elastic says it will only receive critical security updates and has been superseded by the Agent Builder MCP endpoint. It still runs as a Docker image against Elasticsearch 8.x and 9.x.

How do I make the Elasticsearch MCP server read-only?

Connect with an API key whose index privileges are read and view_index_metadata on named index patterns, with the Kibana feature_agentBuilder.read privilege and an expiry. Tools execute with the scope assigned to the key.

How do I connect the Elasticsearch MCP server to Claude?

Elastic documents a client configuration that runs mcp-remote with your Kibana URL and an Authorization header of ApiKey followed by your key. Clients such as Claude Code can also add the endpoint over HTTP and send the header directly.

Start with one thing.

There is nothing to set up first. Write one line and you’ve started.