Skip to main content
Glama
adambbhe
by adambbhe

sanxiao-mcp —— 金蝶云·星辰「三效项目管理」MCP Server

GC032 财务智能体 · 三效端。应用标识 bdi_projectmanagement, 订阅地址 https://cloud.kingdee.com/kae/#/market/detail?sid=1285

依据《三效项目管理 API_2025》官方文档 + 《金蝶三效项目管理API开发框架》实现。 一期只读:查询类全开,写入类代码就位但默认被守卫拒绝。

三效 API 的形状(先理解这个,其余都好办)

三效不是"一个业务一个端点",而是通用单据(Bill)CRUD: 所有单据 —— 项目档案、借款、报销、付款、工时填报、采购申请 —— 都走同一组接口, 靠 formId + 字段标识驱动。

POST https://bj1-api.kingdee.com/bdiprojectapi/common/{action}
后端  openapi/ierp/kapi/app/bdi_projectmanagement/{action}

action ∈ { listQuery, getById, saveOrUpdate, submit, unSubmit,
           audit, unAudit, delete, push, operation }

所以本服务的结构也是"一个出口 + 两层封装",而不是几十个端点常量。

Related MCP server: mcp-timely

目录

sanxiao/
├── config.py    环境与鉴权四要素;url() / headers() 在这里定形
├── forms.py     formId 登记表 + 中文别名解析(项目档案 → bdi_projectfile)
├── query.py     qParams 结构化查询 DSL:构造、校验、还原成类 SQL 可读串
├── models.py    saveOrUpdate 字段模型(8 种 fType + 分录 + 下推 + 附件)
├── guards.py    白名单 + 默认拒绝 + 审计
├── client.py    唯一 HTTP 出口 _post(),读写方法都从这里过
└── server.py    28 个 MCP 工具(通用层 + 语义层)
test_connection.py   L1 配置 → L2 网络 → L3 鉴权 → L4 只读 → L5 守卫
tests/               pytest:query / models / guards / client

鉴权:四个请求头,没有签名

kingdee-star-mcp(jdy 开放网关)不一样 —— 三效不需要 HMAC 签名, 只要携带四个头,全部由云星辰标准 API 事先取得:

取值来源

Token

产品账套级 token,走星辰标准 API 鉴权获取

X-GW-Router-Addr

IDC 域名 = 【实时接收授权】推送报文里的 domain 字段

groupname

授权信息,开放平台推送至沙箱消息接收地址

accountid

同上

踩坑提示:官方文档明确写了"在云平台 API 市场调试时可忽略 X-GW-Router-Addr"。于是很多人在市场里调通了,一到代码就 404 —— 因为代码调用必须带这个头。config.headers() 已处理,别删。

拿到四要素后填进 .env(模板见 .env.example)。

快速开始

pip install -r requirements.txt
cp .env.example .env        # 填入四要素
pytest -q                   # 69 项单测应全绿
python test_connection.py   # 分层联调,结果写入 connection_test_result.txt

Windows 直接双击 run_test.bat

MCP 工具(28 个)

元信息

工具

用途

sx_health

网关地址、只读开关、四要素就绪状态与缺失项

sx_list_forms

已登记的 formId、中文名、默认字段

sx_capabilities

可用 action、只读 operation 白名单、当前放行的写动作

通用层 —— 完整映射官方接口

工具

官方接口

sx_list_query

listQuery

sx_get_by_id

getById

sx_operation

operation(受只读白名单约束)

sx_build_query

本地工具:把简化条件译成 qParams,不发请求

语义层 —— 不必背 formId

sx_list_projects / sx_list_reimbursements / sx_list_loans / sx_list_payments / sx_list_working_hours / sx_get_bill sx_query_cost_budget / sx_query_material_budget / sx_query_working_hour_budget sx_get_user_permission / sx_get_form_config / sx_workflow_status / sx_get_app_parameter

写入层 —— 默认拒绝

sx_build_bill_payload(只组装不发送,一期也能用来给人工核对报文) sx_save_or_update / sx_submit / sx_un_submit / sx_audit / sx_un_audit / sx_delete / sx_push

查询条件怎么写

官方 qParams 是条件数组:顶层各项之间 and,条件组内由 joinKey 连接。

[
  { "childGroup": false, "qKey": "number", "qCp": "like", "qValue": "ew" },
  { "childGroup": true,  "joinKey": "or", "childCondition": [
      { "childGroup": false, "qKey": "number", "qCp": "=", "qValue": "new5" },
      { "childGroup": false, "qKey": "number", "qCp": "=", "qValue": "New" }
  ]}
]
// 等价于 number like '%ew%' and (number='new5' or number='New')

比较符:= > >= < <= != like likeLeft。没有 in —— 用 query.any_of()sx_build_query 的 or 组模拟。分录字段写「分录标识.字段标识」, 如 projectfileteam.teamstaff

安全模型

守卫是白名单 + 默认拒绝三层:

  1. action 分类 —— listQuery/getById/operation 是读,其余七个是写。

  2. operationKey 白名单 —— operation 表面是读接口,但 operationKey 是自由字符串,所以对文档 10.1–10.9 的九个方法再做一次白名单。

  3. 资金类永久禁写 —— 付款单(bdi_ex_pay*)的写与流程动作, 即使 SX_ALLOW_WRITE_ACTIONS=* 也拦。

二期开写的顺序:SX_READONLY=false → 在 SX_ALLOW_WRITE_ACTIONS 里逐个加动作灰度。不要一步到 *

所有调用与拦截都打到 sanxiao.audit logger。

真实报文推翻了文档给人的印象

官方另给的《三效-API参考代码》是一份完整的 bdi_projectfile 单据报文 (已存为 tests/fixtures/projectfile_reference.json)。它比文档示例可信, 并且推翻了四条想当然的假设 —— 每条都在 tests/test_reference_payload.py 里钉死了,改回去会立刻红:

文档示例给人的印象

真实报文

每个字段都有 fValue

空值字段整个不出现 fValue 键,不是 fValue:""

enum 必须配 fValueText

status/enable/enablecostamtctl 都只有 fValue

fValue 都是字符串

见过原生 true / false / 0,与字符串 "10" 混用

fValueText 是 enum 专有

bd 也带,用来放基础资料的显示名

其中第三条最要命:早先 field_from_dict 里一句 str(d["fValue"]), 碰上 {"fType":"enum","fValue":true} 会产出 Python 风格的 "True" —— 大写 T 的字符串,服务端认不得,且报错信息不会告诉你是这儿的问题。 现在 fValue 一律原样透传。

好处是 getById 的返回可以直接喂回 saveOrUpdate(改一两个字段再存), 往返无损,这条路有 test_roundtrip_is_lossless 守着。

另外从报文的 bd 字段里摘出了八个基础资料 formId,已登记进 forms.pybd_employeebd_departmentbd_customerbdi_bd_customer_forkbdi_projecttypesbdi_projectareabdi_projectstautsbdi_projectroles

bdi_projectstauts 不是笔误 —— 官方把 status 拼成了 stauts, formId 和字段名都是这个拼法。别"顺手修正"。

字段标识从哪来

别猜。 权威取法是星辰界面: 单据列表 → 更多 → 引入数据 → 模板管理 → 新增模板。

跑起来之后也可以反查:sx_get_form_config(form_id) 会调 operation.getUserconfig 返回该单据的字段配置。

forms.py 登记了 15 个 formId:七个来自官方文档 (bdi_projectfilebdi_ex_loanbdi_ex_bxbdi_ex_paybdi_fillinworkinghourspur_bill_requestbd_auxinfo), 八个来自参考代码报文里的基础资料引用。其余单据把 formId 直接传给 sx_list_query 即可,不必先登记。

字段名同理 —— 只有 bdi_projectfile 的字段是从真实报文核实过的 (注意它用 status/enable没有 billstatus;那是业务单据的字段)。 其余单据的默认字段仍是按惯例推的,跑通后请用 sx_get_form_config 核实。

与 kingdee-star-mcp 的关系

两者是同一个星辰账套的两个开放能力,各自独立部署:

kingdee-star-mcp

sanxiao-mcp

网关

api.kingdee.com jdy 网关

bj1-api.kingdee.com 三效网关

鉴权

HMAC 签名 + app-token 两层凭据

四个头,无签名

端点

/jdy/v2/{module}/{object} 数百个

common/{action} 十个

覆盖

财务(凭证、报销、往来)

项目管理(项目、工时、预算、报销)

三效的 Token 需要先经星辰标准 API 取得 —— 如果已经在 kingdee-star-mcp 里跑通了授权链路,可以把拿到的 token 与授权推送里的 domain/groupname/ accountid 直接填进本项目的 .env

已知留白

  • 官方文档未给统一的返回体 schema,client._unwrap() 做的是宽松解包: 能认出 errcode/success/data 就归一化,认不出原样返回 —— 宁可多给数据, 不因猜错结构而吞数据。拿到真实返回后可以收紧。

  • 单据状态码文档未列全。参考代码里项目档案 status="A"enable="1", 但 A/B/C 各代表什么、业务单据的 billstatus 取值域,都还没有权威说明。 语义层的 status 参数目前透传原始标识。

  • 参考代码里有几个字段的 fType 自相矛盾 —— phaseplanenddatephaseenddate 声明为 num 却明显是日期。这是厂商报文本身的不一致, 模型层照单全收不做纠正,以免"帮倒忙"。

  • 附件上传走 base64,大文件需要评估网关体积上限,文档未说明。

F
license - not found
C
quality
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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
    A
    quality
    B
    maintenance
    Read-only MCP connector for querying the Protheus (TOTVS) system, exposing 10 GET endpoints as MCP tools with OAuth2 authentication and friendly error handling.
    10
  • A
    license
    B
    quality
    C
    maintenance
    MCP server for Kingdee Cloud (K3Cloud) ERP that enables AI assistants to query and operate ERP data through natural language, supporting bills, metadata, and read/write operations.
    8
    1
    Apache 2.0

View all related MCP servers

Related MCP Connectors

  • A paid remote MCP for AI SDK data query MCP, built to return verdicts, receipts, usage logs, and aud

  • Log, query, and edit expenses, budgets, and accounts in Ledgy from any MCP-compatible AI assistant.

  • Read-only MCP server for ClassQuill, a tutoring-business-management platform.

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/adambbhe/kingdee-sanxiao-MCP'

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