Skip to main content
Glama
Kirill-FD

llm-analytics-mcp

by Kirill-FD

Аналитическая система на базе LLM с интеграцией MCP

MCP-сервер, который даёт языковой модели набор инструментов для анализа табличных данных: загрузка, очистка, построение графиков, сборка отчёта. Собственный чат-интерфейс не разрабатывается — используется веб-интерфейс готовой платформы (Claude как основной клиент, ChatGPT как альтернативный).

Один и тот же реестр инструментов публикуется по двум протоколам сразу:

Протокол

Эндпоинт

Клиент

MCP (Streamable HTTP)

/mcp

Claude — веб, десктоп, любой MCP-клиент

REST + OpenAPI

/tools/*, /openapi.json

ChatGPT Custom GPT Action


Что умеет система

12 инструментов, 5 скиллов. Полный список — вызовом describe_system или в ARCHITECTURE.md.

Инструмент

Скилл

Назначение

list_datasets

Каталог доступных данных

load_data

DataLoadingSkill

Загрузка CSV/TSV/Excel/JSON/Parquet из каталога, пути или URL

describe_data

DataLoadingSkill

Структура, типы, пропуски, дубликаты

clean_data

DataCleaningSkill

Дубликаты, пропуски, нормализация, выбросы

suggest_analysis

InsightGenerationSkill

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

plot_trend

VisualizationSkill

Динамика метрики во времени

plot_distribution

VisualizationSkill

Гистограмма или бар-чарт (тип выбирается сам)

correlation_analysis

VisualizationSkill

Тепловая карта корреляций

plot_breakdown

VisualizationSkill

Разрез метрики по категориям

collect_evidence

InsightGenerationSkill

Проверяемые числа для текста отчёта

build_report

ReportingSkill

Отчёт в Markdown, HTML и PDF

describe_system

Интроспекция: состав скиллов и инструментов

Дополнительные возможности:

  1. Автоподбор анализаsuggest_analysis определяет, какая колонка является временной осью, какие метриками, какие разрезами, и возвращает готовый план вызовов с обоснованием каждого шага.

  2. Мульти-формат и мульти-источник — CSV, TSV, Excel, JSON, Parquet; каталог, локальный путь или HTTP(S)-ссылка. Последнее принципиально для веб-сценария: файл, загруженный в браузерный чат, серверу недоступен.

  3. Сборка отчёта одной командойbuild_report сам достраивает недостающие графики и выдаёт документ в трёх форматах.


Related MCP server: Claude Data Buddy

Установка

Требуется Python 3.10 и новее.

git clone <адрес-репозитория>
cd llm-analytics-mcp

python -m venv .venv
source .venv/bin/activate          # Windows: .venv\Scripts\activate

pip install -r requirements.txt

Шаг 1. Тестовые данные

Данные в репозитории сгенерированы синтетически по схеме Superstore. ТЗ прямо это допускает: «вы можете сгенерировать данные самостоятельно или взять известный датасет».

python scripts/prepare_dataset.py --synthetic --rows 4000

Готовые файлы уже лежат в data/ — команда нужна, только если вы хотите пересоздать их или изменить объём.

Почему синтетика, а не Kaggle

Генератор даёт контроль над тем, что именно демонстрирует система:

  • Заложены проверяемые закономерности — восходящий тренд, годовая сезонность с пиком в конце года и связь «скидка выше 30% → отрицательная прибыль». Благодаря этому выводы анализа содержательны, а не случайны.

  • Дефекты внесены намеренно. Реальный Superstore практически идеально чист: без пропусков и дубликатов DataCleaningSkill отчитался бы «удалено 0 строк», и продемонстрировать очистку было бы нечем.

  • Воспроизводимость. Фиксированный seed=42 — проверяющий получает ровно те же данные и те же числа в отчёте, что и в примере.

  • Репозиторий самодостаточен. Не нужен аккаунт Kaggle, чтобы запустить проект.

Загрузка реального Superstore тоже поддерживается — структура колонок совпадает:

python scripts/prepare_dataset.py --input ~/Downloads/Sample-Superstore.csv

Что создаёт скрипт

Файл

Назначение

data/superstore_clean.csv

Данные, приведённые к колонкам из ТЗ

data/superstore_raw.csv

Та же таблица с внесёнными дефектами

Колонки: Date, Product, Region, Sales, Quantity, Profit (из ТЗ) плюс разрезы Category, Sub-Category, Segment, Discount, Ship Mode. Период — 2021–2024, 48 месяцев.

Состав дефектов печатается при запуске и детерминирован:

Дефект

Объём

Пропуски в Sales / Profit / Quantity

~3.5% / 4.5% / 2%

Полные дубликаты строк

~0.8%

Разнобой в написании Region (west, East, CENTRAL)

~6% строк

Экстремальные выбросы в Sales

12 строк

Альтернативный формат даты (15/03/2022)

~10% строк


Шаг 2. Проверка без сервера

Сквозной прогон всей цепочки — от загрузки до PDF-отчёта:

PYTHONPATH=src python -m analytics_mcp.selfcheck

Скрипт повторяет то, что делает LLM в диалоге, но детерминированно. Полезен как smoke-тест перед демонстрацией: если он проходит, проблема почти наверняка в интеграции, а не в аналитике.


Шаг 3. Запуск сервера

PYTHONPATH=src uvicorn analytics_mcp.app:app --host 127.0.0.1 --port 8000

Проверка:

curl http://127.0.0.1:8000/health

Полезные адреса:

Адрес

Что это

http://127.0.0.1:8000/health

Статус и число зарегистрированных компонентов

http://127.0.0.1:8000/docs

Swagger UI: все инструменты можно вызвать руками

http://127.0.0.1:8000/openapi.json

Спецификация для Custom GPT Action

http://127.0.0.1:8000/mcp

MCP-эндпоинт

Если порт занят. Стартовавший ранее процесс может продолжать отвечать старым кодом — симптом обманчивый: /health отвечает, а изменения не применяются. Перед перезапуском: pkill -f uvicorn.


Шаг 4. Публичный адрес через ngrok

Claude обращается к серверу снаружи, поэтому нужен HTTPS-адрес.

# 1. Установка и регистрация: https://ngrok.com/download
ngrok config add-authtoken <ваш-токен>

# 2. В личном кабинете ngrok зарезервируйте бесплатный статический домен
#    (Domains -> Create Domain). Без него адрес меняется при каждом
#    перезапуске, и настройку коннектора придётся повторять.

# 3. Запуск туннеля
ngrok http 8000 --domain=ваш-домен.ngrok-free.app

Затем пропишите адрес в окружении и перезапустите сервер:

cp .env.example .env
# в .env укажите:
#   PUBLIC_BASE_URL=https://ваш-домен.ngrok-free.app

export PUBLIC_BASE_URL=https://ваш-домен.ngrok-free.app
export MCP_ALLOWED_HOSTS='127.0.0.1:*,localhost:*,*.ngrok-free.app'
PYTHONPATH=src uvicorn analytics_mcp.app:app --host 127.0.0.1 --port 8000

Самая частая причина «не подключается». MCP SDK по умолчанию включает защиту от DNS rebinding и принимает только заголовок Host вида localhost. За туннелем Host содержит домен ngrok, и запрос отклоняется на этапе подключения коннектора, без внятной ошибки в интерфейсе. Переменная MCP_ALLOWED_HOSTS решает ровно эту проблему.


Шаг 5. Подключение к Claude (основной сценарий)

  1. Откройте Settings → Connectors → Add custom connector.

  2. Укажите адрес: https://ваш-домен.ngrok-free.app/mcp (обратите внимание на суффикс /mcp).

  3. Сохраните и убедитесь, что коннектор перешёл в состояние подключённого.

  4. В новом диалоге включите коннектор analytics_mcp через меню инструментов.

  5. Скопируйте содержимое prompts/system_prompt.md в описание проекта (Project instructions) — это задаёт порядок вызовов.

Проверочный запрос: «Какие датасеты доступны?» — модель должна вызвать list_datasets и показать содержимое каталога.


Шаг 6. Подключение к ChatGPT (альтернативный сценарий)

  1. Выгрузите спецификацию с публичным адресом:

    PUBLIC_BASE_URL=https://ваш-домен.ngrok-free.app \
      PYTHONPATH=src python scripts/export_openapi.py
  2. Создайте Custom GPT: Explore GPTs → Create → Configure.

  3. Create new action → Schema — вставьте содержимое openapi.json.

  4. Authentication: None.

  5. В поле Instructions вставьте prompts/system_prompt.md.

Подробности и особенности отображения графиков — в prompts/gpt_action_setup.md.


Демонстрационный сценарий

Порядок запросов подобран так, чтобы на скриншотах была видна цепочка вызовов, а не один запрос. Ключевой кадр — шаг 4: видно, что планирует модель, а не хардкод.

#

Запрос пользователю

Ожидаемые вызовы

1

Какие датасеты доступны?

list_datasets

2

Загрузи superstore_raw и опиши структуру

load_data, describe_data

3

Почисти данные

clean_data

4

Что здесь стоит проанализировать?

suggest_analysis

5

Построй эти графики

plot_trend, plot_breakdown, plot_distribution, correlation_analysis

6

Сделай отчёт с выводами и рекомендациями

collect_evidence, build_report

Пример результата — docs/report_example.md, графики — в docs/plots/.


Скриншоты работы

Материалы демонстрации лежат в docs/screenshots/:

Файл

Что показано

01-list-datasets.png

Claude вызывает list_datasets и показывает каталог сервера

02-clean.png

Отчёт clean_data: нормализация Region, 30 дубликатов, 817 выбросов

02.2-clean.png

Сравнение версий датасета «с заполнением пропусков» и «без»

03-suggest-analysis.png

Модель проверяет гипотезы из отчёта новыми вызовами инструментов

03.2-suggest-analysis.png

Приоритизированный список направлений дальнейшего анализа

04-plots.png

Построение графиков; модель явно отмечает, чего инструменты не умеют

Скриншоты показывают ключевое свойство системы: цепочкой вызовов управляет LLM. Модель сама решает, какие инструменты вызвать, находит ограничения набора (например, отсутствие фильтрации строк) и сообщает о них вместо того, чтобы подгонять вывод.

Проверка интеграции

# Полный цикл по обоим транспортам: initialize, tools/list, tools/call,
# возврат изображения, обработка ошибочных аргументов
python scripts/integration_test.py

Структура репозитория

llm-analytics-mcp/
├── README.md                    инструкция (этот файл)
├── ARCHITECTURE.md              архитектура и роль MCP/скиллов
├── openapi.json                 спецификация для Custom GPT Action
├── requirements.txt
├── .env.example
├── data/                        тестовые данные
├── docs/
│   ├── report_example.md/html/pdf   пример сгенерированного отчёта
│   ├── plots/                       примеры графиков
│   └── screenshots/                 скриншоты диалога
├── prompts/
│   ├── system_prompt.md         инструкция для LLM
│   └── gpt_action_setup.md      настройка Custom GPT Action
├── scripts/
│   ├── prepare_dataset.py       подготовка данных
│   ├── export_openapi.py        выгрузка спецификации
│   └── integration_test.py      проверка обоих транспортов
└── src/analytics_mcp/
    ├── core/                    реестр инструментов, хранилище, модели
    ├── skills/                  бизнес-логика этапов анализа
    ├── tools/                   инструменты, публикуемые наружу
    ├── transports/              адаптеры MCP и REST
    ├── rendering/               оформление графиков, артефакты
    ├── app.py                   сборка ASGI-приложения
    └── selfcheck.py             сквозная самопроверка

Как добавить свой инструмент

Ядро при этом не меняется. Создайте файл src/analytics_mcp/tools/my_tools.py:

from __future__ import annotations

from analytics_mcp.core.datasets import store
from analytics_mcp.core.registry import tool


@tool(tags=("stats",), skill="DataLoadingSkill", title="Топ значений")
def top_values(column: str, dataset_id: str | None = None, limit: int = 10) -> dict:
    """Возвращает самые частые значения колонки.

    Args:
        column: Имя колонки.
        dataset_id: Датасет. По умолчанию — последний использованный.
        limit: Сколько значений вернуть.
    """
    record = store.get(dataset_id)
    record.require_column(column)
    counts = record.df[column].value_counts().head(limit)
    return {str(k): int(v) for k, v in counts.items()}

Перезапустите сервер. Инструмент появится сразу в обоих протоколах: в tools/list у MCP и в /openapi.json у REST. Пакет tools импортирует свои модули автоматически, JSON-схема выводится из сигнатуры, описание — из докстринга.


Известные ограничения

Названы сознательно — это границы прототипа, а не недоделки:

  • Хранилище датасетов в памяти. При перезапуске сервера загруженные данные теряются. Для прототипа приемлемо; в продакшене — Redis или диск.

  • Нет авторизации. Демонстрационный стенд за временным туннелем. Для продакшена — API-ключ в заголовке и проверка на стороне FastAPI.

  • Нет фильтрации строк. Инструменты работают с датасетом целиком: срез «только регион West за 2024 год» построить нельзя. Это заметно в демонстрации — модель честно сообщает, чего не может посчитать, вместо подгонки вывода.

  • Пять скиллов, а не больше. Сознательный выбор: лучше пять работающих, чем десять формальных.

  • Юнит-тестов нет — только сквозная самопроверка selfcheck.py и интеграционный тест обоих транспортов.

F
license - not found
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

View all related MCP servers

Related MCP Connectors

  • Gateway between LLM agents and world data through eight tools and a bundled endpoint catalog.

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

  • The statistical analyst in your AI chat — validated, citable, re-runnable analysis of your data.

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/Kirill-FD/llm-analytics-mcp'

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