Skip to main content
Glama
ukonduru91

Spark History Server MCP

by ukonduru91

Spark History Server MCP (TypeScript)

Da a un LLM acceso de lectura a tu Spark History Server para que pueda ocuparse de la parte tediosa del trabajo con Spark: averiguar por qué falló un trabajo y en qué emplea el tiempo un trabajo lento.

Es una adaptación a TypeScript de kubeflow/mcp-apache-spark-history-server, verificada respuesta por respuesta contra el original en Python; consulta PARITY.md. Además de la adaptación, incluye dos habilidades de agente que convierten las herramientas básicas en un flujo de trabajo experto para el análisis de causas raíz y la optimización del rendimiento.

                    ┌──────────────────┐
  data engineer ──▶ │  LLM client      │   Claude Code / Claude Desktop / any MCP client
                    │  + skills        │   ← skills/ supply the method
                    └────────┬─────────┘
                             │ MCP (stdio or streamable-http)
                    ┌────────▼─────────┐
                    │  this server     │   17 tools, 2 prompts
                    └────────┬─────────┘
                             │ HTTP  GET /api/v1/...
                    ┌────────▼─────────┐
                    │ Spark History    │   your existing one, or the bundled demo
                    │ Server           │
                    └────────┬─────────┘
                             │ reads
                    ┌────────▼─────────┐
                    │ event logs       │   s3://…, hdfs://…, file://…
                    └──────────────────┘

El servidor solo emite peticiones GET a la API REST del History Server. No puede modificar nada.


Contenido

  1. Inicio rápido

  2. Apuntarlo a tu Spark History Server

  3. Conectar tu cliente LLM

  4. Instalar las habilidades

  5. Las herramientas

  6. Cómo funciona

  7. Despliegue

  8. Solución de problemas

  9. Desarrollo


Related MCP server: Spark EventLog MCP Server

1. Inicio rápido

Opción A — Docker (nada que instalar salvo Docker)

Inicia un Spark History Server cargado con registros de eventos de ejemplo y este MCP:

git clone https://github.com/ukonduru91/spark-history-mcp.git
cd spark-history-mcp
docker compose up --build

Los registros incluidos contienen un pipeline saludable y un trabajo deliberadamente fallido, de modo que las herramientas tienen algo real que mostrar antes de apuntarlas a tu propio clúster.

Para ejecutar solo el History Server:

./start_local_spark_history.sh          # macOS / Linux / Git Bash
.\start_local_spark_history.ps1         # Windows PowerShell

Opción B — desde el código fuente

Requiere Node.js 20+ (se recomienda 22).

git clone https://github.com/ukonduru91/spark-history-mcp.git
cd spark-history-mcp
npm install
npm run build
npm start

Comprueba que funciona

node scripts/mcp-cli.mjs list-tools
node scripts/mcp-cli.mjs call list_applications '{"limit": 5}'

Si aparecen aplicaciones, estás conectado.


2. Apuntarlo a tu Spark History Server

Esto es lo único que debes configurar. Hay tres formas, de mayor a menor precedencia: las variables de entorno prevalecen sobre el archivo .env, y este sobre YAML.

a. Variables de entorno (ideal para contenedores y CI)

El anidamiento utiliza un doble guion bajo. LOCAL, abajo, es solo un nombre que eliges para el servidor:

export SHS_SERVERS__LOCAL__URL=http://spark-history.internal:18080
export SHS_SERVERS__LOCAL__DEFAULT=true

b. Un archivo de configuración YAML

El servidor busca uno en este orden:

  1. la ruta indicada en --config, o $SHS_MCP_CONFIG

  2. ./config.yaml en el directorio de trabajo

  3. ~/.config/spark-mcp/config.yaml

servers:
  prod:
    url: "https://spark-history.company.com:18080"
    default: true          # used when a tool call omits `server`
    verify_ssl: true
    ssl_ca_cert: "/etc/ssl/custom-ca/ca-bundle.pem"   # private CA
    timeout: 30            # seconds
    auth:
      username: admin
      password: ${SPARK_PASSWORD}   # see the note below
      # token: <bearer token>       # or a bearer token instead

  staging:
    url: "https://spark-history-staging.company.com:18080"

Sobre los secretos: los valores en YAML son literales — ${SPARK_PASSWORD} no se expande. Mantén las credenciales en variables de entorno (SHS_SERVERS__PROD__AUTH__PASSWORD), que tienen prioridad sobre el archivo. Esto coincide con el comportamiento del proyecto original.

c. Un archivo .env

Mismos nombres de variables que en (a); se lee desde .env en el directorio de trabajo.

Varios servidores

Configura tantos como quieras. Las herramientas aceptan un argumento server opcional; cuando se omite, el servidor descubre qué History Server configurado tiene esa aplicación y lo usa (con caché de 5 minutos). Por tanto, un ingeniero puede preguntar por un id de aplicación sin saber qué clúster la ejecutó.

Todos los ajustes

Ajuste

Variable de entorno

Por defecto

Significado

servers.<n>.url

SHS_SERVERS__<N>__URL

http://localhost:18080

URL base del History Server

servers.<n>.default

SHS_SERVERS__<N>__DEFAULT

false

se usa cuando no se indica server

servers.<n>.auth.username

SHS_SERVERS__<N>__AUTH__USERNAME

autenticación básica

servers.<n>.auth.password

SHS_SERVERS__<N>__AUTH__PASSWORD

autenticación básica

servers.<n>.auth.token

SHS_SERVERS__<N>__AUTH__TOKEN

token de portador

servers.<n>.verify_ssl

SHS_SERVERS__<N>__VERIFY_SSL

true

verificación TLS

servers.<n>.ssl_ca_cert

SHS_SERVERS__<N>__SSL_CA_CERT

paquete PEM para una CA privada

servers.<n>.timeout

SHS_SERVERS__<N>__TIMEOUT

30

tiempo de espera de la solicitud, segundos

servers.<n>.use_proxy

SHS_SERVERS__<N>__USE_PROXY

false

enrutar mediante socks5h://localhost:8157

servers.<n>.include_plan_description

SHS_SERVERS__<N>__INCLUDE_PLAN_DESCRIPTION

false

predeterminado para el texto del plan de get_sql_execution

mcp.transport

SHS_MCP__TRANSPORT

streamable-http

stdio o streamable-http

mcp.address

SHS_MCP__ADDRESS

localhost

dirección de enlace para HTTP

mcp.port

SHS_MCP__PORT

18888

puerto de enlace para HTTP

mcp.debug

SHS_MCP__DEBUG

false

registro detallado

Las variables con un solo guion bajo (SHS_MCP_PORT) siguen funcionando, pero registran una advertencia de obsolescencia, igual que el proyecto original.

Acceder a un History Server al que no puedes enrutar

Un túnel SSH junto con use_proxy: true cubre el caso habitual de un clúster restringido:

ssh -D 8157 -N user@bastion    # SOCKS5 proxy on :8157

3. Conectar tu cliente LLM

stdio (Claude Code, Claude Desktop, la mayoría de los clientes)

{
  "mcpServers": {
    "spark-history": {
      "command": "node",
      "args": ["/absolute/path/to/spark-history-mcp/dist/index.js"],
      "env": {
        "SHS_MCP__TRANSPORT": "stdio",
        "SHS_SERVERS__PROD__URL": "https://spark-history.company.com:18080",
        "SHS_SERVERS__PROD__DEFAULT": "true"
      }
    }
  }
}

Los usuarios de Claude Code pueden hacer lo mismo en una línea:

claude mcp add spark-history \
  --env SHS_MCP__TRANSPORT=stdio \
  --env SHS_SERVERS__PROD__URL=https://spark-history.company.com:18080 \
  --env SHS_SERVERS__PROD__DEFAULT=true \
  -- node /absolute/path/to/spark-history-mcp/dist/index.js

streamable-http (un servidor compartido para un equipo)

Ejecútalo una vez y apunta a todo el mundo a él:

SHS_MCP__TRANSPORT=streamable-http SHS_MCP__ADDRESS=0.0.0.0 npm start

Los clientes se conectan a http://<host>:18888/mcp. El servidor es de solo lectura, pero tampoco tiene autenticación: colócalo detrás de tu ingress interno habitual y activa la protección contra el rebinding de DNS si es accesible desde un navegador:

mcp:
  transport_security:
    enable_dns_rebinding_protection: true
    allowed_hosts: ["spark-mcp.internal:*"]
    allowed_origins: ["https://spark-mcp.internal"]

4. Instalar las habilidades

Las herramientas dan al modelo acceso a los datos. Las habilidades le dan el método: el orden para recopilar evidencia, los umbrales que separan un hallazgo del ruido y la regla de que no debe nombrar una causa que no ha visto en los datos.

# per project
mkdir -p .claude/skills
cp -r skills/spark-rca skills/spark-optimization .claude/skills/

# or for every project
mkdir -p ~/.claude/skills
cp -r skills/spark-rca skills/spark-optimization ~/.claude/skills/

Habilidad

Se ocupa de

Se activa con

spark-rca

trabajos fallidos, eliminados o bloqueados

"por qué falló", un stack trace, un id de aplicación, "OOM", "atascado"

spark-optimization

trabajos lentos, costosos o con regresiones

"por qué es lento", "optimiza", "antes tardaba 20 minutos", "reduce el coste"

Se activan por sí solas ante una pregunta normal: nadie tiene que recordar un comando:

"la carga de las 2 a.m. ha vuelto a fallar, app_1724… — ¿puedes mirarlo?"

Consulta skills/README.md para saber qué contiene cada una y cómo ampliarlas con el conocimiento de tu equipo.


5. Las herramientas

Las 17 herramientas están en src/tools/tools.ts; sus esquemas JSON están en src/schemas/generated.ts. Ejecuta node scripts/mcp-cli.mjs list-tools para verlas con sus argumentos.

Localizar cosas

Herramienta

Devuelve

list_applications

aplicaciones, filtrables por estado y fecha, o una por app_id

list_jobs

trabajos de una aplicación: los fallidos primero por defecto; sort_by duration / failed-tasks / id

list_stages

etapas, mismas opciones de ordenación, métricas de resumen opcionales

list_executors

ejecutores, activos por defecto, include_inactive para el historial completo

list_sql_executions

resúmenes de ejecuciones SQL seleccionados, filtrables por descripción

Profundizar

Herramienta

Devuelve

get_stage

una etapa con distribuciones de métricas por tarea en tus cuantiles

list_stage_task_failures

las excepciones y stack traces por tarea — donde viven las causas raíz

get_sql_execution

una consulta: cabecera, plan físico, métricas por nodo, trabajos, etapas

get_environment

versiones de runtime, propiedades de Spark/sistema/Hadoop, classpath — filtrable por section

get_executor_summary

métricas de ejecutores agregadas para la aplicación

get_executor_thread_dump

volcado de hilos de JVM — solo aplicaciones en ejecución

Diagnóstico

Herramienta

Devuelve

get_job_bottlenecks

etapas y trabajos más lentos, spill, presión de GC, utilización, recomendaciones

get_resource_usage_timeline

resumen de altas/bajas de ejecutores y de la línea temporal de etapas

Comparar dos ejecuciones

Herramienta

Devuelve

compare_job_environments

diff de configuración: qué cambió entre dos ejecuciones

compare_job_performance

diff de recursos y duración

compare_sql_executions

diff de métricas para dos consultas, más un diff opcional de la estructura del plan

compare_stages

métricas de etapa y cuantiles de tareas lado a lado

Prompts

investigate_failure(app_id, server?) y compare_applications(app_a, app_b, server?, context?) — recorridos interactivos del proyecto original, para cuando el ingeniero quiere dirigir en lugar de delegar el análisis.


6. Cómo funciona

Una llamada a una herramienta se convierte en una o más peticiones GET a /api/v1/..., y el JSON regresa con la forma exacta que le daba el original en Python.

src/
  index.ts                 CLI entry, transport selection (stdio | streamable-http)
  config/config.ts         YAML + .env + SHS_* resolution and precedence
  core/
    app.ts                 MCP request handlers; maps results to content blocks
    validation.ts          pydantic-compatible argument validation and messages
    json.ts                Python-compatible JSON rendering
    pyfloat.ts             int/float fidelity across the JSON round-trip
    pyrepr.ts              Python repr() for validation messages
    errors.ts              error text shaping
  api/
    httpClient.ts          HTTP transport, ApiException taxonomy, auth, TLS, SOCKS
    sparkClient.ts         Spark REST facade: pagination, attempts, status filters
  models/
    generated.ts           model shapes, generated from the upstream OpenAPI models
    deserialize.ts         from_dict / model_dump equivalents
    mcpTypes.ts            curated LLM-facing output models
  tools/tools.ts           the 17 tools
  prompts/prompts.ts       the 2 prompts
  schemas/generated.ts     tool + prompt catalogue (names, descriptions, schemas)

Tres detalles que conviene saber si planeas modificarlo:

  • models/generated.ts y schemas/generated.ts se generan mediante tools/gen_models.py y tools/gen_schemas.py, a partir del proyecto original en Python. Regéneralos en lugar de editarlos a mano: eso es lo que mantiene el catálogo y las formas de respuesta idénticos al original.

  • Se usa la API de bajo nivel Server, no McpServer, porque la forma del resultado debe coincidir con la de FastMCP: un bloque de texto por cada elemento de lista, y structuredContent solo para las herramientas cuya firma en Python declaraba un tipo de retorno concreto.

  • El descubrimiento de aplicaciones permite que las herramientas omitan server. ApplicationDiscovery sondea cada servidor configurado en busca del id de aplicación y guarda la respuesta en caché durante 5 minutos.

7. Despliegue

Docker

docker build -t spark-history-mcp .
docker run -p 18888:18888 \
  -e SHS_SERVERS__PROD__URL=https://spark-history.company.com:18080 \
  -e SHS_SERVERS__PROD__DEFAULT=true \
  -e SHS_MCP__ADDRESS=0.0.0.0 \
  spark-history-mcp

Kubernetes

Ejecútalo como un Deployment normal con la URL en las variables de entorno y las credenciales de un Secret:

env:
  - name: SHS_MCP__TRANSPORT
    value: streamable-http
  - name: SHS_MCP__ADDRESS
    value: "0.0.0.0"
  - name: SHS_SERVERS__PROD__URL
    value: http://spark-history-server.spark.svc.cluster.local:18080
  - name: SHS_SERVERS__PROD__DEFAULT
    value: "true"
  - name: SHS_SERVERS__PROD__AUTH__TOKEN
    valueFrom:
      secretKeyRef: { name: spark-history-auth, key: token }

El proceso no tiene estado, aparte de la caché de descubrimiento de 5 minutos, por lo que escala horizontalmente sin coordinación.


8. Solución de problemas

Síntoma

Causa y solución

connect ECONNREFUSED

URL o puerto incorrectos, o el History Server está caído. Comprueba curl $URL/api/v1/applications desde el mismo host

Application '<id>' not found on any server

el id no está en ningún servidor configurado, o el registro de eventos aún no se ha procesado — spark.history.fs.update.interval controla el escaneo

No Spark server named 'x' is configured

el argumento server no coincide con una clave bajo servers:

404 … No tasks reported metrics for N / 0 yet

la respuesta de Spark para una etapa que falló antes de que terminara cualquier tarea. No es un problema de la herramienta — lee las excepciones de las tareas

get_executor_thread_dump errors on a finished app

esperado: el History Server no persiste los volcados de hilos. Solo funcionan mientras la aplicación está en ejecución

Empty list_applications

comprueba que spark.history.fs.logDirectory apunte a donde tus trabajos escriben realmente los registros de eventos, y que spark.eventLog.enabled=true en los trabajos

Respuestas muy grandes

acota con length, limit y section. get_stage(with_summaries=false) es mucho más pequeña

emr_cluster_arn … not included in this TypeScript port

la autenticación de EMR persistent-UI no está portada; apunta a una URL directamente accesible en su lugar

Establece SHS_MCP__DEBUG=true para registros detallados.


9. Desarrollo

npm install
npm run build        # compile to dist/
npm run dev          # run from source, no build step
npm test             # unit tests
npm run typecheck    # tsc --noEmit

Las pruebas de paridad entre implementaciones se encuentran en parity/ — ejecutan las mismas llamadas MCP contra este servidor y el original en Python y comparan cada respuesta. PARITY.md registra los resultados y las diferencias exactas que quedan.

No portado desde upstream

Módulo upstream

Estado

api/emr_persistent_ui_client.py

no portado — un servidor configurado con emr_cluster_arn falla rápidamente con un error explicativo

tools/aws_troubleshooting.py

no portado — actúa como proxy a un endpoint MCP alojado en AWS, registrado solo cuando hay credenciales de AWS

api/spark_html_client.py

no portado — un asistente de capturas de pantalla de Playwright sin llamadas a herramientas


Licencia

Apache-2.0, al igual que el proyecto upstream.

A
license - permissive license
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI assistants to interact with Delta Lake tables stored in MinIO through Spark using natural language queries. Provides read-oriented data operations on Delta Lake tables through the Model Context Protocol.
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables comprehensive analysis of Apache Spark event logs from S3, HTTP, or local sources, providing performance metrics, resource monitoring, shuffle analysis, and automated optimization recommendations with interactive HTML reports.
    MIT
  • F
    license
    Not graded
    quality
    Not graded
    maintenance
    Exposes Spark History Server metrics and metadata as tools for LLM-based analysis of Spark applications. It enables deep optimization of Spark jobs by providing access to job summaries, stage details, SQL execution plans, and executor performance.
  • A
    license
    Not graded
    quality
    A
    maintenance
    Exposes Spark History Server data as tools for AI agents, enabling natural language querying of Spark applications, jobs, stages, and performance metrics.
    189
    Apache 2.0

View all related MCP servers

Related MCP Connectors

  • The grounded data layer for any LLM: governed SQL, metrics, lineage and catalog over your data.

  • Enable language models to perform advanced AI-powered web scraping with enterprise-grade reliabili…

  • LLM chat, text summarization and AI image generation

View all MCP Connectors

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/ukonduru91/spark-history-mcp'

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