Skip to main content
Glama
ibezgachev

sales-analytics

by ibezgachev

sales-analytics-mcp

Prototype of an LLM-based analytics system: an MCP server and a set of skills through which the model loads tabular data (CSV/Excel/JSON), cleans it, builds charts, and writes a report with insights.

There is no chat interface of its own here, and none is planned — the server connects to a ready-made client (Claude Desktop), and the model itself drives the entire call sequence.

Key architectural decision: the dataframe does not cross the LLM boundary. load_data puts the data into the session store and returns a short dataset_id; all other tools accept this id rather than the data itself. The rationale and measurements are in ARCHITECTURE.md.

Stack

Python 3.11+, FastMCP (stdio and streamable-http transports), pandas, matplotlib + seaborn (static PNGs), openpyxl, ruff, pytest.

Related MCP server: Claude Data Buddy

Installation

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]"

Check that everything is set up:

pytest
ruff check .

Running

You usually don't need to start the server by hand — the MCP client does that itself (see the next section). Running it manually is useful to make sure the server starts without errors.

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

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

Both files assemble the same set of tools via core.mcp_app.build_mcp_server(); only the transport differs.

Connecting to Claude Desktop

⚠️ Where claude_desktop_config.json actually lives

The standard path %APPDATA%\Claude\claude_desktop_config.json is valid not for all installations. If Claude Desktop was installed as a Microsoft Store app (MSIX package), this folder doesn't exist at all, and the config lives in the package sandbox:

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

Symptom: you edit the file at the "correct" path (or create it) — and the server never appears in the client, no matter how many times you restart. It's easy to lose half an hour on this and decide the project doesn't work.

A reliable way to determine your variant — find the file by name:

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

Add the mcpServers block to the config (if the file already exists, add a sales-analytics key inside the existing mcpServers, without overwriting the rest):

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

Paths are absolute, backslashes are escaped. On Linux/macOS — /путь/к/проекту/.venv/bin/python without escaping.

After the edit, fully quit the app (via the tray or the Task Manager — just closing the window isn't enough) and launch it again. To verify: sales-analytics with 13 tools should appear in the client's tool list.

Tools

Tool

Purpose

load_data

Loads CSV/Excel/JSON, auto-detects encoding, delimiter, and date format. Returns a dataset_id and a summary

describe_data

Statistics per column type: numbers, categories, dates

clean_data

Duplicates, missing values, text normalization, IQR outliers. Returns a new dataset_id and an operation log

aggregate

A pivot table with numbers, without drawing a chart

plot_trend

Trend of a numeric column by month

plot_distribution

Distribution histogram

correlation_analysis

Correlation heatmap

plot_top_n

Horizontal bar chart of top-N categories

auto_analyze

Picks the chart type on its own based on the column type

analyze_seasonality

Metric distribution by calendar months and quarters

list_datasets

Which dataset_id values are available in this session

prepare_insights_context

Collects statistics, the cleaning log, and chart descriptions into material for the report

export_report

Saves the finished report text to reports/

The first five names from the spec (load_data, describe_data, plot_trend, plot_distribution, correlation_analysis) are kept verbatim.

Each chart returns a path to a PNG and a textual description of what is visible on it — the model doesn't see the image, and without the description it couldn't reference the chart in the report. Why this turned out to be critical and what the testing revealed — in ARCHITECTURE.md.

Example conversation

The system prompt with the step sequence is in prompts/system_prompt.md and is also exposed as an MCP prompt primitive named sales_analysis_workflow — the client can pull it up itself.

The first message can be:

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

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

From then on, the model drives the chain itself: load_datadescribe_dataclean_data → charts → prepare_insights_contextexport_report.

The output is at reports/sample_report.md.

Conversation screenshots: docs/screenshots/ — the run was done in a clean chat, without injecting the system prompt, using only the tool descriptions.

Test data

data/sales_data.csv is a synthetic dataset (180 rows, 2023–2024) with deliberately built-in defects: missing values, duplicates, outliers, inconsistent date formats and region spells. Without them there would be nothing for the cleaning step to clean.

The exact defect set with counts is in data/README.md; this file serves as the reference when checking the cleaning.

Regenerate (reproducibly; random_state is fixed):

python scripts/generate_data.py

OpenAPI integration

openapi.json represents each MCP tool as POST /tools/{name} with the same JSON parameter schema the model sees. This is not a spec for the HTTP routes of server_http.py (that one speaks the MCP protocol rather than plain REST), but a compatible representation for integrations that specifically need OpenAPI — for example, a Custom GPT Action.

A live public HTTPS endpoint wasn't deployed as part of this task — a deliberately placed limitation — see ARCHITECTURE.md.

Regenerate after adding a skill:

python scripts/generate_openapi.py

Development

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

Adding a new skill means one new file in skills/; no changes to core/ or to the server entry points are required. How exactly — in the "How to add a new skill" section in ARCHITECTURE.md.

License

MIT.

Extensibility is confirmed by a diff, not a declaration

The last skill — analyze_seasonality — was added deliberately on its own, after the system had already been written and documented, precisely so that this can be verified.

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

That commit contains exactly two files: skills/seasonality.py and a fix to the tools table in README.md. Not a single line in core/, not a line in server_stdio.py or server_http.py. And yet after restartinging the client, the tool appears in the list as the throngthirteenth, with a parameter schema generated from its signature and docstring.

(The tests for the skill were added in the following commit separately, so that the proof commit — read entirely in half a minute — takes as long to read as possible.)

Wait, let me make that last sentence cleaner:

(The tests for the skill were added in the next commit, separately, so that the commit diff remains minimal and the entire file can be read in half a minute.)

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

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

  • 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

View all related MCP servers

Related MCP Connectors

  • Renders interactive Chart.js charts and dashboards inline in AI conversations.

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

  • Give your agent web search and authoritative datasets: S&P Global, FRED, OECD, SimilarWeb & more.

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/ibezgachev/sales-analytics-mcp'

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