Elasticsearch MCP Server Cursor IDE Setup (2026): Query Indices and Debug Slow Searches from Chat
Set up an Elasticsearch MCP server in Cursor IDE with a scoped API key, mcp.json config, and real prompts for inspecting mappings and debugging slow queries — plus why you should never point it at production with an admin key.
Elasticsearch MCP Server Cursor IDE Setup (2026)
How do you connect Elasticsearch to Cursor IDE? Create a scoped API key on your cluster, add an elasticsearch block to ~/.cursor/mcp.json with your cluster URL and that key, then restart Cursor. Once connected, your AI assistant can inspect index mappings, run search queries, and check cluster health from chat — without you opening Kibana Dev Tools for every question.
The part worth reading before you wire this in: an API key's privileges are whatever you configured when you created it, not something the MCP layer restricts further. A key with broad cluster access means the AI has broad cluster access. More on scoping that safely below.
What This Is Actually Useful For
text vs keyword mismatches are a constant source of "why doesn't my filter match" bugs)Where This Falls Short
Elasticsearch aggregations and deep pagination can be genuinely expensive — a poorly-scoped terms aggregation over a high-cardinality field, or a match_all with a large size, can put real load on a cluster. An AI assistant doesn't know your cluster's capacity the way you do, and there's no built-in query-cost governor in the MCP layer. Don't hand this a key with write access to a production index during business hours and let it run ad hoc aggregations unsupervised — treat it the way you'd treat giving a new team member direct Dev Tools access on day one.
Prerequisites
Step 1: Create a Scoped API Key
Don't reuse your admin credentials. In Kibana Dev Tools (or via a direct REST call to /_security/api_key), create a key limited to the indices you actually want exposed:
POST /_security/api_key
{
"name": "cursor-mcp-readonly",
"role_descriptors": {
"cursor_read_only": {
"cluster": ["monitor"],
"index": [
{
"names": ["my-app-logs-*", "my-app-products"],
"privileges": ["read", "view_index_metadata"]
}
]
}
}
}
This gives the key read access to two specific index patterns and cluster-monitoring visibility (for health checks), but no write, no delete, and no visibility into any other index on the cluster. The response includes an id and api_key — combine them as id:api_key and base64-encode the pair; that's the value most Elasticsearch clients (and this MCP server) expect in the Authorization: ApiKey header.
If you genuinely need the AI to index or update documents as part of your workflow, create a second, separately-named key with create_doc or index privileges scoped to a specific index pattern — don't just widen the read-only key later and lose track of what it's allowed to do.
Step 2: Configure Cursor's MCP Settings
Add the server to ~/.cursor/mcp.json:
{
"mcpServers": {
"elasticsearch": {
"command": "npx",
"args": ["-y", "@elastic/mcp-server-elasticsearch"],
"env": {
"ES_URL": "https://your-deployment.es.us-east-1.aws.found.io:9243",
"ES_API_KEY": "your-base64-encoded-id-and-key"
}
}
}
}
Community and vendor MCP package names in this space shift as the ecosystem matures — confirm current install instructions on the package's own README before standardizing a team config on a specific one. The ES_URL/ES_API_KEY env var shape above is representative of how most Elasticsearch MCP integrations expect credentials; check the specific package's docs if it uses different variable names.
Step 3: Restart Cursor and Verify
Quit and reopen Cursor, then check View → Output → MCP for a clean startup. Test with something cheap and read-only:
What's the mapping for the my-app-products index?
If you get real field names and types back, the connection and the key's index privileges are both working.
Practical Workflows
Check a mapping before writing ingestion code
What type is the "created_at" field on my-app-logs-2026.07? I want to know if it's mapped as date or text before I write the bulk indexing script.
Debug why a filter isn't matching
I'm filtering on status: "active" and getting zero results even though I can see active documents in Kibana. Check the mapping for the status field — is it analyzed as text instead of keyword?
Draft a query before committing it to application code
Write an Elasticsearch Query DSL body that matches products in the "electronics" category with price between 100 and 500, sorted by price ascending
Check cluster health during an incident
What's the current cluster health status, and are any indices in my-app-logs-* red or yellow right now?
Troubleshooting
"security_exception" or 401 on every request
The API key is invalid, expired, or wasn't base64-encoded correctly. Regenerate the key and double check you combined id:api_key (with the colon) before encoding, not just the raw api_key value alone.
"circuit_breaking_exception"
This means a query — usually a large aggregation or an oversized size on a search — is asking for more memory than the node's circuit breaker allows. This isn't a config bug; it's the cluster protecting itself. Narrow the query (smaller time range, more selective filter, a terms aggregation with a lower size) rather than raising breaker limits to work around it.
"index_not_found_exception" for an index you know exists
Check the key's role_descriptors.index.names pattern from Step 1 — if the index doesn't match the pattern you scoped the key to, Elasticsearch returns not-found rather than a permission error, which can be confusing to debug.
Server doesn't appear in Cursor
Run the npx command from Step 2 directly in a terminal. If it throws a connection or auth error there, fix that first — the MCP layer just proxies to the same client library, so it won't work around a broken connection.
Queries feel slow compared to Kibana
Check whether the AI is running unbounded queries (no size limit, wide date ranges) rather than the specific, scoped queries you'd normally write by hand. Being explicit in your prompt about the time range and fields you care about usually fixes this.
Frequently Asked Questions
Q: Can the AI accidentally delete or modify my data through this connection?
A: Only if the API key you configured has write or delete privileges. A key scoped to read and view_index_metadata (as shown in Step 1) can't modify anything — it's worth creating that restricted key even if it means a second, separately-scoped key for the rare case you actually want writes.
Q: Should I point this at my production cluster or a replica?
A: If you have a staging cluster or a read replica, start there — you'll catch prompt-wording problems (an aggregation that's more expensive than you expected, a query scoped wider than intended) without any production load risk. If production is your only option, use a read-only key and be deliberate about query scope, especially aggregations.
Q: Does this work with Elasticsearch Cloud (Elastic Cloud) or only self-managed clusters?
A: Both — the connection is just HTTPS plus an API key, which works the same way whether the cluster is self-managed, on Elastic Cloud, or running in a hosted Kubernetes deployment. Your ES_URL is whatever endpoint your deployment exposes.
Q: What's the actual difference between this and just calling the Elasticsearch REST API myself?
A: The REST API is what's underneath either way. The MCP server's value is letting the AI decide which endpoint and query shape to use based on a plain-language question, without you writing the Query DSL by hand every time — useful for exploration and debugging, less useful once you know exactly what query you need for production code.
Q: Is there a way to limit how expensive a single query can get?
A: Not from the MCP config itself. The real controls are cluster-side: circuit breakers (which will reject a query that asks for too much memory) and the index privileges on your API key. Scoping the key to specific indices, as shown in Step 1, is the most effective lever you actually control from the Cursor side.
Related Guides
---
Related guides
- Jira MCP Server Cursor IDE Setup (2025-2026): 5-Minute Config to Read & Transition Tickets
- Kubernetes MCP Server Setup for Cursor IDE (2026): Query Pods, Logs & Deployments from Chat
- Linear MCP Server Cursor IDE Setup 2026: Manage Issues from Your Editor
- MongoDB MCP Server in Cursor IDE: Query Collections & Debug Schemas (2026)