Skip to main content
Glama
M0-AR

Custom Elasticsearch MCP Server

by M0-AR

Custom Elasticsearch MCP Server

A simple MCP (Model Context Protocol) server for Elasticsearch designed for cloud environments where your public key is already authorized on the server.

Why This Custom Version?

No API Key Required - Unlike the official Elasticsearch MCP server that requires both ES_URL and ES_API_KEY, this version only needs the URL since your public key is already trusted on the cloud server.

Enhanced Tools - Better usability with optional parameters and improved defaults compared to the official version.

What This Does

This MCP server connects Cursor to your Elasticsearch cluster with 4 powerful tools:

  • list_indices - List all indices (optional pattern filter)

  • search - Full Elasticsearch Query DSL support

  • get_mappings - Get field mappings for any index

  • get_shards - View cluster shard information

Quick Start

Build from Source

git clone https://github.com/M0-AR/Custom-Elasticsearch-MCP-Server.git cd Custom-Elasticsearch-MCP-Server docker build -t elasticsearch-mcp:latest .

2. Add to Cursor MCP Configuration

Add this to your .cursor/mcp.json file:

Configuration:

{ "mcpServers": { "elasticsearch-custom": { "command": "docker", "args": [ "run", "-i", "--rm", "--add-host=host.docker.internal:host-gateway", "-e", "ES_URL=http://host.docker.internal:9400", "elasticsearch-mcp:latest" ] } } }

3. Restart Cursor

Close and reopen Cursor. You should see the elasticsearch-custom server with 4 tools enabled.

Configuration

Environment Variables:

  • ES_URL - Your Elasticsearch URL (default: http://localhost:9400)

  • MAX_CONNECTIONS - Maximum concurrent connections (default: 100)

  • MAX_KEEPALIVE_CONNECTIONS - Maximum keepalive connections (default: 20)

  • CONNECTION_TIMEOUT - Connection timeout in seconds (default: 30)

  • REQUEST_TIMEOUT - Request timeout in seconds (default: 30)

For different Elasticsearch ports:

"ES_URL=http://host.docker.internal:9200"

For high-traffic environments:

"MAX_CONNECTIONS=200", "MAX_KEEPALIVE_CONNECTIONS=50", "CONNECTION_TIMEOUT=60", "REQUEST_TIMEOUT=60"

Example Usage

Once connected in Cursor, you can:

  • List all indices: "Show me all elasticsearch indices"

  • Search data: "Search for sales data in hq.sales index"

  • Get mappings: "What fields are in the hq.menuitems index?"

  • Check cluster: "Show me the elasticsearch cluster status"

Comparison with Official Server

Feature

Official Server

This Custom Server

Authentication

Requires ES_URL + ES_API_KEY

Only needs ES_URL (public key authorized)

list_indices

Requires indexPattern parameter

Optional parameter with "*" default

Tools Available

4 tools (same functions)

4 tools (enhanced usability)

Security

API key based

Public key authorization

Concurrency

Synchronous blocking

Async with connection pooling

Performance

Single request at a time

100+ concurrent requests

Concurrent Request Handling

This MCP server is designed to handle multiple parallel requests from multiple applications simultaneously using industry best practices:

Key Features:

Async/Await Architecture - Non-blocking I/O for parallel request processing ✅ Connection Pooling - Reuses HTTP connections (up to 100 concurrent) ✅ HTTP/2 Support - Multiplexes multiple requests over single connection ✅ Configurable Limits - Adjust connection limits for your workload ✅ Thread-Safe - FastMCP handles concurrent tool execution safely

Performance Characteristics:

  • Default: 100 concurrent connections, 20 keepalive connections

  • Scalable: Configure up to 1000+ concurrent connections

  • Efficient: Connection reuse reduces latency by ~50%

  • Reliable: Proper timeout handling prevents connection exhaustion

Configuration for High Traffic:

{ "mcpServers": { "elasticsearch-custom": { "command": "docker", "args": [ "run", "-i", "--rm", "--add-host=host.docker.internal:host-gateway", "-e", "ES_URL=http://host.docker.internal:9400", "-e", "MAX_CONNECTIONS=200", "-e", "MAX_KEEPALIVE_CONNECTIONS=50", "-e", "CONNECTION_TIMEOUT=60", "-e", "REQUEST_TIMEOUT=60", "elasticsearch-mcp:latest" ] } } }

Testing Concurrent Requests:

# Test 10 parallel requests for i in {1..10}; do echo '{"jsonrpc": "2.0", "id": '$i', "method": "tools/call", "params": {"name": "list_indices", "arguments": {}}}' | \ python3 simple_elasticsearch_mcp.py & done wait

Files

  • simple_elasticsearch_mcp.py - Main MCP server

  • Dockerfile - Container build instructions

  • requirements.txt - Python dependencies

Manual Testing

Test the server directly:

python3 simple_elasticsearch_mcp.py

Test with JSON-RPC commands:

1. List all tools:

echo '{"jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {}}' | python3 simple_elasticsearch_mcp.py

2. List all indices:

echo '{"jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": {"name": "list_indices", "arguments": {}}}' | python3 simple_elasticsearch_mcp.py

3. Search for data:

echo '{"jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": {"name": "search", "arguments": {"index": "hq.sales", "queryBody": {"query": {"match_all": {}}, "size": 3}}}}' | python3 simple_elasticsearch_mcp.py

4. Get index mappings:

echo '{"jsonrpc": "2.0", "id": 4, "method": "tools/call", "params": {"name": "get_mappings", "arguments": {"index": "hq.menuitems"}}}' | python3 simple_elasticsearch_mcp.py

5. Check cluster shards:

echo '{"jsonrpc": "2.0", "id": 5, "method": "tools/call", "params": {"name": "get_shards", "arguments": {}}}' | python3 simple_elasticsearch_mcp.py

Set custom Elasticsearch URL:

ES_URL="http://your-es-host:9200" python3 simple_elasticsearch_mcp.py

Troubleshooting

❌ "Connection refused" or "timed out" errors

Root Cause: The most common issue is Docker container networking when Elasticsearch is accessible via SSH tunnel.

Solution: Ensure these requirements are met:

1. SSH Tunnel Must Be Active

If your Elasticsearch is behind SSH tunnel (common for cloud deployments):

# Start SSH tunnel to forward port 9400 ssh -L 9400:localhost:9400 -N -f -l username your-server-ip # Verify tunnel is working curl -X GET "localhost:9400/_cluster/health?pretty"

2. Correct Docker Configuration

Your mcp.json should use exactly this configuration:

"elasticsearch-custom": { "command": "docker", "args": [ "run", "-i", "--rm", "--add-host=host.docker.internal:host-gateway", "-e", "ES_URL=http://host.docker.internal:9400", "elasticsearch-mcp:latest" ] }

Key Points:

  • ✅ Use --add-host=host.docker.internal:host-gateway (not IP addresses)

  • ✅ Use ES_URL=http://host.docker.internal:9400 (not localhost)

  • ✅ SSH tunnel must be running before starting Cursor

3. Test Docker Connectivity

# Test if Docker can reach your Elasticsearch docker run --rm --add-host=host.docker.internal:host-gateway alpine/curl \ curl -s http://host.docker.internal:9400/_cluster/health

4. Complete MCP Docker Test

Test the full MCP workflow with this comprehensive command:

# Full MCP server test with proper initialization { echo '{"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {"protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": {"name": "test-client", "version": "1.0.0"}}}'; echo '{"jsonrpc": "2.0", "method": "notifications/initialized", "params": {}}'; echo '{"jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": {"name": "list_indices", "arguments": {}}}'; } | docker run -i --rm --add-host=host.docker.internal:host-gateway -e ES_URL="http://host.docker.internal:9400" elasticsearch-mcp:latest

Expected Output:

  • Initialization response with server info

  • List of all Elasticsearch indices in JSON format

  • No error messages

5. Alternative: Network Host Mode

If host-gateway doesn't work, try network host mode:

"args": [ "run", "-i", "--rm", "--network=host", "-e", "ES_URL=http://localhost:9400", "elasticsearch-mcp:latest" ]

❌ "Received request before initialization was complete"

Root Cause: MCP protocol requires proper initialization sequence.

Solution: Always initialize before calling tools:

# Correct sequence: echo '{"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {"protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": {"name": "test", "version": "1.0"}}}' echo '{"jsonrpc": "2.0", "method": "notifications/initialized", "params": {}}' echo '{"jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": {"name": "list_indices", "arguments": {}}}'

That's It!

Build → Add to config → Restart Cursor → Done! 🚀

-
security - not tested
F
license - not found
-
quality - not tested

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/M0-AR/Custom-Elasticsearch-MCP-Server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server