Как я собрала локальную MCP-платформу для мониторинга промышленных данных

от автора

PostgreSQL, Airflow, JupyterLab, MinIO, Superset, шесть MCP-сервисов и локальная модель Ollama в одном воспроизводимом Docker Compose-стенде.

Зачем понадобился этот проект

В учебных проектах по инженерии данных компоненты часто существуют отдельно: SQL-задания — в одной папке, ноутбуки — в другой, оркестратор запускается сам по себе, а демонстрация LLM не связана с результатами расчётов. Мне хотелось собрать цельный стенд, в котором один набор данных проходит полный путь:

  1. исходные записи загружаются в PostgreSQL;

  2. Airflow обновляет аналитические витрины и выполняет проверки качества;

  3. Jupyter-ноутбуки воспроизводят ETL-, логистический и ML-сценарии;

  4. сформированные Parquet-файлы сохраняются в MinIO;

  5. операции с платформой становятся доступны через MCP-инструменты;

  6. локальная языковая модель поясняет уже рассчитанные метрики, не подменяя собой вычисления.

Так появился демонстрационный проект MCP-pro-Github. Он работает на синтетических данных о добыче, телеметрии скважин, отказах оборудования и логистике, поэтому его можно запускать и показывать без доступа к производственным системам.

Что находится внутри

Стенд собирается через Docker Compose и объединяет следующие компоненты.

Компонент

Роль в проекте

PostgreSQL 15

Исходные таблицы, аналитические витрины, метрики и LLM-пояснения

Airflow 2.9.1

DAG oil_pipeline для обновления витрин и проверки качества

JupyterLab

ETL-, логистический и ML-ноутбуки

MinIO

Локальное S3-совместимое хранилище Parquet-артефактов

Superset

Интерфейс для ручного подключения источника и построения визуализаций

Ollama

Локальный запуск модели qwen2.5:1.5b

MCP-сервисы

Инструменты для работы с БД, качеством данных, мониторингом, Airflow и Superset

LLM agent

Пояснение рассчитанных метрик и сохранение результата в PostgreSQL

Упрощённо поток выглядит так:

Jupyter / ETL ───► PostgreSQL ───► аналитические витрины        └────────► MinIO         └──► метрики мониторингаMCP-клиент ───► MCP-сервисы ───► PostgreSQL / Airflow / SupersetLLM agent ───► Ollama    └────────► PostgreSQL (сохранённые пояснения)

Данные и конвейер Airflow

В PostgreSQL разворачивается схема с синтетическими таблицами производства, поставок и отказов. На их основе строятся витрины для дальнейшего анализа.

DAG oil_pipeline состоит из двух последовательных задач:

  • refresh_marts создаёт и пополняет витрины производства и логистики;

  • data_quality рассчитывает долю пропусков давления и количество выбросов по объёму добычи.

Повторный запуск не должен дублировать уже перенесённые записи: загрузка сопоставляет ключевые поля исходных таблиц и витрин.

Успешный запуск DAG oil_pipeline

Успешный запуск DAG oil_pipeline

Три воспроизводимых ноутбука

В JupyterLab находятся три самостоятельных сценария.

ETL pipeline

Ноутбук читает исходные таблицы, выполняет преобразования, формирует витрины и выгружает результат в PostgreSQL и MinIO. В конце выполняются проверки: ожидаемые имена объектов должны присутствовать в бакете.

Logistics pipeline

Сценарий анализирует поставки, задержки и связанные с ними показатели, а затем сохраняет итоговый Parquet-артефакт.

ML and anomaly-detection pipeline

Ноутбук обучает детерминированную базовую модель на синтетических данных, формирует прогнозы и признаки аномалий, сохраняет результат в PostgreSQL и MinIO. Это демонстрация инженерного конвейера, а не заявка на качество производственной модели: финальные ячейки проверяют число строк и наличие созданных артефактов.

Такой формат удобен для проверки: пользователь запускает ячейки сверху вниз и видит не только графики, но и явное сообщение check passed.

ML-ноутбук в JupyterLab

ML-ноутбук в JupyterLab

Зачем здесь MinIO

PostgreSQL хранит структурированные данные и результаты запросов, а MinIO — файловые артефакты конвейеров. В приватном бакете oil-data появляются витрины и ML-результаты в формате Parquet.

Это разделяет два вида хранения и одновременно позволяет отработать S3-совместимый интерфейс локально. В демонстрации можно проверить не только факт выполнения Python-кода, но и появление конкретных файлов.

Parquet-артефакты в приватном бакете MinIO

Parquet-артефакты в приватном бакете MinIO

Шесть MCP-сервисов

MCP в проекте используется как единый интерфейс к ограниченным операциям платформы. Каждый сервис отвечает за свой набор инструментов.

MCP-сервис

Доступные операции

postgres

список таблиц и описание схемы

data-quality

число строк, доля пропусков и сводный отчёт о качестве

monitoring

размеры таблиц, health score, метрики и корреляции

airflow

список DAG, состояние и создание запуска DAG

superset

проверка health endpoint и доступности главной страницы

orchestrator

запуск oil_pipeline и краткая сводка состояния компонентов

Контейнер mcp_agents поднимает эти сервисы во внутренней Docker-сети. Smoke test подключается к каждому из них, запрашивает список инструментов и подтверждает, что все шесть интерфейсов инициализированы.

Результат MCP smoke test

Результат MCP smoke test

Важно точно описать роль оркестратора. Инструмент run_pipeline создаёт запуск oil_pipeline через Airflow API и возвращает идентификатор запуска вместе со статусом витрин. platform_status выдаёт компактную сводку готовности основных агентов. То есть это практический слой управления конкретным конвейером, а не универсальный планировщик произвольных действий.

Где используется локальная модель

Языковая модель подключена к двум рассчитанным корреляциям:

  • между задержкой доставки и стоимостью;

  • между давлением в скважине и объёмом добычи.

Сначала обычный Python-код определяет знак метрики, формирует статистическую интерпретацию и уровень уверенности по размеру выборки. Только после этого Ollama получает ограниченный запрос: добавить две короткие строки — осторожный бизнес-контекст и конкретный шаг проверки.

Такое разделение принципиально для воспроизводимости. Число, направление связи и предупреждение о том, что корреляция не доказывает причинность, формируются детерминированно. LLM отвечает только за краткий комментарий. Итог сохраняется в таблицу monitoring_explanations, поэтому результат можно проверить SQL-запросом.

Пример рассчитанных метрик в PostgreSQL

Пример рассчитанных метрик в PostgreSQL

Как запустить проект

Понадобятся Docker Desktop с Docker Compose v2, Unix-подобная оболочка и ресурсы для нескольких контейнеров. Для полной LLM-проверки дополнительно загружается локальная модель Ollama.

git clone https://github.com/irina-probono/MCP-pro-Github.gitcd MCP-pro-Github./scripts/init-env.shdocker compose config --quietdocker compose up -d --builddocker compose ps

init-env.sh создаёт локальную конфигурацию для совместного запуска сервисов. Фактические адреса интерфейсов показывает docker compose ps.

Проверить инициализацию MCP-сервисов можно одной командой:

docker compose exec mcp_agents python mcp/smoke_test.py

Для LLM-сценария модель загружается отдельно:

docker compose exec ollama ollama pull qwen2.5:1.5bdocker compose exec llm_agent python server.py --demo

Как я проверяла воспроизводимость

В репозитории есть два уровня автоматизированных проверок.

static-check.sh проверяет синтаксис Python- и shell-файлов, структуру ноутбуков и ожидаемый состав проекта:

./scripts/static-check.sh

preflight.sh создаёт временную копию проекта, генерирует отдельную конфигурацию, собирает контейнеры и последовательно проверяет DAG, ETL, MCP smoke test и три ноутбука:

./scripts/preflight.sh

Полный вариант также загружает модель и запускает LLM-сценарий:

PREFLIGHT_WITH_LLM=1 ./scripts/preflight.sh

Изолированный запуск полезен тем, что проверяет именно содержимое проекта, а не случайно сохранившееся состояние предыдущих контейнеров. После автоматических тестов интерфейсы можно оставить запущенными для ручного просмотра, а затем удалить временное окружение штатным скриптом очистки.

Что получилось

Проект объединяет полный демонстрационный путь данных: от SQL-схемы и ETL до оркестрации, файловых артефактов, MCP-инструментов и локального пояснения метрик. Все компоненты можно запустить на одном компьютере, а ожидаемые результаты описаны в README и подтверждаются автоматическими проверками.

Для меня главными выводами стали три вещи:

  1. интеграционный проект ценен не количеством контейнеров, а проверяемой связью между ними;

  2. LLM полезнее ставить после детерминированного расчёта и явно ограничивать её роль;

  3. воспроизводимый preflight-сценарий и понятные ожидаемые результаты делают техническую демонстрацию значительно убедительнее.

Репозиторий проекта: MCP-pro-Github.

ссылка на оригинал статьи https://habr.com/ru/articles/1064802/