分析数据访问服务器

一个受控的模型上下文协议(MCP)服务器,为LLM提供对ONDC电子商务分析数据的安全只读访问。

  • by AnkurPandeyOndc
  • Python
  • 本地部署
  • 更新于
在 GitHub 查看 AnkurPandeyOndc/network_overview_mcp

使用说明

ONDC分析MCP服务器

A被治理 模型上下文协议 (MCP)服务器,为LLM提供对PostgreSQL中ONDC电子商务分析数据的安全、只读访问。

它的作用

服务器暴露 4个MCP工具 LLM(Claude等)可以调用该LLM来探索和查询ONDC订单数据:

工具 说明
get_schema 返回表定义、列类型、域/类别映射和NP类型
get_data_freshness 返回最新 order_date 每张桌子
run_safe_sql 验证并执行带有安全防护栏的只读SQL查询
search_docs 搜索已索引的ONDC文档(RAG框架,尚未索引文档)

SQL安全护栏

每个查询都传递给 run_safe_sql 在执行之前进行验证:

  • 仅 SELECT 允许使用语句(不允许插入/更新/删除/删除)
  • SELECT * 被拒绝--需要明确的列名
  • WHERE 条款与 order_date 筛选器是必需的
  • LIMIT 自动注入(默认值1000)或上限(如果过高)
  • 仅在中定义的表 schema/tables.yaml 可访问
  • JOIN需要 ON 仅允许列的条款
  • 多语句查询被拒绝
  • 所有查询都在具有语句超时的只读事务中运行

基于角色的访问

中定义了两个角色 schema/tables.yaml:

  • 分析师 --访问这两个表
  • 观众 --访问 model_for_all_domain 仅

数据库模式

架构: opendata_nodata

model_for_all_domain --按域、类别和网络参与者列出的订单数

列 类型 描述
order_date 日期 订单日期
buyer_np varchar 买家网络参与者名称
seller_np varchar 卖家网络参与者名称
category varchar 产品/服务类别
domain varchar 商业领域(零售B2C、物流等)
np_type varchar 网络参与者类型:np间、np内或null
订单 int4 订单数量

model_for_all_domain_pincode --按域名和城市分类的订单数量

列 类型 描述
order_date 日期 订单日期
domain varchar 业务域
delivery_city varchar 订单交付城市
seller_city varchar 卖家所在城市
订单 int8 订单数量

领域

金融、家居服务、物流、公共交通、零售B2B、零售B2C、零售代金券、打车

先决条件

  • Python 3.11+
  • 诗歌
  • PostgreSQL(远程或本地)
  • Redis(可选——可以禁用)

设置

cd ondc-analytics-mcp
poetry install

配置

复制示例env文件并填写您的数据库凭据:

cp .env.example .env

.env 变量:

变量 默认值 描述
DATABASE_HOST localhost PostgreSQL主机
DATABASE_PORT 5432 PostgreSQL端口
DATABASE_NAME ondc_analytics 数据库名称
DATABASE_USER ondc 数据库用户
DATABASE_PASSWORD ondc_secret 数据库密码
DATABASE_SCHEMA opendata_nodata 架构名称
DATABASE_URL (汽车制造) 完整连接URL--将其设置为覆盖单个变量
REDIS_ENABLED true 设置为 false 完全禁用Redis缓存
REDIS_URL redis://localhost:6379/0 Redis连接URL
TRANSPORT stdio 运输方式: stdio 或 http
MAX_QUERY_ROWS 1000 每个查询返回的最大行数
QUERY_TIMEOUT_SECONDS 30 SQL语句超时
LOG_LEVEL INFO 日志记录级别
AUDIT_LOG_PATH logs/audit.jsonl 审核日志文件的路径

运行服务器

选项1:stdio模式(适用于克劳德桌面/MCP检查器)

poetry run python -m ondc_mcp.server

或者使用MCP检查器进行交互式测试:

poetry run mcp dev src/ondc_mcp/server.py

选项2:HTTP模式(端口8000上的可流式传输HTTP)

TRANSPORT=http poetry run python -m ondc_mcp.server

选项3:Docker Compose(本地Postgres+Redis的全栈)

docker compose up --build

这将开始:

  • PostgreSQL 16(通过以下方式播种样本数据 schema/init.sql)
  • Redis 7
  • 端口8000上的MCP服务器

只运行Postgres和Redis(并在本地运行服务器):

docker compose up postgres redis

连接到克劳德桌面

添加到您的Claude桌面配置(claude_desktop_config.json):

{
  "mcpServers": {
    "ondc-analytics": {
      "command": "poetry",
      "args": ["run", "python", "-m", "ondc_mcp.server"],
      "cwd": "/path/to/ondc-analytics-mcp",
      "env": {
        "DATABASE_HOST": "your-db-host",
        "DATABASE_PORT": "5432",
        "DATABASE_NAME": "your-db-name",
        "DATABASE_USER": "your-db-user",
        "DATABASE_PASSWORD": "your-db-password",
        "REDIS_ENABLED": "false"
      }
    }
  }
}

连接后,Claude将看到所有4个工具,并可以回答以下分析问题:

  • “昨天按订单数排名靠前的域名是什么?”
  • “按类别显示上周的零售B2C订单”
  • “比较班加罗尔和德里的订单量”

查询示例

有效查询:

SELECT domain, SUM(orders) AS total_orders
FROM opendata_nodata.model_for_all_domain
WHERE order_date = '2026-02-08'
GROUP BY domain
LIMIT 10

拒绝——删除表格:

DROP TABLE opendata_nodata.model_for_all_domain
-- Error: "Only SELECT statements are allowed, got: Drop"

拒绝--选择*:

SELECT * FROM opendata_nodata.model_for_all_domain WHERE order_date = '2026-02-08'
-- Error: "SELECT * is not allowed. Please specify explicit column names."

拒绝--无日期筛选器:

SELECT domain FROM opendata_nodata.model_for_all_domain
-- Error: "A WHERE clause with an order_date filter is required"

审核日志记录

每个工具调用和SQL查询都会记录到 logs/audit.jsonl。每个条目包括:

  • timestamp
  • user_id, role
  • raw_sql, validated_sql
  • status (成功/拒绝)
  • rejection_reasons
  • execution_time_ms
  • row_count

运行测试

poetry run pytest tests/ -v

37个测试,涵盖SQL验证器规则、模式注册表、角色访问和RAG骨架。不需要数据库或Redis。

项目结构

ondc-analytics-mcp/
  src/ondc_mcp/
    server.py              # MCP server entry point, tool registration
    config.py              # Environment-based configuration
    db/
      connection.py        # asyncpg connection pool, read-only execution
      schema_registry.py   # Loads table metadata from tables.yaml
    validation/
      sql_validator.py     # SQL AST validation via sqlglot
    security/
      role_access.py       # Role-based table access control
      query_logger.py      # Audit logging
    cache/
      redis_cache.py       # Redis caching with graceful degradation
    tools/
      sql_tool.py          # run_safe_sql implementation
      schema_tool.py       # get_schema implementation
      freshness_tool.py    # get_data_freshness implementation
      rag_tool.py          # search_docs skeleton
    rag/
      ingestion.py         # Document ingestion (skeleton)
      search.py            # Document search (skeleton)
  schema/
    tables.yaml            # Table metadata, domains, roles
    init.sql               # Seed data for local development
  tests/
    test_sql_validator.py  # 22 SQL validation tests
    test_tools.py          # 15 schema, role, RAG tests
  docker-compose.yml
  Dockerfile
  pyproject.toml