@wukongcrm/mcp-server 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/dist/nocode.js +59 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -198,6 +198,12 @@ wukong-mcp
|
|
|
198
198
|
- 打印与消息:`nocode_query_printing`、`nocode_write_printing`、`nocode_query_messages`、`nocode_write_message`
|
|
199
199
|
- 开放能力与应用市场:`nocode_query_integrations`、`nocode_write_integration`、`nocode_query_marketplace`、`nocode_write_marketplace`
|
|
200
200
|
|
|
201
|
+
常见保存动作必须使用旧前端对应的聚合 BO,而不是把单个字段或单个值直接作为 `payload`:
|
|
202
|
+
|
|
203
|
+
- 字段保存:`ModuleFieldSaveBO`,至少包含 `moduleId`、实际 `version`、`mainFieldId`/`tempMainFieldId` 和非空 `moduleFieldList`。
|
|
204
|
+
- 记录保存:`ModuleFieldDataSaveBO`,至少包含 `moduleId`、实际 `version` 和非空 `fieldDataList`;字段值使用 `fieldId`、`fieldName`、`name`、`type`、`value`,修改时增加 `dataId`。
|
|
205
|
+
- 新建模块的实际版本通常从 `0` 开始,应先用 `nocode_get_module` 读取并显式传入,不能根据已发布老模块猜测为 `1`。
|
|
206
|
+
|
|
201
207
|
文件流仍有意不经 MCP 代理,因此应用导入/导出、Excel 导入/导出、跟进导出、打印 PDF/Word 下载不在工具中;打印内容生成和预览 JSON 接口仍可使用。内部测试接口 `/moduleMQ/send` 也不会暴露。
|
|
202
208
|
|
|
203
209
|
### CRM、OA、HRM、财务、进销存与工单工具
|
package/dist/nocode.js
CHANGED
|
@@ -62,7 +62,7 @@ export const nocodeToolDefinitions = [
|
|
|
62
62
|
},
|
|
63
63
|
{
|
|
64
64
|
name: "nocode_get_module_schema",
|
|
65
|
-
description: "
|
|
65
|
+
description: "一次获取无代码模块字段、表单布局、列表头、页面布局、选项、公式、标签和序列号规则;写入记录前应先调用,并优先使用 nocode_get_module 返回的实际 version(新建模块通常为 0);只读。",
|
|
66
66
|
schema: z.object({ ...moduleContextShape, includeExtended: z.boolean().optional() }),
|
|
67
67
|
access: "read"
|
|
68
68
|
},
|
|
@@ -243,7 +243,7 @@ export const nocodeToolDefinitions = [
|
|
|
243
243
|
},
|
|
244
244
|
{
|
|
245
245
|
name: "nocode_write_module",
|
|
246
|
-
description: "保存、启停、复制、发布、丢弃草稿、删除模块、保存页面布局或维护 BI Dashboard
|
|
246
|
+
description: "保存、启停、复制、发布、丢弃草稿、删除模块、保存页面布局或维护 BI Dashboard 模块;action=save 的 payload 使用旧 CRM ModuleSaveBO(常见普通模块包含 applicationId、name、moduleType=1、icon);必须 confirm=true。",
|
|
247
247
|
schema: z.object({
|
|
248
248
|
action: z.enum(["save", "status", "copy", "publish", "discardDraft", "delete", "layout", "deleteCancelledCompanyData", "dashboardSave", "dashboardRemove"]),
|
|
249
249
|
moduleId: idSchema.optional(),
|
|
@@ -257,14 +257,14 @@ export const nocodeToolDefinitions = [
|
|
|
257
257
|
},
|
|
258
258
|
{
|
|
259
259
|
name: "nocode_write_field",
|
|
260
|
-
description: "
|
|
260
|
+
description: "保存字段,或修改普通/固定模块列表字段排序和样式;action=save 的 payload 必须是聚合 ModuleFieldSaveBO,包含 moduleId、实际 version、mainFieldId 或 tempMainFieldId、moduleFieldList,不能直接传单个字段;必须 confirm=true,否则只返回固定接口和请求预览。",
|
|
261
261
|
schema: z.object({ action: z.enum(["save", "sort", "style", "fixedSort", "fixedStyle"]), ...payloadWriteShape }),
|
|
262
262
|
access: "write",
|
|
263
263
|
destructive: true
|
|
264
264
|
},
|
|
265
265
|
{
|
|
266
266
|
name: "nocode_write_record",
|
|
267
|
-
description: "新增/修改、删除、转移负责人或设置分组;payload
|
|
267
|
+
description: "新增/修改、删除、转移负责人或设置分组;action=save 的 payload 必须是 ModuleFieldDataSaveBO,包含 moduleId、实际 version、fieldDataList;每个字段值应包含 fieldId、fieldName、name、type、value,修改时再带 dataId;必须 confirm=true,否则只返回预览。",
|
|
268
268
|
schema: z.object({ action: z.enum(["save", "delete", "transfer", "setCategory"]), ...payloadWriteShape }),
|
|
269
269
|
access: "write",
|
|
270
270
|
destructive: true
|
|
@@ -430,9 +430,11 @@ export function createNocodeToolHandlers(config = {}) {
|
|
|
430
430
|
const moduleId = requiredId(args.moduleId, "moduleId");
|
|
431
431
|
const version = requiredVersion(args.version);
|
|
432
432
|
const query = cleanObject({ moduleId: numericValue(moduleId), version, categoryId: args.categoryId });
|
|
433
|
+
// 旧后端会直接拆箱 filterHidden;显式传 false 与无代码前端的字段配置请求保持一致,避免空值触发 500。
|
|
434
|
+
const formQuery = { ...query, filterHidden: false };
|
|
433
435
|
const [fields, form, listHead, layout, unionModules] = await Promise.all([
|
|
434
436
|
client.post("/moduleField/queryList", query),
|
|
435
|
-
client.post("/moduleField/formList",
|
|
437
|
+
client.post("/moduleField/formList", formQuery),
|
|
436
438
|
client.post("/moduleField/queryListHead", query),
|
|
437
439
|
client.post(`/moduleM/pageLayout/${moduleId}/${version}`),
|
|
438
440
|
client.post(`/moduleM/unionModules/${moduleId}/${version}`)
|
|
@@ -517,14 +519,14 @@ export function createNocodeToolHandlers(config = {}) {
|
|
|
517
519
|
nocode_query_marketplace: async (args) => executeNocodeRead(client, queryMarketplaceRoute(args)),
|
|
518
520
|
nocode_write_application: async (args) => executeApplicationWrite(client, args),
|
|
519
521
|
nocode_write_module: async (args) => executeModuleWrite(client, args),
|
|
520
|
-
nocode_write_field: async (args) =>
|
|
522
|
+
nocode_write_field: async (args) => executeFieldWrite(client, args, {
|
|
521
523
|
save: "/moduleField/save",
|
|
522
524
|
sort: "/moduleField/setFieldSort",
|
|
523
525
|
style: "/moduleField/setFieldStyle",
|
|
524
526
|
fixedSort: "/moduleField/fixed/setFieldSort",
|
|
525
527
|
fixedStyle: "/moduleField/fixed/setFieldStyle"
|
|
526
528
|
}),
|
|
527
|
-
nocode_write_record: async (args) =>
|
|
529
|
+
nocode_write_record: async (args) => executeRecordWrite(client, args, {
|
|
528
530
|
save: "/moduleFieldData/save",
|
|
529
531
|
delete: "/moduleFieldData/delete",
|
|
530
532
|
transfer: "/moduleFieldData/transfer",
|
|
@@ -874,11 +876,11 @@ async function executeApplicationWrite(client, args) {
|
|
|
874
876
|
switch (action) {
|
|
875
877
|
case "create":
|
|
876
878
|
targetPath = "/moduleMetadata/save";
|
|
877
|
-
body =
|
|
879
|
+
body = applicationPayload(args.payload, action);
|
|
878
880
|
break;
|
|
879
881
|
case "update":
|
|
880
882
|
targetPath = "/moduleMetadata/update";
|
|
881
|
-
body =
|
|
883
|
+
body = applicationPayload(args.payload, action);
|
|
882
884
|
break;
|
|
883
885
|
case "status":
|
|
884
886
|
targetPath = `/moduleMetadata/updateStatus/${requiredId(args.applicationId, "applicationId")}`;
|
|
@@ -954,6 +956,20 @@ async function executePayloadWrite(client, args, paths) {
|
|
|
954
956
|
}
|
|
955
957
|
return confirmedPost(client, args, action, targetPath, safePayload(args.payload));
|
|
956
958
|
}
|
|
959
|
+
async function executeFieldWrite(client, args, paths) {
|
|
960
|
+
const action = String(args.action);
|
|
961
|
+
if (action === "save") {
|
|
962
|
+
validateAggregateSavePayload(args.payload, "ModuleFieldSaveBO", "moduleFieldList");
|
|
963
|
+
}
|
|
964
|
+
return executePayloadWrite(client, args, paths);
|
|
965
|
+
}
|
|
966
|
+
async function executeRecordWrite(client, args, paths) {
|
|
967
|
+
const action = String(args.action);
|
|
968
|
+
if (action === "save") {
|
|
969
|
+
validateAggregateSavePayload(args.payload, "ModuleFieldDataSaveBO", "fieldDataList");
|
|
970
|
+
}
|
|
971
|
+
return executePayloadWrite(client, args, paths);
|
|
972
|
+
}
|
|
957
973
|
async function executeSceneWrite(client, args) {
|
|
958
974
|
const action = String(args.action);
|
|
959
975
|
const targetPath = action === "delete" || action === "default"
|
|
@@ -1075,6 +1091,40 @@ function safePayload(value) {
|
|
|
1075
1091
|
}
|
|
1076
1092
|
return value;
|
|
1077
1093
|
}
|
|
1094
|
+
function applicationPayload(value, action) {
|
|
1095
|
+
const payload = safePayload(value);
|
|
1096
|
+
const name = typeof payload.name === "string" ? payload.name.trim() : "";
|
|
1097
|
+
if (!name) {
|
|
1098
|
+
throw new Error("无代码应用名称不能为空。");
|
|
1099
|
+
}
|
|
1100
|
+
if (Array.from(name).length > 20) {
|
|
1101
|
+
throw new Error("无代码应用名称不能超过 20 个字符。");
|
|
1102
|
+
}
|
|
1103
|
+
const description = payload.description;
|
|
1104
|
+
if (description !== undefined && (typeof description !== "string" || Array.from(description).length > 50)) {
|
|
1105
|
+
throw new Error("无代码应用描述必须是字符串且不能超过 50 个字符。");
|
|
1106
|
+
}
|
|
1107
|
+
const icon = typeof payload.icon === "string" ? payload.icon.trim() : "";
|
|
1108
|
+
if (!icon) {
|
|
1109
|
+
throw new Error("无代码应用图标不能为空。");
|
|
1110
|
+
}
|
|
1111
|
+
// 创建时补齐旧前端提交的非业务默认值;更新仍保留调用方提供的完整应用配置。
|
|
1112
|
+
return action === "create"
|
|
1113
|
+
? { ...payload, name, icon, description: description ?? "", iconColor: payload.iconColor ?? "#EBECF0", manageUserIds: payload.manageUserIds ?? [] }
|
|
1114
|
+
: { ...payload, name, icon };
|
|
1115
|
+
}
|
|
1116
|
+
function validateAggregateSavePayload(value, boName, listField) {
|
|
1117
|
+
const payload = safePayload(value);
|
|
1118
|
+
requiredId(payload.moduleId, "payload.moduleId");
|
|
1119
|
+
// 新建模块的有效版本通常为 0;不能用 requiredVersion 的默认值掩盖调用方漏传版本。
|
|
1120
|
+
if (payload.version === undefined) {
|
|
1121
|
+
throw new Error(`${boName} 必须包含实际 version;请先读取模块详情。`);
|
|
1122
|
+
}
|
|
1123
|
+
requiredVersion(payload.version);
|
|
1124
|
+
if (!Array.isArray(payload[listField]) || payload[listField].length === 0) {
|
|
1125
|
+
throw new Error(`${boName} 必须包含非空 ${listField}。`);
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1078
1128
|
function cleanObject(input) {
|
|
1079
1129
|
const output = {};
|
|
1080
1130
|
for (const [key, value] of Object.entries(input)) {
|