Skip to main content
Glama
Kirill-FD

llm-analytics-mcp

by Kirill-FD

基于 LLM 的集成 MCP 分析系统

MCP 服务器,为语言模型提供一组用于分析表格数据的工具:加载、清洗、绘图、生成报告。不开发自有聊天界面——使用现成平台的 Web 界面(Claude 作为主要客户端,ChatGPT 作为备选)。

同一个工具注册表同时通过两种协议发布:

协议

端点

客户端

MCP(Streamable HTTP)

/mcp

Claude — Web、桌面端、任意 MCP 客户端

REST + OpenAPI

/tools/*、/openapi.json

ChatGPT Custom GPT Action


系统能做什么

12 个工具,5 项技能。 完整列表可通过调用 describe_system 或查看 ARCHITECTURE.md 获得。

工具

技能

用途

list_datasets

—

可用数据目录

load_data

DataLoadingSkill

从目录、路径或 URL 加载 CSV/TSV/Excel/JSON/Parquet

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) 链接。最后一点对于 Web 场景至关重要:上传到浏览器聊天中的文件,服务器无法访问。

  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 在对话中所做的工作。适合作为演示前的冒烟测试:如果它能通过,问题几乎肯定出在集成,而不是分析功能。


第 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 防护,只接受形如 localhost 的 Host 头。通过隧道访问时,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. 身份验证: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()}

重启服务器。该工具会立即出现在两种协议中:MCP 的 tools/list 和 REST 的 /openapi.json。tools 包会自动导入自己的模块,JSON schema 从函数签名生成,描述来自 docstring。


已知限制

这些是主动列出的——它们是原型的边界,而不是未完成的部分:

  • 内存中的数据集存储。 服务器重启后,已加载的数据会丢失。 对原型来说可以接受;在生产环境中改用 Redis 或磁盘。

  • 没有授权。 演示环境位于临时隧道后面。 生产环境需要在请求头中使用 API 密钥,并在 FastAPI 端进行校验。

  • 没有行过滤。 工具处理的是整个数据集: 无法构建“仅 2024 年 West 地区”的切片。这在演示中很明显—— 模型会如实报告自己无法计算的内容, 而不是对输出进行捏造。

  • 技能只有五个,而不是更多。 这是一个有意识的选择: 五个能用的技能胜过十个形式化的技能。

  • 没有单元测试——只有 selfcheck.py 的端到端自检, 以及两种传输方式的集成测试。

Related MCP Connectors

Related MCP Servers