Skip to main content
Glama
ibezgachev

sales-analytics

by ibezgachev

sales-analytics-mcp

Прототип аналитической системы на базе LLM: MCP-сервер и набор скиллов, через которые модель загружает табличные данные (CSV/Excel/JSON), очищает их, строит графики и пишет отчёт с выводами.

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

Ключевое архитектурное решение: датафрейм не пересекает границу LLM. load_data кладёт данные в session store и возвращает короткий dataset_id; все остальные инструменты принимают этот id, а не сами данные. Обоснование и замеры — в ARCHITECTURE.md.

Стек

Python 3.11+, FastMCP (транспорты stdio и streamable-http), pandas, matplotlib + seaborn (статичные PNG), openpyxl, ruff, pytest.

Related MCP server: Excel MCP Server

Установка

git clone https://github.com/ibezgachev/sales-analytics-mcp.git
cd sales-analytics-mcp

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

pip install -e ".[dev]"

Проверка, что всё встало:

pytest
ruff check .

Запуск

Обычно сервер запускать руками не нужно — MCP-клиент делает это сам (см. следующий раздел). Ручной запуск полезен, чтобы убедиться, что сервер стартует без ошибок.

# транспорт stdio — для локальных клиентов вроде Claude Desktop
python server_stdio.py

# транспорт streamable-http — http://127.0.0.1:8000/mcp
python server_http.py

Оба файла собирают один и тот же набор инструментов через core.mcp_app.build_mcp_server(); различается только транспорт.

Подключение к Claude Desktop

⚠️ Где на самом деле лежит claude_desktop_config.json

Стандартный путь %APPDATA%\Claude\claude_desktop_config.json верен не для всех установок. Если Claude Desktop поставлен как приложение из Microsoft Store (MSIX-пакет), этой папки не существует вовсе, а конфиг лежит в песочнице пакета:

%LOCALAPPDATA%\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude\claude_desktop_config.json

Симптом: правишь файл по «правильному» пути (или создаёшь его) — и сервер не появляется в клиенте, сколько ни перезапускай. На поиск этого легко потерять полчаса и решить, что проект не работает.

Надёжный способ определить свой вариант — найти файл по имени:

Get-ChildItem -Path $env:LOCALAPPDATA,$env:APPDATA -Recurse -Filter claude_desktop_config.json -ErrorAction SilentlyContinue

Добавьте в конфиг блок mcpServers (если файл уже есть — допишите ключ sales-analytics внутрь существующего mcpServers, не затирая остальное):

{
  "mcpServers": {
    "sales-analytics": {
      "command": "C:\\путь\\к\\проекту\\.venv\\Scripts\\python.exe",
      "args": ["C:\\путь\\к\\проекту\\server_stdio.py"]
    }
  }
}

Пути — абсолютные, обратные слэши экранированы. На Linux/macOS — /путь/к/проекту/.venv/bin/python без экранирования.

После правки полностью завершите приложение (через трей или диспетчер задач — закрытия окна недостаточно) и запустите заново. Проверить: в списке инструментов клиента должен появиться sales-analytics с 13 инструментами.

Инструменты

Инструмент

Назначение

load_data

Загрузка CSV/Excel/JSON, автоопределение кодировки, разделителя и формата дат. Возвращает dataset_id и сводку

describe_data

Статистика по типу колонки: числа, категории, даты

clean_data

Дубли, пропуски, нормализация текста, выбросы по IQR. Возвращает новый dataset_id и лог операций

aggregate

Сводная таблица числами, без построения графика

plot_trend

Динамика числовой колонки по месяцам

plot_distribution

Гистограмма распределения

correlation_analysis

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

plot_top_n

Горизонтальная столбчатая диаграмма топ-N категорий

auto_analyze

Сам выбирает тип графика по типу колонки

analyze_seasonality

Распределение показателя по календарным месяцам и кварталам

list_datasets

Какие dataset_id доступны в этой сессии

prepare_insights_context

Собирает статистику, лог очистки и описания графиков в материал для отчёта

export_report

Сохраняет готовый текст отчёта в reports/

Первые пять имён из ТЗ (load_data, describe_data, plot_trend, plot_distribution, correlation_analysis) сохранены дословно.

Каждый график возвращает путь к PNG и текстовое описание того, что на нём видно — модель не видит изображение, и без описания не смогла бы сослаться на график в отчёте. Почему это оказалось критично и что выяснилось при проверке — в ARCHITECTURE.md.

Пример диалога

Системный промпт с последовательностью шагов лежит в prompts/system_prompt.md и дублируется как MCP-примитив prompt с именем sales_analysis_workflow — клиент может подтянуть его сам.

Первое сообщение может быть таким:

Проанализируй данные о продажах из файла
C:\путь\к\проекту\data\sales_data.csv

Загрузи их, посмотри структуру, почисти от дефектов, построй графики
и дай развёрнутый отчёт с выводами и практическими рекомендациями.

Дальше модель ведёт цепочку сама: load_data → describe_data → clean_data → графики → prepare_insights_context → export_report.

Что получилось на выходе — reports/sample_report.md.

Скриншоты диалога: docs/screenshots/ — прогон проведён в чистом чате, без подгрузки системного промпта, только по описаниям инструментов.

Тестовые данные

data/sales_data.csv — синтетический датасет (180 строк, 2023–2024), в который намеренно заложены дефекты: пропуски, дубли, выбросы, разнобой в форматах дат и в написании регионов. Без них очистке нечего было бы чистить.

Точный состав дефектов с количествами — data/README.md; этот файл служит эталоном при проверке очистки.

Пересоздать (воспроизводимо, random_state зафиксирован):

python scripts/generate_data.py

Интеграция через OpenAPI

openapi.json представляет каждый MCP-инструмент как POST /tools/{name} с той же JSON-схемой параметров, которую видит модель. Это не спецификация HTTP-маршрутов server_http.py (тот говорит на протоколе MCP, а не на обычном REST), а совместимое представление для интеграций, которым нужен именно OpenAPI — например, Custom GPT Action.

Живой публичный HTTPS-эндпоинт в рамках задания не разворачивался, это осознанное ограничение — см. ARCHITECTURE.md.

Перегенерировать после добавления скилла:

python scripts/generate_openapi.py

Разработка

ruff check .          # линтер
ruff format .         # форматтер
pytest                # тесты

Добавление нового скилла — это один новый файл в skills/; правок в core/ и в серверных точках входа не требуется. Как именно — в разделе «Как добавить новый скилл» в ARCHITECTURE.md.

Лицензия

MIT.

Расширяемость подтверждается диффом, а не декларацией

Последний скилл — analyze_seasonality — добавлен намеренно отдельно от остальных, уже после того как система была написана и задокументирована, именно чтобы это можно было проверить.

git show --stat "$(git log --format=%H --grep='скилл анализа сезонности' -1)"

В этом коммите — ровно два файла: skills/seasonality.py и правка таблицы инструментов в README.md. Ни строки в core/, ни строки в server_stdio.py и server_http.py. При этом после перезапуска клиента инструмент появляется в списке тринадцатым, со схемой параметров, построенной из сигнатуры и докстринга.

(Тесты на скилл добавлены следующим коммитом — отдельно, чтобы дифф коммита-доказательства оставался минимальным и его можно было прочитать целиком за полминуты.)

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables AI-powered business intelligence and data analysis using pandas and LLM code generation. Supports automated data processing, statistical analysis, and visualization creation through natural language interactions.
    15
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables LLM agents to load, explore, and analyze CSV and Excel files using DuckDB, with tools for SQL querying, statistical analysis, expense optimization, and anomaly detection.
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Enables LLMs to profile and analyze tabular data files (CSV, Parquet, Excel, JSON) by extracting schema, statistics, data quality issues, and dtype suggestions, returning structured JSON.
    7
    50 PyPI
    3
    MIT