Custom Elasticsearch
Un servidor MCP simple para Elasticsearch, diseñado para entornos en la nube donde tu clave pública ya está autorizada.
Documentación
Servidor MCP de Elasticsearch personalizado
Un servidor MCP (Protocolo de Contexto de Modelo) sencillo para Elasticsearch, diseñado para entornos en la nube donde tu clave pública ya está autorizada en el servidor.
¿Por qué esta versión personalizada?
Sin necesidad de clave de API — A diferencia del servidor MCP oficial de Elasticsearch que requiere tanto ES_URL como ES_API_KEY, esta versión solo necesita la URL, ya que tu clave pública ya es de confianza en el servidor en la nube.
Herramientas mejoradas — Mejor usabilidad con parámetros opcionales y valores predeterminados mejorados en comparación con la versión oficial.
Qué hace esto
Este servidor MCP conecta Cursor a tu clúster de Elasticsearch con 4 herramientas potentes:
list_indices— Lista todos los índices (filtro de patrón opcional)search— Soporte completo de Elasticsearch Query DSLget_mappings— Obtiene los mapeos de campos para cualquier índiceget_shards— Ve la información de los fragmentos del clúster
Inicio rápido
Compilar desde el código fuente
git clone https://github.com/M0-AR/Custom-Elasticsearch-MCP-Server.git
cd Custom-Elasticsearch-MCP-Server
docker build -t elasticsearch-mcp:latest .
2. Agregar a la configuración de MCP en Cursor
Agrega esto a tu archivo .cursor/mcp.json:
Configuración:
{
"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. Reiniciar Cursor
Cierra y vuelve a abrir Cursor. Deberías ver el servidor elasticsearch-custom con 4 herramientas habilitadas.
Configuración
Variables de entorno:
ES_URL— Tu URL de Elasticsearch (predeterminado:http://localhost:9400)MAX_CONNECTIONS— Máximo de conexiones concurrentes (predeterminado:100)MAX_KEEPALIVE_CONNECTIONS— Máximo de conexiones keepalive (predeterminado:20)CONNECTION_TIMEOUT— Tiempo de espera de conexión en segundos (predeterminado:30)REQUEST_TIMEOUT— Tiempo de espera de solicitud en segundos (predeterminado:30)
Para diferentes puertos de Elasticsearch:
"ES_URL=http://host.docker.internal:9200"
Para entornos de alto tráfico:
"MAX_CONNECTIONS=200",
"MAX_KEEPALIVE_CONNECTIONS=50",
"CONNECTION_TIMEOUT=60",
"REQUEST_TIMEOUT=60"
Ejemplo de uso
Una vez conectado en Cursor, puedes:
- Listar todos los índices: "Muéstrame todos los índices de Elasticsearch"
- Buscar datos: "Buscar datos de ventas en el índice hq.sales"
- Obtener mapeos: "¿Qué campos hay en el índice hq.menuitems?"
- Verificar el clúster: "Muéstrame el estado del clúster de Elasticsearch"
Comparación con el servidor oficial
| Característica | Servidor oficial | Este servidor personalizado |
|---|---|---|
| Autenticación | Requiere ES_URL + ES_API_KEY | Solo necesita ES_URL (clave pública autorizada) |
| list_indices | Requiere el parámetro indexPattern | Parámetro opcional con valor predeterminado "*" |
| Herramientas disponibles | 4 herramientas (mismas funciones) | 4 herramientas (usabilidad mejorada) |
| Seguridad | Basada en clave de API | Autorización mediante clave pública |
| Concurrencia | Bloqueo síncrono | Asíncrono con agrupación de conexiones |
| Rendimiento | Una solicitud a la vez | Más de 100 solicitudes concurrentes |
Manejo de solicitudes concurrentes
Este servidor MCP está diseñado para manejar múltiples solicitudes paralelas de varias aplicaciones simultáneamente, utilizando las mejores prácticas de la industria:
Características clave:
✅ Arquitectura Async/Await — E/S sin bloqueo para procesamiento de solicitudes en paralelo ✅ Agrupación de conexiones — Reutiliza conexiones HTTP (hasta 100 concurrentes) ✅ Soporte HTTP/2 — Multiplexa múltiples solicitudes sobre una sola conexión ✅ Límites configurables — Ajusta los límites de conexión según tu carga de trabajo ✅ Seguro para subprocesos — FastMCP maneja la ejecución concurrente de herramientas de manera segura
Características de rendimiento:
- Predeterminado: 100 conexiones concurrentes, 20 conexiones keepalive
- Escalable: Configura hasta más de 1000 conexiones concurrentes
- Eficiente: La reutilización de conexiones reduce la latencia en ~50%
- Confiable: El manejo adecuado de tiempos de espera evita el agotamiento de conexiones
Configuración para alto tráfico:
{
"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"
]
}
}
}
Prueba de solicitudes concurrentes:
# 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
Archivos
simple_elasticsearch_mcp.py— Servidor MCP principalDockerfile— Instrucciones de compilación del contenedorrequirements.txt— Dependencias de Python
Pruebas manuales
Prueba el servidor directamente:
python3 simple_elasticsearch_mcp.py
Prueba con comandos JSON-RPC:
1. Listar todas las herramientas:
echo '{"jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {}}' | python3 simple_elasticsearch_mcp.py
2. Listar todos los índices:
echo '{"jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": {"name": "list_indices", "arguments": {}}}' | python3 simple_elasticsearch_mcp.py
3. Buscar datos:
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. Obtener mapeos de índices:
echo '{"jsonrpc": "2.0", "id": 4, "method": "tools/call", "params": {"name": "get_mappings", "arguments": {"index": "hq.menuitems"}}}' | python3 simple_elasticsearch_mcp.py
5. Verificar fragmentos del clúster:
echo '{"jsonrpc": "2.0", "id": 5, "method": "tools/call", "params": {"name": "get_shards", "arguments": {}}}' | python3 simple_elasticsearch_mcp.py
Establecer una URL personalizada de Elasticsearch:
ES_URL="http://your-es-host:9200" python3 simple_elasticsearch_mcp.py
Solución de problemas
❌ Errores de "Conexión rechazada" o "tiempo de espera agotado"
Causa raíz: El problema más común es la red de contenedores Docker cuando Elasticsearch es accesible a través de un túnel SSH.
Solución: Asegúrate de que se cumplan estos requisitos:
1. El túnel SSH debe estar activo
Si tu Elasticsearch está detrás de un túnel SSH (común en implementaciones en la nube):
# 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. Configuración correcta de Docker
Tu mcp.json debe usar exactamente esta configuración:
"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"
]
}
Puntos clave:
- ✅ Usa
--add-host=host.docker.internal:host-gateway(no direcciones IP) - ✅ Usa
ES_URL=http://host.docker.internal:9400(no localhost) - ✅ El túnel SSH debe estar en ejecución antes de iniciar Cursor
3. Prueba la conectividad de Docker
# 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. Prueba completa de MCP con Docker
Prueba el flujo de trabajo completo de MCP con este comando integral:
# 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
Salida esperada:
- Respuesta de inicialización con información del servidor
- Lista de todos los índices de Elasticsearch en formato JSON
- Sin mensajes de error
5. Alternativa: Modo de red de host
Si host-gateway no funciona, prueba el modo de red de host:
"args": [
"run", "-i", "--rm", "--network=host",
"-e", "ES_URL=http://localhost:9400",
"elasticsearch-mcp:latest"
]
❌ "Se recibió una solicitud antes de que se completara la inicialización"
Causa raíz: El protocolo MCP requiere una secuencia de inicialización adecuada.
Solución: Siempre inicializa antes de llamar a las herramientas:
# 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": {}}}'
¡Eso es todo!
Compila → Agrega a la configuración → Reinicia Cursor → ¡Listo! 🚀