@cloudbase/cloudbase-mcp 2.32.0 → 2.32.2

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/dist/index.js CHANGED
@@ -3474,7 +3474,7 @@ ${envIdSection}
3474
3474
  ## 环境信息
3475
3475
  - 操作系统: ${os_1.default.type()} ${os_1.default.release()}
3476
3476
  - Node.js版本: ${process.version}
3477
- - MCP 版本:${process.env.npm_package_version || ( true ? "2.32.0" : 0)}
3477
+ - MCP 版本:${process.env.npm_package_version || ( true ? "2.32.2" : 0)}
3478
3478
  - 系统架构: ${os_1.default.arch()}
3479
3479
  - 时间: ${new Date().toISOString()}
3480
3480
  - 请求ID: ${requestId}
@@ -3555,7 +3555,7 @@ function createWrappedHandler(name, handler, server) {
3555
3555
  requestId: (typeof error === 'object' && error && 'requestId' in error) ? error.requestId : '',
3556
3556
  ide: server.ide || process.env.INTEGRATION_IDE || ''
3557
3557
  });
3558
- const mcpVersion = true ? "2.32.0" : 0;
3558
+ const mcpVersion = true ? "2.32.2" : 0;
3559
3559
  const requestIdSuffix = requestId ? `\n🆔 RequestId: ${requestId}` : '';
3560
3560
  const enhancedErrorMessage = `${errorMessage}${requestIdSuffix}\n\n📦 CloudBase MCP v${mcpVersion}\n🔗 遇到问题?请复制以下链接到浏览器打开\n即可自动携带错误详情快速创建 GitHub Issue:\n${issueLink}`;
3561
3561
  // 创建新的错误对象,保持原有的错误类型但更新消息
@@ -13752,7 +13752,7 @@ class TelemetryReporter {
13752
13752
  const arch = os_1.default.arch(); // 系统架构
13753
13753
  // Build-time injected version; guard for vitest / non-webpack runtimes.
13754
13754
  const mcpVersion = process.env.npm_package_version ||
13755
- ( true ? "2.32.0" : 0);
13755
+ ( true ? "2.32.2" : 0);
13756
13756
  return {
13757
13757
  userAgent: `${osType} ${osRelease} ${arch} ${nodeVersion} CloudBase-MCP/${mcpVersion}`,
13758
13758
  deviceId: this.deviceId,
@@ -19659,7 +19659,7 @@ function registerSetupTools(server) {
19659
19659
  server.registerTool("downloadTemplate", {
19660
19660
  title: "下载项目模板",
19661
19661
  description: `自动下载并部署CloudBase项目模板。
19662
- **Note**: Call this tool when the user requests to create a new project using a CloudBase template.\n\n支持的模板:\n- react: React + CloudBase 全栈应用模板\n- vue: Vue + CloudBase 全栈应用模板\n- miniprogram: 微信小程序 + 云开发模板 \n- uniapp: UniApp + CloudBase 跨端应用模板\n- rules: 只包含AI编辑器配置文件(包含Cursor、WindSurf、CodeBuddy等所有主流编辑器配置),适合在已有项目中补充AI编辑器配置\n\n支持的IDE类型:\n- all: 下载所有IDE配置\n- cursor: Cursor AI编辑器\n- 其他IDE类型见下方列表\n\n注意:如果未传入 ide 参数且无法从环境变量检测到 IDE,将提示错误并要求传入 ide 参数\n- windsurf: WindSurf AI编辑器\n- codebuddy: CodeBuddy AI编辑器\n- claude-code: Claude Code AI编辑器\n- cline: Cline AI编辑器\n- gemini-cli: Gemini CLI\n- opencode: OpenCode AI编辑器\n- qwen-code: 通义灵码\n- baidu-comate: 百度Comate\n- openai-codex-cli: OpenAI Codex CLI\n- augment-code: Augment Code\n- github-copilot: GitHub Copilot\n- roocode: RooCode AI编辑器\n- tongyi-lingma: 通义灵码\n- trae: Trae AI编辑器\n- qoder: Qoder AI编辑器\n- antigravity: Google Antigravity AI编辑器\n- vscode: Visual Studio Code\n- kiro: Kiro AI编辑器\n- aider: Aider AI编辑器\n\n特别说明:\n- rules 模板会自动包含当前 mcp 版本号信息(版本号:${ true ? "2.32.0" : 0}),便于后续维护和版本追踪\n- 下载 rules 模板时,如果项目中已存在 README.md 文件,系统会自动保护该文件不被覆盖(除非设置 overwrite=true)`,
19662
+ **Note**: Call this tool when the user requests to create a new project using a CloudBase template.\n\n支持的模板:\n- react: React + CloudBase 全栈应用模板\n- vue: Vue + CloudBase 全栈应用模板\n- miniprogram: 微信小程序 + 云开发模板 \n- uniapp: UniApp + CloudBase 跨端应用模板\n- rules: 只包含AI编辑器配置文件(包含Cursor、WindSurf、CodeBuddy等所有主流编辑器配置),适合在已有项目中补充AI编辑器配置\n\n支持的IDE类型:\n- all: 下载所有IDE配置\n- cursor: Cursor AI编辑器\n- 其他IDE类型见下方列表\n\n注意:如果未传入 ide 参数且无法从环境变量检测到 IDE,将提示错误并要求传入 ide 参数\n- windsurf: WindSurf AI编辑器\n- codebuddy: CodeBuddy AI编辑器\n- claude-code: Claude Code AI编辑器\n- cline: Cline AI编辑器\n- gemini-cli: Gemini CLI\n- opencode: OpenCode AI编辑器\n- qwen-code: 通义灵码\n- baidu-comate: 百度Comate\n- openai-codex-cli: OpenAI Codex CLI\n- augment-code: Augment Code\n- github-copilot: GitHub Copilot\n- roocode: RooCode AI编辑器\n- tongyi-lingma: 通义灵码\n- trae: Trae AI编辑器\n- qoder: Qoder AI编辑器\n- antigravity: Google Antigravity AI编辑器\n- vscode: Visual Studio Code\n- kiro: Kiro AI编辑器\n- aider: Aider AI编辑器\n\n特别说明:\n- rules 模板会自动包含当前 mcp 版本号信息(版本号:${ true ? "2.32.2" : 0}),便于后续维护和版本追踪\n- 下载 rules 模板时,如果项目中已存在 README.md 文件,系统会自动保护该文件不被覆盖(除非设置 overwrite=true)`,
19663
19663
  inputSchema: {
19664
19664
  template: zod_1.z
19665
19665
  .enum(["react", "vue", "miniprogram", "uniapp", "rules"])
@@ -22279,6 +22279,8 @@ exports.QbaseError = exports.MSG_TYPES = exports.XPAY_EVENT_TYPES = void 0;
22279
22279
  exports.mergeSubscribeList = mergeSubscribeList;
22280
22280
  exports.mergeUnsubscribeList = mergeUnsubscribeList;
22281
22281
  exports.mergeSetEnableList = mergeSetEnableList;
22282
+ exports.resolvePushMode = resolvePushMode;
22283
+ exports.pickContainerConfigPublic = pickContainerConfigPublic;
22282
22284
  exports.registerMsgPushTools = registerMsgPushTools;
22283
22285
  const zod_1 = __webpack_require__(2971);
22284
22286
  const tool_result_js_1 = __webpack_require__(9835);
@@ -22565,6 +22567,25 @@ async function uploadCallbackConfig(server, appid, state) {
22565
22567
  throw new QbaseError(ret, `uploadappconfig 失败(ret=${ret}): ${errmsg || "未知错误"}。请重新查询最新配置后重试。`);
22566
22568
  }
22567
22569
  }
22570
+ function resolvePushMode(container) {
22571
+ return container?.qbase_open === true ? "container" : "cloudfunction";
22572
+ }
22573
+ /** Public subset of container callback fields returned to agents */
22574
+ function pickContainerConfigPublic(container) {
22575
+ if (!container)
22576
+ return undefined;
22577
+ return {
22578
+ qbase_open: container.qbase_open === true,
22579
+ qbase_container_path: typeof container.qbase_container_path === "string"
22580
+ ? container.qbase_container_path
22581
+ : undefined,
22582
+ qbase_env: typeof container.qbase_env === "string" ? container.qbase_env : undefined,
22583
+ text_mode: typeof container.text_mode === "number" ? container.text_mode : undefined,
22584
+ };
22585
+ }
22586
+ const CONTAINER_MODE_BLOCK_NOTE = "当前为云托管模式(整包接收),云函数 callbacks 存在但不生效;如需云函数模式请调 ensureCloudFunctionMode 切换";
22587
+ const CONTAINER_MODE_WRITE_ERROR = "当前 pushMode=container(云托管整包接收),云函数回调配置存在但不生效。" +
22588
+ "如需云函数模式请调 action=ensureCloudFunctionMode 切换。";
22568
22589
  /** 读取云托管消息推送配置;无配置(云函数模式)返回 null */
22569
22590
  async function readContainerConfig(server, appid) {
22570
22591
  const resp = await callQbase(server, appid, "getContainerCallbackConfig", {});
@@ -22585,6 +22606,55 @@ async function setContainerConfig(server, appid, cfg) {
22585
22606
  throw new QbaseError(ret, `setcontainercallbackconfig 失败(ret=${ret}): ${resp.base_resp?.errmsg ?? "未知错误"}`);
22586
22607
  }
22587
22608
  }
22609
+ function buildContainerModeBlockedPayload(action) {
22610
+ return (0, tool_result_js_1.buildJsonToolResult)({
22611
+ ok: false,
22612
+ code: "CONTAINER_MODE_ACTIVE",
22613
+ pushMode: "container",
22614
+ message: CONTAINER_MODE_WRITE_ERROR,
22615
+ next_step: {
22616
+ tool: "manageMessagePush",
22617
+ action: "ensureCloudFunctionMode",
22618
+ required_params: ["appid", "env_id", "function_name", "confirm"],
22619
+ hint: `先切换到云函数模式后再执行 ${action}`,
22620
+ },
22621
+ });
22622
+ }
22623
+ /**
22624
+ * Verify function_name exists in envId via optional host hook or CloudBase Manager list.
22625
+ * Returns an error tool result when missing / unreadable; null when OK.
22626
+ */
22627
+ async function assertCloudFunctionExists(server, envId, functionName) {
22628
+ const override = server.pluginOptions?.msgPush?.listCloudFunctions;
22629
+ // 兼容性降级:host 未提供 listCloudFunctions hook(如微信 IDE 无腾讯云凭据)时
22630
+ // 跳过存在性校验,保持原有 subscribe 行为(写配置不阻断);仅 host 显式启用时校验。
22631
+ if (!override) {
22632
+ return null;
22633
+ }
22634
+ let names;
22635
+ try {
22636
+ names = await override(envId);
22637
+ }
22638
+ catch (e) {
22639
+ // hook 本身失败(如网络/权限)时降级放行,不阻断订阅
22640
+ return null;
22641
+ }
22642
+ if (!names.includes(functionName)) {
22643
+ return (0, tool_result_js_1.buildJsonToolResult)({
22644
+ ok: false,
22645
+ code: "FUNCTION_NOT_FOUND",
22646
+ message: `云函数 ${functionName} 不存在于环境 ${envId},请先创建或修正参数`,
22647
+ envId,
22648
+ function_name: functionName,
22649
+ next_step: {
22650
+ tool: "manageFunctions",
22651
+ action: "createFunction",
22652
+ required_params: ["functionName"],
22653
+ },
22654
+ });
22655
+ }
22656
+ return null;
22657
+ }
22588
22658
  function buildTransportUnavailablePayload(toolName, action) {
22589
22659
  return (0, tool_result_js_1.buildJsonToolResult)({
22590
22660
  ok: false,
@@ -22653,11 +22723,11 @@ function registerMsgPushTools(server) {
22653
22723
  server.registerTool?.("queryMessagePush", {
22654
22724
  title: "查询小程序消息推送配置",
22655
22725
  description: "查询小程序云开发消息推送配置(qbase getappconfig)或全部合法消息推送事件约束(getcallbacksupportlist)。" +
22656
- "消息推送把小程序事件/消息(含虚拟支付回调、text/image 等消息类型)送到云函数,无需自建服务器。" +
22657
- "action=list 返回当前配置列表(msgType/event/env/functionName/enable)与 version(乐观锁版本号);" +
22658
- "action=listSupportedEvents 返回全部合法约束(按消息类型分组:event 组含事件名列表;text/image/voice/video/miniprogrampage 组 events 为空数组)," +
22659
- "事件类用 manageMessagePush(event_types=...),消息类型用 manageMessagePush(msg_type=...)。" +
22660
- "需要微信 IDE 登录态通道(宿主注入 cloudBaseOptions.requestFn),独立 CloudBase MCP 运行会返回指引错误。",
22726
+ "推送模式有两种:云函数(默认,按 (msgType,event) 逐条回调)与云托管(qbase_open=true,整包接收所有消息到容器 path)。" +
22727
+ "action=list 同时返回 pushMode(cloudfunction|container)、containerConfig、callbacks 与 version;" +
22728
+ "云托管模式下 callbacks 可能仍存在但不生效(见 note),需 ensureCloudFunctionMode 切回云函数模式后才会按回调推送。" +
22729
+ "action=listSupportedEvents 返回全部合法约束(按消息类型分组)。" +
22730
+ "需要微信 IDE 登录态通道(宿主注入 cloudBaseOptions.requestFn)。",
22661
22731
  inputSchema: {
22662
22732
  appid: zod_1.z
22663
22733
  .string()
@@ -22665,7 +22735,7 @@ function registerMsgPushTools(server) {
22665
22735
  env: zod_1.z.string().optional().describe("可选:环境 ID;传入时 list 仅返回该环境的订阅条目"),
22666
22736
  action: zod_1.z
22667
22737
  .enum(["list", "listSupportedEvents"])
22668
- .describe("list: 查询当前消息推送配置列表\nlistSupportedEvents: 查询全部合法消息推送事件约束(按 msgType 分组)"),
22738
+ .describe("list: 查询当前消息推送配置列表(含 pushMode/containerConfig)\nlistSupportedEvents: 查询全部合法消息推送事件约束(按 msgType 分组)"),
22669
22739
  },
22670
22740
  annotations: {
22671
22741
  readOnlyHint: true,
@@ -22677,7 +22747,17 @@ function registerMsgPushTools(server) {
22677
22747
  return buildTransportUnavailablePayload("queryMessagePush", action);
22678
22748
  }
22679
22749
  if (action === "list") {
22680
- const state = await readCallbackConfig(server, appid);
22750
+ const [state, containerRaw] = await Promise.all([
22751
+ readCallbackConfig(server, appid),
22752
+ // 兼容性降级:微信侧 apihttpagent 通道不支持 getcontainercallbackconfig
22753
+ // (ret=-9991)时,容器配置读取失败不阻断 list(pushMode 默认 cloudfunction)
22754
+ readContainerConfig(server, appid).catch((e) => {
22755
+ console.warn(`[msg-push] 读取云托管容器配置失败,降级为云函数模式推断: ${e instanceof Error ? e.message : String(e)}`);
22756
+ return null;
22757
+ }),
22758
+ ]);
22759
+ const container = containerRaw;
22760
+ const pushMode = resolvePushMode(container);
22681
22761
  const callbacks = env
22682
22762
  ? state.list.filter((c) => c.env === env)
22683
22763
  : state.list;
@@ -22687,12 +22767,22 @@ function registerMsgPushTools(server) {
22687
22767
  message: "查询消息推送配置成功",
22688
22768
  version: state.version,
22689
22769
  enable: state.enable,
22770
+ pushMode,
22771
+ containerConfig: pickContainerConfigPublic(container),
22690
22772
  callbacks,
22773
+ note: pushMode === "container" ? CONTAINER_MODE_BLOCK_NOTE : undefined,
22691
22774
  filteredByEnv: env ?? undefined,
22692
- next_steps: [
22693
- "manageMessagePush(action=subscribe) 订阅事件(缺省 event_types 时默认订阅虚拟支付 7 事件)",
22694
- "queryMessagePush(action=listSupportedEvents) 查看全部合法事件",
22695
- ],
22775
+ next_steps: pushMode === "container"
22776
+ ? [
22777
+ "当前为云托管模式:云函数 subscribe/unsubscribe/setEnable 会被拒绝",
22778
+ "manageMessagePush(action=ensureCloudFunctionMode) 切回云函数模式",
22779
+ "manageMessagePush(action=setContainerCallback) 更新云托管 path/env/text_mode",
22780
+ ]
22781
+ : [
22782
+ "manageMessagePush(action=subscribe) 订阅事件(缺省 event_types 时默认订阅虚拟支付 7 事件)",
22783
+ "manageMessagePush(action=ensureContainerMode) 切换到云托管整包接收",
22784
+ "queryMessagePush(action=listSupportedEvents) 查看全部合法事件",
22785
+ ],
22696
22786
  });
22697
22787
  }
22698
22788
  if (action === "listSupportedEvents") {
@@ -22737,29 +22827,38 @@ function registerMsgPushTools(server) {
22737
22827
  server.registerTool?.("manageMessagePush", {
22738
22828
  title: "管理小程序消息推送配置",
22739
22829
  description: "管理小程序云开发消息推送配置(写操作,需 confirm=\"yes\" 确认)。" +
22740
- "基于「读全量 → merge → 全量覆盖(带 version 乐观锁)」实现声明式幂等(对齐 kubectl apply:event_types 是期望集合,重复执行收敛到同一状态;" +
22741
- "version 冲突即 RFC 7232 If-Match 412,返回可重试错误:重读 → merge → 重试)。" +
22742
- "msg_type 区分两类条目(缺省 \"event\",向后兼容):" +
22743
- "msg_type=\"event\" 操作事件类(需 event_types;subscribe 缺省时默认虚拟支付 7 个 xpay_* 事件);" +
22744
- "msg_type=\"text\"|\"image\"|\"voice\"|\"video\"|\"miniprogrampage\" 操作消息类型条目(event 固定空串,勿传 event_types)。" +
22745
- "action=subscribe 订阅到指定云函数;同一 (msgType,event) 只能推到一个云函数(一事一函数),已绑定其他函数会自动重绑并说明。" +
22746
- "action=unsubscribe 移除匹配订阅(msg_type=event 时 event_types 必填;消息类型时按 msg_type 移除)。" +
22747
- "action=setEnable 启用/停用匹配订阅(msg_type=event 时 event_types + enable 必填;消息类型时 msg_type + enable)。" +
22748
- "action=ensureCloudFunctionMode 确保推送模式为云函数(若为云托管整包接收则切换 qbase_open=false,需确认)。" +
22749
- "集合无变化时不发起写请求(幂等 no-op,无需确认)。" +
22750
- "需要微信 IDE 登录态通道(宿主注入 cloudBaseOptions.requestFn)。",
22830
+ "推送模式:云函数(默认,按 (msgType,event) 回调)vs 云托管(整包接收;云托管模式下 subscribe/unsubscribe/setEnable 会被拒绝,先 ensureCloudFunctionMode)。" +
22831
+ "基于「读全量 → merge → 全量覆盖(带 version 乐观锁)」实现声明式幂等。" +
22832
+ "msg_type 缺省 \"event\";消息类型用 msg_type=text|image|voice|video|miniprogrampage。" +
22833
+ "action=subscribe 前会校验 function_name 在环境中真实存在。" +
22834
+ "action=ensureCloudFunctionMode 关闭云托管整包接收;action=ensureContainerMode 开启云托管(需 qbase_container_path/qbase_env/text_mode);" +
22835
+ "action=setContainerCallback 更新云托管 path/env/text_mode。" +
22836
+ "集合无变化时不发起写请求(幂等 no-op)。需要微信 IDE 登录态通道。",
22751
22837
  inputSchema: {
22752
22838
  appid: zod_1.z
22753
22839
  .string()
22754
22840
  .describe("小程序 AppID(必填,与微信开发者工具一致;用于选择微信登录态会话)"),
22755
- env_id: zod_1.z.string().describe("环境 ID(订阅条目绑定的云开发环境)"),
22756
- function_name: zod_1.z.string().describe("接收消息推送的云函数名"),
22841
+ env_id: zod_1.z
22842
+ .string()
22843
+ .describe("环境 ID(云函数订阅绑定的云开发环境;ensureContainerMode/setContainerCallback 未传 qbase_env 时也可作为云托管环境默认值)"),
22844
+ function_name: zod_1.z
22845
+ .string()
22846
+ .describe("接收消息推送的云函数名(subscribe/unsubscribe/setEnable/ensureCloudFunctionMode 使用;云托管相关 action 可传占位)"),
22757
22847
  action: zod_1.z
22758
- .enum(["subscribe", "unsubscribe", "setEnable", "ensureCloudFunctionMode"])
22759
- .describe("subscribe: 订阅到指定云函数(msg_type=event 时 event_types 缺省=虚拟支付 7 事件;消息类型时按 msg_type 订阅)\n" +
22760
- "unsubscribe: 移除匹配订阅(msg_type=event 时 event_types 必填)\n" +
22761
- "setEnable: 启用/停用匹配订阅(msg_type=event 时 event_types + enable 必填)\n" +
22762
- "ensureCloudFunctionMode: 确保为云函数推送模式(云托管整包接收时切换,需确认)"),
22848
+ .enum([
22849
+ "subscribe",
22850
+ "unsubscribe",
22851
+ "setEnable",
22852
+ "ensureCloudFunctionMode",
22853
+ "ensureContainerMode",
22854
+ "setContainerCallback",
22855
+ ])
22856
+ .describe("subscribe: 订阅到指定云函数(云托管模式下拒绝)\n" +
22857
+ "unsubscribe: 移除匹配订阅(云托管模式下拒绝)\n" +
22858
+ "setEnable: 启用/停用匹配订阅(云托管模式下拒绝)\n" +
22859
+ "ensureCloudFunctionMode: 切到云函数推送模式(关闭 qbase_open)\n" +
22860
+ "ensureContainerMode: 切到云托管整包接收(需 qbase_container_path + text_mode)\n" +
22861
+ "setContainerCallback: 更新云托管回调 path/env/text_mode"),
22763
22862
  msg_type: zod_1.z
22764
22863
  .enum(exports.MSG_TYPES)
22765
22864
  .optional()
@@ -22770,10 +22869,20 @@ function registerMsgPushTools(server) {
22770
22869
  .array(zod_1.z.string())
22771
22870
  .optional()
22772
22871
  .describe("要操作的事件列表(仅 msg_type=\"event\" 时使用;可先 queryMessagePush(action=listSupportedEvents) 查询全量约束)。" +
22773
- "subscribe 缺省时默认订阅虚拟支付 7 个事件:xpay_goods_deliver_notify、xpay_coin_pay_notify、xpay_complaint_notify、" +
22774
- "xpay_subscribe_signing_result_notify、xpay_subscribe_pay_fail_notify、xpay_subscribe_ios_refund_query_notify、xpay_refund_notify;" +
22775
- "unsubscribe / setEnable 且 msg_type=event 时必填。消息类型操作请勿传本参数。"),
22872
+ "subscribe 缺省时默认订阅虚拟支付 7 个事件;unsubscribe / setEnable 且 msg_type=event 时必填。"),
22776
22873
  enable: zod_1.z.boolean().optional().describe("setEnable 时必填:true 启用订阅 / false 停用订阅"),
22874
+ qbase_container_path: zod_1.z
22875
+ .string()
22876
+ .optional()
22877
+ .describe("云托管回调路径/URL(ensureContainerMode 必填;setContainerCallback 可选更新)"),
22878
+ qbase_env: zod_1.z
22879
+ .string()
22880
+ .optional()
22881
+ .describe("云托管服务所在环境 ID(ensureContainerMode/setContainerCallback 可选;缺省用 env_id)"),
22882
+ text_mode: zod_1.z
22883
+ .union([zod_1.z.literal(1), zod_1.z.literal(2)])
22884
+ .optional()
22885
+ .describe("云托管消息正文编码:1=json,2=xml(ensureContainerMode 必填;setContainerCallback 可选更新)"),
22777
22886
  confirm: zod_1.z
22778
22887
  .string()
22779
22888
  .optional()
@@ -22786,7 +22895,7 @@ function registerMsgPushTools(server) {
22786
22895
  openWorldHint: true,
22787
22896
  category: CATEGORY,
22788
22897
  },
22789
- }, async ({ appid, env_id, function_name, action, msg_type, event_types, enable, confirm, }) => {
22898
+ }, async ({ appid, env_id, function_name, action, msg_type, event_types, enable, qbase_container_path, qbase_env, text_mode, confirm, }) => {
22790
22899
  if (!getTransport(server)) {
22791
22900
  return buildTransportUnavailablePayload("manageMessagePush", action);
22792
22901
  }
@@ -22801,16 +22910,16 @@ function registerMsgPushTools(server) {
22801
22910
  success: true,
22802
22911
  code: "NO_CHANGE",
22803
22912
  message: "当前已是云函数推送模式(云托管整包接收未开启),无需变更",
22804
- containerConfig: current ?? undefined,
22913
+ pushMode: "cloudfunction",
22914
+ containerConfig: pickContainerConfigPublic(current),
22805
22915
  });
22806
22916
  }
22807
22917
  if (!confirmed) {
22808
22918
  return buildConfirmPayload({
22809
22919
  toolName: "manageMessagePush",
22810
22920
  action,
22811
- message: `当前推送模式为云托管整包接收(qbase_open=true,环境 ${current.qbase_env ?? "-"},路径 ${current.qbase_container_path ?? "-"}),` +
22812
- `事件会整包进入云托管而非云函数。\n即将执行 setcontainercallbackconfig 关闭云托管整包接收(qbase_open=false),` +
22813
- `使消息推送按事件进入云函数 ${env_id}/${function_name}。`,
22921
+ message: `切换后停止云托管整包接收(qbase_open=false),消息按云函数回调推送;若 callbacks 为空则收不到任何消息。\n` +
22922
+ `当前云托管配置:环境 ${current.qbase_env ?? "-"},路径 ${current.qbase_container_path ?? "-"},text_mode=${current.text_mode ?? "-"}。`,
22814
22923
  requiredParams: ["appid", "env_id", "function_name", "confirm"],
22815
22924
  });
22816
22925
  }
@@ -22830,6 +22939,140 @@ function registerMsgPushTools(server) {
22830
22939
  success: true,
22831
22940
  message: "已切换到云函数推送模式(setcontainercallbackconfig qbase_open=false 成功)",
22832
22941
  action,
22942
+ pushMode: "cloudfunction",
22943
+ });
22944
+ }
22945
+ if (action === "ensureContainerMode") {
22946
+ const path = qbase_container_path?.trim();
22947
+ const containerEnv = (qbase_env ?? env_id)?.trim();
22948
+ if (!path) {
22949
+ throw new Error('ensureContainerMode 必须提供 qbase_container_path(云托管回调路径/URL)');
22950
+ }
22951
+ if (text_mode !== 1 && text_mode !== 2) {
22952
+ throw new Error("ensureContainerMode 必须提供 text_mode(1=json / 2=xml)");
22953
+ }
22954
+ if (!containerEnv) {
22955
+ throw new Error("ensureContainerMode 必须提供 qbase_env 或 env_id(云托管服务所在环境)");
22956
+ }
22957
+ const current = await readContainerConfig(server, appid);
22958
+ const alreadySame = current?.qbase_open === true &&
22959
+ current.qbase_container_path === path &&
22960
+ current.qbase_env === containerEnv &&
22961
+ Number(current.text_mode) === text_mode;
22962
+ if (alreadySame) {
22963
+ return (0, tool_result_js_1.buildJsonToolResult)({
22964
+ ok: true,
22965
+ success: true,
22966
+ code: "NO_CHANGE",
22967
+ message: "当前已是云托管推送模式且配置一致,无需变更",
22968
+ pushMode: "container",
22969
+ containerConfig: pickContainerConfigPublic(current),
22970
+ });
22971
+ }
22972
+ if (!confirmed) {
22973
+ return buildConfirmPayload({
22974
+ toolName: "manageMessagePush",
22975
+ action,
22976
+ message: `切换后所有消息类型整包推送到云托管服务(path=${path},env=${containerEnv},text_mode=${text_mode}),云函数回调失效。\n` +
22977
+ `当前:pushMode=${resolvePushMode(current)},` +
22978
+ `path=${current?.qbase_container_path ?? "-"},env=${current?.qbase_env ?? "-"},text_mode=${current?.text_mode ?? "-"}。`,
22979
+ requiredParams: [
22980
+ "appid",
22981
+ "env_id",
22982
+ "qbase_container_path",
22983
+ "text_mode",
22984
+ "confirm",
22985
+ ],
22986
+ });
22987
+ }
22988
+ const nextCfg = {
22989
+ ...(current ?? {}),
22990
+ qbase_open: true,
22991
+ qbase_container_path: path,
22992
+ qbase_env: containerEnv,
22993
+ text_mode,
22994
+ };
22995
+ await setContainerConfig(server, appid, nextCfg);
22996
+ logger?.({
22997
+ type: "toolInfo",
22998
+ toolName: "manageMessagePush",
22999
+ message: "已切换到云托管推送模式",
23000
+ appid,
23001
+ envId: containerEnv,
23002
+ });
23003
+ return (0, tool_result_js_1.buildJsonToolResult)({
23004
+ ok: true,
23005
+ success: true,
23006
+ message: "已切换到云托管推送模式(qbase_open=true)",
23007
+ action,
23008
+ pushMode: "container",
23009
+ containerConfig: pickContainerConfigPublic(nextCfg),
23010
+ });
23011
+ }
23012
+ if (action === "setContainerCallback") {
23013
+ const current = await readContainerConfig(server, appid);
23014
+ const nextPath = qbase_container_path?.trim() ||
23015
+ (typeof current?.qbase_container_path === "string"
23016
+ ? current.qbase_container_path
23017
+ : undefined);
23018
+ const nextEnv = (qbase_env ?? env_id)?.trim() ||
23019
+ (typeof current?.qbase_env === "string" ? current.qbase_env : undefined);
23020
+ const nextTextMode = text_mode === 1 || text_mode === 2
23021
+ ? text_mode
23022
+ : typeof current?.text_mode === "number"
23023
+ ? current.text_mode
23024
+ : undefined;
23025
+ if (!nextPath) {
23026
+ throw new Error("setContainerCallback 需要 qbase_container_path(或当前已有配置可沿用)");
23027
+ }
23028
+ if (!nextEnv) {
23029
+ throw new Error("setContainerCallback 需要 qbase_env 或 env_id(或当前已有配置可沿用)");
23030
+ }
23031
+ if (nextTextMode !== 1 && nextTextMode !== 2) {
23032
+ throw new Error("setContainerCallback 需要 text_mode(1=json / 2=xml,或当前已有配置可沿用)");
23033
+ }
23034
+ const nextCfg = {
23035
+ ...(current ?? {}),
23036
+ qbase_open: current?.qbase_open === true,
23037
+ qbase_container_path: nextPath,
23038
+ qbase_env: nextEnv,
23039
+ text_mode: nextTextMode,
23040
+ };
23041
+ const same = current?.qbase_container_path === nextPath &&
23042
+ current?.qbase_env === nextEnv &&
23043
+ Number(current?.text_mode) === nextTextMode &&
23044
+ (current?.qbase_open === true) === (nextCfg.qbase_open === true);
23045
+ if (same) {
23046
+ return (0, tool_result_js_1.buildJsonToolResult)({
23047
+ ok: true,
23048
+ success: true,
23049
+ code: "NO_CHANGE",
23050
+ message: "云托管回调配置无变化(幂等)",
23051
+ pushMode: resolvePushMode(current),
23052
+ containerConfig: pickContainerConfigPublic(current),
23053
+ });
23054
+ }
23055
+ if (!confirmed) {
23056
+ const before = pickContainerConfigPublic(current) ?? {};
23057
+ const after = pickContainerConfigPublic(nextCfg) ?? {};
23058
+ return buildConfirmPayload({
23059
+ toolName: "manageMessagePush",
23060
+ action,
23061
+ message: `即将更新云托管回调配置:\n` +
23062
+ `- 旧: path=${before.qbase_container_path ?? "-"}, env=${before.qbase_env ?? "-"}, text_mode=${before.text_mode ?? "-"}, qbase_open=${before.qbase_open ?? false}\n` +
23063
+ `- 新: path=${after.qbase_container_path ?? "-"}, env=${after.qbase_env ?? "-"}, text_mode=${after.text_mode ?? "-"}, qbase_open=${after.qbase_open ?? false}`,
23064
+ requiredParams: ["appid", "confirm"],
23065
+ });
23066
+ }
23067
+ await setContainerConfig(server, appid, nextCfg);
23068
+ return (0, tool_result_js_1.buildJsonToolResult)({
23069
+ ok: true,
23070
+ success: true,
23071
+ message: "已更新云托管回调配置",
23072
+ action,
23073
+ pushMode: resolvePushMode(nextCfg),
23074
+ before: pickContainerConfigPublic(current),
23075
+ after: pickContainerConfigPublic(nextCfg),
22833
23076
  });
22834
23077
  }
22835
23078
  // Message-type entries use a fixed empty event; event_types must not be supplied
@@ -22837,6 +23080,13 @@ function registerMsgPushTools(server) {
22837
23080
  throw new Error(`msg_type="${resolvedMsgType}" 时不应传 event_types(消息类型条目的 event 固定为空串 "");` +
22838
23081
  `请去掉 event_types,仅传 msg_type / function_name / enable(setEnable 时)`);
22839
23082
  }
23083
+ // Reject cloud-function callback writes while container mode is active (silent-failure guard)
23084
+ {
23085
+ const container = await readContainerConfig(server, appid);
23086
+ if (resolvePushMode(container) === "container") {
23087
+ return buildContainerModeBlockedPayload(action);
23088
+ }
23089
+ }
22840
23090
  // subscribe / unsubscribe / setEnable 共用流程:读 → 校验 → merge → 确认 → 覆盖写
22841
23091
  let eventList;
22842
23092
  if (!isEventMsgType) {
@@ -22932,6 +23182,12 @@ function registerMsgPushTools(server) {
22932
23182
  warnings: warnings.length ? warnings : undefined,
22933
23183
  });
22934
23184
  }
23185
+ // 4b. subscribe:校验云函数真实存在(仅有变更时)
23186
+ if (action === "subscribe") {
23187
+ const missing = await assertCloudFunctionExists(server, env_id, function_name);
23188
+ if (missing)
23189
+ return missing;
23190
+ }
22935
23191
  // 5. 有变更 → 需确认
22936
23192
  const diffText = buildMergeDiffText(action, result, env_id, function_name);
22937
23193
  if (!confirmed) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudbase/cloudbase-mcp",
3
- "version": "2.32.0",
3
+ "version": "2.32.2",
4
4
  "mcpName": "io.github.TencentCloudBase/cloudbase-mcp",
5
5
  "packageManager": "pnpm@10.8.0",
6
6
  "description": "CloudBase MCP Server — operate Tencent CloudBase (database, auth, functions, storage, hosting) from AI coding tools via the Model Context Protocol. Part of CloudBase AI Toolkit.",
package/server.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "name": "io.github.TencentCloudBase/cloudbase-mcp",
4
4
  "title": "CloudBase",
5
5
  "description": "CloudBase MCP: DB, functions, storage, hosting via @cloudbase/cloudbase-mcp",
6
- "version": "2.32.0",
6
+ "version": "2.32.2",
7
7
  "websiteUrl": "https://github.com/TencentCloudBase/CloudBase-AI-Toolkit",
8
8
  "repository": {
9
9
  "url": "https://github.com/TencentCloudBase/CloudBase-AI-Toolkit",
@@ -25,7 +25,7 @@
25
25
  "registryType": "npm",
26
26
  "registryBaseUrl": "https://registry.npmjs.org",
27
27
  "identifier": "@cloudbase/cloudbase-mcp",
28
- "version": "2.32.0",
28
+ "version": "2.32.2",
29
29
  "runtimeHint": "npx",
30
30
  "transport": {
31
31
  "type": "stdio"