flycode-mcp 1.13.0 → 1.14.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 CHANGED
@@ -11,7 +11,7 @@ A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server for the
11
11
  - 基于官方 `@modelcontextprotocol/sdk` 实现,使用标准 `stdio` 传输协议。
12
12
  - 启动即完成 APaaS IDE 平台鉴权链路:账号登录 → 获取租户信息 → 获取 IDE Token。
13
13
  - 内置统一请求层 `request`,自动按请求类型(`center` / `tenant` / `business`)切换中心服务地址、当前租户连接地址或当前租户业务地址,并自动注入鉴权 Token:`business` 类型主要用于 H5 表单查询(需以特定预览账号 token 发起)。
14
- - 当前提供工具:业务逻辑类 `page_model_logic_directories`(分页查询业务逻辑所属目录,返回各业务模型目录项,含 modellogic 用到的 modelcode)、`page_model_logic_list`(分页查询业务逻辑列表)、`get_model_logic`(查询单个业务逻辑详情)、`save_model_logic`(新增业务逻辑:保存完整 `LogicResult`)、`patch_model_logic`(局部补丁修改业务逻辑的 input/output 结构或顶层元数据,无需回传整份对象,替代旧版轻量保存)、`str_replace_flycode`(批量局部替换 flycode 脚本,或用 `rewrite: true` 整份重写);实体类 `page_entity_list`(分页查询实体列表)、`get_entity`(查询实体详情);表单 / 页面类 `page_form_directories`(查询表单所属目录,取回的 `directorytypecode` 即表单 `pageinfo.directorytypecode` 的取值;该接口不支持分页、全量数百条,故在服务层强制收敛——默认最多回 30 条、硬上限 200 条,未传筛选条件时只回顶级目录,并回 `truncated` / `hint` 提示)、`page_form_list`(分页查询表单 / 页面列表)、`get_form`(查询表单 / 页面详情);H5 表单类 `page_h5_form`(分页查询 H5 表单列表)、`get_h5_form`(查询 H5 表单详情,含 `confjson` 内容 JSON);函数类 `page_function_list`(分页查询 flycode 函数列表)、`get_function`(查询 flycode 函数详情,含 `confjson` 函数代码内容);数据库函数类 `page_database_function_list`(分页查询 PostgreSQL 自定义数据库函数列表,列表结果随行返回函数体 `functionscript`);SQL 执行类 `run_sql`(在业务库中执行一条 SELECT 查询,返回查询结果数据与结果总数);通用类 `generate_unique_code`(生成唯一编码,用于新建实体 / 领域 / 表单时生成 JSON 中的 `code` 字段)。
14
+ - 当前提供工具:业务逻辑类 `page_model_logic_directories`(分页查询业务逻辑所属目录,返回各业务模型目录项,含 modellogic 用到的 modelcode)、`page_model_logic_list`(分页查询业务逻辑列表)、`get_model_logic`(查询单个业务逻辑详情)、`save_model_logic`(新增业务逻辑:保存完整 `LogicResult`)、`patch_model_logic`(局部补丁修改业务逻辑的 input/output 结构或顶层元数据,无需回传整份对象,替代旧版轻量保存)、`str_replace_flycode`(批量局部替换 flycode 脚本,或用 `rewrite: true` 整份重写);实体类 `page_entity_list`(分页查询实体列表)、`get_entity`(查询实体详情)、`page_entity_directories`(查询实体所属目录,取回的 `directorytypecode` 即 `create_entity` 的 `directorytypecode` 必填入参;该接口不支持分页、全量数百条,故在服务层强制收敛——默认最多回 30 条、硬上限 200 条,未传筛选条件时只回顶级目录,并回 `truncated` / `hint` 提示)、`create_entity`(新增实体:仅传必要参数,完整实体对象由 MCP 侧组装后调平台保存;保存后处于未发布态需手动发布)、`patch_entity`(给已有实体加字段的 patch ops,当前仅实现 `add_field`;修改 / 删除字段保留未实现、运行时提示去 IDE 平台手动操作;数据字典不允许调整字段);表单 / 页面类 `page_form_directories`(查询表单所属目录,取回的 `directorytypecode` 即表单 `pageinfo.directorytypecode` 的取值;该接口不支持分页、全量数百条,故在服务层强制收敛——默认最多回 30 条、硬上限 200 条,未传筛选条件时只回顶级目录,并回 `truncated` / `hint` 提示)、`page_form_list`(分页查询表单 / 页面列表)、`get_form`(查询表单 / 页面详情);H5 表单类 `page_h5_form`(分页查询 H5 表单列表)、`get_h5_form`(查询 H5 表单详情,含 `confjson` 内容 JSON);函数类 `page_function_list`(分页查询 flycode 函数列表)、`get_function`(查询 flycode 函数详情,含 `confjson` 函数代码内容);数据库函数类 `page_database_function_list`(分页查询 PostgreSQL 自定义数据库函数列表,列表结果随行返回函数体 `functionscript`);SQL 执行类 `run_sql`(在业务库中执行一条 SELECT 查询,返回查询结果数据与结果总数);通用类 `generate_unique_code`(生成唯一编码,用于新建实体 / 领域 / 表单时生成 JSON 中的 `code` 字段)。
15
15
 
16
16
  ---
17
17
 
@@ -31,7 +31,7 @@ A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server for the
31
31
  环境变量:
32
32
 
33
33
  - `PROGRESSIVE_DISCLOSURE=on`(默认):启用渐进式披露。
34
- - `PROGRESSIVE_DISCLOSURE=off`:退化回「全部 22 个工具始终启用」的原有行为,作为客户端未实现 `tools/list_changed` 重拉时的兜底。若 `mcp_activate` 启用某域后调用域工具仍报 `tool not found`,说明当前客户端不支持该通知,请设为 `off`。
34
+ - `PROGRESSIVE_DISCLOSURE=off`:退化回「全部 25 个工具始终启用」的原有行为,作为客户端未实现 `tools/list_changed` 重拉时的兜底。若 `mcp_activate` 启用某域后调用域工具仍报 `tool not found`,说明当前客户端不支持该通知,请设为 `off`。
35
35
 
36
36
  ---
37
37
 
@@ -371,6 +371,79 @@ npm run docs:dev
371
371
  - `message`:保存时编写的提交信息(作用类似 git 提交信息)
372
372
  - `properties`:实体属性数组,每个属性含 `propertyname` / `columnname` / `propertytypecode`(字段类型映射)/ `relationobjectcode`(关联实体)/ `idxtype`(索引方式)/ `publishstatus` / `status` 等
373
373
 
374
+ ### `page_entity_directories` — 分页查询实体所属目录
375
+
376
+ 根据目录名等条件查询 APaaS 平台中的实体目录(只读、幂等)。底层调用 `entityClient.pageDirectories`(接口 `POST /bizserv/biz/getDirectorys`,与表单目录同源,实体传 `directorycategory: "1"`)。返回的 `directorytypecode` 即 `create_entity` 的 `directorytypecode` 必填入参。
377
+
378
+ **输入参数:**
379
+
380
+ | 参数 | 类型 | 必填 | 说明 |
381
+ | ------------- | ------ | ---- | -------------------------------------------------------------------------- |
382
+ | `keys` | string | 否 | 目录名称模糊匹配(建议优先用它检索,避免拉全量) |
383
+ | `directorytypecode` | string | 否 | 目录编码精确匹配 |
384
+ | `parentdirectorytypecode` | string | 否 | 父目录编码精确匹配;传 `"root"` 只看顶级目录 |
385
+ | `centername` / `centercode` | string | 否 | 所属业务中心名称 / 编码模糊或精确匹配 |
386
+ | `marktype` | string | 否 | 创建标记精确匹配:0-平台;1-产品;2-租户 |
387
+ | `limit` | string | 否 | 返回条数上限,默认 30,硬上限 200 |
388
+ | `offset` | string | 否 | 起始偏移,默认 0;配合 `limit` 翻页 |
389
+
390
+ **返回:** 实体目录列表的 JSON(`items`),含 `directorytypecode` / `directorytypename` / `parentdirectorytypecode` / `marktype` 等,以及 `total` / `truncated` / `hint` 收敛提示。该接口不支持分页(全量数百条),工具已在服务层强制收敛。
391
+
392
+ ### `create_entity` — 新增实体(数据表)
393
+
394
+ 新增一张数据表(实体),仅传入必要参数,完整实体对象由 MCP 侧组装后调平台保存接口(非只读、有事务性保护)。底层调用 `service/entity.ts` 的 `createEntity`:构造实体骨架(`datapattern` 固定 `"1"`、自动补主键、非字典实体可选初始字段)→ 一次性保存到 `POST /bizserv/biz/saveObject`。
395
+
396
+ **输入参数:**
397
+
398
+ | 参数 | 类型 | 必填 | 说明 |
399
+ | --------------- | ------ | ---- | -------------------------------------------------------------------------- |
400
+ | `objectname` | string | 是 | 实体中文名 |
401
+ | `objecttypecode`| string | 是 | 实体分类:1-基本对象;2-树型对象;3-数据字典;4-关联对象 |
402
+ | `tablename` | string | 是 | 数据库表名;`objectmark` 自动复制此值 |
403
+ | `directorytypecode` | string | 是 | 所属目录编码,来自 `page_entity_directories` 查询到的 `directorytypecode` |
404
+ | `parentobjectcode` | string | 否 | 父实体编码,树型 / 关联实体使用 |
405
+ | `propertydescr` | string | 否 | 实体描述 |
406
+ | `initialFields` | array | 否 | 可选初始字段(每项仅 `propertyname` / `propertytypecode` / `columnname` 必填);数据字典忽略此参数。非字典实体若未提供主键(`propertytypecode=1`),MCP 会自动补一个「主键 / id」 |
407
+ | `commitMessage` | object | 是 | 提交信息,结构与 `save_model_logic` 的 `commitMessage` 一致 |
408
+ | `confirm` | boolean | 否 | 是否确认落库,默认 `false`。必须显式 `true` 才会真正保存 |
409
+ | `dryRun` | boolean | 否 | 是否仅预览不落库,默认 `true`。置 `false` 才执行保存(需配合 `confirm=true`) |
410
+ | `verify` | boolean | 否 | 保存后是否回读校验,默认 `true` |
411
+
412
+ **返回:** `{ ok, applied, verified, errorCode, message, diff, publishStatus, needManualPublish, entityCode, entityName }`。`publishStatus` 实体级固定 `2`(数据字典为 `1`);`needManualPublish` 为 `true` 时提示需到平台手动发布。
413
+
414
+ > **写操作有风险,默认先预览后确认**:`confirm=false` + `dryRun=true` 时只回一份「将要创建什么」的预览(`errorCode: "DRY_RUN"`),确认无误后再以 `confirm=true`、`dryRun=false` 真正落库。保存后实体处于「未发布」态(数据字典除外),需到平台手动点发布才会真正改表结构。
415
+ >
416
+ > 数据字典(`objecttypecode=3`)字段由平台预置,创建时 `properties` 强制为空、忽略 `initialFields`,且 `publishstatus=1` 已发布。
417
+
418
+ ### `patch_entity` — 给已有实体加字段(patch ops,当前仅 `add_field`)
419
+
420
+ 对已有实体做字段级修改,当前仅实现 `add_field`(新增字段),其余字段级 op 保留未实现。完整对象由 MCP 侧按 ops 在内存副本上预演、再整体保存到 `POST /bizserv/biz/saveObject`(非只读、有事务性保护)。底层调用 `service/entity.ts` 的 `patchEntity`。
421
+
422
+ **输入参数:**
423
+
424
+ | 参数 | 类型 | 必填 | 说明 |
425
+ | --------------- | ------ | ---- | -------------------------------------------------------------------------- |
426
+ | `objectcode` | string | 是 | 目标实体的编码 |
427
+ | `ops` | array | 是 | 字段操作数组,至少一个元素;按数组顺序事务性执行,任一失败整批回滚。仅 `add_field` 已实现 |
428
+ | `commitMessage` | object | 是 | 提交信息,整批 ops 共用一个;结构与 `save_model_logic` 的 `commitMessage` 一致 |
429
+ | `confirm` | boolean | 否 | 是否确认落库,默认 `false`。必须显式 `true` 才会真正保存 |
430
+ | `dryRun` | boolean | 否 | 是否仅预览不落库,默认 `true`。置 `false` 才执行保存(需配合 `confirm=true`) |
431
+ | `verify` | boolean | 否 | 保存后是否回读校验,默认 `true` |
432
+
433
+ `ops[]` 元素(`op` 判别联合):
434
+
435
+ | `op` | 必填载荷 | 说明 |
436
+ | --------------- | ----------------------------------------------------- | -------------------------------------------------------------------------- |
437
+ | `add_field` | `propertyname` / `propertytypecode` / `columnname`(均必填)+ 可选 `propertydescr` / `idxtype` / 关联属性 | 新增一个字段(`columnname` 为数据库列名);事务性预演通过后才落库 |
438
+ | `modify_field` | `propertycode` + `patch` | **保留未实现**:传入会直接失败并提示「修改 / 删除字段请让用户到 IDE 平台手动操作」 |
439
+ | `delete_field` | `propertycode` | **保留未实现**:同上,运行时拒绝 |
440
+
441
+ > **写操作有风险,默认先预览后确认**:同 `create_entity`,`confirm=false` + `dryRun=true` 仅预览;保存后处于未发布态、需手动发布。
442
+ >
443
+ > **数据字典不允许调整字段**:数据字典(`objecttypecode=3`)字段由平台预置,传入 `add_field` / `modify_field` / `delete_field` 任一均会失败并提示「数据字典不允许调整字段」。
444
+
445
+ **返回:** `{ ok, applied, verified, errorCode, message, diff, ops[] }`,`ops[]` 与入参一一对应,便于定位失败项。
446
+
374
447
  ### `page_form_list` — 分页查询表单 / 页面列表
375
448
 
376
449
  根据查询条件分页查询 APaaS 平台中的表单 / 页面定义(只读、幂等)。底层调用 `formClient.pageFormList`(接口 `POST /bizserv/bizpage/pageList`)。
@@ -464,13 +537,14 @@ npm run docs:dev
464
537
  | `dryRun` | boolean | 否 | 只预演输出 diff、不落库,默认 `false` |
465
538
  | `verify` | boolean | 否 | 保存后回读校验改动是否生效,默认 `true` |
466
539
 
467
- **10 类 ops:**
540
+ **11 类 ops:**
468
541
 
469
542
  | op | 关键参数 | 说明 |
470
543
  | ---------------------- | ----------------------------------------------------------------------- | --------------------------------------------------------------------------- |
471
544
  | `set_pageinfo` | `patch` | 浅合并进 pageinfo(如改标题 / 状态) |
472
- | `set_attrs` | `code`、`patch` | 按 `code` 定位节点,浅合并属性(如 `hidden` / `required`);patch 含数组属性时会整体覆盖该数组 |
473
- | `patch_node_array_item`| `nodeCode`、`arrayProp`、`itemKey?`、`itemKeyValue`、`patch` | 按 `nodeCode`+`arrayProp` 定位节点内数组,按 `itemKey`(默认 `code`)找到单个元素浅合并(如只改表格某列的 `options`),其余元素与其它属性不受影响,避免整段覆盖数组与规避大 payload |
545
+ | `set_attrs` | `code`、`patch`、`overwriteArray?` | 按 `code` 定位节点,浅合并**标量**属性(如 `hidden` / `required`);`patch` 含数组属性时默认**阻断**(报 `ARRAY_OVERWRITE_BLOCKED`),需显式 `overwriteArray:true` 才整段覆盖(避免误改丢列);action 结构请用 `patch_action_array_item` |
546
+ | `patch_node_array_item`| `nodeCode`、`arrayProp`、`mode?`、`itemKey?`、`itemKeyValue?`、`item?`、`position?`、`patch?`、`elementArrayProp?`、`elementItemKey?`、`elementItemKeyValue?`、`createIfMissing?` | 按 `nodeCode`+`arrayProp` 定位节点内数组;`mode` 默认 `merge`(按 `itemKey` 浅合并单个元素,如只改某列 `options`),另支持 `append`/`insert`/`remove`;`elementArrayProp` 支持钻到「数组内元素的嵌套数组」(如 `cols[colCode].options`)。目标数组缺失时默认 `ARRAY_NOT_FOUND` 阻断(`createIfMissing:true` 才新建),`remove` 清空调自动删属性避免空壳 |
547
+ | `patch_action_array_item`| `handlerCode`、`actionIndex?`/`actionCode?`、`scope?`、`parentProp?`、`arrayProp`、`mode`、`itemKey?`、`itemKeyValue?`、`item?`、`position?`、`patch?`、`elementArrayProp?`、`elementItemKey?`、`elementItemKeyValue?`、`createIfMissing?` | 改 presenter.handlers/initial 中某 action 内部数组(如 `datarequest.setter` 绑定「界面输出→控件 code」、`param.properties`);`mode` 支持 `merge`/`append`/`insert`/`remove`。**把状态输出绑定到新控件只需传一条新 setter**;真实绑定若在嵌套数组(如 `setter[0].properties` 模型级属性映射),用 `itemKey`/`itemKeyValue` 定位外层元素 + `elementArrayProp` 钻进去即可,无需内联整段 setter;目标数组缺失默认 `ARRAY_NOT_FOUND` 阻断 |
474
548
  | `insert_node` | `parentCode`、`node`、`position?` | 在父节点下插入新节点 |
475
549
  | `remove_node` | `code`、`checkRefs?` | 按 `code` 删除节点,默认校验引用 |
476
550
  | `move_node` | `code`、`newParentCode`、`position?` | 移动节点到新父节点下 |
@@ -648,7 +722,7 @@ flycode-mcp/
648
722
  │ │ └── theme/ # 二次元卡通主题(style.css / index.ts)
649
723
  │ ├── public/ # 静态资源(mascot.svg 卡通吉祥物)
650
724
  │ ├── guide/ # 快速开始 / 接入客户端 / 准备账号
651
- │ ├── capabilities/ # 能力清单与详解(20 个工具,用户视角)
725
+ │ ├── capabilities/ # 能力清单与详解(25 个工具,用户视角)
652
726
  │ ├── cookbook.md # 常见场景话术
653
727
  │ ├── faq.md # 排错 FAQ
654
728
  │ ├── changelog.md # 版本更新记录(按 git tag 整理,用户视角)
@@ -659,7 +733,7 @@ flycode-mcp/
659
733
  │ ├── service/ # 业务封装
660
734
  │ │ ├── auth.ts # 登录 → 获取租户信息 → 获取 IDE Token
661
735
  │ │ ├── logic.ts # 保存业务逻辑(saveModelLogic / patchLogic(12 类 ops,事务性)/ replaceFlyCodeSegments):提交信息处理 + 局部补丁 + 异常兜底
662
- │ │ ├── form.ts # 表单骨架 getFormOutline / 局部读取 getFormFragment / 补丁合并引擎 patchForm(10 类 ops,事务性)/ 全量保存 saveForm
736
+ │ │ ├── form.ts # 表单骨架 getFormOutline / 局部读取 getFormFragment / 补丁合并引擎 patchForm(11 类 ops,事务性)/ 全量保存 saveForm
663
737
  │ │ └── h5.ts # H5 表单查询鉴权(解析 SFA系统管理员预览账号 token) + 列表/详情查询 service 封装
664
738
  │ ├── clients/ # 平台接口封装
665
739
  │ │ ├── auth.ts # 登录 / 获取租户信息 / 获取 IDE Token 请求
@@ -682,7 +756,8 @@ flycode-mcp/
682
756
  │ │ │ ├── write.ts # 写入类工具(save_model_logic / patch_model_logic / str_replace_flycode)
683
757
  │ │ │ └── schemas.ts # 业务逻辑共享 zod schema(LogicResult / 参数 / operations / bindjson)
684
758
  │ │ ├── entity/
685
- │ │ │ ├── read.ts # 只读类工具(page_entity_list / get_entity)
759
+ │ │ │ ├── read.ts # 只读类工具(page_entity_list / get_entity / page_entity_directories)
760
+ │ │ │ ├── write.ts # 写入类工具(create_entity / patch_entity)
686
761
  │ │ │ └── schemas.ts # 实体共享 zod schema(EntityResult / EntityProperty,宽松透传结构)
687
762
  │ │ ├── form/
688
763
  │ │ │ ├── read.ts # 只读类工具(page_form_list / get_form / get_form_outline / get_form_fragment)
@@ -717,7 +792,7 @@ flycode-mcp/
717
792
  2. **登录**:`service/auth.ts` 中的 `authenticate()` 调用 `/api/multiplat/auth/login` 获取 Token,存入内存。
718
793
  3. **定位租户与环境**:`authenticate()` 调用 `/api/multiplat/auth/getTenantInfo`,依据 `tenantCode + envName` 匹配出目标租户,保存其连接信息(`conn.config`)到内存。
719
794
  4. **获取 IDE Token**:`authenticate()` 调用 `/api/multiplat/auth/getIdeToken` 换取 IDE 专用 Token 并覆盖内存中的 Token。
720
- 5. **注册并启动**:创建 `McpServer`,注册 `page_model_logic_list`、`get_model_logic`、`save_model_logic`、`patch_model_logic`、`str_replace_flycode`、`page_entity_list`、`get_entity`、`page_form_list`、`get_form`、`get_form_outline`、`get_form_fragment`、`patch_form`、`save_form`、`page_h5_form`、`get_h5_form`、`page_function_list`、`get_function`、`page_database_function_list`、`run_sql`、`generate_unique_code` 等工具,通过 `StdioServerTransport` 监听请求。
795
+ 5. **注册并启动**:创建 `McpServer`,注册 `page_model_logic_list`、`get_model_logic`、`save_model_logic`、`patch_model_logic`、`str_replace_flycode`、`page_entity_list`、`get_entity`、`page_entity_directories`、`create_entity`、`patch_entity`、`page_form_list`、`get_form`、`get_form_outline`、`get_form_fragment`、`patch_form`、`save_form`、`page_h5_form`、`get_h5_form`、`page_function_list`、`get_function`、`page_database_function_list`、`run_sql`、`generate_unique_code` 等工具,通过 `StdioServerTransport` 监听请求。
721
796
  6. **业务请求**:工具被调用时,`logicClient` / `entityClient` / `formClient` / `functionClient` / `runClient` / `h5Client` 通过 `request({ type: "tenant" })` 或 `request({ type: "business" })` 自动切换到当前租户连接地址或业务地址。`h5Client` 的 H5 表单查询需以特定预览账号(职位为 `SFA系统管理员`)的 token 发起,该 token 由 `service/h5.ts` 通过 `test-case.ts` 的预览账号列表接口解析后,以 `request({ type: "business", token })` 显式传入。`request` 在请求头统一注入 Token:若调用方在配置里显式传入 `token`(如 `request({ url, method, type: "business", token: "xxxx" })`),则优先使用该传入 Token;否则回退到内存中的 Token(由 `authenticate()` 写入或通过 `setToken` 设置)。注入后自定义 `token` 字段会被剔除,不会泄漏给后端。
722
797
 
723
798
  ---