@cloudbase/cloudbase-mcp 2.32.0 → 2.32.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/dist/index.cjs CHANGED
@@ -72571,6 +72571,8 @@ exports.QbaseError = exports.MSG_TYPES = exports.XPAY_EVENT_TYPES = void 0;
72571
72571
  exports.mergeSubscribeList = mergeSubscribeList;
72572
72572
  exports.mergeUnsubscribeList = mergeUnsubscribeList;
72573
72573
  exports.mergeSetEnableList = mergeSetEnableList;
72574
+ exports.resolvePushMode = resolvePushMode;
72575
+ exports.pickContainerConfigPublic = pickContainerConfigPublic;
72574
72576
  exports.registerMsgPushTools = registerMsgPushTools;
72575
72577
  const zod_1 = __webpack_require__(7552);
72576
72578
  const tool_result_js_1 = __webpack_require__(9835);
@@ -72857,6 +72859,25 @@ async function uploadCallbackConfig(server, appid, state) {
72857
72859
  throw new QbaseError(ret, `uploadappconfig 失败(ret=${ret}): ${errmsg || "未知错误"}。请重新查询最新配置后重试。`);
72858
72860
  }
72859
72861
  }
72862
+ function resolvePushMode(container) {
72863
+ return container?.qbase_open === true ? "container" : "cloudfunction";
72864
+ }
72865
+ /** Public subset of container callback fields returned to agents */
72866
+ function pickContainerConfigPublic(container) {
72867
+ if (!container)
72868
+ return undefined;
72869
+ return {
72870
+ qbase_open: container.qbase_open === true,
72871
+ qbase_container_path: typeof container.qbase_container_path === "string"
72872
+ ? container.qbase_container_path
72873
+ : undefined,
72874
+ qbase_env: typeof container.qbase_env === "string" ? container.qbase_env : undefined,
72875
+ text_mode: typeof container.text_mode === "number" ? container.text_mode : undefined,
72876
+ };
72877
+ }
72878
+ const CONTAINER_MODE_BLOCK_NOTE = "当前为云托管模式(整包接收),云函数 callbacks 存在但不生效;如需云函数模式请调 ensureCloudFunctionMode 切换";
72879
+ const CONTAINER_MODE_WRITE_ERROR = "当前 pushMode=container(云托管整包接收),云函数回调配置存在但不生效。" +
72880
+ "如需云函数模式请调 action=ensureCloudFunctionMode 切换。";
72860
72881
  /** 读取云托管消息推送配置;无配置(云函数模式)返回 null */
72861
72882
  async function readContainerConfig(server, appid) {
72862
72883
  const resp = await callQbase(server, appid, "getContainerCallbackConfig", {});
@@ -72877,6 +72898,55 @@ async function setContainerConfig(server, appid, cfg) {
72877
72898
  throw new QbaseError(ret, `setcontainercallbackconfig 失败(ret=${ret}): ${resp.base_resp?.errmsg ?? "未知错误"}`);
72878
72899
  }
72879
72900
  }
72901
+ function buildContainerModeBlockedPayload(action) {
72902
+ return (0, tool_result_js_1.buildJsonToolResult)({
72903
+ ok: false,
72904
+ code: "CONTAINER_MODE_ACTIVE",
72905
+ pushMode: "container",
72906
+ message: CONTAINER_MODE_WRITE_ERROR,
72907
+ next_step: {
72908
+ tool: "manageMessagePush",
72909
+ action: "ensureCloudFunctionMode",
72910
+ required_params: ["appid", "env_id", "function_name", "confirm"],
72911
+ hint: `先切换到云函数模式后再执行 ${action}`,
72912
+ },
72913
+ });
72914
+ }
72915
+ /**
72916
+ * Verify function_name exists in envId via optional host hook or CloudBase Manager list.
72917
+ * Returns an error tool result when missing / unreadable; null when OK.
72918
+ */
72919
+ async function assertCloudFunctionExists(server, envId, functionName) {
72920
+ const override = server.pluginOptions?.msgPush?.listCloudFunctions;
72921
+ // 兼容性降级:host 未提供 listCloudFunctions hook(如微信 IDE 无腾讯云凭据)时
72922
+ // 跳过存在性校验,保持原有 subscribe 行为(写配置不阻断);仅 host 显式启用时校验。
72923
+ if (!override) {
72924
+ return null;
72925
+ }
72926
+ let names;
72927
+ try {
72928
+ names = await override(envId);
72929
+ }
72930
+ catch (e) {
72931
+ // hook 本身失败(如网络/权限)时降级放行,不阻断订阅
72932
+ return null;
72933
+ }
72934
+ if (!names.includes(functionName)) {
72935
+ return (0, tool_result_js_1.buildJsonToolResult)({
72936
+ ok: false,
72937
+ code: "FUNCTION_NOT_FOUND",
72938
+ message: `云函数 ${functionName} 不存在于环境 ${envId},请先创建或修正参数`,
72939
+ envId,
72940
+ function_name: functionName,
72941
+ next_step: {
72942
+ tool: "manageFunctions",
72943
+ action: "createFunction",
72944
+ required_params: ["functionName"],
72945
+ },
72946
+ });
72947
+ }
72948
+ return null;
72949
+ }
72880
72950
  function buildTransportUnavailablePayload(toolName, action) {
72881
72951
  return (0, tool_result_js_1.buildJsonToolResult)({
72882
72952
  ok: false,
@@ -72945,11 +73015,11 @@ function registerMsgPushTools(server) {
72945
73015
  server.registerTool?.("queryMessagePush", {
72946
73016
  title: "查询小程序消息推送配置",
72947
73017
  description: "查询小程序云开发消息推送配置(qbase getappconfig)或全部合法消息推送事件约束(getcallbacksupportlist)。" +
72948
- "消息推送把小程序事件/消息(含虚拟支付回调、text/image 等消息类型)送到云函数,无需自建服务器。" +
72949
- "action=list 返回当前配置列表(msgType/event/env/functionName/enable)与 version(乐观锁版本号);" +
72950
- "action=listSupportedEvents 返回全部合法约束(按消息类型分组:event 组含事件名列表;text/image/voice/video/miniprogrampage 组 events 为空数组)," +
72951
- "事件类用 manageMessagePush(event_types=...),消息类型用 manageMessagePush(msg_type=...)。" +
72952
- "需要微信 IDE 登录态通道(宿主注入 cloudBaseOptions.requestFn),独立 CloudBase MCP 运行会返回指引错误。",
73018
+ "推送模式有两种:云函数(默认,按 (msgType,event) 逐条回调)与云托管(qbase_open=true,整包接收所有消息到容器 path)。" +
73019
+ "action=list 同时返回 pushMode(cloudfunction|container)、containerConfig、callbacks 与 version;" +
73020
+ "云托管模式下 callbacks 可能仍存在但不生效(见 note),需 ensureCloudFunctionMode 切回云函数模式后才会按回调推送。" +
73021
+ "action=listSupportedEvents 返回全部合法约束(按消息类型分组)。" +
73022
+ "需要微信 IDE 登录态通道(宿主注入 cloudBaseOptions.requestFn)。",
72953
73023
  inputSchema: {
72954
73024
  appid: zod_1.z
72955
73025
  .string()
@@ -72957,7 +73027,7 @@ function registerMsgPushTools(server) {
72957
73027
  env: zod_1.z.string().optional().describe("可选:环境 ID;传入时 list 仅返回该环境的订阅条目"),
72958
73028
  action: zod_1.z
72959
73029
  .enum(["list", "listSupportedEvents"])
72960
- .describe("list: 查询当前消息推送配置列表\nlistSupportedEvents: 查询全部合法消息推送事件约束(按 msgType 分组)"),
73030
+ .describe("list: 查询当前消息推送配置列表(含 pushMode/containerConfig)\nlistSupportedEvents: 查询全部合法消息推送事件约束(按 msgType 分组)"),
72961
73031
  },
72962
73032
  annotations: {
72963
73033
  readOnlyHint: true,
@@ -72969,7 +73039,11 @@ function registerMsgPushTools(server) {
72969
73039
  return buildTransportUnavailablePayload("queryMessagePush", action);
72970
73040
  }
72971
73041
  if (action === "list") {
72972
- const state = await readCallbackConfig(server, appid);
73042
+ const [state, container] = await Promise.all([
73043
+ readCallbackConfig(server, appid),
73044
+ readContainerConfig(server, appid),
73045
+ ]);
73046
+ const pushMode = resolvePushMode(container);
72973
73047
  const callbacks = env
72974
73048
  ? state.list.filter((c) => c.env === env)
72975
73049
  : state.list;
@@ -72979,12 +73053,22 @@ function registerMsgPushTools(server) {
72979
73053
  message: "查询消息推送配置成功",
72980
73054
  version: state.version,
72981
73055
  enable: state.enable,
73056
+ pushMode,
73057
+ containerConfig: pickContainerConfigPublic(container),
72982
73058
  callbacks,
73059
+ note: pushMode === "container" ? CONTAINER_MODE_BLOCK_NOTE : undefined,
72983
73060
  filteredByEnv: env ?? undefined,
72984
- next_steps: [
72985
- "manageMessagePush(action=subscribe) 订阅事件(缺省 event_types 时默认订阅虚拟支付 7 事件)",
72986
- "queryMessagePush(action=listSupportedEvents) 查看全部合法事件",
72987
- ],
73061
+ next_steps: pushMode === "container"
73062
+ ? [
73063
+ "当前为云托管模式:云函数 subscribe/unsubscribe/setEnable 会被拒绝",
73064
+ "manageMessagePush(action=ensureCloudFunctionMode) 切回云函数模式",
73065
+ "manageMessagePush(action=setContainerCallback) 更新云托管 path/env/text_mode",
73066
+ ]
73067
+ : [
73068
+ "manageMessagePush(action=subscribe) 订阅事件(缺省 event_types 时默认订阅虚拟支付 7 事件)",
73069
+ "manageMessagePush(action=ensureContainerMode) 切换到云托管整包接收",
73070
+ "queryMessagePush(action=listSupportedEvents) 查看全部合法事件",
73071
+ ],
72988
73072
  });
72989
73073
  }
72990
73074
  if (action === "listSupportedEvents") {
@@ -73029,29 +73113,38 @@ function registerMsgPushTools(server) {
73029
73113
  server.registerTool?.("manageMessagePush", {
73030
73114
  title: "管理小程序消息推送配置",
73031
73115
  description: "管理小程序云开发消息推送配置(写操作,需 confirm=\"yes\" 确认)。" +
73032
- "基于「读全量 → merge → 全量覆盖(带 version 乐观锁)」实现声明式幂等(对齐 kubectl apply:event_types 是期望集合,重复执行收敛到同一状态;" +
73033
- "version 冲突即 RFC 7232 If-Match 412,返回可重试错误:重读 → merge → 重试)。" +
73034
- "msg_type 区分两类条目(缺省 \"event\",向后兼容):" +
73035
- "msg_type=\"event\" 操作事件类(需 event_types;subscribe 缺省时默认虚拟支付 7 个 xpay_* 事件);" +
73036
- "msg_type=\"text\"|\"image\"|\"voice\"|\"video\"|\"miniprogrampage\" 操作消息类型条目(event 固定空串,勿传 event_types)。" +
73037
- "action=subscribe 订阅到指定云函数;同一 (msgType,event) 只能推到一个云函数(一事一函数),已绑定其他函数会自动重绑并说明。" +
73038
- "action=unsubscribe 移除匹配订阅(msg_type=event 时 event_types 必填;消息类型时按 msg_type 移除)。" +
73039
- "action=setEnable 启用/停用匹配订阅(msg_type=event 时 event_types + enable 必填;消息类型时 msg_type + enable)。" +
73040
- "action=ensureCloudFunctionMode 确保推送模式为云函数(若为云托管整包接收则切换 qbase_open=false,需确认)。" +
73041
- "集合无变化时不发起写请求(幂等 no-op,无需确认)。" +
73042
- "需要微信 IDE 登录态通道(宿主注入 cloudBaseOptions.requestFn)。",
73116
+ "推送模式:云函数(默认,按 (msgType,event) 回调)vs 云托管(整包接收;云托管模式下 subscribe/unsubscribe/setEnable 会被拒绝,先 ensureCloudFunctionMode)。" +
73117
+ "基于「读全量 → merge → 全量覆盖(带 version 乐观锁)」实现声明式幂等。" +
73118
+ "msg_type 缺省 \"event\";消息类型用 msg_type=text|image|voice|video|miniprogrampage。" +
73119
+ "action=subscribe 前会校验 function_name 在环境中真实存在。" +
73120
+ "action=ensureCloudFunctionMode 关闭云托管整包接收;action=ensureContainerMode 开启云托管(需 qbase_container_path/qbase_env/text_mode);" +
73121
+ "action=setContainerCallback 更新云托管 path/env/text_mode。" +
73122
+ "集合无变化时不发起写请求(幂等 no-op)。需要微信 IDE 登录态通道。",
73043
73123
  inputSchema: {
73044
73124
  appid: zod_1.z
73045
73125
  .string()
73046
73126
  .describe("小程序 AppID(必填,与微信开发者工具一致;用于选择微信登录态会话)"),
73047
- env_id: zod_1.z.string().describe("环境 ID(订阅条目绑定的云开发环境)"),
73048
- function_name: zod_1.z.string().describe("接收消息推送的云函数名"),
73127
+ env_id: zod_1.z
73128
+ .string()
73129
+ .describe("环境 ID(云函数订阅绑定的云开发环境;ensureContainerMode/setContainerCallback 未传 qbase_env 时也可作为云托管环境默认值)"),
73130
+ function_name: zod_1.z
73131
+ .string()
73132
+ .describe("接收消息推送的云函数名(subscribe/unsubscribe/setEnable/ensureCloudFunctionMode 使用;云托管相关 action 可传占位)"),
73049
73133
  action: zod_1.z
73050
- .enum(["subscribe", "unsubscribe", "setEnable", "ensureCloudFunctionMode"])
73051
- .describe("subscribe: 订阅到指定云函数(msg_type=event 时 event_types 缺省=虚拟支付 7 事件;消息类型时按 msg_type 订阅)\n" +
73052
- "unsubscribe: 移除匹配订阅(msg_type=event 时 event_types 必填)\n" +
73053
- "setEnable: 启用/停用匹配订阅(msg_type=event 时 event_types + enable 必填)\n" +
73054
- "ensureCloudFunctionMode: 确保为云函数推送模式(云托管整包接收时切换,需确认)"),
73134
+ .enum([
73135
+ "subscribe",
73136
+ "unsubscribe",
73137
+ "setEnable",
73138
+ "ensureCloudFunctionMode",
73139
+ "ensureContainerMode",
73140
+ "setContainerCallback",
73141
+ ])
73142
+ .describe("subscribe: 订阅到指定云函数(云托管模式下拒绝)\n" +
73143
+ "unsubscribe: 移除匹配订阅(云托管模式下拒绝)\n" +
73144
+ "setEnable: 启用/停用匹配订阅(云托管模式下拒绝)\n" +
73145
+ "ensureCloudFunctionMode: 切到云函数推送模式(关闭 qbase_open)\n" +
73146
+ "ensureContainerMode: 切到云托管整包接收(需 qbase_container_path + text_mode)\n" +
73147
+ "setContainerCallback: 更新云托管回调 path/env/text_mode"),
73055
73148
  msg_type: zod_1.z
73056
73149
  .enum(exports.MSG_TYPES)
73057
73150
  .optional()
@@ -73062,10 +73155,20 @@ function registerMsgPushTools(server) {
73062
73155
  .array(zod_1.z.string())
73063
73156
  .optional()
73064
73157
  .describe("要操作的事件列表(仅 msg_type=\"event\" 时使用;可先 queryMessagePush(action=listSupportedEvents) 查询全量约束)。" +
73065
- "subscribe 缺省时默认订阅虚拟支付 7 个事件:xpay_goods_deliver_notify、xpay_coin_pay_notify、xpay_complaint_notify、" +
73066
- "xpay_subscribe_signing_result_notify、xpay_subscribe_pay_fail_notify、xpay_subscribe_ios_refund_query_notify、xpay_refund_notify;" +
73067
- "unsubscribe / setEnable 且 msg_type=event 时必填。消息类型操作请勿传本参数。"),
73158
+ "subscribe 缺省时默认订阅虚拟支付 7 个事件;unsubscribe / setEnable 且 msg_type=event 时必填。"),
73068
73159
  enable: zod_1.z.boolean().optional().describe("setEnable 时必填:true 启用订阅 / false 停用订阅"),
73160
+ qbase_container_path: zod_1.z
73161
+ .string()
73162
+ .optional()
73163
+ .describe("云托管回调路径/URL(ensureContainerMode 必填;setContainerCallback 可选更新)"),
73164
+ qbase_env: zod_1.z
73165
+ .string()
73166
+ .optional()
73167
+ .describe("云托管服务所在环境 ID(ensureContainerMode/setContainerCallback 可选;缺省用 env_id)"),
73168
+ text_mode: zod_1.z
73169
+ .union([zod_1.z.literal(1), zod_1.z.literal(2)])
73170
+ .optional()
73171
+ .describe("云托管消息正文编码:1=json,2=xml(ensureContainerMode 必填;setContainerCallback 可选更新)"),
73069
73172
  confirm: zod_1.z
73070
73173
  .string()
73071
73174
  .optional()
@@ -73078,7 +73181,7 @@ function registerMsgPushTools(server) {
73078
73181
  openWorldHint: true,
73079
73182
  category: CATEGORY,
73080
73183
  },
73081
- }, async ({ appid, env_id, function_name, action, msg_type, event_types, enable, confirm, }) => {
73184
+ }, async ({ appid, env_id, function_name, action, msg_type, event_types, enable, qbase_container_path, qbase_env, text_mode, confirm, }) => {
73082
73185
  if (!getTransport(server)) {
73083
73186
  return buildTransportUnavailablePayload("manageMessagePush", action);
73084
73187
  }
@@ -73093,16 +73196,16 @@ function registerMsgPushTools(server) {
73093
73196
  success: true,
73094
73197
  code: "NO_CHANGE",
73095
73198
  message: "当前已是云函数推送模式(云托管整包接收未开启),无需变更",
73096
- containerConfig: current ?? undefined,
73199
+ pushMode: "cloudfunction",
73200
+ containerConfig: pickContainerConfigPublic(current),
73097
73201
  });
73098
73202
  }
73099
73203
  if (!confirmed) {
73100
73204
  return buildConfirmPayload({
73101
73205
  toolName: "manageMessagePush",
73102
73206
  action,
73103
- message: `当前推送模式为云托管整包接收(qbase_open=true,环境 ${current.qbase_env ?? "-"},路径 ${current.qbase_container_path ?? "-"}),` +
73104
- `事件会整包进入云托管而非云函数。\n即将执行 setcontainercallbackconfig 关闭云托管整包接收(qbase_open=false),` +
73105
- `使消息推送按事件进入云函数 ${env_id}/${function_name}。`,
73207
+ message: `切换后停止云托管整包接收(qbase_open=false),消息按云函数回调推送;若 callbacks 为空则收不到任何消息。\n` +
73208
+ `当前云托管配置:环境 ${current.qbase_env ?? "-"},路径 ${current.qbase_container_path ?? "-"},text_mode=${current.text_mode ?? "-"}。`,
73106
73209
  requiredParams: ["appid", "env_id", "function_name", "confirm"],
73107
73210
  });
73108
73211
  }
@@ -73122,6 +73225,140 @@ function registerMsgPushTools(server) {
73122
73225
  success: true,
73123
73226
  message: "已切换到云函数推送模式(setcontainercallbackconfig qbase_open=false 成功)",
73124
73227
  action,
73228
+ pushMode: "cloudfunction",
73229
+ });
73230
+ }
73231
+ if (action === "ensureContainerMode") {
73232
+ const path = qbase_container_path?.trim();
73233
+ const containerEnv = (qbase_env ?? env_id)?.trim();
73234
+ if (!path) {
73235
+ throw new Error('ensureContainerMode 必须提供 qbase_container_path(云托管回调路径/URL)');
73236
+ }
73237
+ if (text_mode !== 1 && text_mode !== 2) {
73238
+ throw new Error("ensureContainerMode 必须提供 text_mode(1=json / 2=xml)");
73239
+ }
73240
+ if (!containerEnv) {
73241
+ throw new Error("ensureContainerMode 必须提供 qbase_env 或 env_id(云托管服务所在环境)");
73242
+ }
73243
+ const current = await readContainerConfig(server, appid);
73244
+ const alreadySame = current?.qbase_open === true &&
73245
+ current.qbase_container_path === path &&
73246
+ current.qbase_env === containerEnv &&
73247
+ Number(current.text_mode) === text_mode;
73248
+ if (alreadySame) {
73249
+ return (0, tool_result_js_1.buildJsonToolResult)({
73250
+ ok: true,
73251
+ success: true,
73252
+ code: "NO_CHANGE",
73253
+ message: "当前已是云托管推送模式且配置一致,无需变更",
73254
+ pushMode: "container",
73255
+ containerConfig: pickContainerConfigPublic(current),
73256
+ });
73257
+ }
73258
+ if (!confirmed) {
73259
+ return buildConfirmPayload({
73260
+ toolName: "manageMessagePush",
73261
+ action,
73262
+ message: `切换后所有消息类型整包推送到云托管服务(path=${path},env=${containerEnv},text_mode=${text_mode}),云函数回调失效。\n` +
73263
+ `当前:pushMode=${resolvePushMode(current)},` +
73264
+ `path=${current?.qbase_container_path ?? "-"},env=${current?.qbase_env ?? "-"},text_mode=${current?.text_mode ?? "-"}。`,
73265
+ requiredParams: [
73266
+ "appid",
73267
+ "env_id",
73268
+ "qbase_container_path",
73269
+ "text_mode",
73270
+ "confirm",
73271
+ ],
73272
+ });
73273
+ }
73274
+ const nextCfg = {
73275
+ ...(current ?? {}),
73276
+ qbase_open: true,
73277
+ qbase_container_path: path,
73278
+ qbase_env: containerEnv,
73279
+ text_mode,
73280
+ };
73281
+ await setContainerConfig(server, appid, nextCfg);
73282
+ logger?.({
73283
+ type: "toolInfo",
73284
+ toolName: "manageMessagePush",
73285
+ message: "已切换到云托管推送模式",
73286
+ appid,
73287
+ envId: containerEnv,
73288
+ });
73289
+ return (0, tool_result_js_1.buildJsonToolResult)({
73290
+ ok: true,
73291
+ success: true,
73292
+ message: "已切换到云托管推送模式(qbase_open=true)",
73293
+ action,
73294
+ pushMode: "container",
73295
+ containerConfig: pickContainerConfigPublic(nextCfg),
73296
+ });
73297
+ }
73298
+ if (action === "setContainerCallback") {
73299
+ const current = await readContainerConfig(server, appid);
73300
+ const nextPath = qbase_container_path?.trim() ||
73301
+ (typeof current?.qbase_container_path === "string"
73302
+ ? current.qbase_container_path
73303
+ : undefined);
73304
+ const nextEnv = (qbase_env ?? env_id)?.trim() ||
73305
+ (typeof current?.qbase_env === "string" ? current.qbase_env : undefined);
73306
+ const nextTextMode = text_mode === 1 || text_mode === 2
73307
+ ? text_mode
73308
+ : typeof current?.text_mode === "number"
73309
+ ? current.text_mode
73310
+ : undefined;
73311
+ if (!nextPath) {
73312
+ throw new Error("setContainerCallback 需要 qbase_container_path(或当前已有配置可沿用)");
73313
+ }
73314
+ if (!nextEnv) {
73315
+ throw new Error("setContainerCallback 需要 qbase_env 或 env_id(或当前已有配置可沿用)");
73316
+ }
73317
+ if (nextTextMode !== 1 && nextTextMode !== 2) {
73318
+ throw new Error("setContainerCallback 需要 text_mode(1=json / 2=xml,或当前已有配置可沿用)");
73319
+ }
73320
+ const nextCfg = {
73321
+ ...(current ?? {}),
73322
+ qbase_open: current?.qbase_open === true,
73323
+ qbase_container_path: nextPath,
73324
+ qbase_env: nextEnv,
73325
+ text_mode: nextTextMode,
73326
+ };
73327
+ const same = current?.qbase_container_path === nextPath &&
73328
+ current?.qbase_env === nextEnv &&
73329
+ Number(current?.text_mode) === nextTextMode &&
73330
+ (current?.qbase_open === true) === (nextCfg.qbase_open === true);
73331
+ if (same) {
73332
+ return (0, tool_result_js_1.buildJsonToolResult)({
73333
+ ok: true,
73334
+ success: true,
73335
+ code: "NO_CHANGE",
73336
+ message: "云托管回调配置无变化(幂等)",
73337
+ pushMode: resolvePushMode(current),
73338
+ containerConfig: pickContainerConfigPublic(current),
73339
+ });
73340
+ }
73341
+ if (!confirmed) {
73342
+ const before = pickContainerConfigPublic(current) ?? {};
73343
+ const after = pickContainerConfigPublic(nextCfg) ?? {};
73344
+ return buildConfirmPayload({
73345
+ toolName: "manageMessagePush",
73346
+ action,
73347
+ message: `即将更新云托管回调配置:\n` +
73348
+ `- 旧: path=${before.qbase_container_path ?? "-"}, env=${before.qbase_env ?? "-"}, text_mode=${before.text_mode ?? "-"}, qbase_open=${before.qbase_open ?? false}\n` +
73349
+ `- 新: path=${after.qbase_container_path ?? "-"}, env=${after.qbase_env ?? "-"}, text_mode=${after.text_mode ?? "-"}, qbase_open=${after.qbase_open ?? false}`,
73350
+ requiredParams: ["appid", "confirm"],
73351
+ });
73352
+ }
73353
+ await setContainerConfig(server, appid, nextCfg);
73354
+ return (0, tool_result_js_1.buildJsonToolResult)({
73355
+ ok: true,
73356
+ success: true,
73357
+ message: "已更新云托管回调配置",
73358
+ action,
73359
+ pushMode: resolvePushMode(nextCfg),
73360
+ before: pickContainerConfigPublic(current),
73361
+ after: pickContainerConfigPublic(nextCfg),
73125
73362
  });
73126
73363
  }
73127
73364
  // Message-type entries use a fixed empty event; event_types must not be supplied
@@ -73129,6 +73366,13 @@ function registerMsgPushTools(server) {
73129
73366
  throw new Error(`msg_type="${resolvedMsgType}" 时不应传 event_types(消息类型条目的 event 固定为空串 "");` +
73130
73367
  `请去掉 event_types,仅传 msg_type / function_name / enable(setEnable 时)`);
73131
73368
  }
73369
+ // Reject cloud-function callback writes while container mode is active (silent-failure guard)
73370
+ {
73371
+ const container = await readContainerConfig(server, appid);
73372
+ if (resolvePushMode(container) === "container") {
73373
+ return buildContainerModeBlockedPayload(action);
73374
+ }
73375
+ }
73132
73376
  // subscribe / unsubscribe / setEnable 共用流程:读 → 校验 → merge → 确认 → 覆盖写
73133
73377
  let eventList;
73134
73378
  if (!isEventMsgType) {
@@ -73224,6 +73468,12 @@ function registerMsgPushTools(server) {
73224
73468
  warnings: warnings.length ? warnings : undefined,
73225
73469
  });
73226
73470
  }
73471
+ // 4b. subscribe:校验云函数真实存在(仅有变更时)
73472
+ if (action === "subscribe") {
73473
+ const missing = await assertCloudFunctionExists(server, env_id, function_name);
73474
+ if (missing)
73475
+ return missing;
73476
+ }
73227
73477
  // 5. 有变更 → 需确认
73228
73478
  const diffText = buildMergeDiffText(action, result, env_id, function_name);
73229
73479
  if (!confirmed) {
@@ -149159,7 +149409,7 @@ class TelemetryReporter {
149159
149409
  const arch = os_1.default.arch(); // 系统架构
149160
149410
  // Build-time injected version; guard for vitest / non-webpack runtimes.
149161
149411
  const mcpVersion = process.env.npm_package_version ||
149162
- ( true ? "2.32.0" : 0);
149412
+ ( true ? "2.32.1" : 0);
149163
149413
  return {
149164
149414
  userAgent: `${osType} ${osRelease} ${arch} ${nodeVersion} CloudBase-MCP/${mcpVersion}`,
149165
149415
  deviceId: this.deviceId,
@@ -232930,7 +233180,7 @@ ${envIdSection}
232930
233180
  ## 环境信息
232931
233181
  - 操作系统: ${os_1.default.type()} ${os_1.default.release()}
232932
233182
  - Node.js版本: ${process.version}
232933
- - MCP 版本:${process.env.npm_package_version || ( true ? "2.32.0" : 0)}
233183
+ - MCP 版本:${process.env.npm_package_version || ( true ? "2.32.1" : 0)}
232934
233184
  - 系统架构: ${os_1.default.arch()}
232935
233185
  - 时间: ${new Date().toISOString()}
232936
233186
  - 请求ID: ${requestId}
@@ -233011,7 +233261,7 @@ function createWrappedHandler(name, handler, server) {
233011
233261
  requestId: (typeof error === 'object' && error && 'requestId' in error) ? error.requestId : '',
233012
233262
  ide: server.ide || process.env.INTEGRATION_IDE || ''
233013
233263
  });
233014
- const mcpVersion = true ? "2.32.0" : 0;
233264
+ const mcpVersion = true ? "2.32.1" : 0;
233015
233265
  const requestIdSuffix = requestId ? `\n🆔 RequestId: ${requestId}` : '';
233016
233266
  const enhancedErrorMessage = `${errorMessage}${requestIdSuffix}\n\n📦 CloudBase MCP v${mcpVersion}\n🔗 遇到问题?请复制以下链接到浏览器打开\n即可自动携带错误详情快速创建 GitHub Issue:\n${issueLink}`;
233017
233267
  // 创建新的错误对象,保持原有的错误类型但更新消息
@@ -252400,7 +252650,7 @@ function registerSetupTools(server) {
252400
252650
  server.registerTool("downloadTemplate", {
252401
252651
  title: "下载项目模板",
252402
252652
  description: `自动下载并部署CloudBase项目模板。
252403
- **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)`,
252653
+ **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.1" : 0}),便于后续维护和版本追踪\n- 下载 rules 模板时,如果项目中已存在 README.md 文件,系统会自动保护该文件不被覆盖(除非设置 overwrite=true)`,
252404
252654
  inputSchema: {
252405
252655
  template: zod_1.z
252406
252656
  .enum(["react", "vue", "miniprogram", "uniapp", "rules"])
package/dist/index.d.ts CHANGED
@@ -391,6 +391,12 @@ export declare type MsgPushAction = "getAppConfig" | "uploadAppConfig" | "getCal
391
391
  export declare interface MsgPushOverrides {
392
392
  /** 消息推送 qbase CGI 对应的 Cloud API service 名(默认 "qbase");宿主可按后端契约覆盖 */
393
393
  service?: string;
394
+ /**
395
+ * Optional readonly hook to list cloud function names in an env.
396
+ * Used by manageMessagePush(action=subscribe) to reject unknown function_name.
397
+ * Hosts may inject this; when omitted the tool falls back to CloudBase Manager getFunctionList.
398
+ */
399
+ listCloudFunctions?: (envId: string) => Promise<string[]>;
394
400
  }
395
401
 
396
402
  /** 消息推送 qbase 响应(业务码 ret === 0 为成功;由宿主 requestFn 解包后返回) */