Spark History Server MCP
Spark History Server MCP (TypeScript)
Дайте LLM доступ на чтение к вашему Spark History Server, чтобы он мог выполнять утомительную часть работы со Spark: выяснять, почему задание упало, и находить, где медленное задание тратит время.
Это порт на TypeScript проекта kubeflow/mcp-apache-spark-history-server, проверенный ответ-в-ответ против оригинального Python-кода — см. PARITY.md. Поверх порта он поставляет два агентских навыка, которые превращают сырые инструменты в экспертный рабочий процесс для анализа первопричин и настройки производительности.
┌──────────────────┐
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://…
└──────────────────┘Сервер отправляет только GET-запросы к REST API History Server. Он не может ничего изменить.
Содержание
Related MCP server: Spark History MCP Server
1. Быстрый старт
Вариант A — Docker (ничего устанавливать не нужно, кроме Docker)
Запускает Spark History Server с образцами журналов событий и этим MCP:
git clone https://github.com/ukonduru91/spark-history-mcp.git
cd spark-history-mcp
docker compose up --buildUI Spark History Server | |
REST API Spark History | |
Конечная точка MCP |
В комплект входят журналы, включающие исправный конвейер и намеренно упавшее задание, так что инструментам есть что показать, прежде чем вы направите их на свой собственный кластер.
Чтобы запустить только History Server:
./start_local_spark_history.sh # macOS / Linux / Git Bash
.\start_local_spark_history.ps1 # Windows PowerShellВариант B — из исходников
Требуется Node.js 20+ (рекомендуется 22).
git clone https://github.com/ukonduru91/spark-history-mcp.git
cd spark-history-mcp
npm install
npm run build
npm startПроверка работоспособности
node scripts/mcp-cli.mjs list-tools
node scripts/mcp-cli.mjs call list_applications '{"limit": 5}'Если приложения возвращаются, вы подключены.
2. Подключение к вашему Spark History Server
Это единственное, что вам нужно настроить. Три способа, в порядке убывания
приоритета — переменные окружения имеют приоритет над файлом .env, который
имеет приоритет над YAML.
a. Переменные окружения (лучше всего для контейнеров и CI)
Вложенность использует двойное подчёркивание. LOCAL ниже — это просто имя,
которое вы выбираете для сервера:
export SHS_SERVERS__LOCAL__URL=http://spark-history.internal:18080
export SHS_SERVERS__LOCAL__DEFAULT=trueb. YAML-файл конфигурации
Сервер ищет его в следующем порядке:
путь, указанный в
--config, или$SHS_MCP_CONFIG./config.yamlв рабочем каталоге~/.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"О секретах: значения в YAML являются литеральными —
${SPARK_PASSWORD}не раскрывается. Храните учётные данные в переменных окружения (SHS_SERVERS__PROD__AUTH__PASSWORD), которые переопределяют файл. Это соответствует поведению вышестоящего проекта.
c. Файл .env
Те же имена переменных, что и в (a), читаются из .env в рабочем каталоге.
Несколько серверов
Настройте столько, сколько нужно. Инструменты принимают необязательный аргумент
server; когда он опущен, сервер обнаруживает, на каком из настроенных
History Server находится это приложение, и использует его (кэшируется на 5 минут).
Таким образом, инженер может спросить об идентификаторе приложения, не зная, на
каком кластере оно выполнялось.
Все настройки
Настройка | Переменная окружения | По умолчанию | Значение |
|
|
| Базовый URL History Server |
|
|
| использовать, когда |
|
| — | базовая аутентификация |
|
| — | базовая аутентификация |
|
| — | токен-носитель |
|
|
| проверка TLS |
|
| — | PEM-пакет для частного CA |
|
|
| таймаут запроса, секунды |
|
|
| маршрутизация через |
|
|
| по умолчанию для текста плана |
|
|
|
|
|
|
| адрес привязки для HTTP |
|
|
| порт привязки для HTTP |
|
|
| подробное журналирование |
Переменные с одним подчёркиванием (SHS_MCP_PORT) по-прежнему работают, но
выводят предупреждение об устаревании, точно так же, как в вышестоящем проекте.
Доступ к History Server, к которому нет маршрута
SSH-туннель плюс use_proxy: true покрывает типичный случай закрытого кластера:
ssh -D 8157 -N user@bastion # SOCKS5 proxy on :81573. Подключение вашего LLM-клиента
stdio (Claude Code, Claude Desktop, большинство клиентов)
{
"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"
}
}
}
}Пользователи Claude Code могут сделать то же самое одной строкой:
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.jsstreamable-http (один общий сервер для команды)
Запустите один раз, укажите всем на него:
SHS_MCP__TRANSPORT=streamable-http SHS_MCP__ADDRESS=0.0.0.0 npm startКлиенты подключаются к http://<host>:18888/mcp. Сервер доступен только для
чтения, но также не требует аутентификации — поместите его за обычный внутренний
вход и включите защиту от DNS-реббиндинга, если он доступен из браузера:
mcp:
transport_security:
enable_dns_rebinding_protection: true
allowed_hosts: ["spark-mcp.internal:*"]
allowed_origins: ["https://spark-mcp.internal"]4. Установка навыков
Инструменты дают модели доступ к данным. Навыки дают ей метод — порядок сбора доказательств, пороговые значения, отделяющие находку от шума, и правило, что она не должна называть причину, которую не видела в данных.
# 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/Навык | Обрабатывает | Срабатывает на |
| упавшие, убитые или зависшие задания | "почему упало", стек-трейс, id приложения, "OOM", "зависло" |
| медленные, дорогие или регрессировавшие задания | "почему так медленно", "настрой", "раньше занимало 20 минут", "снизить стоимость" |
Они срабатывают сами по себе от обычного вопроса — никому не нужно запоминать команду:
"ночная загрузка в 2 часа снова упала, app_1724… — не посмотришь?"
См. skills/README.md о том, что внутри каждого навыка и как расширить их знаниями вашей команды.
5. Инструменты
Все 17 находятся в src/tools/tools.ts; их JSON-схемы — в
src/schemas/generated.ts. Выполните
node scripts/mcp-cli.mjs list-tools, чтобы увидеть их с аргументами.
Поиск
Инструмент | Возвращает |
| приложения, фильтруемые по статусу и дате, или одно по |
| задания для приложения — по умолчанию сначала упавшие; |
| стадии, те же параметры сортировки, необязательные сводные метрики |
| исполнители, по умолчанию активные, |
| курируемые сводки SQL-выполнений, фильтруемые по описанию |
Глубокое погружение
Инструмент | Возвращает |
| одну стадию с распределением метрик по задачам на ваших квантилях |
| исключения и стек-трейсы по задачам — где живут первопричины |
| один запрос: заголовок, физический план, метрики по узлам, задания, стадии |
| версии рантайма, свойства Spark/системы/Hadoop, classpath — фильтр по |
| агрегированные метрики исполнителей для приложения |
| дамп потоков JVM — только для работающих приложений |
Диагностика
Инструмент | Возвращает |
| самые медленные стадии и задания, spill, давление GC, утилизация, рекомендации |
| сводка добавления/удаления исполнителей и временной шкалы стадий |
Сравнение двух запусков
Инструмент | Возвращает |
| diff конфигурации — что изменилось между двумя запусками |
| diff ресурсов и длительности |
| diff метрик для двух запросов, плюс необязательный diff структуры плана |
| метрики стадий и квантили задач бок о бок |
Промпты
investigate_failure(app_id, server?) и
compare_applications(app_a, app_b, server?, context?) — интерактивные
пошаговые руководства из вышестоящего проекта, для случаев, когда инженер хочет
вести сам, а не передавать анализ модели.
6. Как это работает
Вызов инструмента превращается в один или несколько GET-запросов к /api/v1/...,
и JSON возвращается в том же виде, в каком его формировал оригинал на 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)Три детали, о которых стоит знать, если вы планируете модифицировать его:
models/generated.tsиschemas/generated.tsгенерируются скриптамиtools/gen_models.pyиtools/gen_schemas.pyиз вышестоящего Python-проекта. Лучше перегенерировать, чем редактировать вручную — именно это сохраняет каталог и формы ответов идентичными оригиналу.Используется низкоуровневый API
Server, а неMcpServer, потому что форма результата должна совпадать с FastMCP: один текстовый блок на элемент списка, иstructuredContentтолько для тех инструментов, чья сигнатура на Python объявляла конкретный тип возврата.Обнаружение приложений позволяет инструментам опускать
server.ApplicationDiscoveryопрашивает каждый настроенный сервер на предмет идентификатора приложения и кэширует ответ на 5 минут.
7. Развертывание
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-mcpKubernetes
Запустите его как обычный Deployment с URL в переменных окружения и учетными данными из 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 }Процесс не имеет состояния, кроме 5-минутного кэша обнаружения, поэтому он масштабируется горизонтально без координации.
8. Устранение неполадок
Симптом | Причина и исправление |
| неверный URL или порт, или History Server не работает. Проверьте |
| идентификатор отсутствует на любом настроенном сервере, или журнал событий еще не подхвачен — |
| аргумент |
| собственный ответ Spark для стадии, которая завершилась с ошибкой до завершения каких-либо задач. Это не проблема инструмента — вместо этого читайте исключения задач |
| ожидаемо: History Server не сохраняет дампы потоков. Они работают только пока приложение запущено |
Пустой | проверьте, что |
Очень большие ответы | сузьте с помощью |
| аутентификация EMR persistent-UI не перенесена; вместо этого укажите напрямую доступный URL |
Установите SHS_MCP__DEBUG=true для подробных журналов.
9. Разработка
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Тестирование паритета между реализациями находится в parity/ — оно выполняет те же вызовы MCP к этому серверу и к оригиналу на Python и сравнивает каждый ответ. PARITY.md фиксирует результаты и точные различия, которые остаются.
Не перенесено из апстрима
Модуль апстрима | Статус |
| не перенесено — сервер, настроенный с |
| не перенесено — проксирует к MCP-эндпоинту, размещенному на AWS, регистрируется только при наличии учетных данных AWS |
| не перенесено — вспомогательный инструмент для скриншотов Playwright, не используется ни одним инструментом |
Лицензия
Apache-2.0, как и в апстриме.
This server cannot be deployed
Maintenance
Related MCP Connectors
Your Databricks Lakehouse in natural language: run SQL on your SQL warehouses, track long-running qu
LLM Observability & Orchestration Agent
Code intelligence for LLMs. Analyze, search, and retrieve code from any public git repository.
LLM Observability & Orchestration Agent (Langchain)
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables 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
- FlicenseNot gradedqualityNot gradedmaintenanceExposes 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.-
- AlicenseNot gradedqualityAmaintenanceExposes Spark History Server data as tools for AI agents, enabling natural language querying of Spark applications, jobs, stages, and performance metrics.142 PyPI203Apache 2.0
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to query Hadoop MapReduce job history, including job listing, details, counters, configuration, and logs via the JobHistory REST API.1-