18 KiB
试产排程评估系统 — MCP 服务说明
服务名称: bexell-scheduling
协议版本: MCP (Model Context Protocol),Streamable HTTP 传输
挂载路径: /bexell/mcp
部署方式: mcp-server-demo 单进程多模组之一(与 ERP/CRM 模组共享进程与端口 8001)
鉴权方式: 动态 Bearer Token(mcp-auth 后端校验)
生成时间: 2026-09-02
一、概述
Bexell 模组是 mcp-server-demo 统一服务中的一个独立 MCP 模组,基于 MCPServer 框架(MCP Python SDK)实现,对外提供 4 个 MCP Tool,服务"试产排程评估及优化"场景。
统一服务通过 Starlette Mount 将三个模组挂载到不同路径,单进程、单端口(8001):
| 模组 | MCP 端点 | 服务名称 |
|---|---|---|
| ERP | http://localhost:8001/erp/mcp |
mcp-for-erp-auto |
| CRM | http://localhost:8001/crm/mcp |
mcp-for-crm-auto |
| Bexell | http://localhost:8001/bexell/mcp |
bexell-scheduling |
MCP 服务面向 IndepthAI Skill 层(trial-production-scheduling-evaluator)提供数据查询与产能计算能力,是智能体完成"试产排程评估"任务的核心数据通道。
二、架构定位
┌──────────────────────────────────────────┐
│ IndepthAI Skill 层 │
│ trial-production-scheduling-evaluator │
│ (解析输入 → 调用 MCP → 格式化输出) │
└──────────────────┬───────────────────────┘
│ MCP 协议(Streamable HTTP + Bearer Token)
┌──────────────────▼───────────────────────┐
│ mcp-server-demo 统一服务 (:8001) │
│ │
│ /erp/mcp ── ERP 模组 │
│ /crm/mcp ── CRM 模组 │
│ /bexell/mcp ── Bexell 模组(4 工具)◄──│
│ │
│ 鉴权:mcp-auth 后端 verify-token API │
└──────────────────┬───────────────────────┘
│ SQLAlchemy ORM(独立连接池)
┌──────────────────▼───────────────────────┐
│ PostgreSQL (bexell_schedule_ai) │
│ 5 张表 + 1 个视图,无需新增 │
└──────────────────────────────────────────┘
模组化优势:
| 维度 | 说明 |
|---|---|
| 独立连接池 | Bexell 模组使用 BEXELL_DB_* 环境变量配置独立 SQLAlchemy Engine,与 ERP/CRM 数据库完全隔离 |
| 独立鉴权 | 使用 BEXELL_MCP_AUTH_API_KEY 调用 mcp-auth 后端,token 校验按 service 隔离 |
| 统一运维 | 单进程、单端口,三个模组共享 uvicorn 服务与生命周期管理 |
| 数据一致性 | Tool 计算复用同一数据库,评估公式在单条聚合 SQL 内完成 |
| 可演进性 | 模组目录结构统一(tools.py / db.py / models.py),可独立拆分部署 |
三、鉴权
MCP 端点已启用 动态 Bearer Token 鉴权,未携带或携带无效 token 的请求返回 401 Unauthorized。
校验流程:
- 客户端在请求头携带
Authorization: Bearer <token> - MCP 服务调用 mcp-auth 后端
POST {MCP_AUTH_API_URL}/api/auth/verify-token,以X-API-Key: {BEXELL_MCP_AUTH_API_KEY}标识调用方服务 - 后端统一查询
mcp_auth.mcp_token表,返回{"valid": bool, "client_id": str, "service_scope": str} - token 与
bexell-scheduling服务作用域匹配才校验通过 - 进程内缓存校验结果 30s(
MCP_AUTH_CACHE_TTL),减少对后端的重复调用
客户端配置示例:
{
"bexell-scheduling": {
"type": "http",
"url": "http://127.0.0.1:8001/bexell/mcp",
"headers": {
"Content-Type": "application/json",
"Accept": "application/json, text/event-stream",
"Authorization": "Bearer <token>"
}
}
}
相关环境变量:
| 环境变量 | 说明 |
|---|---|
MCP_PUBLIC_URL / BEXELL_MCP_PUBLIC_URL |
服务对外地址(OAuth 资源元数据),模组独立地址未设置时回退通用值 |
MCP_AUTH_API_URL |
mcp-auth 后端地址,如 https://mcp-auth-admin.digiwincloud.com.cn/mcp-auth-api |
BEXELL_MCP_AUTH_API_KEY |
Bexell 模组独立 API Key(由 mcp-auth 后端签发) |
MCP_AUTH_CACHE_TTL |
token 校验结果缓存秒数,默认 30 |
四、MCP Tool 清单
| # | Tool 名称 | 类型 | 用途 |
|---|---|---|---|
| 1 | get_equipment_by_type |
基础查询 | 按设备类型查询该类型所有设备的基础产能信息 |
| 2 | get_schedule_occupied |
基础查询 | 获取指定类型全部设备的已占用产能合计 |
| 3 | get_product_load |
基础查询 | 查询指定品号在目标设备类型各设备上的标准产能 |
| 4 | evaluate_trial_capacity |
一体化计算 | 服务端一次性完成全部数据聚合和公式计算,返回评估结果与推荐设备 |
五、Tool 详细说明
5.1 get_equipment_by_type — 按类型查询设备产能
用途: 根据设备类型获取该类型所有设备的基础产能参数,供 Skill 做数据展示或分步计算。
输入参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
equipment_type |
string | 是 | 设备类型,可选值:冲压、表面、检测 |
输出字段:
| 字段 | 类型 | 说明 |
|---|---|---|
equipment_code |
string | 设备编号(如 CY001、DN003、VJ002) |
equipment_name |
string | 设备名称(如 冲压机1、镀镍机3) |
equipment_type |
string | 设备类型 |
max_capacity |
number | 极限产能(H) |
standard_capacity |
number | 标准产能(H) |
min_startup |
number | 最小开机产能(H) |
line_change_cost |
number | 换线成本系数 |
数据来源: equipment_capacity 表(ORM 模型 EquipmentCapacity)
查询逻辑: WHERE equipment_type = :type ORDER BY equipment_code
设备类型与数量:
| 设备类型 | 编号范围 | 数量 |
|---|---|---|
| 冲压 | CY001 ~ CY010 | 10 台 |
| 表面 | DN001 ~ DN012 | 12 台 |
| 检测 | VJ001 ~ VJ005 | 5 台 |
5.2 get_schedule_occupied — 查询排产占用产能
用途: 获取指定类型全部设备当前已被排产计划占用的产能合计,反映设备负荷现状。
输入参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
equipment_type |
string | 是 | 设备类型,如 冲压、表面、检测 |
输出字段:
| 字段 | 类型 | 说明 |
|---|---|---|
equipment_code |
string | 设备编号 |
equipment_name |
string | 设备名称 |
total_occupied_capacity |
number | 占用产能合计(H),无排产时为 0 |
数据来源: product_equipment_schedule 表(ORM 模型 ProductEquipmentSchedule)
查询逻辑: GROUP BY equipment_code,SUM(occupied_capacity),COALESCE 无记录返回 0
5.3 get_product_load — 查询品号设备标准产能
用途: 获取指定品号在目标设备类型各设备上生产时的标准产能消耗系数,用于计算试产需求对设备产能的占用量。
输入参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
product_code |
string | 是 | 品号,如 A0001、A0002、A0003 |
equipment_type |
string | 是 | 设备类型,如 冲压、表面、检测 |
输出字段:
| 字段 | 类型 | 说明 |
|---|---|---|
product_code |
string | 品号 |
product_name |
string | 品名 |
equipment_code |
string | 设备编号 |
equipment_name |
string | 设备名称 |
standard_capacity |
number | 该品号在该设备上每生产 1 件所消耗的产能(H/件) |
数据来源: product_equipment_load 表 JOIN equipment_capacity 表(ORM 模型 ProductEquipmentLoad)
查询逻辑: 按品号 + 设备类型联合过滤,按设备编号排序
品号与标准产能示例(以 A0003 圆柱电池钢壳为例):
| 设备类型 | 设备编号 | 标准产能(H/件) |
|---|---|---|
| 冲压 | CY001~CY010 | 0.2 |
| 表面 | DN001~DN012 | 0.1 |
| 检测 | VJ001~VJ005 | 0.01 |
5.4 evaluate_trial_capacity — 一体化试产产能评估 ⭐
用途: 核心工具。服务端一次性完成全部数据聚合和公式计算,返回每台设备的可用产能明细和最优推荐设备。Skill 层只需调用一次即可完成评估,无需多次查询和自行计算。
评估范围: 覆盖该品号配置了标准产能的全部设备类型(冲压/表面/检测)的所有设备,结果按可用产能降序混合排名。
输入参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
product_code |
string | 是 | 品号,如 A0003 |
trial_quantity |
integer | 是 | 试产数量,如 10 |
输出结构:
{
"product_code": "A0003",
"product_name": "圆柱电池钢壳",
"trial_quantity": 10,
"evaluated_at": "2026-08-22T15:30:00",
"results": [
{
"rank": 1,
"equipment_code": "CY003",
"equipment_name": "冲压机3",
"equipment_type": "冲压",
"max_capacity": 15.00,
"occupied_capacity": 8.00,
"line_change_cost": 1.00,
"min_startup_buffer": 0.40,
"product_standard_capacity": 0.2,
"trial_demand": 2.00,
"available_capacity": 3.60,
"status": "可用"
}
],
"recommended": {
"equipment_code": "CY003",
"equipment_name": "冲压机3",
"available_capacity": 3.60
}
}
输出字段说明(results 数组内每条记录):
| 字段 | 类型 | 说明 |
|---|---|---|
rank |
integer | 排名(按可用产能降序,跨设备类型混合排名) |
equipment_code |
string | 设备编号 |
equipment_name |
string | 设备名称 |
equipment_type |
string | 设备类型 |
max_capacity |
number | 极限产能(H) |
occupied_capacity |
number | 当前占用产能合计(H) |
line_change_cost |
number | 换线成本 |
min_startup_buffer |
number | 最小开机缓冲(= min_startup × 0.1) |
product_standard_capacity |
number | 该品号在该设备的标准产能(H/件) |
trial_demand |
number | 试产需求(= 试产数量 × 标准产能) |
available_capacity |
number | 可用产能(核心指标) |
status |
string | 状态:可用(≥0)或 已满负荷(<0) |
核心计算公式:
可用产能 = 极限产能
− 占用产能合计
− 换线成本
− 最小开机 × 0.1
− 试产数量 × 品号标准产能
数据来源(一次聚合查询,单条 SQL 完成):
| 公式因子 | 来源表 | 字段 |
|---|---|---|
| 极限产能 | equipment_capacity |
max_capacity |
| 占用产能合计 | product_equipment_schedule |
SUM(occupied_capacity) |
| 换线成本 | equipment_capacity |
line_change_cost |
| 最小开机 | equipment_capacity |
min_startup |
| 品号标准产能 | product_equipment_load |
standard_capacity |
| 品名 | product_info |
product_name |
推荐逻辑: 取 results 中排名第一(可用产能最大)且 available_capacity >= 0 的设备;若无设备满足条件,recommended 返回 null。
六、Tool 调用策略
| 场景 | 推荐方式 | 说明 |
|---|---|---|
| 试产评估(默认) | 直接调用 evaluate_trial_capacity |
一次调用完成全部计算,Skill 只需格式化输出 |
| 分步调试 / 中间数据展示 | Tool 1 → Tool 2 → Tool 3 → Skill 内计算 | 适用于需要逐步展示数据来源或教学演示场景 |
| 仅查看设备信息 | 调用 get_equipment_by_type |
不涉及排产计算,纯基础数据查询 |
| 仅查看负荷现状 | 调用 get_schedule_occupied |
查看当前排产占用情况 |
七、数据模型依赖
Bexell 模组复用 bexell_schedule_ai 库中以下现有表和 ORM 模型(定义于 src/modules/bexell/models.py),无需新增任何表结构:
| 表 / 视图 | ORM 模型 | 说明 |
|---|---|---|
sys_parameter |
SysParameter |
系统参数(sys_s_parameter = 影响系数 0.1) |
equipment_capacity |
EquipmentCapacity |
设备基础产能(极限/标准/最小开机/换线成本) |
product_info |
ProductInfo |
品号主数据 |
product_equipment_load |
ProductEquipmentLoad |
品号 × 设备标准产能(81 行种子数据) |
product_equipment_schedule |
ProductEquipmentSchedule |
排产明细(排产数量 & 占用产能) |
v_equipment_realtime_capacity |
—(视图) | 设备实时产能视图(评估工具未直接使用,供查询参考) |
表关系:
┌─────────────────────┐
│ sys_parameter │ 系统参数(影响系数 0.1)
└─────────────────────┘
┌─────────────────────┐ ┌──────────────────────────┐
│ equipment_capacity │────▶│ product_equipment_load │
│ • 设备基础产能 │ │ • 品号×设备 标准产能 │
│ • 极限/标准/开机 │ │ • 关联 product_info │
│ • 换线成本 │ │ • 关联 equipment_capacity│
└──────────┬──────────┘ └──────────────────────────┘
│
│ LEFT JOIN(占用产能聚合)
▼
┌──────────────────────────────┐
│ product_equipment_schedule │
│ • 排产明细 │
│ • 排产数量 & 占用产能 │
└──────────────────────────────┘
八、Skill 集成
MCP 服务配套 Skill:trial-production-scheduling-evaluator
Skill 执行流程:
用户输入(品号 + 试产数量 + 设备类型)
│
▼
Step 1: 解析参数 & 校验
│
▼
Step 2: 调用 evaluate_trial_capacity
│ 传入 product_code + trial_quantity
▼
Step 3: 结果排序 & 状态标记
│ 可用产能 ≥ 0 → "可用"
│ 可用产能 < 0 → "已满负荷"
▼
Step 4: 格式化输出评估报告
• 推荐设备(★)
• 全部候选设备明细表
• 风险提示
触发场景:
- 评估试产排程
- 查询设备可用产能
- 推荐试产设备
- 计算设备产能负荷
九、错误处理
| 错误场景 | 返回内容 |
|---|---|
| token 缺失 / 无效 / 服务作用域不匹配 | MCP 层返回 401 Unauthorized(本地缓存 30s,后端不可达时同样拒绝) |
| 品号不存在 | {"error": "品号 XXX 不存在"} |
| 品号在某设备无标准产能配置 | 该设备不参与排名(JOIN 过滤),不报错 |
| 所有设备已满负荷 | recommended 返回 null,results 中所有 status 为 "已满负荷" |
| 数据库连接失败 | 由 SQLAlchemy(pool_pre_ping)与统一服务异常处理捕获 |
十、技术实现要点
| 项目 | 说明 |
|---|---|
| 框架 | MCPServer(MCP Python SDK),非 FastAPI 挂载 |
| 挂载方式 | server.py 中 Starlette Mount("/bexell", bexell_server.streamable_http_app(streamable_http_path="/mcp")),子路径 /mcp |
| 鉴权 | get_auth(service="BEXELL") 构建 AuthSettings + ApiTokenVerifier,Bearer Token 动态校验 |
| 数据库访问 | 模组独立 SQLAlchemy Engine(BEXELL_DB_* 环境变量),pool_size=10、pool_pre_ping=True |
| ORM 模型 | src/modules/bexell/models.py 中定义 5 张表模型 |
| 核心计算 | evaluate_trial_capacity 通过单条聚合 SQL 完成(LEFT JOIN 占用聚合 + JOIN 品号负荷),避免多次往返 |
| 影响系数 | 公式中 0.1 对应 sys_parameter.sys_s_parameter(当前为 SQL 硬编码) |
| 并发安全 | 每次工具调用独立获取/关闭 DB Session |
| 生命周期 | 父 app lifespan 统一管理 session manager 启动与连接池关闭(close_bexell_engine) |
十一、文件结构
mcp-server-demo/
├── .env.example # 环境变量模板(BEXELL_MCP_AUTH_API_KEY、BEXELL_DB_* 等)
├── sql/bexell_init.sql # bexell_schedule_ai 建表 + 种子数据(5 表 + 1 视图)
├── src/
│ ├── server.py # 统一服务入口:Mount("/bexell") + lifespan
│ ├── auth.py # 动态 Bearer Token 鉴权(mcp-auth 后端校验)
│ └── modules/
│ └── bexell/
│ ├── __init__.py
│ ├── tools.py # MCPServer + 4 个 MCP Tool
│ ├── db.py # 独立 SQLAlchemy Engine / SessionLocal
│ └── models.py # 5 张表 ORM 模型
└── docs/bexell/
└── mcp-services.md # 本文档
启动方式:
cd mcp-server-demo
set -a; source .env; set +a
cd src && python server.py
# Bexell MCP 端点: http://localhost:8001/bexell/mcp