@cloudbase/cloudbase-mcp 2.11.0 → 2.12.0

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
@@ -562,7 +562,7 @@ ${envIdSection}
562
562
  ## 环境信息
563
563
  - 操作系统: ${os_1.default.type()} ${os_1.default.release()}
564
564
  - Node.js版本: ${process.version}
565
- - MCP 版本:${process.env.npm_package_version || "2.11.0" || 0}
565
+ - MCP 版本:${process.env.npm_package_version || "2.12.0" || 0}
566
566
  - 系统架构: ${os_1.default.arch()}
567
567
  - 时间: ${new Date().toISOString()}
568
568
  - 请求ID: ${requestId}
@@ -1085,10 +1085,15 @@ class InteractiveServer {
1085
1085
  3722, 3723, 3724, 3725, 3726, 3727, 3728, 3729, 3730, 3731, 3732, 3733,
1086
1086
  3734, 3735,
1087
1087
  ];
1088
+ /** Idle timeout for HTTP/WS connections (e.g. long login). Avoids "connection disconnected" after ~1 min. */
1089
+ static SERVER_IDLE_MS = 30 * 60 * 1000; // 30 minutes
1090
+ /** WebSocket ping interval to keep connection alive past proxies/firewalls. */
1091
+ static WS_PING_INTERVAL_MS = 25 * 1000; // 25 seconds
1088
1092
  constructor(mcpServer) {
1089
1093
  this._mcpServer = mcpServer;
1090
1094
  this.app = (0, express_1.default)();
1091
1095
  this.server = http_1.default.createServer(this.app);
1096
+ this.applyServerTimeouts();
1092
1097
  this.wss = new ws_1.WebSocketServer({ server: this.server });
1093
1098
  this.setupExpress();
1094
1099
  this.setupWebSocket();
@@ -1104,6 +1109,16 @@ class InteractiveServer {
1104
1109
  this.isRunning = false;
1105
1110
  }
1106
1111
  }
1112
+ /** Apply timeouts so long-lived login does not cause "connection disconnected". */
1113
+ applyServerTimeouts() {
1114
+ this.server.timeout = 0;
1115
+ if (typeof this.server.keepAliveTimeout === "number") {
1116
+ this.server.keepAliveTimeout = InteractiveServer.SERVER_IDLE_MS;
1117
+ }
1118
+ if (typeof this.server.headersTimeout === "number") {
1119
+ this.server.headersTimeout = Math.max(this.server.headersTimeout || 0, InteractiveServer.SERVER_IDLE_MS);
1120
+ }
1121
+ }
1107
1122
  setupExpress() {
1108
1123
  this.app.use(express_1.default.json());
1109
1124
  this.app.get("/env-setup/:sessionId", (req, res) => {
@@ -1207,6 +1222,16 @@ class InteractiveServer {
1207
1222
  setupWebSocket() {
1208
1223
  this.wss.on("connection", (ws) => {
1209
1224
  (0, logger_js_1.debug)("WebSocket client connected");
1225
+ // Keep connection alive during long login so proxies/firewalls do not close it
1226
+ const pingInterval = setInterval(() => {
1227
+ if (ws.readyState === ws_1.WebSocket.OPEN) {
1228
+ ws.ping();
1229
+ }
1230
+ }, InteractiveServer.WS_PING_INTERVAL_MS);
1231
+ ws.on("close", () => {
1232
+ clearInterval(pingInterval);
1233
+ (0, logger_js_1.debug)("WebSocket client disconnected");
1234
+ });
1210
1235
  ws.on("message", async (message) => {
1211
1236
  try {
1212
1237
  const data = JSON.parse(message.toString());
@@ -1316,9 +1341,6 @@ class InteractiveServer {
1316
1341
  (0, logger_js_1.error)("WebSocket message parsing error", err instanceof Error ? err : new Error(String(err)));
1317
1342
  }
1318
1343
  });
1319
- ws.on("close", () => {
1320
- (0, logger_js_1.debug)("WebSocket client disconnected");
1321
- });
1322
1344
  });
1323
1345
  }
1324
1346
  async start() {
@@ -1360,13 +1382,15 @@ class InteractiveServer {
1360
1382
  reject(err);
1361
1383
  }
1362
1384
  };
1385
+ // Host: default 0.0.0.0 so Cloud IDE / VSCode Remote port-forward can connect; set INTERACTIVE_SERVER_HOST=127.0.0.1 for local-only
1386
+ const host = process.env.INTERACTIVE_SERVER_HOST ?? "0.0.0.0";
1363
1387
  // 设置成功监听处理
1364
1388
  const listeningHandler = () => {
1365
1389
  const address = this.server.address();
1366
1390
  if (address && typeof address === "object") {
1367
1391
  this.port = address.port;
1368
1392
  this.isRunning = true;
1369
- (0, logger_js_1.info)(`Interactive server started successfully on http://localhost:${this.port}`);
1393
+ (0, logger_js_1.info)(`Interactive server started successfully on http://${host}:${this.port}`);
1370
1394
  // 移除临时监听器
1371
1395
  this.server.removeListener("error", errorHandler);
1372
1396
  this.server.removeListener("listening", listeningHandler);
@@ -1381,7 +1405,7 @@ class InteractiveServer {
1381
1405
  this.server.once("error", errorHandler);
1382
1406
  this.server.once("listening", listeningHandler);
1383
1407
  try {
1384
- this.server.listen(portToTry, "127.0.0.1");
1408
+ this.server.listen(portToTry, host);
1385
1409
  }
1386
1410
  catch (err) {
1387
1411
  (0, logger_js_1.error)(`Failed to bind to port ${portToTry}:`, err instanceof Error ? err : new Error(String(err)));
@@ -1422,6 +1446,7 @@ class InteractiveServer {
1422
1446
  this.port = 0;
1423
1447
  // 重新创建整个服务器实例以便下次使用
1424
1448
  this.server = http_1.default.createServer(this.app);
1449
+ this.applyServerTimeouts();
1425
1450
  this.wss = new ws_1.WebSocketServer({ server: this.server });
1426
1451
  this.setupWebSocket();
1427
1452
  (0, logger_js_1.debug)("HTTP and WebSocket servers recreated for next use");
@@ -1512,11 +1537,9 @@ class InteractiveServer {
1512
1537
  (0, logger_js_1.warn)(`Please manually open: ${url}`);
1513
1538
  }
1514
1539
  (0, logger_js_1.info)("Waiting for user selection...");
1515
- // Use shorter timeout for CodeBuddy when notification is sent (2 minutes)
1516
- // This prevents hanging while still giving users enough time to respond
1517
- // Otherwise use the default 10 minutes timeout
1518
- const timeoutDuration = (isCodeBuddy && notificationSent) ? 2 * 60 * 1000 : 10 * 60 * 1000;
1519
- (0, logger_js_1.debug)(`[collectEnvId] Using timeout duration: ${timeoutDuration / 1000} seconds (CodeBuddy: ${isCodeBuddy}, notification sent: ${notificationSent})`);
1540
+ // Use same 10 minutes for all IDEs so long login (re-auth, switch account) does not close the server
1541
+ const timeoutDuration = 10 * 60 * 1000;
1542
+ (0, logger_js_1.debug)(`[collectEnvId] Using timeout duration: ${timeoutDuration / 1000} seconds`);
1520
1543
  return new Promise((resolve) => {
1521
1544
  this.currentResolver = (result) => {
1522
1545
  // 用户选择完成后,关闭服务器
@@ -7381,7 +7404,11 @@ function registerGatewayTools(server) {
7381
7404
  description: "创建云函数的 HTTP 访问",
7382
7405
  inputSchema: {
7383
7406
  name: zod_1.z.string().describe("函数名"),
7384
- path: zod_1.z.string().describe("HTTP 访问路径")
7407
+ path: zod_1.z.string().describe("HTTP 访问路径"),
7408
+ type: zod_1.z
7409
+ .enum(["Event", "HTTP"])
7410
+ .optional()
7411
+ .describe("函数类型,Event 为事件型云函数(默认),HTTP 为 HTTP 云函数")
7385
7412
  },
7386
7413
  annotations: {
7387
7414
  readOnlyHint: false,
@@ -7390,10 +7417,12 @@ function registerGatewayTools(server) {
7390
7417
  openWorldHint: true,
7391
7418
  category: "gateway"
7392
7419
  }
7393
- }, async ({ name, path }) => {
7420
+ }, async ({ name, path, type }) => {
7394
7421
  const cloudbase = await getManager();
7422
+ // Event 云函数 type=1,HTTP 云函数 type=6
7423
+ const accessType = type === "HTTP" ? 6 : 1;
7395
7424
  const result = await cloudbase.access.createAccess({
7396
- type: 1,
7425
+ type: accessType, // HTTP 云函数使用 type=6,需要类型断言
7397
7426
  name,
7398
7427
  path
7399
7428
  });
@@ -8663,7 +8692,7 @@ class TelemetryReporter {
8663
8692
  const nodeVersion = process.version; // Node.js版本
8664
8693
  const arch = os_1.default.arch(); // 系统架构
8665
8694
  // 从构建时注入的版本号获取MCP版本信息
8666
- const mcpVersion = process.env.npm_package_version || "2.11.0" || 0;
8695
+ const mcpVersion = process.env.npm_package_version || "2.12.0" || 0;
8667
8696
  return {
8668
8697
  userAgent: `${osType} ${osRelease} ${arch} ${nodeVersion} CloudBase-MCP/${mcpVersion}`,
8669
8698
  deviceId: this.deviceId,
@@ -8979,20 +9008,22 @@ exports.TRIGGER_CONFIG_EXAMPLES = exports.SUPPORTED_TRIGGER_TYPES = exports.DEFA
8979
9008
  exports.registerFunctionTools = registerFunctionTools;
8980
9009
  const zod_1 = __webpack_require__(2971);
8981
9010
  const cloudbase_manager_js_1 = __webpack_require__(3431);
9011
+ const logger_js_1 = __webpack_require__(3039);
8982
9012
  const path_1 = __importDefault(__webpack_require__(2521));
8983
9013
  // 支持的 Node.js 运行时列表
8984
9014
  exports.SUPPORTED_NODEJS_RUNTIMES = [
8985
- 'Nodejs18.15',
8986
- 'Nodejs16.13',
8987
- 'Nodejs14.18',
8988
- 'Nodejs12.16',
8989
- 'Nodejs10.15',
8990
- 'Nodejs8.9',
9015
+ "Nodejs20.19",
9016
+ "Nodejs18.15",
9017
+ "Nodejs16.13",
9018
+ "Nodejs14.18",
9019
+ "Nodejs12.16",
9020
+ "Nodejs10.15",
9021
+ "Nodejs8.9",
8991
9022
  ];
8992
- exports.DEFAULT_NODEJS_RUNTIME = 'Nodejs18.15';
9023
+ exports.DEFAULT_NODEJS_RUNTIME = "Nodejs18.15";
8993
9024
  // Supported trigger types
8994
9025
  exports.SUPPORTED_TRIGGER_TYPES = [
8995
- 'timer', // Timer trigger
9026
+ "timer", // Timer trigger
8996
9027
  ];
8997
9028
  // Trigger configuration examples
8998
9029
  exports.TRIGGER_CONFIG_EXAMPLES = {
@@ -9003,8 +9034,8 @@ exports.TRIGGER_CONFIG_EXAMPLES = {
9003
9034
  "0 30 9 * * * *", // Execute at 9:30 AM every day
9004
9035
  "0 0 12 * * * *", // Execute at 12:00 PM every day
9005
9036
  "0 0 0 1 1 * *", // Execute at midnight on January 1st every year
9006
- ]
9007
- }
9037
+ ],
9038
+ },
9008
9039
  };
9009
9040
  /**
9010
9041
  * 处理函数根目录路径,确保不包含函数名
@@ -9035,18 +9066,27 @@ function registerFunctionTools(server) {
9035
9066
  title: "查询云函数列表或详情",
9036
9067
  description: "获取云函数列表或单个函数详情。通过 action 参数区分操作类型:list=获取函数列表(默认,无需额外参数),detail=获取函数详情(需要提供 name 参数指定函数名称)",
9037
9068
  inputSchema: {
9038
- action: zod_1.z.enum(["list", "detail"]).optional().describe("操作类型:list=获取函数列表(默认,无需额外参数),detail=获取函数详情(需要提供 name 参数)"),
9069
+ action: zod_1.z
9070
+ .enum(["list", "detail"])
9071
+ .optional()
9072
+ .describe("操作类型:list=获取函数列表(默认,无需额外参数),detail=获取函数详情(需要提供 name 参数)"),
9039
9073
  limit: zod_1.z.number().optional().describe("范围(list 操作时使用)"),
9040
9074
  offset: zod_1.z.number().optional().describe("偏移(list 操作时使用)"),
9041
- name: zod_1.z.string().optional().describe("要查询的函数名称。当 action='detail' 时,此参数为必填项,必须提供已存在的函数名称。可通过 action='list' 操作获取可用的函数名称列表"),
9042
- codeSecret: zod_1.z.string().optional().describe("代码保护密钥(detail 操作时使用)")
9075
+ name: zod_1.z
9076
+ .string()
9077
+ .optional()
9078
+ .describe("要查询的函数名称。当 action='detail' 时,此参数为必填项,必须提供已存在的函数名称。可通过 action='list' 操作获取可用的函数名称列表"),
9079
+ codeSecret: zod_1.z
9080
+ .string()
9081
+ .optional()
9082
+ .describe("代码保护密钥(detail 操作时使用)"),
9043
9083
  },
9044
9084
  annotations: {
9045
9085
  readOnlyHint: true,
9046
9086
  openWorldHint: true,
9047
- category: "functions"
9048
- }
9049
- }, async ({ action = "list", limit, offset, name, codeSecret }) => {
9087
+ category: "functions",
9088
+ },
9089
+ }, async ({ action = "list", limit, offset, name, codeSecret, }) => {
9050
9090
  // 使用闭包中的 cloudBaseOptions
9051
9091
  const cloudbase = await getManager();
9052
9092
  if (action === "list") {
@@ -9056,9 +9096,9 @@ function registerFunctionTools(server) {
9056
9096
  content: [
9057
9097
  {
9058
9098
  type: "text",
9059
- text: JSON.stringify(result, null, 2)
9060
- }
9061
- ]
9099
+ text: JSON.stringify(result, null, 2),
9100
+ },
9101
+ ],
9062
9102
  };
9063
9103
  }
9064
9104
  else if (action === "detail") {
@@ -9071,9 +9111,9 @@ function registerFunctionTools(server) {
9071
9111
  content: [
9072
9112
  {
9073
9113
  type: "text",
9074
- text: JSON.stringify(result, null, 2)
9075
- }
9076
- ]
9114
+ text: JSON.stringify(result, null, 2),
9115
+ },
9116
+ ],
9077
9117
  };
9078
9118
  }
9079
9119
  else {
@@ -9083,59 +9123,115 @@ function registerFunctionTools(server) {
9083
9123
  // createFunction - 创建云函数 (cloud-incompatible)
9084
9124
  server.registerTool("createFunction", {
9085
9125
  title: "创建云函数",
9086
- description: "创建云函数",
9126
+ description: "创建云函数。云函数分为事件型云函数和 HTTP 云函数,请确认你要创建的函数类型。",
9087
9127
  inputSchema: {
9088
- func: zod_1.z.object({
9128
+ func: zod_1.z
9129
+ .object({
9089
9130
  name: zod_1.z.string().describe("函数名称"),
9131
+ type: zod_1.z
9132
+ .enum(["Event", "HTTP"])
9133
+ .optional()
9134
+ .describe("函数类型,Event 为事件型云函数,HTTP 为 HTTP 云函数"),
9135
+ protocolType: zod_1.z
9136
+ .enum(["HTTP", "WS"])
9137
+ .optional()
9138
+ .describe("HTTP 云函数的协议类型,HTTP 为 HTTP 协议(默认),WS 为 WebSocket 协议,仅当 type 为 HTTP 时有效"),
9139
+ protocolParams: zod_1.z
9140
+ .object({
9141
+ wsParams: zod_1.z
9142
+ .object({
9143
+ idleTimeOut: zod_1.z.number().optional().describe("WebSocket 空闲超时时间(秒),默认 15 秒"),
9144
+ })
9145
+ .optional()
9146
+ .describe("WebSocket 协议参数"),
9147
+ })
9148
+ .optional()
9149
+ .describe("协议参数配置,仅当 protocolType 为 WS 时有效"),
9150
+ instanceConcurrencyConfig: zod_1.z
9151
+ .object({
9152
+ dynamicEnabled: zod_1.z.boolean().optional().describe("是否启用动态并发,默认 false"),
9153
+ maxConcurrency: zod_1.z.number().optional().describe("最大并发数,默认 10"),
9154
+ })
9155
+ .optional()
9156
+ .describe("多并发配置,仅当 type 为 HTTP 时有效"),
9090
9157
  timeout: zod_1.z.number().optional().describe("函数超时时间"),
9091
9158
  envVariables: zod_1.z.record(zod_1.z.string()).optional().describe("环境变量"),
9092
- vpc: zod_1.z.object({
9159
+ vpc: zod_1.z
9160
+ .object({
9093
9161
  vpcId: zod_1.z.string(),
9094
- subnetId: zod_1.z.string()
9095
- }).optional().describe("私有网络配置"),
9096
- runtime: zod_1.z.string().optional().describe("运行时环境,建议指定为 'Nodejs18.15',其他可选值:" + exports.SUPPORTED_NODEJS_RUNTIMES.join(',')),
9097
- triggers: zod_1.z.array(zod_1.z.object({
9162
+ subnetId: zod_1.z.string(),
9163
+ })
9164
+ .optional()
9165
+ .describe("私有网络配置"),
9166
+ runtime: zod_1.z
9167
+ .string()
9168
+ .optional()
9169
+ .describe("运行时环境,建议指定为 'Nodejs18.15',其他可选值:" +
9170
+ exports.SUPPORTED_NODEJS_RUNTIMES.join(",")),
9171
+ triggers: zod_1.z
9172
+ .array(zod_1.z.object({
9098
9173
  name: zod_1.z.string().describe("Trigger name"),
9099
- type: zod_1.z.enum(exports.SUPPORTED_TRIGGER_TYPES).describe("Trigger type, currently only supports 'timer'"),
9100
- config: zod_1.z.string().describe("Trigger configuration. For timer triggers, use cron expression format: second minute hour day month week year. IMPORTANT: Must include exactly 7 fields (second minute hour day month week year). Examples: '0 0 2 1 * * *' (monthly), '0 30 9 * * * *' (daily at 9:30 AM)")
9101
- })).optional().describe("Trigger configuration array"),
9174
+ type: zod_1.z
9175
+ .enum(exports.SUPPORTED_TRIGGER_TYPES)
9176
+ .describe("Trigger type, currently only supports 'timer'"),
9177
+ config: zod_1.z
9178
+ .string()
9179
+ .describe("Trigger configuration. For timer triggers, use cron expression format: second minute hour day month week year. IMPORTANT: Must include exactly 7 fields (second minute hour day month week year). Examples: '0 0 2 1 * * *' (monthly), '0 30 9 * * * *' (daily at 9:30 AM)"),
9180
+ }))
9181
+ .optional()
9182
+ .describe("Trigger configuration array"),
9102
9183
  handler: zod_1.z.string().optional().describe("函数入口"),
9103
- ignore: zod_1.z.union([zod_1.z.string(), zod_1.z.array(zod_1.z.string())]).optional().describe("忽略文件"),
9184
+ ignore: zod_1.z
9185
+ .union([zod_1.z.string(), zod_1.z.array(zod_1.z.string())])
9186
+ .optional()
9187
+ .describe("忽略文件"),
9104
9188
  isWaitInstall: zod_1.z.boolean().optional().describe("是否等待依赖安装"),
9105
- layers: zod_1.z.array(zod_1.z.object({
9189
+ layers: zod_1.z
9190
+ .array(zod_1.z.object({
9106
9191
  name: zod_1.z.string(),
9107
- version: zod_1.z.number()
9108
- })).optional().describe("Layer配置")
9109
- }).describe("函数配置"),
9110
- functionRootPath: zod_1.z.string().optional().describe("函数根目录(云函数目录的父目录),这里需要传操作系统上文件的绝对路径,注意:不要包含函数名本身,例如函数名为 'hello',应传入 '/path/to/cloudfunctions',而不是 '/path/to/cloudfunctions/hello'"),
9111
- force: zod_1.z.boolean().describe("是否覆盖")
9192
+ version: zod_1.z.number(),
9193
+ }))
9194
+ .optional()
9195
+ .describe("Layer配置"),
9196
+ })
9197
+ .describe("函数配置"),
9198
+ functionRootPath: zod_1.z
9199
+ .string()
9200
+ .optional()
9201
+ .describe("函数根目录(云函数目录的父目录),这里需要传操作系统上文件的绝对路径,注意:不要包含函数名本身,例如函数名为 'hello',应传入 '/path/to/cloudfunctions',而不是 '/path/to/cloudfunctions/hello'"),
9202
+ force: zod_1.z.boolean().describe("是否覆盖"),
9112
9203
  },
9113
9204
  annotations: {
9114
9205
  readOnlyHint: false,
9115
9206
  destructiveHint: false,
9116
9207
  idempotentHint: false,
9117
9208
  openWorldHint: true,
9118
- category: "functions"
9119
- }
9120
- }, async ({ func, functionRootPath, force }) => {
9121
- // 自动填充默认 runtime
9122
- if (!func.runtime) {
9123
- func.runtime = exports.DEFAULT_NODEJS_RUNTIME;
9124
- }
9125
- else {
9126
- // 验证 runtime 格式,防止常见的空格问题
9127
- const normalizedRuntime = func.runtime.replace(/\s+/g, '');
9128
- if (exports.SUPPORTED_NODEJS_RUNTIMES.includes(normalizedRuntime)) {
9129
- func.runtime = normalizedRuntime;
9209
+ category: "functions",
9210
+ },
9211
+ }, async ({ func, functionRootPath, force, }) => {
9212
+ (0, logger_js_1.debug)(`[createFunction] name=${func.name}, type=${func.type || "Event"}`);
9213
+ // HTTP 云函数跳过 runtime 验证,Event 云函数进行验证
9214
+ const isHttpFunction = func.type === "HTTP";
9215
+ if (!isHttpFunction) {
9216
+ // 自动填充默认 runtime
9217
+ if (!func.runtime) {
9218
+ func.runtime = exports.DEFAULT_NODEJS_RUNTIME;
9130
9219
  }
9131
- else if (func.runtime.includes(' ')) {
9132
- console.warn(`检测到 runtime 参数包含空格: "${func.runtime}",已自动移除空格`);
9133
- func.runtime = normalizedRuntime;
9220
+ else {
9221
+ // 验证 runtime 格式,防止常见的空格问题
9222
+ const normalizedRuntime = func.runtime.replace(/\s+/g, "");
9223
+ if (exports.SUPPORTED_NODEJS_RUNTIMES.includes(normalizedRuntime)) {
9224
+ func.runtime = normalizedRuntime;
9225
+ }
9226
+ else if (func.runtime.includes(" ")) {
9227
+ console.warn(`检测到 runtime 参数包含空格: "${func.runtime}",已自动移除空格`);
9228
+ func.runtime = normalizedRuntime;
9229
+ }
9230
+ }
9231
+ // 验证 runtime 是否有效
9232
+ if (!exports.SUPPORTED_NODEJS_RUNTIMES.includes(func.runtime)) {
9233
+ throw new Error(`不支持的运行时环境: "${func.runtime}"。支持的值:${exports.SUPPORTED_NODEJS_RUNTIMES.join(", ")}`);
9134
9234
  }
9135
- }
9136
- // 验证 runtime 是否有效
9137
- if (!exports.SUPPORTED_NODEJS_RUNTIMES.includes(func.runtime)) {
9138
- throw new Error(`不支持的运行时环境: "${func.runtime}"。支持的值:${exports.SUPPORTED_NODEJS_RUNTIMES.join(', ')}`);
9139
9235
  }
9140
9236
  // 强制设置 installDependency 为 true(不暴露给AI)
9141
9237
  func.installDependency = true;
@@ -9146,16 +9242,16 @@ function registerFunctionTools(server) {
9146
9242
  const result = await cloudbase.functions.createFunction({
9147
9243
  func,
9148
9244
  functionRootPath: processedRootPath,
9149
- force
9245
+ force,
9150
9246
  });
9151
9247
  (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
9152
9248
  return {
9153
9249
  content: [
9154
9250
  {
9155
9251
  type: "text",
9156
- text: JSON.stringify(result, null, 2)
9157
- }
9158
- ]
9252
+ text: JSON.stringify(result, null, 2),
9253
+ },
9254
+ ],
9159
9255
  };
9160
9256
  });
9161
9257
  // updateFunctionCode - 更新函数代码 (cloud-incompatible)
@@ -9164,7 +9260,9 @@ function registerFunctionTools(server) {
9164
9260
  description: "更新已存在函数的代码。注意:此工具仅用于更新代码,不支持修改函数配置(如 runtime)。如果需要修改 runtime,需要删除函数后使用 createFunction 重新创建。",
9165
9261
  inputSchema: {
9166
9262
  name: zod_1.z.string().describe("函数名称"),
9167
- functionRootPath: zod_1.z.string().describe("函数根目录(云函数目录的父目录),这里需要传操作系统上文件的绝对路径"),
9263
+ functionRootPath: zod_1.z
9264
+ .string()
9265
+ .describe("函数根目录(云函数目录的父目录),这里需要传操作系统上文件的绝对路径"),
9168
9266
  // zipFile: z.string().optional().describe("Base64编码的函数包"),
9169
9267
  // handler: z.string().optional().describe("函数入口"),
9170
9268
  // runtime: z.string().optional().describe("运行时(可选值:" + SUPPORTED_NODEJS_RUNTIMES.join(',') + ",默认 Nodejs 18.15)")
@@ -9174,9 +9272,9 @@ function registerFunctionTools(server) {
9174
9272
  destructiveHint: false,
9175
9273
  idempotentHint: false,
9176
9274
  openWorldHint: true,
9177
- category: "functions"
9178
- }
9179
- }, async ({ name, functionRootPath, zipFile, handler }) => {
9275
+ category: "functions",
9276
+ },
9277
+ }, async ({ name, functionRootPath, zipFile, handler, }) => {
9180
9278
  // 处理函数根目录路径,确保不包含函数名
9181
9279
  const processedRootPath = processFunctionRootPath(functionRootPath, name);
9182
9280
  // 构建更新参数,强制设置 installDependency 为 true(不暴露给AI)
@@ -9185,9 +9283,9 @@ function registerFunctionTools(server) {
9185
9283
  func: {
9186
9284
  name,
9187
9285
  installDependency: true,
9188
- ...(handler && { handler })
9286
+ ...(handler && { handler }),
9189
9287
  },
9190
- functionRootPath: processedRootPath
9288
+ functionRootPath: processedRootPath,
9191
9289
  };
9192
9290
  // 如果提供了zipFile,则添加到参数中
9193
9291
  if (zipFile) {
@@ -9201,9 +9299,9 @@ function registerFunctionTools(server) {
9201
9299
  content: [
9202
9300
  {
9203
9301
  type: "text",
9204
- text: JSON.stringify(result, null, 2)
9205
- }
9206
- ]
9302
+ text: JSON.stringify(result, null, 2),
9303
+ },
9304
+ ],
9207
9305
  };
9208
9306
  });
9209
9307
  // updateFunctionConfig - 更新函数配置
@@ -9211,24 +9309,29 @@ function registerFunctionTools(server) {
9211
9309
  title: "更新云函数配置",
9212
9310
  description: "更新云函数配置",
9213
9311
  inputSchema: {
9214
- funcParam: zod_1.z.object({
9312
+ funcParam: zod_1.z
9313
+ .object({
9215
9314
  name: zod_1.z.string().describe("函数名称"),
9216
9315
  timeout: zod_1.z.number().optional().describe("超时时间"),
9217
9316
  envVariables: zod_1.z.record(zod_1.z.string()).optional().describe("环境变量"),
9218
- vpc: zod_1.z.object({
9317
+ vpc: zod_1.z
9318
+ .object({
9219
9319
  vpcId: zod_1.z.string(),
9220
- subnetId: zod_1.z.string()
9221
- }).optional().describe("VPC配置"),
9320
+ subnetId: zod_1.z.string(),
9321
+ })
9322
+ .optional()
9323
+ .describe("VPC配置"),
9222
9324
  // runtime: z.string().optional().describe("运行时(可选值:" + SUPPORTED_NODEJS_RUNTIMES.join(',') + ",默认 Nodejs 18.15)")
9223
- }).describe("函数配置")
9325
+ })
9326
+ .describe("函数配置"),
9224
9327
  },
9225
9328
  annotations: {
9226
9329
  readOnlyHint: false,
9227
9330
  destructiveHint: false,
9228
9331
  idempotentHint: false,
9229
9332
  openWorldHint: true,
9230
- category: "functions"
9231
- }
9333
+ category: "functions",
9334
+ },
9232
9335
  }, async ({ funcParam }) => {
9233
9336
  // 自动填充默认 runtime
9234
9337
  // if (!funcParam.runtime) {
@@ -9238,10 +9341,15 @@ function registerFunctionTools(server) {
9238
9341
  const cloudbase = await getManager();
9239
9342
  const functionDetail = await cloudbase.functions.getFunctionDetail(funcParam.name);
9240
9343
  functionDetail.Environment;
9241
- const vpc = (typeof functionDetail.VpcConfig === 'object' && functionDetail.VpcConfig !== null && functionDetail.VpcConfig.SubnetId && functionDetail.VpcConfig.VpcId) ? {
9242
- subnetId: functionDetail.VpcConfig.SubnetId,
9243
- vpcId: functionDetail.VpcConfig.VpcId
9244
- } : undefined;
9344
+ const vpc = typeof functionDetail.VpcConfig === "object" &&
9345
+ functionDetail.VpcConfig !== null &&
9346
+ functionDetail.VpcConfig.SubnetId &&
9347
+ functionDetail.VpcConfig.VpcId
9348
+ ? {
9349
+ subnetId: functionDetail.VpcConfig.SubnetId,
9350
+ vpcId: functionDetail.VpcConfig.VpcId,
9351
+ }
9352
+ : undefined;
9245
9353
  const result = await cloudbase.functions.updateFunctionConfig({
9246
9354
  name: funcParam.name,
9247
9355
  envVariables: Object.assign({}, functionDetail.Environment.Variables.reduce((acc, curr) => {
@@ -9256,9 +9364,9 @@ function registerFunctionTools(server) {
9256
9364
  content: [
9257
9365
  {
9258
9366
  type: "text",
9259
- text: JSON.stringify(result, null, 2)
9260
- }
9261
- ]
9367
+ text: JSON.stringify(result, null, 2),
9368
+ },
9369
+ ],
9262
9370
  };
9263
9371
  });
9264
9372
  // invokeFunction - 调用函数
@@ -9267,16 +9375,16 @@ function registerFunctionTools(server) {
9267
9375
  description: "调用云函数",
9268
9376
  inputSchema: {
9269
9377
  name: zod_1.z.string().describe("函数名称"),
9270
- params: zod_1.z.record(zod_1.z.any()).optional().describe("调用参数")
9378
+ params: zod_1.z.record(zod_1.z.any()).optional().describe("调用参数"),
9271
9379
  },
9272
9380
  annotations: {
9273
9381
  readOnlyHint: false,
9274
9382
  destructiveHint: false,
9275
9383
  idempotentHint: false,
9276
9384
  openWorldHint: true,
9277
- category: "functions"
9278
- }
9279
- }, async ({ name, params }) => {
9385
+ category: "functions",
9386
+ },
9387
+ }, async ({ name, params, }) => {
9280
9388
  // 使用闭包中的 cloudBaseOptions
9281
9389
  try {
9282
9390
  const cloudbase = await getManager();
@@ -9286,13 +9394,13 @@ function registerFunctionTools(server) {
9286
9394
  content: [
9287
9395
  {
9288
9396
  type: "text",
9289
- text: JSON.stringify(result, null, 2)
9290
- }
9291
- ]
9397
+ text: JSON.stringify(result, null, 2),
9398
+ },
9399
+ ],
9292
9400
  };
9293
9401
  }
9294
9402
  catch (error) {
9295
- const errorMessage = (error instanceof Error ? error.message : String(error));
9403
+ const errorMessage = error instanceof Error ? error.message : String(error);
9296
9404
  if (errorMessage.includes("Function not found") ||
9297
9405
  errorMessage.includes("函数不存在")) {
9298
9406
  throw new Error(`${errorMessage}\n\n` +
@@ -9309,19 +9417,31 @@ function registerFunctionTools(server) {
9309
9417
  description: "获取云函数日志基础信息(LogList),如需日志详情请用 RequestId 调用 getFunctionLogDetail 工具。此接口基于 manger-node 4.4.0+ 的 getFunctionLogsV2 实现,不返回具体日志内容。参数 offset+limit 不得大于 10000,startTime/endTime 间隔不得超过一天。",
9310
9418
  inputSchema: {
9311
9419
  name: zod_1.z.string().describe("函数名称"),
9312
- offset: zod_1.z.number().optional().describe("数据的偏移量,Offset+Limit 不能大于 10000"),
9313
- limit: zod_1.z.number().optional().describe("返回数据的长度,Offset+Limit 不能大于 10000"),
9314
- startTime: zod_1.z.string().optional().describe("查询的具体日期,例如:2017-05-16 20:00:00,只能与 EndTime 相差一天之内"),
9315
- endTime: zod_1.z.string().optional().describe("查询的具体日期,例如:2017-05-16 20:59:59,只能与 StartTime 相差一天之内"),
9420
+ offset: zod_1.z
9421
+ .number()
9422
+ .optional()
9423
+ .describe("数据的偏移量,Offset+Limit 不能大于 10000"),
9424
+ limit: zod_1.z
9425
+ .number()
9426
+ .optional()
9427
+ .describe("返回数据的长度,Offset+Limit 不能大于 10000"),
9428
+ startTime: zod_1.z
9429
+ .string()
9430
+ .optional()
9431
+ .describe("查询的具体日期,例如:2017-05-16 20:00:00,只能与 EndTime 相差一天之内"),
9432
+ endTime: zod_1.z
9433
+ .string()
9434
+ .optional()
9435
+ .describe("查询的具体日期,例如:2017-05-16 20:59:59,只能与 StartTime 相差一天之内"),
9316
9436
  requestId: zod_1.z.string().optional().describe("执行该函数对应的 requestId"),
9317
- qualifier: zod_1.z.string().optional().describe("函数版本,默认为 $LATEST")
9437
+ qualifier: zod_1.z.string().optional().describe("函数版本,默认为 $LATEST"),
9318
9438
  },
9319
9439
  annotations: {
9320
9440
  readOnlyHint: true,
9321
9441
  openWorldHint: true,
9322
- category: "functions"
9323
- }
9324
- }, async ({ name, offset, limit, startTime, endTime, requestId, qualifier }) => {
9442
+ category: "functions",
9443
+ },
9444
+ }, async ({ name, offset, limit, startTime, endTime, requestId, qualifier, }) => {
9325
9445
  if ((offset || 0) + (limit || 0) > 10000) {
9326
9446
  throw new Error("offset+limit 不能大于 10000");
9327
9447
  }
@@ -9333,15 +9453,23 @@ function registerFunctionTools(server) {
9333
9453
  }
9334
9454
  }
9335
9455
  const cloudbase = await getManager();
9336
- const result = await cloudbase.functions.getFunctionLogsV2({ name, offset, limit, startTime, endTime, requestId, qualifier });
9456
+ const result = await cloudbase.functions.getFunctionLogsV2({
9457
+ name,
9458
+ offset,
9459
+ limit,
9460
+ startTime,
9461
+ endTime,
9462
+ requestId,
9463
+ qualifier,
9464
+ });
9337
9465
  (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
9338
9466
  return {
9339
9467
  content: [
9340
9468
  {
9341
9469
  type: "text",
9342
- text: JSON.stringify(result, null, 2)
9343
- }
9344
- ]
9470
+ text: JSON.stringify(result, null, 2),
9471
+ },
9472
+ ],
9345
9473
  };
9346
9474
  });
9347
9475
  // getFunctionLogDetail - 查询日志详情(参数直接展开)
@@ -9349,15 +9477,21 @@ function registerFunctionTools(server) {
9349
9477
  title: "获取云函数日志详情",
9350
9478
  description: "根据 getFunctionLogs 返回的 RequestId 查询日志详情。参数 startTime、endTime、requestId,返回日志内容(LogJson 等)。仅支持 manger-node 4.4.0+。",
9351
9479
  inputSchema: {
9352
- startTime: zod_1.z.string().optional().describe("查询的具体日期,例如:2017-05-16 20:00:00,只能与 EndTime 相差一天之内"),
9353
- endTime: zod_1.z.string().optional().describe("查询的具体日期,例如:2017-05-16 20:59:59,只能与 StartTime 相差一天之内"),
9354
- requestId: zod_1.z.string().describe("执行该函数对应的 requestId")
9480
+ startTime: zod_1.z
9481
+ .string()
9482
+ .optional()
9483
+ .describe("查询的具体日期,例如:2017-05-16 20:00:00,只能与 EndTime 相差一天之内"),
9484
+ endTime: zod_1.z
9485
+ .string()
9486
+ .optional()
9487
+ .describe("查询的具体日期,例如:2017-05-16 20:59:59,只能与 StartTime 相差一天之内"),
9488
+ requestId: zod_1.z.string().describe("执行该函数对应的 requestId"),
9355
9489
  },
9356
9490
  annotations: {
9357
9491
  readOnlyHint: true,
9358
9492
  openWorldHint: true,
9359
- category: "functions"
9360
- }
9493
+ category: "functions",
9494
+ },
9361
9495
  }, async ({ startTime, endTime, requestId }) => {
9362
9496
  if (startTime && endTime) {
9363
9497
  const start = new Date(startTime).getTime();
@@ -9370,16 +9504,16 @@ function registerFunctionTools(server) {
9370
9504
  const result = await cloudbase.functions.getFunctionLogDetail({
9371
9505
  startTime,
9372
9506
  endTime,
9373
- logRequestId: requestId
9507
+ logRequestId: requestId,
9374
9508
  });
9375
9509
  (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
9376
9510
  return {
9377
9511
  content: [
9378
9512
  {
9379
9513
  type: "text",
9380
- text: JSON.stringify(result, null, 2)
9381
- }
9382
- ]
9514
+ text: JSON.stringify(result, null, 2),
9515
+ },
9516
+ ],
9383
9517
  };
9384
9518
  });
9385
9519
  // manageFunctionTriggers - 管理云函数触发器(创建/删除)
@@ -9387,23 +9521,32 @@ function registerFunctionTools(server) {
9387
9521
  title: "管理云函数触发器",
9388
9522
  description: "创建或删除云函数触发器,通过 action 参数区分操作类型",
9389
9523
  inputSchema: {
9390
- action: zod_1.z.enum(["create", "delete"]).describe("操作类型:create=创建触发器,delete=删除触发器"),
9524
+ action: zod_1.z
9525
+ .enum(["create", "delete"])
9526
+ .describe("操作类型:create=创建触发器,delete=删除触发器"),
9391
9527
  name: zod_1.z.string().describe("函数名"),
9392
- triggers: zod_1.z.array(zod_1.z.object({
9528
+ triggers: zod_1.z
9529
+ .array(zod_1.z.object({
9393
9530
  name: zod_1.z.string().describe("Trigger name"),
9394
- type: zod_1.z.enum(exports.SUPPORTED_TRIGGER_TYPES).describe("Trigger type, currently only supports 'timer'"),
9395
- config: zod_1.z.string().describe("Trigger configuration. For timer triggers, use cron expression format: second minute hour day month week year. IMPORTANT: Must include exactly 7 fields (second minute hour day month week year). Examples: '0 0 2 1 * * *' (monthly), '0 30 9 * * * *' (daily at 9:30 AM)")
9396
- })).optional().describe("触发器配置数组(创建时必需)"),
9397
- triggerName: zod_1.z.string().optional().describe("触发器名称(删除时必需)")
9531
+ type: zod_1.z
9532
+ .enum(exports.SUPPORTED_TRIGGER_TYPES)
9533
+ .describe("Trigger type, currently only supports 'timer'"),
9534
+ config: zod_1.z
9535
+ .string()
9536
+ .describe("Trigger configuration. For timer triggers, use cron expression format: second minute hour day month week year. IMPORTANT: Must include exactly 7 fields (second minute hour day month week year). Examples: '0 0 2 1 * * *' (monthly), '0 30 9 * * * *' (daily at 9:30 AM)"),
9537
+ }))
9538
+ .optional()
9539
+ .describe("触发器配置数组(创建时必需)"),
9540
+ triggerName: zod_1.z.string().optional().describe("触发器名称(删除时必需)"),
9398
9541
  },
9399
9542
  annotations: {
9400
9543
  readOnlyHint: false,
9401
9544
  destructiveHint: false,
9402
9545
  idempotentHint: false,
9403
9546
  openWorldHint: true,
9404
- category: "functions"
9405
- }
9406
- }, async ({ action, name, triggers, triggerName }) => {
9547
+ category: "functions",
9548
+ },
9549
+ }, async ({ action, name, triggers, triggerName, }) => {
9407
9550
  // 使用闭包中的 cloudBaseOptions
9408
9551
  const cloudbase = await getManager();
9409
9552
  if (action === "create") {
@@ -9416,9 +9559,9 @@ function registerFunctionTools(server) {
9416
9559
  content: [
9417
9560
  {
9418
9561
  type: "text",
9419
- text: JSON.stringify(result, null, 2)
9420
- }
9421
- ]
9562
+ text: JSON.stringify(result, null, 2),
9563
+ },
9564
+ ],
9422
9565
  };
9423
9566
  }
9424
9567
  else if (action === "delete") {
@@ -9431,9 +9574,9 @@ function registerFunctionTools(server) {
9431
9574
  content: [
9432
9575
  {
9433
9576
  type: "text",
9434
- text: JSON.stringify(result, null, 2)
9435
- }
9436
- ]
9577
+ text: JSON.stringify(result, null, 2),
9578
+ },
9579
+ ],
9437
9580
  };
9438
9581
  }
9439
9582
  else {
@@ -10096,7 +10239,7 @@ function registerSetupTools(server) {
10096
10239
  title: "下载项目模板",
10097
10240
  description: `自动下载并部署CloudBase项目模板。⚠️ **MANDATORY FOR NEW PROJECTS** ⚠️
10098
10241
 
10099
- **CRITICAL**: This tool MUST be called FIRST when starting a new project.\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.11.0" : 0}),便于后续维护和版本追踪\n- 下载 rules 模板时,如果项目中已存在 README.md 文件,系统会自动保护该文件不被覆盖(除非设置 overwrite=true)`,
10242
+ **CRITICAL**: This tool MUST be called FIRST when starting a new project.\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.12.0" : 0}),便于后续维护和版本追踪\n- 下载 rules 模板时,如果项目中已存在 README.md 文件,系统会自动保护该文件不被覆盖(除非设置 overwrite=true)`,
10100
10243
  inputSchema: {
10101
10244
  template: zod_1.z
10102
10245
  .enum(["react", "vue", "miniprogram", "uniapp", "rules"])
@@ -11505,8 +11648,10 @@ function getJavaScripts(wsPort) {
11505
11648
  }
11506
11649
  }
11507
11650
 
11508
- // WebSocket connection
11509
- const ws = new WebSocket('ws://localhost:${wsPort}');
11651
+ // WebSocket: same host as page so it works in remote VS Code / Cloud IDE (no localhost)
11652
+ const wsScheme = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
11653
+ const wsUrl = wsScheme + '//' + window.location.host;
11654
+ const ws = new WebSocket(wsUrl);
11510
11655
 
11511
11656
  ws.onopen = () => {
11512
11657
  console.log('[env-setup] WebSocket connected');