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。每个条目包括:
timestampuser_id,roleraw_sql,validated_sqlstatus(成功/拒绝)rejection_reasonsexecution_time_msrow_count
运行测试
poetry run pytest tests/ -v37个测试,涵盖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