sanxiao-mcp
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,走星辰标准 API 鉴权获取 |
| IDC 域名 = 【实时接收授权】推送报文里的 |
| 授权信息,开放平台推送至沙箱消息接收地址 |
| 同上 |
踩坑提示:官方文档明确写了"在云平台 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.txtWindows 直接双击 run_test.bat。
MCP 工具(28 个)
元信息
工具 | 用途 |
| 网关地址、只读开关、四要素就绪状态与缺失项 |
| 已登记的 formId、中文名、默认字段 |
| 可用 action、只读 operation 白名单、当前放行的写动作 |
通用层 —— 完整映射官方接口
工具 | 官方接口 |
|
|
|
|
|
|
| 本地工具:把简化条件译成 |
语义层 —— 不必背 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。
安全模型
守卫是白名单 + 默认拒绝三层:
action 分类 ——
listQuery/getById/operation是读,其余七个是写。operationKey 白名单 ——
operation表面是读接口,但operationKey是自由字符串,所以对文档 10.1–10.9 的九个方法再做一次白名单。资金类永久禁写 —— 付款单(
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
里钉死了,改回去会立刻红:
文档示例给人的印象 | 真实报文 |
每个字段都有 | 空值字段整个不出现 |
|
|
| 见过原生 |
|
|
其中第三条最要命:早先 field_from_dict 里一句 str(d["fValue"]),
碰上 {"fType":"enum","fValue":true} 会产出 Python 风格的 "True" ——
大写 T 的字符串,服务端认不得,且报错信息不会告诉你是这儿的问题。
现在 fValue 一律原样透传。
好处是 getById 的返回可以直接喂回 saveOrUpdate(改一两个字段再存),
往返无损,这条路有 test_roundtrip_is_lossless 守着。
另外从报文的 bd 字段里摘出了八个基础资料 formId,已登记进 forms.py:
bd_employee、bd_department、bd_customer、bdi_bd_customer_fork、
bdi_projecttypes、bdi_projectarea、bdi_projectstauts、bdi_projectroles。
bdi_projectstauts不是笔误 —— 官方把 status 拼成了 stauts, formId 和字段名都是这个拼法。别"顺手修正"。
字段标识从哪来
别猜。 权威取法是星辰界面: 单据列表 → 更多 → 引入数据 → 模板管理 → 新增模板。
跑起来之后也可以反查:sx_get_form_config(form_id) 会调
operation.getUserconfig 返回该单据的字段配置。
forms.py 登记了 15 个 formId:七个来自官方文档
(bdi_projectfile、bdi_ex_loan、bdi_ex_bx、bdi_ex_pay、
bdi_fillinworkinghours、pur_bill_request、bd_auxinfo),
八个来自参考代码报文里的基础资料引用。其余单据把 formId
直接传给 sx_list_query 即可,不必先登记。
字段名同理 —— 只有 bdi_projectfile 的字段是从真实报文核实过的
(注意它用 status/enable,没有 billstatus;那是业务单据的字段)。
其余单据的默认字段仍是按惯例推的,跑通后请用 sx_get_form_config 核实。
与 kingdee-star-mcp 的关系
两者是同一个星辰账套的两个开放能力,各自独立部署:
kingdee-star-mcp | sanxiao-mcp | |
网关 |
|
|
鉴权 | HMAC 签名 + app-token 两层凭据 | 四个头,无签名 |
端点 |
|
|
覆盖 | 财务(凭证、报销、往来) | 项目管理(项目、工时、预算、报销) |
三效的 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自相矛盾 ——phaseplanenddate、phaseenddate声明为num却明显是日期。这是厂商报文本身的不一致, 模型层照单全收不做纠正,以免"帮倒忙"。附件上传走 base64,大文件需要评估网关体积上限,文档未说明。
Maintenance
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
- FlicenseNot gradedqualityBmaintenanceExposes enterprise WeChat approval, report, and check-in data reading capabilities through the MCP protocol, enabling WorkBuddy and CodeBuddy to read historical business data.7
- AlicenseAqualityBmaintenanceA read-only MCP server for querying Timely time tracking data, providing tools for project overviews, time spent summaries, and work log entries.3MIT
- FlicenseAqualityBmaintenanceRead-only MCP connector for querying the Protheus (TOTVS) system, exposing 10 GET endpoints as MCP tools with OAuth2 authentication and friendly error handling.10
- AlicenseBqualityCmaintenanceMCP 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.81Apache 2.0
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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