@cloudbase/cloudbase-mcp 2.13.0 → 2.14.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
@@ -32,11 +32,12 @@ import * as __WEBPACK_EXTERNAL_MODULE_winston__ from "winston";
32
32
  Object.defineProperty(exports, "__esModule", ({ value: true }));
33
33
  exports.simplifyEnvList = simplifyEnvList;
34
34
  exports.registerEnvTools = registerEnvTools;
35
+ const toolbox_1 = __webpack_require__(2090);
35
36
  const zod_1 = __webpack_require__(2971);
36
37
  const auth_js_1 = __webpack_require__(7291);
37
38
  const cloudbase_manager_js_1 = __webpack_require__(3431);
38
39
  const logger_js_1 = __webpack_require__(3039);
39
- const interactive_js_1 = __webpack_require__(3461);
40
+ const tool_result_js_1 = __webpack_require__(9835);
40
41
  const rag_js_1 = __webpack_require__(4215);
41
42
  /**
42
43
  * Simplify environment list data by keeping only essential fields for AI assistant
@@ -68,17 +69,119 @@ function simplifyEnvList(envList) {
68
69
  return simplified;
69
70
  });
70
71
  }
72
+ function formatDeviceAuthHint(deviceAuthInfo) {
73
+ if (!deviceAuthInfo) {
74
+ return "";
75
+ }
76
+ const lines = [
77
+ "",
78
+ "### Device Flow 授权信息",
79
+ `- user_code: ${deviceAuthInfo.user_code}`,
80
+ ];
81
+ if (deviceAuthInfo.verification_uri) {
82
+ lines.push(`- verification_uri: ${deviceAuthInfo.verification_uri}`);
83
+ }
84
+ lines.push(`- expires_in: ${deviceAuthInfo.expires_in}s`);
85
+ lines.push("", "请在另一台可用浏览器设备打开 `verification_uri` 并输入 `user_code` 完成授权。");
86
+ return lines.join("\n");
87
+ }
88
+ function emitDeviceAuthNotice(server, deviceAuthInfo) {
89
+ // Temporarily disabled: avoid sending logging notifications for device auth
90
+ }
91
+ async function fetchAvailableEnvCandidates(cloudBaseOptions, server) {
92
+ try {
93
+ return await (0, cloudbase_manager_js_1.listAvailableEnvCandidates)({
94
+ cloudBaseOptions,
95
+ });
96
+ }
97
+ catch {
98
+ return [];
99
+ }
100
+ }
101
+ const CODEBUDDY_AUTH_ACTIONS = ["status", "set_env"];
102
+ const DEFAULT_AUTH_ACTIONS = [
103
+ "status",
104
+ "start_auth",
105
+ "set_env",
106
+ "logout",
107
+ ];
108
+ function getCurrentIde(server) {
109
+ return server.ide || process.env.INTEGRATION_IDE || "";
110
+ }
111
+ function isCodeBuddyIde(server) {
112
+ return getCurrentIde(server) === "CodeBuddy";
113
+ }
114
+ function getSupportedAuthActions(server) {
115
+ return isCodeBuddyIde(server) ? CODEBUDDY_AUTH_ACTIONS : DEFAULT_AUTH_ACTIONS;
116
+ }
117
+ function buildAuthRequiredNextStep(server) {
118
+ if (isCodeBuddyIde(server)) {
119
+ return (0, tool_result_js_1.buildAuthNextStep)("status", {
120
+ suggestedArgs: { action: "status" },
121
+ });
122
+ }
123
+ return (0, tool_result_js_1.buildAuthNextStep)("start_auth", {
124
+ suggestedArgs: { action: "start_auth", authMode: "device" },
125
+ });
126
+ }
127
+ function buildSetEnvNextStep(envCandidates) {
128
+ const singleEnvId = envCandidates.length === 1 ? envCandidates[0].envId : undefined;
129
+ return (0, tool_result_js_1.buildAuthNextStep)("set_env", {
130
+ requiredParams: singleEnvId ? undefined : ["envId"],
131
+ suggestedArgs: singleEnvId
132
+ ? { action: "set_env", envId: singleEnvId }
133
+ : { action: "set_env" },
134
+ });
135
+ }
136
+ async function getGuidePrompt(server) {
137
+ if (getCurrentIde(server) === "CodeBuddy" ||
138
+ process.env.CLOUDBASE_GUIDE_PROMPT === "false") {
139
+ return "";
140
+ }
141
+ try {
142
+ return await (0, rag_js_1.getClaudePrompt)();
143
+ }
144
+ catch (promptError) {
145
+ (0, logger_js_1.debug)("Failed to get CLAUDE prompt", { error: promptError });
146
+ return "";
147
+ }
148
+ }
71
149
  function registerEnvTools(server) {
72
150
  // 获取 cloudBaseOptions,如果没有则为 undefined
73
151
  const cloudBaseOptions = server.cloudBaseOptions;
74
152
  const getManager = () => (0, cloudbase_manager_js_1.getCloudBaseManager)({ cloudBaseOptions, mcpServer: server });
75
153
  const hasEnvId = typeof cloudBaseOptions?.envId === 'string' && cloudBaseOptions?.envId.length > 0;
76
- // login - 登录云开发环境
77
- server.registerTool?.("login", {
78
- title: "登录云开发",
79
- description: "登录云开发环境,在生成包含云开发 CloudBase 相关功能前**必须**先调用此工具进行登录。登录云开发环境并选择要使用的环境。",
154
+ const supportedAuthActions = getSupportedAuthActions(server);
155
+ const authActionEnum = [...supportedAuthActions];
156
+ // auth - CloudBase (云开发) 开发阶段登录与环境绑定
157
+ server.registerTool?.("auth", {
158
+ title: "CloudBase 开发阶段登录与环境",
159
+ description: "CloudBase(腾讯云开发)开发阶段登录与环境绑定。登录后即可访问云资源;环境(env)是云函数、数据库、静态托管等资源的隔离单元,绑定环境后其他 MCP 工具才能操作该环境。支持:查询状态、发起登录、绑定环境(set_env)、退出登录。",
80
160
  inputSchema: {
81
- forceUpdate: zod_1.z.boolean().optional().describe("是否强制重新选择环境"),
161
+ action: zod_1.z
162
+ .enum(authActionEnum)
163
+ .optional()
164
+ .describe("动作:status=查询状态,start_auth=发起登录,set_env=绑定环境(传envId),logout=退出登录"),
165
+ ...(supportedAuthActions.includes("start_auth")
166
+ ? {
167
+ authMode: zod_1.z
168
+ .enum(["device", "web"])
169
+ .optional()
170
+ .describe("认证模式:device=设备码授权,web=浏览器回调授权"),
171
+ }
172
+ : {}),
173
+ envId: zod_1.z
174
+ .string()
175
+ .optional()
176
+ .describe("环境ID(CloudBase 环境唯一标识),绑定后工具将操作该环境。action=set_env 时必填"),
177
+ ...(supportedAuthActions.includes("logout")
178
+ ? {
179
+ confirm: zod_1.z
180
+ .literal("yes")
181
+ .optional()
182
+ .describe("action=logout 时确认操作,传 yes"),
183
+ }
184
+ : {}),
82
185
  },
83
186
  annotations: {
84
187
  readOnlyHint: false,
@@ -87,135 +190,326 @@ function registerEnvTools(server) {
87
190
  openWorldHint: true,
88
191
  category: "env",
89
192
  },
90
- }, async ({ forceUpdate = false }) => {
91
- let isSwitching = false;
193
+ }, async (rawArgs) => {
194
+ const action = rawArgs.action ?? "status";
195
+ const authMode = rawArgs.authMode === "device" || rawArgs.authMode === "web"
196
+ ? rawArgs.authMode
197
+ : undefined;
198
+ const envId = rawArgs.envId;
199
+ const confirm = rawArgs.confirm === "yes" ? "yes" : undefined;
200
+ let deviceAuthInfo;
201
+ const onDeviceCode = (info) => {
202
+ deviceAuthInfo = info;
203
+ (0, auth_js_1.setPendingAuthProgressState)(info, "device");
204
+ // emitDeviceAuthNotice(server, info);
205
+ };
206
+ const authChallenge = () => deviceAuthInfo
207
+ ? {
208
+ user_code: deviceAuthInfo.user_code,
209
+ verification_uri: deviceAuthInfo.verification_uri,
210
+ expires_in: deviceAuthInfo.expires_in,
211
+ }
212
+ : undefined;
92
213
  try {
93
- // 使用 while 循环处理用户切换账号的情况
94
- while (true) {
95
- // CRITICAL: Ensure server is passed correctly
96
- (0, logger_js_1.debug)("[env] Calling _promptAndSetEnvironmentId with server:", {
97
- hasServer: !!server,
98
- serverType: typeof server,
99
- hasServerServer: !!server?.server,
100
- hasServerIde: !!server?.ide,
101
- serverIde: server?.ide
102
- });
103
- const { selectedEnvId, cancelled, error, noEnvs, switch: switchAccount, } = await (0, interactive_js_1._promptAndSetEnvironmentId)(forceUpdate, {
104
- server, // Pass ExtendedMcpServer instance
105
- loginFromCloudBaseLoginPage: isSwitching,
106
- // When switching account, ignore environment variables to force Web login
107
- ignoreEnvVars: isSwitching,
214
+ if (!supportedAuthActions.includes(action)) {
215
+ return (0, tool_result_js_1.buildJsonToolResult)({
216
+ ok: false,
217
+ code: "NOT_SUPPORTED",
218
+ message: `当前 IDE 不支持 auth(action="${action}")。`,
219
+ next_step: (0, tool_result_js_1.buildAuthNextStep)("status", {
220
+ suggestedArgs: { action: "status" },
221
+ }),
108
222
  });
109
- isSwitching = Boolean(switchAccount);
110
- (0, logger_js_1.debug)("login", {
111
- selectedEnvId,
112
- cancelled,
113
- error,
114
- noEnvs,
115
- switchAccount,
223
+ }
224
+ if (action === "status") {
225
+ const loginState = await (0, auth_js_1.peekLoginState)();
226
+ const authFlowState = await (0, auth_js_1.getAuthProgressState)();
227
+ const envId = (0, cloudbase_manager_js_1.getCachedEnvId)() ||
228
+ process.env.CLOUDBASE_ENV_ID ||
229
+ (typeof loginState?.envId === "string" ? loginState.envId : undefined);
230
+ const authStatus = loginState
231
+ ? "READY"
232
+ : authFlowState.status === "PENDING"
233
+ ? "PENDING"
234
+ : "REQUIRED";
235
+ const envCandidates = await fetchAvailableEnvCandidates(cloudBaseOptions, server);
236
+ const envStatus = envId
237
+ ? "READY"
238
+ : envCandidates.length > 1
239
+ ? "MULTIPLE"
240
+ : envCandidates.length === 1
241
+ ? "READY"
242
+ : "NONE";
243
+ const message = authStatus === "READY"
244
+ ? `当前已登录${envId ? `,环境: ${envId}` : ",但未绑定环境"}`
245
+ : authStatus === "PENDING"
246
+ ? "设备码授权进行中,请完成浏览器授权后再次调用 auth(action=\"status\")"
247
+ : isCodeBuddyIde(server)
248
+ ? "当前未登录。CodeBuddy 暂不支持在 tool 内发起认证,请在外部完成认证后再次调用 auth(action=\"status\")。"
249
+ : "当前未登录,请先执行 auth(action=\"start_auth\")";
250
+ return (0, tool_result_js_1.buildJsonToolResult)({
251
+ ok: true,
252
+ code: "STATUS",
253
+ auth_status: authStatus,
254
+ env_status: envStatus,
255
+ current_env_id: envId || null,
256
+ env_candidates: envCandidates,
257
+ auth_challenge: authFlowState.status === "PENDING" && authFlowState.authChallenge
258
+ ? {
259
+ user_code: authFlowState.authChallenge.user_code,
260
+ verification_uri: authFlowState.authChallenge.verification_uri,
261
+ expires_in: authFlowState.authChallenge.expires_in,
262
+ }
263
+ : undefined,
264
+ message,
265
+ next_step: authStatus === "REQUIRED"
266
+ ? buildAuthRequiredNextStep(server)
267
+ : authStatus === "PENDING"
268
+ ? (0, tool_result_js_1.buildAuthNextStep)("status", {
269
+ suggestedArgs: { action: "status" },
270
+ })
271
+ : !envId
272
+ ? buildSetEnvNextStep(envCandidates)
273
+ : (0, tool_result_js_1.buildAuthNextStep)("status", {
274
+ suggestedArgs: { action: "status" },
275
+ }),
116
276
  });
117
- if (error) {
118
- return { content: [{ type: "text", text: error }] };
119
- }
120
- if (cancelled) {
121
- return { content: [{ type: "text", text: "用户取消了登录" }] };
277
+ }
278
+ if (action === "start_auth") {
279
+ const region = server.cloudBaseOptions?.region || process.env.TCB_REGION;
280
+ const auth = toolbox_1.AuthSupervisor.getInstance({});
281
+ const authFlowState = await (0, auth_js_1.getAuthProgressState)();
282
+ if (authFlowState.status === "PENDING" && authFlowState.authChallenge) {
283
+ return (0, tool_result_js_1.buildJsonToolResult)({
284
+ ok: true,
285
+ code: "AUTH_PENDING",
286
+ message: "设备码授权进行中,请在浏览器中打开 verification_uri 并输入 user_code 完成授权。",
287
+ auth_challenge: {
288
+ user_code: authFlowState.authChallenge.user_code,
289
+ verification_uri: authFlowState.authChallenge.verification_uri,
290
+ expires_in: authFlowState.authChallenge.expires_in,
291
+ },
292
+ next_step: (0, tool_result_js_1.buildAuthNextStep)("status", {
293
+ suggestedArgs: { action: "status" },
294
+ }),
295
+ });
122
296
  }
123
- // 用户选择切换账号,先 logout 再重新登录
124
- if (switchAccount) {
125
- (0, logger_js_1.debug)("User requested switch account, logging out...");
126
- try {
127
- await (0, auth_js_1.logout)();
128
- (0, cloudbase_manager_js_1.resetCloudBaseManagerCache)();
129
- (0, logger_js_1.debug)("Logged out successfully, restarting login flow...");
130
- // Set isSwitching to true so next iteration will ignore env vars
131
- // and force Web authentication to allow account switching
132
- isSwitching = true;
133
- // 继续循环,重新显示登录界面
134
- continue;
135
- }
136
- catch (logoutError) {
137
- (0, logger_js_1.debug)("Logout failed during switch", { error: logoutError });
138
- continue;
297
+ // 1. 如果已经有登录态,直接返回 AUTH_READY
298
+ try {
299
+ const existingLoginState = await (0, auth_js_1.peekLoginState)();
300
+ if (existingLoginState) {
301
+ const envId = typeof existingLoginState.envId === "string" ? existingLoginState.envId : null;
302
+ const envCandidates = envId
303
+ ? []
304
+ : await fetchAvailableEnvCandidates(cloudBaseOptions, server);
305
+ return (0, tool_result_js_1.buildJsonToolResult)({
306
+ ok: true,
307
+ code: "AUTH_READY",
308
+ message: envId
309
+ ? `认证成功,当前登录态 envId: ${envId}`
310
+ : "认证成功",
311
+ auth_challenge: authChallenge(),
312
+ env_candidates: envCandidates,
313
+ next_step: envId
314
+ ? (0, tool_result_js_1.buildAuthNextStep)("status", {
315
+ suggestedArgs: { action: "status" },
316
+ })
317
+ : buildSetEnvNextStep(envCandidates),
318
+ });
139
319
  }
140
320
  }
141
- if (selectedEnvId) {
142
- // Get CLAUDE.md prompt content (skip for CodeBuddy IDE)
143
- let promptContent = "";
144
- const currentIde = server.ide || process.env.INTEGRATION_IDE;
145
- if (currentIde !== "CodeBuddy" && process.env.CLOUDBASE_GUIDE_PROMPT !== "false") {
146
- try {
147
- promptContent = await (0, rag_js_1.getClaudePrompt)();
321
+ catch {
322
+ // 忽略 getLoginState 错误,继续尝试发起登录
323
+ }
324
+ // 2. 设备码模式:监听到 device code 即返回 AUTH_PENDING,后续由 toolbox 异步轮询并更新本地 credential
325
+ const effectiveMode = authMode && (authMode === "device" || authMode === "web")
326
+ ? authMode
327
+ : process.env.TCB_AUTH_MODE === "web"
328
+ ? "web"
329
+ : "device";
330
+ if (effectiveMode === "device") {
331
+ let resolveCode;
332
+ let rejectCode;
333
+ const codeReady = new Promise((resolve, reject) => {
334
+ resolveCode = resolve;
335
+ rejectCode = reject;
336
+ });
337
+ const deviceOnCode = (info) => {
338
+ onDeviceCode(info);
339
+ if (resolveCode) {
340
+ resolveCode();
148
341
  }
149
- catch (promptError) {
150
- (0, logger_js_1.debug)("Failed to get CLAUDE prompt", { error: promptError });
151
- // Continue with login success even if prompt fetch fails
342
+ };
343
+ try {
344
+ // 启动 Device Flow,全流程由 toolbox 负责轮询和写入 credential,这里不等待完成
345
+ auth
346
+ .loginByWebAuth({
347
+ flow: "device",
348
+ onDeviceCode: deviceOnCode,
349
+ })
350
+ .then(() => {
351
+ (0, auth_js_1.resolveAuthProgressState)();
352
+ })
353
+ .catch((err) => {
354
+ (0, auth_js_1.rejectAuthProgressState)(err);
355
+ // 如果在拿到 device code 之前就失败,则唤醒当前调用并返回错误
356
+ if (!deviceAuthInfo && rejectCode) {
357
+ rejectCode(err);
358
+ }
359
+ });
360
+ }
361
+ catch (err) {
362
+ if (rejectCode) {
363
+ rejectCode(err);
152
364
  }
153
365
  }
154
- const successMessage = `✅ 登录成功,当前环境: ${selectedEnvId}`;
155
- const promptMessage = promptContent
156
- ? `\n\n⚠️ 重要提示:后续所有云开发相关的开发工作必须严格遵循以下开发规范和最佳实践:\n\n${promptContent}`
157
- : "";
158
- return {
159
- content: [
160
- {
161
- type: "text",
162
- text: successMessage + promptMessage,
163
- },
164
- ],
165
- };
366
+ try {
367
+ await codeReady;
368
+ }
369
+ catch (err) {
370
+ const message = err instanceof Error ? err.message : String(err ?? "unknown error");
371
+ return (0, tool_result_js_1.buildJsonToolResult)({
372
+ ok: false,
373
+ code: "AUTH_REQUIRED",
374
+ message: `设备码登录初始化失败: ${message}`,
375
+ next_step: (0, tool_result_js_1.buildAuthNextStep)("start_auth", {
376
+ suggestedArgs: { action: "start_auth", authMode: "device" },
377
+ }),
378
+ });
379
+ }
380
+ if (!deviceAuthInfo) {
381
+ return (0, tool_result_js_1.buildJsonToolResult)({
382
+ ok: false,
383
+ code: "AUTH_REQUIRED",
384
+ message: "未获取到设备码信息,请重试设备码登录",
385
+ next_step: (0, tool_result_js_1.buildAuthNextStep)("start_auth", {
386
+ suggestedArgs: { action: "start_auth", authMode: "device" },
387
+ }),
388
+ });
389
+ }
390
+ const envCandidates = await fetchAvailableEnvCandidates(cloudBaseOptions, server);
391
+ return (0, tool_result_js_1.buildJsonToolResult)({
392
+ ok: true,
393
+ code: "AUTH_PENDING",
394
+ message: "已发起设备码登录,请在浏览器中打开 verification_uri 并输入 user_code 完成授权。授权完成后请再次调用 auth(action=\"status\")。",
395
+ auth_challenge: authChallenge(),
396
+ env_candidates: envCandidates,
397
+ next_step: (0, tool_result_js_1.buildAuthNextStep)("status", {
398
+ suggestedArgs: { action: "status" },
399
+ }),
400
+ });
401
+ }
402
+ // 3. 非 Device Flow(显式 web 模式)仍然使用 getLoginState 阻塞等待
403
+ const loginState = await (0, auth_js_1.ensureLogin)({
404
+ region,
405
+ authMode: effectiveMode,
406
+ });
407
+ if (!loginState) {
408
+ return (0, tool_result_js_1.buildJsonToolResult)({
409
+ ok: false,
410
+ code: "AUTH_REQUIRED",
411
+ message: "未获取到登录态,请先完成认证",
412
+ next_step: (0, tool_result_js_1.buildAuthNextStep)("start_auth", {
413
+ suggestedArgs: { action: "start_auth", authMode: effectiveMode },
414
+ }),
415
+ });
166
416
  }
167
- throw new Error("登录失败");
417
+ const envId = typeof loginState.envId === "string" ? loginState.envId : null;
418
+ const envCandidates = envId
419
+ ? []
420
+ : await fetchAvailableEnvCandidates(cloudBaseOptions, server);
421
+ return (0, tool_result_js_1.buildJsonToolResult)({
422
+ ok: true,
423
+ code: "AUTH_READY",
424
+ message: envId ? `认证成功,当前登录态 envId: ${envId}` : "认证成功",
425
+ auth_challenge: authChallenge(),
426
+ env_candidates: envCandidates,
427
+ next_step: envId
428
+ ? (0, tool_result_js_1.buildAuthNextStep)("status", {
429
+ suggestedArgs: { action: "status" },
430
+ })
431
+ : buildSetEnvNextStep(envCandidates),
432
+ });
168
433
  }
434
+ if (action === "set_env") {
435
+ const loginState = await (0, auth_js_1.peekLoginState)();
436
+ if (!loginState) {
437
+ return (0, tool_result_js_1.buildJsonToolResult)({
438
+ ok: false,
439
+ code: "AUTH_REQUIRED",
440
+ message: isCodeBuddyIde(server)
441
+ ? "当前未登录。CodeBuddy 暂不支持在 tool 内发起认证,请在外部完成认证后再次调用 auth(action=\"status\")。"
442
+ : "当前未登录,请先执行 auth(action=\"start_auth\")。",
443
+ next_step: buildAuthRequiredNextStep(server),
444
+ });
445
+ }
446
+ const envCandidates = await fetchAvailableEnvCandidates(cloudBaseOptions, server);
447
+ if (!envId) {
448
+ return (0, tool_result_js_1.buildJsonToolResult)({
449
+ ok: false,
450
+ code: "INVALID_ARGS",
451
+ message: "action=set_env 时必须提供 envId",
452
+ env_candidates: envCandidates,
453
+ next_step: buildSetEnvNextStep(envCandidates),
454
+ });
455
+ }
456
+ const target = envCandidates.find((item) => item.envId === envId);
457
+ if (envCandidates.length > 0 && !target) {
458
+ return (0, tool_result_js_1.buildJsonToolResult)({
459
+ ok: false,
460
+ code: "INVALID_ARGS",
461
+ message: `未找到环境: ${envId}`,
462
+ env_candidates: envCandidates,
463
+ next_step: buildSetEnvNextStep(envCandidates),
464
+ });
465
+ }
466
+ await cloudbase_manager_js_1.envManager.setEnvId(envId);
467
+ return (0, tool_result_js_1.buildJsonToolResult)({
468
+ ok: true,
469
+ code: "ENV_READY",
470
+ message: `环境设置成功,当前环境: ${envId}`,
471
+ current_env_id: envId,
472
+ });
473
+ }
474
+ if (action === "logout") {
475
+ if (confirm !== "yes") {
476
+ return (0, tool_result_js_1.buildJsonToolResult)({
477
+ ok: false,
478
+ code: "INVALID_ARGS",
479
+ message: "action=logout 时必须传 confirm=\"yes\"",
480
+ next_step: (0, tool_result_js_1.buildAuthNextStep)("logout", {
481
+ suggestedArgs: { action: "logout", confirm: "yes" },
482
+ }),
483
+ });
484
+ }
485
+ await (0, auth_js_1.logout)();
486
+ (0, cloudbase_manager_js_1.resetCloudBaseManagerCache)();
487
+ return (0, tool_result_js_1.buildJsonToolResult)({
488
+ ok: true,
489
+ code: "LOGGED_OUT",
490
+ message: "✅ 已退出登录",
491
+ });
492
+ }
493
+ return (0, tool_result_js_1.buildJsonToolResult)({
494
+ ok: false,
495
+ code: "NOT_SUPPORTED",
496
+ message: `不支持的 auth action: ${action}`,
497
+ next_step: (0, tool_result_js_1.buildAuthNextStep)("status", {
498
+ suggestedArgs: { action: "status" },
499
+ }),
500
+ });
169
501
  }
170
502
  catch (error) {
171
- return {
172
- content: [
173
- {
174
- type: "text",
175
- text: `登录失败: ${error instanceof Error ? error.message : String(error)}`,
176
- },
177
- ],
178
- };
179
- }
180
- });
181
- // logout - 退出云开发环境
182
- server.registerTool?.("logout", {
183
- title: "退出登录",
184
- description: "退出云开发环境",
185
- inputSchema: {
186
- confirm: zod_1.z.literal("yes").describe("确认操作,默认传 yes"),
187
- },
188
- annotations: {
189
- readOnlyHint: false,
190
- destructiveHint: false,
191
- idempotentHint: true,
192
- openWorldHint: false,
193
- category: "env",
194
- },
195
- }, async () => {
196
- try {
197
- // 登出账户
198
- await (0, auth_js_1.logout)();
199
- // 清理环境ID缓存
200
- (0, cloudbase_manager_js_1.resetCloudBaseManagerCache)();
201
- return {
202
- content: [
203
- {
204
- type: "text",
205
- text: "✅ 已退出登录",
206
- },
207
- ],
208
- };
209
- }
210
- catch (error) {
211
- return {
212
- content: [
213
- {
214
- type: "text",
215
- text: `退出失败: ${error instanceof Error ? error.message : String(error)}`,
216
- },
217
- ],
218
- };
503
+ const message = error instanceof Error ? error.message : String(error);
504
+ return (0, tool_result_js_1.buildJsonToolResult)({
505
+ ok: false,
506
+ code: "INTERNAL_ERROR",
507
+ message: `auth 执行失败: ${message}`,
508
+ auth_challenge: authChallenge(),
509
+ next_step: (0, tool_result_js_1.buildAuthNextStep)("status", {
510
+ suggestedArgs: { action: "status" },
511
+ }),
512
+ });
219
513
  }
220
514
  });
221
515
  // envQuery - 环境查询(合并 listEnvs + getEnvInfo + getEnvAuthDomains + getWebsiteConfig)
@@ -289,6 +583,10 @@ function registerEnvTools(server) {
289
583
  }
290
584
  }
291
585
  catch (fallbackError) {
586
+ const toolPayloadResult = (0, tool_result_js_1.toolPayloadErrorToResult)(fallbackError);
587
+ if (toolPayloadResult) {
588
+ return toolPayloadResult;
589
+ }
292
590
  (0, logger_js_1.debug)("降级到 listEnvs() 也失败:", fallbackError instanceof Error ? fallbackError : new Error(String(fallbackError)));
293
591
  return {
294
592
  content: [
@@ -352,6 +650,10 @@ function registerEnvTools(server) {
352
650
  };
353
651
  }
354
652
  catch (error) {
653
+ const toolPayloadResult = (0, tool_result_js_1.toolPayloadErrorToResult)(error);
654
+ if (toolPayloadResult) {
655
+ return toolPayloadResult;
656
+ }
355
657
  return {
356
658
  content: [
357
659
  {
@@ -405,6 +707,10 @@ function registerEnvTools(server) {
405
707
  };
406
708
  }
407
709
  catch (error) {
710
+ const toolPayloadResult = (0, tool_result_js_1.toolPayloadErrorToResult)(error);
711
+ if (toolPayloadResult) {
712
+ return toolPayloadResult;
713
+ }
408
714
  return {
409
715
  content: [
410
716
  {
@@ -480,7 +786,20 @@ function registerCapiTools(server) {
480
786
  throw new Error(`${service}/${action} Cloud API is not exposed or does not exist. Please use another API.`);
481
787
  }
482
788
  if (service === 'tcb') {
483
- const tcbCapiForbidList = ['DescribeStorageACL', 'ModifyStorageACL', 'DescribeSecurityRule'];
789
+ const tcbCapiForbidList = [
790
+ // 未明确对外的云API
791
+ 'DescribeStorageACL', 'ModifyStorageACL', 'DescribeSecurityRule',
792
+ // 要下线的云API
793
+ "ListTables",
794
+ "DescribeCloudBaseGWAPI",
795
+ "DescribeCloudBaseGWService",
796
+ "CreateCloudBaseGWAPI",
797
+ "DeleteCloudBaseGWAPI",
798
+ "ModifyCloudBaseGWAPI",
799
+ "DeleteCloudBaseGWDomain",
800
+ "BindCloudBaseGWDomain",
801
+ "BindCloudBaseAccessDomain"
802
+ ];
484
803
  if (tcbCapiForbidList.includes(action)) {
485
804
  throw new Error(`${service}/${action} Cloud API is not exposed or does not exist. Please use another API.`);
486
805
  }
@@ -526,6 +845,7 @@ const cloudbase_manager_js_1 = __webpack_require__(3431);
526
845
  const cloud_mode_js_1 = __webpack_require__(9684);
527
846
  const logger_js_1 = __webpack_require__(3039);
528
847
  const telemetry_js_1 = __webpack_require__(5880);
848
+ const tool_result_js_1 = __webpack_require__(9835);
529
849
  /**
530
850
  * 生成 GitHub Issue 创建链接
531
851
  * @param toolName 工具名称
@@ -573,7 +893,7 @@ ${envIdSection}
573
893
  ## 环境信息
574
894
  - 操作系统: ${os_1.default.type()} ${os_1.default.release()}
575
895
  - Node.js版本: ${process.version}
576
- - MCP 版本:${process.env.npm_package_version || "2.13.0" || 0}
896
+ - MCP 版本:${process.env.npm_package_version || "2.14.2" || 0}
577
897
  - 系统架构: ${os_1.default.arch()}
578
898
  - 时间: ${new Date().toISOString()}
579
899
  - 请求ID: ${requestId}
@@ -638,6 +958,11 @@ function createWrappedHandler(name, handler, server) {
638
958
  if (!isTestEnvironment) {
639
959
  server.logger?.({ type: 'errorToolCall', toolName: name, args: sanitizeArgs(args), message: errorMessage, duration: Date.now() - startTime });
640
960
  }
961
+ // Preserve structured tool guidance such as next_step.
962
+ // These errors are expected control flow and should be serialized by the outer server wrapper.
963
+ if ((0, tool_result_js_1.isToolPayloadError)(error)) {
964
+ throw error;
965
+ }
641
966
  // In tests, avoid any extra work that may block (envId lookup, issue link generation, etc.)
642
967
  if (isTestEnvironment) {
643
968
  throw error instanceof Error ? error : new Error(String(error));
@@ -784,6 +1109,7 @@ const security_rule_js_1 = __webpack_require__(7862);
784
1109
  const cloud_mode_js_1 = __webpack_require__(9684);
785
1110
  const logger_js_1 = __webpack_require__(3039);
786
1111
  const tencet_cloud_js_1 = __webpack_require__(5018);
1112
+ const tool_result_js_1 = __webpack_require__(9835);
787
1113
  const tool_wrapper_js_1 = __webpack_require__(1363);
788
1114
  // 默认插件列表
789
1115
  const DEFAULT_PLUGINS = [
@@ -898,6 +1224,18 @@ async function createCloudBaseMcpServer(options) {
898
1224
  ...(ide === "CodeBuddy" ? { logging: {} } : {}),
899
1225
  },
900
1226
  });
1227
+ const originalRegisterTool = server.registerTool.bind(server);
1228
+ server.registerTool = ((name, meta, handler) => originalRegisterTool(name, meta, async (args) => {
1229
+ try {
1230
+ return await handler(args);
1231
+ }
1232
+ catch (error) {
1233
+ if ((0, tool_result_js_1.isToolPayloadError)(error)) {
1234
+ return (0, tool_result_js_1.buildJsonToolResult)(error.payload);
1235
+ }
1236
+ throw error;
1237
+ }
1238
+ }));
901
1239
  // Only set logging handler if logging capability is declared
902
1240
  if (ide === "CodeBuddy") {
903
1241
  server.server.setRequestHandler(types_js_1.SetLevelRequestSchema, (request, extra) => {
@@ -4087,6 +4425,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4087
4425
  };
4088
4426
  Object.defineProperty(exports, "__esModule", ({ value: true }));
4089
4427
  exports.envManager = void 0;
4428
+ exports.listAvailableEnvCandidates = listAvailableEnvCandidates;
4090
4429
  exports.getEnvId = getEnvId;
4091
4430
  exports.resetCloudBaseManagerCache = resetCloudBaseManagerCache;
4092
4431
  exports.getCachedEnvId = getCachedEnvId;
@@ -4096,9 +4435,134 @@ exports.extractRequestId = extractRequestId;
4096
4435
  exports.logCloudBaseResult = logCloudBaseResult;
4097
4436
  const manager_node_1 = __importDefault(__webpack_require__(6665));
4098
4437
  const auth_js_1 = __webpack_require__(7291);
4099
- const interactive_js_1 = __webpack_require__(3461);
4100
4438
  const logger_js_1 = __webpack_require__(3039);
4101
- const ENV_ID_TIMEOUT = 600000; // 10 minutes (600 seconds) - matches InteractiveServer timeout
4439
+ const tool_result_js_1 = __webpack_require__(9835);
4440
+ // Timeout for envId auto-resolution flow.
4441
+ // 10 minutes (600 seconds) - matches InteractiveServer timeout
4442
+ const ENV_ID_TIMEOUT = 600000;
4443
+ function toEnvCandidates(envList) {
4444
+ if (!Array.isArray(envList)) {
4445
+ return [];
4446
+ }
4447
+ return envList
4448
+ .filter((item) => item?.EnvId)
4449
+ .map((item) => ({
4450
+ envId: item.EnvId,
4451
+ alias: item.Alias,
4452
+ region: item.Region,
4453
+ status: item.Status,
4454
+ env_type: item.EnvType,
4455
+ }));
4456
+ }
4457
+ function createManagerFromLoginState(loginState, region) {
4458
+ return new manager_node_1.default({
4459
+ secretId: loginState.secretId,
4460
+ secretKey: loginState.secretKey,
4461
+ envId: loginState.envId,
4462
+ token: loginState.token,
4463
+ proxy: process.env.http_proxy,
4464
+ region,
4465
+ });
4466
+ }
4467
+ async function listAvailableEnvCandidates(options) {
4468
+ const { cloudBaseOptions, loginState: providedLoginState } = options ?? {};
4469
+ if (cloudBaseOptions?.envId) {
4470
+ return [{
4471
+ envId: cloudBaseOptions.envId,
4472
+ }];
4473
+ }
4474
+ let cloudbase;
4475
+ if (cloudBaseOptions?.secretId && cloudBaseOptions?.secretKey) {
4476
+ cloudbase = createCloudBaseManagerWithOptions(cloudBaseOptions);
4477
+ }
4478
+ else {
4479
+ const loginState = providedLoginState ?? await (0, auth_js_1.peekLoginState)();
4480
+ if (!loginState?.secretId || !loginState?.secretKey) {
4481
+ return [];
4482
+ }
4483
+ const region = cloudBaseOptions?.region ?? process.env.TCB_REGION ?? undefined;
4484
+ cloudbase = createManagerFromLoginState(loginState, region);
4485
+ }
4486
+ try {
4487
+ const result = await cloudbase.commonService("tcb", "2018-06-08").call({
4488
+ Action: "DescribeEnvs",
4489
+ Param: {
4490
+ EnvTypes: ["weda", "baas"],
4491
+ IsVisible: false,
4492
+ Channels: ["dcloud", "iotenable", "tem", "scene_module"],
4493
+ },
4494
+ });
4495
+ const envList = result?.EnvList || result?.Data?.EnvList || [];
4496
+ return toEnvCandidates(envList);
4497
+ }
4498
+ catch {
4499
+ try {
4500
+ const fallback = await cloudbase.env.listEnvs();
4501
+ return toEnvCandidates(fallback?.EnvList || []);
4502
+ }
4503
+ catch {
4504
+ return [];
4505
+ }
4506
+ }
4507
+ }
4508
+ function throwAuthRequiredError() {
4509
+ (0, tool_result_js_1.throwToolPayloadError)({
4510
+ ok: false,
4511
+ code: "AUTH_REQUIRED",
4512
+ message: "当前未登录,请先调用 auth 工具完成认证。",
4513
+ next_step: (0, tool_result_js_1.buildAuthNextStep)("start_auth", {
4514
+ suggestedArgs: {
4515
+ action: "start_auth",
4516
+ authMode: "device",
4517
+ },
4518
+ }),
4519
+ });
4520
+ }
4521
+ async function throwPendingAuthError() {
4522
+ const authState = await (0, auth_js_1.getAuthProgressState)();
4523
+ (0, tool_result_js_1.throwToolPayloadError)({
4524
+ ok: false,
4525
+ code: "AUTH_PENDING",
4526
+ message: authState.lastError || "设备码授权进行中,请先完成登录后再重试当前工具。",
4527
+ auth_challenge: authState.authChallenge
4528
+ ? {
4529
+ user_code: authState.authChallenge.user_code,
4530
+ verification_uri: authState.authChallenge.verification_uri,
4531
+ expires_in: authState.authChallenge.expires_in,
4532
+ }
4533
+ : undefined,
4534
+ next_step: (0, tool_result_js_1.buildAuthNextStep)("status", {
4535
+ suggestedArgs: {
4536
+ action: "status",
4537
+ },
4538
+ }),
4539
+ });
4540
+ }
4541
+ async function throwEnvRequiredError(options) {
4542
+ const envCandidates = options?.envCandidates ?? (await listAvailableEnvCandidates(options));
4543
+ const singleEnvId = envCandidates.length === 1 ? envCandidates[0].envId : undefined;
4544
+ (0, tool_result_js_1.throwToolPayloadError)({
4545
+ ok: false,
4546
+ code: "ENV_REQUIRED",
4547
+ message: envCandidates.length === 0
4548
+ ? "当前已登录,但还没有可用环境,请先调用 auth 工具完成环境选择或创建环境。"
4549
+ : envCandidates.length === 1
4550
+ ? `当前已登录,但尚未绑定环境。可直接选择环境 ${singleEnvId}。`
4551
+ : "当前已登录,但尚未绑定环境,请先调用 auth 工具选择环境。",
4552
+ env_candidates: envCandidates,
4553
+ next_step: (0, tool_result_js_1.buildAuthNextStep)("set_env", {
4554
+ requiredParams: singleEnvId ? undefined : ["envId"],
4555
+ suggestedArgs: singleEnvId
4556
+ ? {
4557
+ action: "set_env",
4558
+ envId: singleEnvId,
4559
+ }
4560
+ : {
4561
+ action: "set_env",
4562
+ },
4563
+ }),
4564
+ });
4565
+ }
4102
4566
  // 统一的环境ID管理类
4103
4567
  class EnvironmentManager {
4104
4568
  cachedEnvId = null;
@@ -4110,7 +4574,7 @@ class EnvironmentManager {
4110
4574
  delete process.env.CLOUDBASE_ENV_ID;
4111
4575
  }
4112
4576
  // 获取环境ID的核心逻辑
4113
- async getEnvId(mcpServer) {
4577
+ async getEnvId() {
4114
4578
  // 1. 优先使用内存缓存
4115
4579
  if (this.cachedEnvId) {
4116
4580
  (0, logger_js_1.debug)('使用内存缓存的环境ID:', { envId: this.cachedEnvId });
@@ -4120,17 +4584,10 @@ class EnvironmentManager {
4120
4584
  if (this.envIdPromise) {
4121
4585
  return this.envIdPromise;
4122
4586
  }
4123
- // 3. 开始获取环境ID (pass mcpServer for IDE detection)
4124
- this.envIdPromise = this._fetchEnvId(mcpServer);
4125
- // 增加超时保护
4126
- const timeoutPromise = new Promise((_, reject) => {
4127
- const id = setTimeout(() => {
4128
- clearTimeout(id);
4129
- reject(new Error(`EnvId 获取超时(${ENV_ID_TIMEOUT / 1000}秒)`));
4130
- }, ENV_ID_TIMEOUT);
4131
- });
4587
+ // 3. 开始获取环境ID
4588
+ this.envIdPromise = this._fetchEnvId();
4132
4589
  try {
4133
- const result = await Promise.race([this.envIdPromise, timeoutPromise]);
4590
+ const result = await this.envIdPromise;
4134
4591
  return result;
4135
4592
  }
4136
4593
  catch (err) {
@@ -4138,7 +4595,7 @@ class EnvironmentManager {
4138
4595
  throw err;
4139
4596
  }
4140
4597
  }
4141
- async _fetchEnvId(mcpServer) {
4598
+ async _fetchEnvId() {
4142
4599
  try {
4143
4600
  // 1. 检查进程环境变量
4144
4601
  if (process.env.CLOUDBASE_ENV_ID) {
@@ -4146,48 +4603,23 @@ class EnvironmentManager {
4146
4603
  this.cachedEnvId = process.env.CLOUDBASE_ENV_ID;
4147
4604
  return this.cachedEnvId;
4148
4605
  }
4149
- // 2. 自动设置环境ID (pass mcpServer for IDE detection)
4150
- (0, logger_js_1.debug)('未找到环境ID,尝试自动设置...');
4151
- let setupResult;
4152
- try {
4153
- setupResult = await (0, interactive_js_1._promptAndSetEnvironmentId)(true, { server: mcpServer });
4154
- }
4155
- catch (setupError) {
4156
- // Preserve original error information
4157
- const errorObj = setupError instanceof Error ? setupError : new Error(String(setupError));
4158
- (0, logger_js_1.error)('自动设置环境ID时发生异常:', {
4159
- error: errorObj.message,
4160
- stack: errorObj.stack,
4161
- name: errorObj.name,
4162
- });
4163
- // Re-throw with enhanced context
4164
- const enhancedError = new Error(`自动设置环境ID失败: ${errorObj.message}`);
4165
- enhancedError.originalError = errorObj;
4166
- enhancedError.failureInfo = {
4167
- reason: 'unknown_error',
4168
- error: errorObj.message,
4169
- errorCode: 'SETUP_EXCEPTION',
4170
- };
4171
- throw enhancedError;
4172
- }
4173
- const autoEnvId = setupResult.selectedEnvId;
4174
- if (!autoEnvId) {
4175
- // Build detailed error message from failure info
4176
- const errorMessage = this._buildDetailedErrorMessage(setupResult.failureInfo);
4177
- (0, logger_js_1.error)('自动设置环境ID失败:', {
4178
- reason: setupResult.failureInfo?.reason,
4179
- errorCode: setupResult.failureInfo?.errorCode,
4180
- error: setupResult.failureInfo?.error,
4181
- details: setupResult.failureInfo?.details,
4182
- });
4183
- // Create error with detailed information
4184
- const detailedError = new Error(errorMessage);
4185
- detailedError.failureInfo = setupResult.failureInfo;
4186
- throw detailedError;
4606
+ // 2. 如果登录态里已有 envId,直接复用
4607
+ const loginState = await (0, auth_js_1.peekLoginState)();
4608
+ if (typeof loginState?.envId === 'string' && loginState.envId.length > 0) {
4609
+ (0, logger_js_1.debug)('使用登录态中的环境ID:', { envId: loginState.envId });
4610
+ this._setCachedEnvId(loginState.envId);
4611
+ return loginState.envId;
4612
+ }
4613
+ // 3. 单环境自动绑定;多环境时返回结构化引导,不再触发交互弹窗
4614
+ const envCandidates = await listAvailableEnvCandidates({ loginState });
4615
+ if (envCandidates.length === 1) {
4616
+ const singleEnvId = envCandidates[0].envId;
4617
+ (0, logger_js_1.debug)('自动绑定唯一环境:', { envId: singleEnvId });
4618
+ this._setCachedEnvId(singleEnvId);
4619
+ return singleEnvId;
4187
4620
  }
4188
- (0, logger_js_1.debug)('自动设置环境ID成功:', { envId: autoEnvId });
4189
- this._setCachedEnvId(autoEnvId);
4190
- return autoEnvId;
4621
+ await throwEnvRequiredError({ loginState, envCandidates });
4622
+ throw new Error('Unreachable after throwEnvRequiredError');
4191
4623
  }
4192
4624
  catch (err) {
4193
4625
  // Log the error with full context before re-throwing
@@ -4211,65 +4643,6 @@ class EnvironmentManager {
4211
4643
  process.env.CLOUDBASE_ENV_ID = envId;
4212
4644
  (0, logger_js_1.debug)('已更新环境ID缓存:', { envId });
4213
4645
  }
4214
- // Build detailed error message from failure info
4215
- _buildDetailedErrorMessage(failureInfo) {
4216
- if (!failureInfo) {
4217
- return "CloudBase Environment ID not found after auto setup. Please set CLOUDBASE_ENV_ID or run setupEnvironmentId tool.";
4218
- }
4219
- const { reason, error: errorMsg, errorCode, helpUrl, details } = failureInfo;
4220
- let message = "CloudBase Environment ID not found after auto setup.\n\n";
4221
- message += `原因: ${this._getReasonDescription(reason)}\n`;
4222
- if (errorMsg) {
4223
- message += `错误: ${errorMsg}\n`;
4224
- }
4225
- if (errorCode) {
4226
- message += `错误代码: ${errorCode}\n`;
4227
- }
4228
- // Add specific details based on failure reason
4229
- if (reason === 'tcb_init_failed' && details?.initTcbError) {
4230
- const initError = details.initTcbError;
4231
- if (initError.needRealNameAuth) {
4232
- message += "\n需要完成实名认证才能使用 CloudBase 服务。\n";
4233
- }
4234
- if (initError.needCamAuth) {
4235
- message += "\n需要 CAM 权限才能使用 CloudBase 服务。\n";
4236
- }
4237
- }
4238
- if (reason === 'env_creation_failed' && details?.createEnvError) {
4239
- const createError = details.createEnvError;
4240
- message += `\n环境创建失败: ${createError.message || '未知错误'}\n`;
4241
- }
4242
- if (reason === 'env_query_failed' && details?.queryEnvError) {
4243
- message += `\n环境查询失败: ${details.queryEnvError}\n`;
4244
- }
4245
- if (reason === 'timeout' && details?.timeoutDuration) {
4246
- message += `\n超时时间: ${details.timeoutDuration / 1000} 秒\n`;
4247
- message += "提示: 请确保浏览器窗口已打开,并在规定时间内完成环境选择。\n";
4248
- }
4249
- message += "\n解决方案:\n";
4250
- message += "1. 手动设置环境ID: 设置环境变量 CLOUDBASE_ENV_ID\n";
4251
- message += "2. 使用工具设置: 运行 setupEnvironmentId 工具\n";
4252
- if (helpUrl) {
4253
- message += `3. 查看帮助文档: ${helpUrl}\n`;
4254
- }
4255
- else {
4256
- message += "3. 查看帮助文档: https://docs.cloudbase.net/cli-v1/env\n";
4257
- }
4258
- return message;
4259
- }
4260
- _getReasonDescription(reason) {
4261
- const descriptions = {
4262
- 'timeout': '环境选择超时',
4263
- 'cancelled': '用户取消了环境选择',
4264
- 'no_environments': '没有可用环境',
4265
- 'login_failed': '登录失败',
4266
- 'tcb_init_failed': 'CloudBase 服务初始化失败',
4267
- 'env_query_failed': '环境列表查询失败',
4268
- 'env_creation_failed': '环境创建失败',
4269
- 'unknown_error': '未知错误',
4270
- };
4271
- return descriptions[reason] || '未知原因';
4272
- }
4273
4646
  // 手动设置环境ID(用于外部调用)
4274
4647
  async setEnvId(envId) {
4275
4648
  this._setCachedEnvId(envId);
@@ -4290,6 +4663,16 @@ async function getEnvId(cloudBaseOptions) {
4290
4663
  (0, logger_js_1.debug)('使用传入的 envId:', { envId: cloudBaseOptions.envId });
4291
4664
  return cloudBaseOptions.envId;
4292
4665
  }
4666
+ const cachedEnvId = envManager.getCachedEnvId() || process.env.CLOUDBASE_ENV_ID;
4667
+ if (cachedEnvId) {
4668
+ (0, logger_js_1.debug)('使用缓存中的 envId:', { envId: cachedEnvId });
4669
+ return cachedEnvId;
4670
+ }
4671
+ const loginState = await (0, auth_js_1.peekLoginState)();
4672
+ if (typeof loginState?.envId === 'string' && loginState.envId.length > 0) {
4673
+ (0, logger_js_1.debug)('使用登录态中的 envId:', { envId: loginState.envId });
4674
+ return loginState.envId;
4675
+ }
4293
4676
  // 否则使用默认逻辑
4294
4677
  return envManager.getEnvId();
4295
4678
  }
@@ -4305,37 +4688,89 @@ function getCachedEnvId() {
4305
4688
  * 每次都实时获取最新的 token/secretId/secretKey
4306
4689
  */
4307
4690
  async function getCloudBaseManager(options = {}) {
4308
- const { requireEnvId = true, cloudBaseOptions, mcpServer } = options;
4309
- // 如果传入了 cloudBaseOptions,直接使用传入的配置
4310
- if (cloudBaseOptions) {
4691
+ const { requireEnvId = true, cloudBaseOptions, authStrategy = 'fail_fast', } = options;
4692
+ const hasDirectCredentials = !!(cloudBaseOptions?.secretId && cloudBaseOptions?.secretKey);
4693
+ // 如果传入了完整凭据,优先使用显式 CloudBase 配置
4694
+ if (cloudBaseOptions && hasDirectCredentials) {
4695
+ let resolvedEnvId = cloudBaseOptions.envId;
4696
+ if (requireEnvId && !resolvedEnvId) {
4697
+ const envCandidates = await listAvailableEnvCandidates({ cloudBaseOptions });
4698
+ if (envCandidates.length === 1) {
4699
+ const singleEnvId = envCandidates[0].envId;
4700
+ cloudBaseOptions.envId = singleEnvId;
4701
+ resolvedEnvId = singleEnvId;
4702
+ (0, logger_js_1.debug)('自动绑定唯一环境(显式配置):', { envId: singleEnvId });
4703
+ }
4704
+ else if (authStrategy === 'fail_fast') {
4705
+ await throwEnvRequiredError({ cloudBaseOptions, envCandidates });
4706
+ }
4707
+ else {
4708
+ (0, tool_result_js_1.throwToolPayloadError)({
4709
+ ok: false,
4710
+ code: "ENV_REQUIRED",
4711
+ message: "当前显式 CloudBase 凭据未绑定环境,请补充 envId 或先选择环境。",
4712
+ env_candidates: envCandidates,
4713
+ next_step: (0, tool_result_js_1.buildAuthNextStep)("set_env", {
4714
+ suggestedArgs: { action: "set_env" },
4715
+ requiredParams: ["envId"],
4716
+ }),
4717
+ });
4718
+ }
4719
+ }
4311
4720
  (0, logger_js_1.debug)('使用传入的 CloudBase 配置');
4312
- return createCloudBaseManagerWithOptions(cloudBaseOptions);
4721
+ return createCloudBaseManagerWithOptions({
4722
+ ...cloudBaseOptions,
4723
+ envId: resolvedEnvId,
4724
+ });
4313
4725
  }
4314
4726
  try {
4315
4727
  // Get region from environment variable for auth URL
4316
- // Note: At this point, cloudBaseOptions is undefined (checked above), so only use env var
4317
- const region = process.env.TCB_REGION;
4318
- const loginState = await (0, auth_js_1.getLoginState)({ region });
4728
+ const region = cloudBaseOptions?.region ?? process.env.TCB_REGION;
4729
+ const loginState = authStrategy === 'ensure'
4730
+ ? await (0, auth_js_1.getLoginState)({ region })
4731
+ : await (0, auth_js_1.peekLoginState)();
4732
+ if (!loginState) {
4733
+ const authState = await (0, auth_js_1.getAuthProgressState)();
4734
+ if (authState.status === 'PENDING') {
4735
+ await throwPendingAuthError();
4736
+ }
4737
+ throwAuthRequiredError();
4738
+ }
4319
4739
  const { envId: loginEnvId, secretId, secretKey, token } = loginState;
4320
- let finalEnvId;
4740
+ let finalEnvId = cloudBaseOptions?.envId;
4321
4741
  if (requireEnvId) {
4322
- // Optimize: Check if envManager has cached envId first (fast path)
4323
- // If cached, use it directly; otherwise check loginEnvId before calling getEnvId()
4324
- // This avoids unnecessary async calls when we have a valid envId available
4325
- const cachedEnvId = envManager.getCachedEnvId();
4326
- if (cachedEnvId) {
4327
- (0, logger_js_1.debug)('使用 envManager 缓存的环境ID:', { cachedEnvId });
4328
- finalEnvId = cachedEnvId;
4329
- }
4330
- else if (loginEnvId) {
4331
- // If no cache but loginState has envId, use it to avoid triggering auto-setup
4332
- (0, logger_js_1.debug)('使用 loginState 中的环境ID:', { loginEnvId });
4333
- finalEnvId = loginEnvId;
4334
- }
4335
- else {
4336
- // Only call envManager.getEnvId() when neither cache nor loginState has envId
4337
- // This may trigger auto-setup flow (pass mcpServer for IDE detection)
4338
- finalEnvId = await envManager.getEnvId(mcpServer);
4742
+ if (!finalEnvId) {
4743
+ // Optimize: Check if envManager has cached envId first (fast path)
4744
+ // If cached, use it directly; otherwise check loginEnvId before calling getEnvId()
4745
+ // This avoids unnecessary async calls when we have a valid envId available
4746
+ const cachedEnvId = envManager.getCachedEnvId() || process.env.CLOUDBASE_ENV_ID;
4747
+ if (cachedEnvId) {
4748
+ (0, logger_js_1.debug)('使用 envManager 缓存的环境ID:', { cachedEnvId });
4749
+ finalEnvId = cachedEnvId;
4750
+ }
4751
+ else if (loginEnvId) {
4752
+ // If no cache but loginState has envId, use it directly
4753
+ (0, logger_js_1.debug)('使用 loginState 中的环境ID:', { loginEnvId });
4754
+ finalEnvId = loginEnvId;
4755
+ }
4756
+ else {
4757
+ if (authStrategy === 'fail_fast') {
4758
+ const envCandidates = await listAvailableEnvCandidates({ loginState });
4759
+ if (envCandidates.length === 1) {
4760
+ const singleEnvId = envCandidates[0].envId;
4761
+ await envManager.setEnvId(singleEnvId);
4762
+ finalEnvId = singleEnvId;
4763
+ (0, logger_js_1.debug)('自动绑定唯一环境:', { envId: singleEnvId });
4764
+ }
4765
+ else {
4766
+ await throwEnvRequiredError({ loginState, envCandidates });
4767
+ }
4768
+ }
4769
+ else {
4770
+ // ensure 模式下也保持非交互:单环境自动绑定,多环境返回 ENV_REQUIRED
4771
+ finalEnvId = await envManager.getEnvId();
4772
+ }
4773
+ }
4339
4774
  }
4340
4775
  }
4341
4776
  // envId priority: envManager.cachedEnvId > envManager.getEnvId() > loginState.envId > undefined
@@ -4572,6 +5007,7 @@ async function _promptAndSetEnvironmentId(autoSelectSingle, options) {
4572
5007
  hasServerServer: !!server?.server,
4573
5008
  hasServerIde: !!server?.ide,
4574
5009
  ignoreEnvVars: options?.ignoreEnvVars,
5010
+ authMode: options?.authMode,
4575
5011
  optionsKeys: options ? Object.keys(options).join(', ') : 'null',
4576
5012
  });
4577
5013
  if (!server) {
@@ -4588,6 +5024,9 @@ async function _promptAndSetEnvironmentId(autoSelectSingle, options) {
4588
5024
  fromCloudBaseLoginPage: options?.loginFromCloudBaseLoginPage,
4589
5025
  ignoreEnvVars: options?.ignoreEnvVars,
4590
5026
  region,
5027
+ authMode: options?.authMode,
5028
+ clientId: options?.clientId,
5029
+ onDeviceCode: options?.onDeviceCode,
4591
5030
  });
4592
5031
  (0, logger_js_1.debug)("[interactive] Login state:", {
4593
5032
  hasLoginState: !!loginState,
@@ -7299,6 +7738,15 @@ async function registerRagTools(server) {
7299
7738
  ],
7300
7739
  };
7301
7740
  }
7741
+ // 向量检索模式下必须提供 id 和 content,避免后端报「知识库名称不能为空」
7742
+ if (mode === "vector") {
7743
+ if (!id) {
7744
+ throw new Error("知识库名称不能为空: please provide `id` when mode=vector (cloudbase / scf / miniprogram).");
7745
+ }
7746
+ if (!content || !content.trim()) {
7747
+ throw new Error("检索内容不能为空: please provide non-empty `content` when mode=vector.");
7748
+ }
7749
+ }
7302
7750
  // 枚举到后端 id 映射
7303
7751
  const backendId = KnowledgeBaseIdMap[id] || id;
7304
7752
  const signInRes = await fetch("https://tcb-advanced-a656fc.api.tcloudbasegateway.com/auth/v1/signin/anonymously", {
@@ -8703,7 +9151,7 @@ class TelemetryReporter {
8703
9151
  const nodeVersion = process.version; // Node.js版本
8704
9152
  const arch = os_1.default.arch(); // 系统架构
8705
9153
  // 从构建时注入的版本号获取MCP版本信息
8706
- const mcpVersion = process.env.npm_package_version || "2.13.0" || 0;
9154
+ const mcpVersion = process.env.npm_package_version || "2.14.2" || 0;
8707
9155
  return {
8708
9156
  userAgent: `${osType} ${osRelease} ${arch} ${nodeVersion} CloudBase-MCP/${mcpVersion}`,
8709
9157
  deviceId: this.deviceId,
@@ -9015,23 +9463,71 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
9015
9463
  return (mod && mod.__esModule) ? mod : { "default": mod };
9016
9464
  };
9017
9465
  Object.defineProperty(exports, "__esModule", ({ value: true }));
9018
- exports.TRIGGER_CONFIG_EXAMPLES = exports.SUPPORTED_TRIGGER_TYPES = exports.DEFAULT_NODEJS_RUNTIME = exports.SUPPORTED_NODEJS_RUNTIMES = void 0;
9466
+ exports.WRITE_FUNCTION_LAYER_ACTIONS = exports.READ_FUNCTION_LAYER_ACTIONS = exports.TRIGGER_CONFIG_EXAMPLES = exports.SUPPORTED_TRIGGER_TYPES = exports.DEFAULT_NODEJS_RUNTIME = exports.SUPPORTED_NODEJS_RUNTIMES = exports.RECOMMENDED_RUNTIMES = exports.DEFAULT_RUNTIME = exports.ALL_SUPPORTED_RUNTIMES = exports.SUPPORTED_RUNTIMES = void 0;
9467
+ exports.formatRuntimeList = formatRuntimeList;
9019
9468
  exports.registerFunctionTools = registerFunctionTools;
9020
9469
  const zod_1 = __webpack_require__(2971);
9021
9470
  const cloudbase_manager_js_1 = __webpack_require__(3431);
9022
9471
  const logger_js_1 = __webpack_require__(3039);
9023
9472
  const path_1 = __importDefault(__webpack_require__(2521));
9024
- // 支持的 Node.js 运行时列表
9025
- exports.SUPPORTED_NODEJS_RUNTIMES = [
9026
- "Nodejs20.19",
9027
- "Nodejs18.15",
9028
- "Nodejs16.13",
9029
- "Nodejs14.18",
9030
- "Nodejs12.16",
9031
- "Nodejs10.15",
9032
- "Nodejs8.9",
9033
- ];
9034
- exports.DEFAULT_NODEJS_RUNTIME = "Nodejs18.15";
9473
+ // 所有支持的运行时环境(按语言分类)
9474
+ exports.SUPPORTED_RUNTIMES = {
9475
+ nodejs: [
9476
+ "Nodejs20.19",
9477
+ "Nodejs18.15",
9478
+ "Nodejs16.13",
9479
+ "Nodejs14.18",
9480
+ "Nodejs12.16",
9481
+ "Nodejs10.15",
9482
+ "Nodejs8.9",
9483
+ ],
9484
+ python: [
9485
+ "Python3.10",
9486
+ "Python3.9",
9487
+ "Python3.7",
9488
+ "Python3.6",
9489
+ "Python2.7",
9490
+ ],
9491
+ php: [
9492
+ "Php8.0",
9493
+ "Php7.4",
9494
+ "Php7.2",
9495
+ ],
9496
+ java: [
9497
+ "Java8",
9498
+ "Java11",
9499
+ ],
9500
+ golang: [
9501
+ "Golang1",
9502
+ ],
9503
+ };
9504
+ // 所有支持的运行时(扁平化数组,用于验证)
9505
+ exports.ALL_SUPPORTED_RUNTIMES = Object.values(exports.SUPPORTED_RUNTIMES).flat();
9506
+ // 默认运行时
9507
+ exports.DEFAULT_RUNTIME = "Nodejs18.15";
9508
+ // 推荐运行时(用于文档和提示)
9509
+ exports.RECOMMENDED_RUNTIMES = {
9510
+ nodejs: "Nodejs18.15",
9511
+ python: "Python3.9",
9512
+ php: "Php7.4",
9513
+ java: "Java11",
9514
+ golang: "Golang1",
9515
+ };
9516
+ // 保留向后兼容
9517
+ exports.SUPPORTED_NODEJS_RUNTIMES = exports.SUPPORTED_RUNTIMES.nodejs;
9518
+ exports.DEFAULT_NODEJS_RUNTIME = exports.DEFAULT_RUNTIME;
9519
+ /**
9520
+ * 格式化运行时列表(按语言分类)
9521
+ * 用于错误提示和用户引导
9522
+ */
9523
+ function formatRuntimeList() {
9524
+ return Object.entries(exports.SUPPORTED_RUNTIMES)
9525
+ .map(([lang, runtimes]) => {
9526
+ const capitalizedLang = lang.charAt(0).toUpperCase() + lang.slice(1);
9527
+ return ` ${capitalizedLang}: ${runtimes.join(', ')}`;
9528
+ })
9529
+ .join('\n');
9530
+ }
9035
9531
  // Supported trigger types
9036
9532
  exports.SUPPORTED_TRIGGER_TYPES = [
9037
9533
  "timer", // Timer trigger
@@ -9048,6 +9544,41 @@ exports.TRIGGER_CONFIG_EXAMPLES = {
9048
9544
  ],
9049
9545
  },
9050
9546
  };
9547
+ exports.READ_FUNCTION_LAYER_ACTIONS = [
9548
+ "listLayers",
9549
+ "listLayerVersions",
9550
+ "getLayerVersion",
9551
+ "getFunctionLayers",
9552
+ ];
9553
+ exports.WRITE_FUNCTION_LAYER_ACTIONS = [
9554
+ "createLayerVersion",
9555
+ "deleteLayerVersion",
9556
+ "attachLayer",
9557
+ "detachLayer",
9558
+ "updateFunctionLayers",
9559
+ ];
9560
+ function jsonContent(body) {
9561
+ return {
9562
+ content: [
9563
+ {
9564
+ type: "text",
9565
+ text: JSON.stringify(body, null, 2),
9566
+ },
9567
+ ],
9568
+ };
9569
+ }
9570
+ function normalizeFunctionLayers(layers) {
9571
+ if (!Array.isArray(layers)) {
9572
+ return [];
9573
+ }
9574
+ return layers
9575
+ .filter((layer) => Boolean(layer))
9576
+ .map((layer) => ({
9577
+ LayerName: String(layer.LayerName ?? ""),
9578
+ LayerVersion: Number(layer.LayerVersion ?? 0),
9579
+ }))
9580
+ .filter((layer) => Boolean(layer.LayerName) && Number.isFinite(layer.LayerVersion));
9581
+ }
9051
9582
  /**
9052
9583
  * 处理函数根目录路径,确保不包含函数名
9053
9584
  * @param functionRootPath 用户输入的路径
@@ -9075,12 +9606,12 @@ function registerFunctionTools(server) {
9075
9606
  // getFunctionList - 获取云函数列表或详情(推荐)
9076
9607
  server.registerTool?.("getFunctionList", {
9077
9608
  title: "查询云函数列表或详情",
9078
- description: "获取云函数列表或单个函数详情。通过 action 参数区分操作类型:list=获取函数列表(默认,无需额外参数),detail=获取函数详情(需要提供 name 参数指定函数名称)",
9609
+ description: "获取云函数列表或单个函数详情。通过 action 参数区分操作类型:list=获取函数列表(默认,无需额外参数),detail=获取函数详情(需要提供 name 参数指定函数名称,返回结果中包含函数当前绑定的 Layers 信息)",
9079
9610
  inputSchema: {
9080
9611
  action: zod_1.z
9081
9612
  .enum(["list", "detail"])
9082
9613
  .optional()
9083
- .describe("操作类型:list=获取函数列表(默认,无需额外参数),detail=获取函数详情(需要提供 name 参数)"),
9614
+ .describe("操作类型:list=获取函数列表(默认,无需额外参数),detail=获取函数详情(需要提供 name 参数,返回结果中包含当前绑定的 Layers)"),
9084
9615
  limit: zod_1.z.number().optional().describe("范围(list 操作时使用)"),
9085
9616
  offset: zod_1.z.number().optional().describe("偏移(list 操作时使用)"),
9086
9617
  name: zod_1.z
@@ -9134,7 +9665,11 @@ function registerFunctionTools(server) {
9134
9665
  // createFunction - 创建云函数 (cloud-incompatible)
9135
9666
  server.registerTool("createFunction", {
9136
9667
  title: "创建云函数",
9137
- description: "创建云函数。云函数分为事件型云函数和 HTTP 云函数,请确认你要创建的函数类型。",
9668
+ description: "创建云函数。云函数分为事件型云函数(Event)和 HTTP 云函数。\n\n" +
9669
+ "支持的运行时:\n" +
9670
+ "- Event 函数: Node.js, Python, PHP, Java, Go\n" +
9671
+ "- HTTP 函数: 所有语言(通过 scf_bootstrap 启动脚本)\n\n" +
9672
+ "注意: 运行时创建后不可修改,请谨慎选择。",
9138
9673
  inputSchema: {
9139
9674
  func: zod_1.z
9140
9675
  .object({
@@ -9177,8 +9712,18 @@ function registerFunctionTools(server) {
9177
9712
  runtime: zod_1.z
9178
9713
  .string()
9179
9714
  .optional()
9180
- .describe("运行时环境,建议指定为 'Nodejs18.15',其他可选值:" +
9181
- exports.SUPPORTED_NODEJS_RUNTIMES.join("")),
9715
+ .describe("运行时环境。Event 函数支持多种运行时:\n" +
9716
+ formatRuntimeList() + "\n\n" +
9717
+ "推荐运行时:\n" +
9718
+ ` Node.js: ${exports.RECOMMENDED_RUNTIMES.nodejs}\n` +
9719
+ ` Python: ${exports.RECOMMENDED_RUNTIMES.python}\n` +
9720
+ ` PHP: ${exports.RECOMMENDED_RUNTIMES.php}\n` +
9721
+ ` Java: ${exports.RECOMMENDED_RUNTIMES.java}\n` +
9722
+ ` Go: ${exports.RECOMMENDED_RUNTIMES.golang}\n\n` +
9723
+ "注意:\n" +
9724
+ "- HTTP 函数已支持所有语言(通过 scf_bootstrap 启动脚本)\n" +
9725
+ "- Node.js 函数会自动安装依赖\n" +
9726
+ "- Python/PHP/Java/Go 函数需要预先打包依赖到函数目录"),
9182
9727
  triggers: zod_1.z
9183
9728
  .array(zod_1.z.object({
9184
9729
  name: zod_1.z.string().describe("Trigger name"),
@@ -9226,12 +9771,14 @@ function registerFunctionTools(server) {
9226
9771
  if (!isHttpFunction) {
9227
9772
  // 自动填充默认 runtime
9228
9773
  if (!func.runtime) {
9229
- func.runtime = exports.DEFAULT_NODEJS_RUNTIME;
9774
+ func.runtime = exports.DEFAULT_RUNTIME;
9775
+ console.log(`未指定 runtime,使用默认值: ${exports.DEFAULT_RUNTIME}\n` +
9776
+ `可选运行时:\n${formatRuntimeList()}`);
9230
9777
  }
9231
9778
  else {
9232
9779
  // 验证 runtime 格式,防止常见的空格问题
9233
9780
  const normalizedRuntime = func.runtime.replace(/\s+/g, "");
9234
- if (exports.SUPPORTED_NODEJS_RUNTIMES.includes(normalizedRuntime)) {
9781
+ if (exports.ALL_SUPPORTED_RUNTIMES.includes(normalizedRuntime)) {
9235
9782
  func.runtime = normalizedRuntime;
9236
9783
  }
9237
9784
  else if (func.runtime.includes(" ")) {
@@ -9240,8 +9787,13 @@ function registerFunctionTools(server) {
9240
9787
  }
9241
9788
  }
9242
9789
  // 验证 runtime 是否有效
9243
- if (!exports.SUPPORTED_NODEJS_RUNTIMES.includes(func.runtime)) {
9244
- throw new Error(`不支持的运行时环境: "${func.runtime}"。支持的值:${exports.SUPPORTED_NODEJS_RUNTIMES.join(", ")}`);
9790
+ if (!exports.ALL_SUPPORTED_RUNTIMES.includes(func.runtime)) {
9791
+ throw new Error(`不支持的运行时环境: "${func.runtime}"\n\n` +
9792
+ `支持的运行时:\n${formatRuntimeList()}\n\n` +
9793
+ `提示:\n` +
9794
+ `- Node.js 函数会自动安装依赖\n` +
9795
+ `- Python/PHP/Java/Go 函数需要预先打包依赖到函数目录\n` +
9796
+ `- 详细信息请参考文档: https://docs.cloudbase.net/api-reference/manager/node/function#createfunction`);
9245
9797
  }
9246
9798
  }
9247
9799
  // 强制设置 installDependency 为 true(不暴露给AI)
@@ -9594,6 +10146,379 @@ function registerFunctionTools(server) {
9594
10146
  throw new Error(`不支持的操作类型: ${action}`);
9595
10147
  }
9596
10148
  });
10149
+ server.registerTool?.("readFunctionLayers", {
10150
+ title: "查询云函数层信息",
10151
+ description: "查询云函数层及函数层配置。通过 action 区分操作:listLayers=查询层列表,listLayerVersions=查询指定层的版本列表,getLayerVersion=查询层版本详情(含下载地址/元信息),getFunctionLayers=查询指定函数当前绑定的层。返回格式:JSON 包含 success、data(含 action 与对应结果字段)、message;data.layers 或 data.layerVersions 为数组,getFunctionLayers 的 data.layers 每项为 { LayerName, LayerVersion }。",
10152
+ inputSchema: {
10153
+ action: zod_1.z
10154
+ .enum(exports.READ_FUNCTION_LAYER_ACTIONS)
10155
+ .describe("操作类型:listLayers=查询层列表,listLayerVersions=查询指定层的版本列表,getLayerVersion=查询层版本详情,getFunctionLayers=查询指定函数当前绑定的层"),
10156
+ name: zod_1.z
10157
+ .string()
10158
+ .optional()
10159
+ .describe("层名称。listLayerVersions 和 getLayerVersion 操作时必填"),
10160
+ version: zod_1.z
10161
+ .number()
10162
+ .optional()
10163
+ .describe("层版本号。getLayerVersion 操作时必填"),
10164
+ runtime: zod_1.z
10165
+ .string()
10166
+ .optional()
10167
+ .describe("运行时筛选。listLayers 操作时可选"),
10168
+ searchKey: zod_1.z
10169
+ .string()
10170
+ .optional()
10171
+ .describe("层名称搜索关键字。listLayers 操作时可选"),
10172
+ offset: zod_1.z.number().optional().describe("分页偏移。listLayers 操作时可选"),
10173
+ limit: zod_1.z.number().optional().describe("分页数量。listLayers 操作时可选"),
10174
+ functionName: zod_1.z
10175
+ .string()
10176
+ .optional()
10177
+ .describe("函数名称。getFunctionLayers 操作时必填"),
10178
+ codeSecret: zod_1.z
10179
+ .string()
10180
+ .optional()
10181
+ .describe("代码保护密钥。getFunctionLayers 操作时可选"),
10182
+ },
10183
+ annotations: {
10184
+ readOnlyHint: true,
10185
+ openWorldHint: true,
10186
+ category: "functions",
10187
+ },
10188
+ }, async ({ action, name, version, runtime, searchKey, offset, limit, functionName, codeSecret, }) => {
10189
+ if (action === "listLayers") {
10190
+ const cloudbase = await getManager();
10191
+ const result = await cloudbase.functions.listLayers({
10192
+ offset,
10193
+ limit,
10194
+ runtime,
10195
+ searchKey,
10196
+ });
10197
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
10198
+ return jsonContent({
10199
+ success: true,
10200
+ data: {
10201
+ action,
10202
+ layers: result.Layers || [],
10203
+ totalCount: result.TotalCount || 0,
10204
+ requestId: result.RequestId,
10205
+ },
10206
+ message: `Successfully retrieved ${result.Layers?.length || 0} layer entries`,
10207
+ nextActions: [
10208
+ { tool: "readFunctionLayers", action: "listLayerVersions", reason: "List versions of a layer" },
10209
+ { tool: "writeFunctionLayers", action: "createLayerVersion", reason: "Create a new layer version" },
10210
+ ],
10211
+ });
10212
+ }
10213
+ if (action === "listLayerVersions") {
10214
+ if (!name) {
10215
+ throw new Error("查询层版本列表时,name 参数是必需的");
10216
+ }
10217
+ const cloudbase = await getManager();
10218
+ const result = await cloudbase.functions.listLayerVersions({ name });
10219
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
10220
+ return jsonContent({
10221
+ success: true,
10222
+ data: {
10223
+ action,
10224
+ name,
10225
+ layerVersions: result.LayerVersions || [],
10226
+ requestId: result.RequestId,
10227
+ },
10228
+ message: `Successfully retrieved ${result.LayerVersions?.length || 0} versions for layer '${name}'`,
10229
+ nextActions: [
10230
+ { tool: "readFunctionLayers", action: "getLayerVersion", reason: "Get version details and download info" },
10231
+ { tool: "writeFunctionLayers", action: "attachLayer", reason: "Bind this layer to a function" },
10232
+ ],
10233
+ });
10234
+ }
10235
+ if (action === "getLayerVersion") {
10236
+ if (!name) {
10237
+ throw new Error("查询层版本详情时,name 参数是必需的");
10238
+ }
10239
+ if (typeof version !== "number") {
10240
+ throw new Error("查询层版本详情时,version 参数是必需的");
10241
+ }
10242
+ const cloudbase = await getManager();
10243
+ const result = await cloudbase.functions.getLayerVersion({
10244
+ name,
10245
+ version,
10246
+ });
10247
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
10248
+ return jsonContent({
10249
+ success: true,
10250
+ data: {
10251
+ action,
10252
+ name,
10253
+ version,
10254
+ layerVersion: result,
10255
+ downloadInfo: {
10256
+ location: result.Location,
10257
+ codeSha256: result.CodeSha256,
10258
+ },
10259
+ requestId: result.RequestId,
10260
+ },
10261
+ message: `Successfully retrieved details for layer '${name}' version ${version}`,
10262
+ nextActions: [
10263
+ { tool: "writeFunctionLayers", action: "attachLayer", reason: "Bind this layer version to a function" },
10264
+ { tool: "writeFunctionLayers", action: "deleteLayerVersion", reason: "Delete this layer version" },
10265
+ ],
10266
+ });
10267
+ }
10268
+ if (!functionName) {
10269
+ throw new Error("查询函数层配置时,functionName 参数是必需的");
10270
+ }
10271
+ const cloudbase = await getManager();
10272
+ const result = await cloudbase.functions.getFunctionDetail(functionName, codeSecret);
10273
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
10274
+ const layers = normalizeFunctionLayers(result.Layers);
10275
+ return jsonContent({
10276
+ success: true,
10277
+ data: {
10278
+ action,
10279
+ functionName,
10280
+ layers,
10281
+ count: layers.length,
10282
+ requestId: result.RequestId,
10283
+ },
10284
+ message: `Successfully retrieved ${layers.length} bound layers for function '${functionName}'`,
10285
+ nextActions: [
10286
+ { tool: "writeFunctionLayers", action: "attachLayer", reason: "Add a layer to this function" },
10287
+ { tool: "writeFunctionLayers", action: "detachLayer", reason: "Remove a layer from this function" },
10288
+ { tool: "writeFunctionLayers", action: "updateFunctionLayers", reason: "Replace or reorder bound layers" },
10289
+ ],
10290
+ });
10291
+ });
10292
+ server.registerTool?.("writeFunctionLayers", {
10293
+ title: "管理云函数层",
10294
+ description: "管理云函数层和函数层绑定。通过 action 区分操作:createLayerVersion=创建层版本,deleteLayerVersion=删除层版本,attachLayer=给函数追加绑定层,detachLayer=解绑函数层,updateFunctionLayers=整体更新函数层数组以调整顺序或批量更新。返回格式:JSON 包含 success、data(含 action 与结果字段,如 layerVersion、layers)、message、nextActions(建议的后续操作)。",
10295
+ inputSchema: {
10296
+ action: zod_1.z
10297
+ .enum(exports.WRITE_FUNCTION_LAYER_ACTIONS)
10298
+ .describe("操作类型:createLayerVersion=创建层版本,deleteLayerVersion=删除层版本,attachLayer=追加绑定层,detachLayer=解绑层,updateFunctionLayers=整体更新函数层数组"),
10299
+ name: zod_1.z
10300
+ .string()
10301
+ .optional()
10302
+ .describe("层名称。createLayerVersion 和 deleteLayerVersion 操作时必填"),
10303
+ version: zod_1.z
10304
+ .number()
10305
+ .optional()
10306
+ .describe("层版本号。deleteLayerVersion 操作时必填"),
10307
+ contentPath: zod_1.z
10308
+ .string()
10309
+ .optional()
10310
+ .describe("层内容路径,可以是目录或 ZIP 文件路径。createLayerVersion 操作时与 base64Content 二选一"),
10311
+ base64Content: zod_1.z
10312
+ .string()
10313
+ .optional()
10314
+ .describe("层内容的 base64 编码。createLayerVersion 操作时与 contentPath 二选一"),
10315
+ runtimes: zod_1.z
10316
+ .array(zod_1.z.string())
10317
+ .optional()
10318
+ .describe("层适用的运行时列表。createLayerVersion 操作时必填"),
10319
+ description: zod_1.z
10320
+ .string()
10321
+ .optional()
10322
+ .describe("层版本描述。createLayerVersion 操作时可选"),
10323
+ licenseInfo: zod_1.z
10324
+ .string()
10325
+ .optional()
10326
+ .describe("许可证信息。createLayerVersion 操作时可选"),
10327
+ functionName: zod_1.z
10328
+ .string()
10329
+ .optional()
10330
+ .describe("函数名称。attachLayer、detachLayer、updateFunctionLayers 操作时必填"),
10331
+ layerName: zod_1.z
10332
+ .string()
10333
+ .optional()
10334
+ .describe("要绑定或解绑的层名称。attachLayer 和 detachLayer 操作时必填"),
10335
+ layerVersion: zod_1.z
10336
+ .number()
10337
+ .optional()
10338
+ .describe("要绑定或解绑的层版本号。attachLayer 和 detachLayer 操作时必填"),
10339
+ layers: zod_1.z
10340
+ .array(zod_1.z.object({
10341
+ LayerName: zod_1.z.string().describe("层名称"),
10342
+ LayerVersion: zod_1.z.number().describe("层版本号"),
10343
+ }))
10344
+ .optional()
10345
+ .describe("目标函数层数组。updateFunctionLayers 操作时必填,顺序即最终顺序"),
10346
+ codeSecret: zod_1.z
10347
+ .string()
10348
+ .optional()
10349
+ .describe("代码保护密钥。attachLayer 和 detachLayer 操作时可选"),
10350
+ },
10351
+ annotations: {
10352
+ readOnlyHint: false,
10353
+ destructiveHint: true,
10354
+ idempotentHint: false,
10355
+ openWorldHint: true,
10356
+ category: "functions",
10357
+ },
10358
+ }, async ({ action, name, version, contentPath, base64Content, runtimes, description, licenseInfo, functionName, layerName, layerVersion, layers, codeSecret, }) => {
10359
+ if (action === "createLayerVersion") {
10360
+ if (!name) {
10361
+ throw new Error("创建层版本时,name 参数是必需的");
10362
+ }
10363
+ if (!runtimes || runtimes.length === 0) {
10364
+ throw new Error("创建层版本时,runtimes 参数是必需的");
10365
+ }
10366
+ if (!contentPath && !base64Content) {
10367
+ throw new Error("创建层版本时,contentPath 和 base64Content 至少需要提供一个");
10368
+ }
10369
+ const cloudbase = await getManager();
10370
+ const result = await cloudbase.functions.createLayer({
10371
+ name,
10372
+ contentPath,
10373
+ base64Content,
10374
+ runtimes,
10375
+ description,
10376
+ licenseInfo,
10377
+ });
10378
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
10379
+ return jsonContent({
10380
+ success: true,
10381
+ data: {
10382
+ action,
10383
+ name,
10384
+ layerVersion: result.LayerVersion,
10385
+ requestId: result.RequestId,
10386
+ },
10387
+ message: `Successfully created a new version for layer '${name}'`,
10388
+ nextActions: [
10389
+ { tool: "readFunctionLayers", action: "listLayerVersions", reason: "List all versions of this layer" },
10390
+ { tool: "writeFunctionLayers", action: "attachLayer", reason: "Bind this version to a function" },
10391
+ ],
10392
+ });
10393
+ }
10394
+ if (action === "deleteLayerVersion") {
10395
+ if (!name) {
10396
+ throw new Error("删除层版本时,name 参数是必需的");
10397
+ }
10398
+ if (typeof version !== "number") {
10399
+ throw new Error("删除层版本时,version 参数是必需的");
10400
+ }
10401
+ const cloudbase = await getManager();
10402
+ const result = await cloudbase.functions.deleteLayerVersion({
10403
+ name,
10404
+ version,
10405
+ });
10406
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
10407
+ return jsonContent({
10408
+ success: true,
10409
+ data: {
10410
+ action,
10411
+ name,
10412
+ version,
10413
+ requestId: result.RequestId,
10414
+ },
10415
+ message: `Successfully deleted layer '${name}' version ${version}`,
10416
+ nextActions: [
10417
+ { tool: "readFunctionLayers", action: "listLayers", reason: "List remaining layers" },
10418
+ ],
10419
+ });
10420
+ }
10421
+ if (action === "attachLayer" ||
10422
+ action === "detachLayer" ||
10423
+ action === "updateFunctionLayers") {
10424
+ if (!functionName) {
10425
+ throw new Error(`${action} 操作时,functionName 参数是必需的`);
10426
+ }
10427
+ }
10428
+ const envId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
10429
+ const cloudbase = await getManager();
10430
+ if (action === "attachLayer") {
10431
+ if (!layerName) {
10432
+ throw new Error("attachLayer 操作时,layerName 参数是必需的");
10433
+ }
10434
+ if (typeof layerVersion !== "number") {
10435
+ throw new Error("attachLayer 操作时,layerVersion 参数是必需的");
10436
+ }
10437
+ const result = await cloudbase.functions.attachLayer({
10438
+ envId,
10439
+ functionName: functionName,
10440
+ layerName,
10441
+ layerVersion,
10442
+ codeSecret,
10443
+ });
10444
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
10445
+ const detail = await cloudbase.functions.getFunctionDetail(functionName, codeSecret);
10446
+ const boundLayers = normalizeFunctionLayers(detail.Layers);
10447
+ return jsonContent({
10448
+ success: true,
10449
+ data: {
10450
+ action,
10451
+ functionName,
10452
+ layers: boundLayers,
10453
+ requestId: result.RequestId,
10454
+ },
10455
+ message: `Successfully attached layer '${layerName}' version ${layerVersion} to function '${functionName}'`,
10456
+ nextActions: [
10457
+ { tool: "readFunctionLayers", action: "getFunctionLayers", reason: "Verify bound layers" },
10458
+ { tool: "writeFunctionLayers", action: "detachLayer", reason: "Remove this layer from function" },
10459
+ ],
10460
+ });
10461
+ }
10462
+ if (action === "detachLayer") {
10463
+ if (!layerName) {
10464
+ throw new Error("detachLayer 操作时,layerName 参数是必需的");
10465
+ }
10466
+ if (typeof layerVersion !== "number") {
10467
+ throw new Error("detachLayer 操作时,layerVersion 参数是必需的");
10468
+ }
10469
+ const result = await cloudbase.functions.unAttachLayer({
10470
+ envId,
10471
+ functionName: functionName,
10472
+ layerName,
10473
+ layerVersion,
10474
+ codeSecret,
10475
+ });
10476
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
10477
+ const detail = await cloudbase.functions.getFunctionDetail(functionName, codeSecret);
10478
+ const boundLayers = normalizeFunctionLayers(detail.Layers);
10479
+ return jsonContent({
10480
+ success: true,
10481
+ data: {
10482
+ action,
10483
+ functionName,
10484
+ layers: boundLayers,
10485
+ requestId: result.RequestId,
10486
+ },
10487
+ message: `Successfully detached layer '${layerName}' version ${layerVersion} from function '${functionName}'`,
10488
+ nextActions: [
10489
+ { tool: "readFunctionLayers", action: "getFunctionLayers", reason: "Verify current bound layers" },
10490
+ ],
10491
+ });
10492
+ }
10493
+ if (!layers || layers.length === 0) {
10494
+ throw new Error("updateFunctionLayers 操作时,layers 参数是必需的");
10495
+ }
10496
+ const normalizedLayers = normalizeFunctionLayers(layers);
10497
+ if (normalizedLayers.length === 0) {
10498
+ throw new Error("updateFunctionLayers 操作时,layers 参数必须包含有效的 LayerName 和 LayerVersion");
10499
+ }
10500
+ const result = await cloudbase.functions.updateFunctionLayer({
10501
+ envId,
10502
+ functionName: functionName,
10503
+ layers: normalizedLayers,
10504
+ });
10505
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
10506
+ const detail = await cloudbase.functions.getFunctionDetail(functionName);
10507
+ const boundLayers = normalizeFunctionLayers(detail.Layers);
10508
+ return jsonContent({
10509
+ success: true,
10510
+ data: {
10511
+ action,
10512
+ functionName,
10513
+ layers: boundLayers,
10514
+ requestId: result.RequestId,
10515
+ },
10516
+ message: `Successfully updated bound layers for function '${functionName}'`,
10517
+ nextActions: [
10518
+ { tool: "readFunctionLayers", action: "getFunctionLayers", reason: "Verify updated layer order" },
10519
+ ],
10520
+ });
10521
+ });
9597
10522
  // // Layer相关功能
9598
10523
  // // createLayer - 创建Layer
9599
10524
  // server.tool(
@@ -9992,6 +10917,7 @@ const INTEGRATION_IDE_MAPPING = {
9992
10917
  CodeBuddy: "codebuddy",
9993
10918
  CodeBuddyManual: "codebuddy",
9994
10919
  CodeBuddyCode: "codebuddy",
10920
+ CodeBuddyPlugin: "codebuddy",
9995
10921
  "Claude Code": "claude-code",
9996
10922
  CLINE: "cline",
9997
10923
  "Gemini CLI": "gemini-cli",
@@ -10250,7 +11176,7 @@ function registerSetupTools(server) {
10250
11176
  title: "下载项目模板",
10251
11177
  description: `自动下载并部署CloudBase项目模板。⚠️ **MANDATORY FOR NEW PROJECTS** ⚠️
10252
11178
 
10253
- **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.13.0" : 0}),便于后续维护和版本追踪\n- 下载 rules 模板时,如果项目中已存在 README.md 文件,系统会自动保护该文件不被覆盖(除非设置 overwrite=true)`,
11179
+ **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.14.2" : 0}),便于后续维护和版本追踪\n- 下载 rules 模板时,如果项目中已存在 README.md 文件,系统会自动保护该文件不被覆盖(除非设置 overwrite=true)`,
10254
11180
  inputSchema: {
10255
11181
  template: zod_1.z
10256
11182
  .enum(["react", "vue", "miniprogram", "uniapp", "rules"])
@@ -11578,7 +12504,13 @@ async function getUinForTelemetry() {
11578
12504
  const loginState = await (0, auth_js_1.getLoginState)({ region });
11579
12505
  // Try to extract UIN from loginState
11580
12506
  // Note: actual field name may vary, adjust based on actual response
11581
- return loginState.uin || undefined;
12507
+ if (loginState &&
12508
+ typeof loginState === "object" &&
12509
+ "uin" in loginState &&
12510
+ typeof loginState.uin !== "undefined") {
12511
+ return String(loginState.uin);
12512
+ }
12513
+ return undefined;
11582
12514
  }
11583
12515
  catch (err) {
11584
12516
  (0, logger_js_1.debug)('Failed to get UIN for telemetry', { error: err instanceof Error ? err.message : String(err) });
@@ -11887,10 +12819,10 @@ function registerHostingTools(server) {
11887
12819
  // uploadFiles - 上传文件到静态网站托管 (cloud-incompatible)
11888
12820
  server.registerTool("uploadFiles", {
11889
12821
  title: "上传静态文件",
11890
- description: "上传文件到静态网站托管",
12822
+ description: "上传文件到静态网站托管。部署前请先完成构建;如果站点会部署到子路径,请检查构建配置中的 publicPath、base、assetPrefix 等是否使用相对路径,避免静态资源加载失败。",
11891
12823
  inputSchema: {
11892
- localPath: zod_1.z.string().optional().describe("本地文件或文件夹路径,需要是绝对路径,例如 /tmp/files/data.txt"),
11893
- cloudPath: zod_1.z.string().optional().describe("云端文件或文件夹路径,例如files/data.txt"),
12824
+ localPath: zod_1.z.string().optional().describe("本地文件或文件夹路径,需要是绝对路径,例如 /tmp/files/data.txt"),
12825
+ cloudPath: zod_1.z.string().optional().describe("云端文件或文件夹路径,例如 files/data.txt。若部署到子路径,请同时检查构建配置中的 publicPath、base、assetPrefix 等是否为相对路径。"),
11894
12826
  files: zod_1.z.array(zod_1.z.object({
11895
12827
  localPath: zod_1.z.string(),
11896
12828
  cloudPath: zod_1.z.string()
@@ -12139,56 +13071,181 @@ function registerHostingTools(server) {
12139
13071
 
12140
13072
 
12141
13073
  Object.defineProperty(exports, "__esModule", ({ value: true }));
13074
+ exports.getAuthProgressStateSync = getAuthProgressStateSync;
13075
+ exports.getAuthProgressState = getAuthProgressState;
13076
+ exports.setPendingAuthProgressState = setPendingAuthProgressState;
13077
+ exports.resolveAuthProgressState = resolveAuthProgressState;
13078
+ exports.rejectAuthProgressState = rejectAuthProgressState;
13079
+ exports.resetAuthProgressState = resetAuthProgressState;
13080
+ exports.peekLoginState = peekLoginState;
13081
+ exports.ensureLogin = ensureLogin;
12142
13082
  exports.getLoginState = getLoginState;
12143
13083
  exports.logout = logout;
12144
13084
  const toolbox_1 = __webpack_require__(2090);
12145
13085
  const logger_js_1 = __webpack_require__(3039);
12146
13086
  const tencet_cloud_js_1 = __webpack_require__(5018);
12147
- const auth = toolbox_1.AuthSupevisor.getInstance({});
12148
- async function getLoginState(options) {
13087
+ const auth = toolbox_1.AuthSupervisor.getInstance({});
13088
+ const authProgressState = {
13089
+ status: "IDLE",
13090
+ updatedAt: Date.now(),
13091
+ };
13092
+ function updateAuthProgressState(partial) {
13093
+ Object.assign(authProgressState, partial, {
13094
+ updatedAt: Date.now(),
13095
+ });
13096
+ return getAuthProgressStateSync();
13097
+ }
13098
+ function normalizeLoginStateFromEnvVars(options) {
12149
13099
  const { TENCENTCLOUD_SECRETID, TENCENTCLOUD_SECRETKEY, TENCENTCLOUD_SESSIONTOKEN, } = process.env;
12150
- (0, logger_js_1.debug)("TENCENTCLOUD_SECRETID", { secretId: TENCENTCLOUD_SECRETID });
12151
- // If ignoreEnvVars is true (e.g., when switching account), skip environment variables
12152
- // and force Web authentication to allow account switching
12153
13100
  if (!options?.ignoreEnvVars && TENCENTCLOUD_SECRETID && TENCENTCLOUD_SECRETKEY) {
12154
- (0, logger_js_1.debug)("loginByApiSecret");
12155
13101
  return {
12156
13102
  secretId: TENCENTCLOUD_SECRETID,
12157
13103
  secretKey: TENCENTCLOUD_SECRETKEY,
12158
13104
  token: TENCENTCLOUD_SESSIONTOKEN,
13105
+ envId: process.env.CLOUDBASE_ENV_ID,
12159
13106
  };
12160
- // await auth.loginByApiSecret(TENCENTCLOUD_SECRETID, TENCENTCLOUD_SECRETKEY, TENCENTCLOUD_SESSIONTOKEN)
12161
13107
  }
12162
- const loginState = await auth.getLoginState();
13108
+ return null;
13109
+ }
13110
+ function mapAuthErrorStatus(error) {
13111
+ const message = error instanceof Error ? error.message : String(error ?? "");
13112
+ if (message.includes("拒绝") || message.includes("denied")) {
13113
+ return "DENIED";
13114
+ }
13115
+ if (message.includes("过期") || message.includes("expired")) {
13116
+ return "EXPIRED";
13117
+ }
13118
+ return "ERROR";
13119
+ }
13120
+ function getAuthProgressStateSync() {
13121
+ return {
13122
+ ...authProgressState,
13123
+ authChallenge: authProgressState.authChallenge
13124
+ ? { ...authProgressState.authChallenge }
13125
+ : undefined,
13126
+ };
13127
+ }
13128
+ async function getAuthProgressState() {
13129
+ const loginState = await peekLoginState();
13130
+ if (loginState && authProgressState.status === "PENDING") {
13131
+ updateAuthProgressState({
13132
+ status: "READY",
13133
+ lastError: undefined,
13134
+ });
13135
+ }
13136
+ if (authProgressState.status === "PENDING" &&
13137
+ authProgressState.authChallenge?.expires_in) {
13138
+ const issuedAt = authProgressState.updatedAt;
13139
+ const expiresAt = issuedAt + authProgressState.authChallenge.expires_in * 1000;
13140
+ if (Date.now() > expiresAt) {
13141
+ updateAuthProgressState({
13142
+ status: "EXPIRED",
13143
+ lastError: "设备码已过期,请重新发起授权",
13144
+ });
13145
+ }
13146
+ }
13147
+ return getAuthProgressStateSync();
13148
+ }
13149
+ function setPendingAuthProgressState(challenge, authMode = "device") {
13150
+ return updateAuthProgressState({
13151
+ status: "PENDING",
13152
+ authMode,
13153
+ authChallenge: challenge,
13154
+ lastError: undefined,
13155
+ });
13156
+ }
13157
+ function resolveAuthProgressState() {
13158
+ return updateAuthProgressState({
13159
+ status: "READY",
13160
+ lastError: undefined,
13161
+ });
13162
+ }
13163
+ function rejectAuthProgressState(error) {
13164
+ const message = error instanceof Error ? error.message : String(error ?? "unknown error");
13165
+ return updateAuthProgressState({
13166
+ status: mapAuthErrorStatus(error),
13167
+ lastError: message,
13168
+ });
13169
+ }
13170
+ function resetAuthProgressState() {
13171
+ return updateAuthProgressState({
13172
+ status: "IDLE",
13173
+ authMode: undefined,
13174
+ authChallenge: undefined,
13175
+ lastError: undefined,
13176
+ });
13177
+ }
13178
+ async function peekLoginState(options) {
13179
+ const envVarLoginState = normalizeLoginStateFromEnvVars(options);
13180
+ if (envVarLoginState) {
13181
+ (0, logger_js_1.debug)("loginByApiSecret");
13182
+ return envVarLoginState;
13183
+ }
13184
+ return auth.getLoginState();
13185
+ }
13186
+ async function ensureLogin(options) {
13187
+ (0, logger_js_1.debug)("TENCENTCLOUD_SECRETID", { secretId: process.env.TENCENTCLOUD_SECRETID });
13188
+ const loginState = await peekLoginState({
13189
+ ignoreEnvVars: options?.ignoreEnvVars,
13190
+ });
12163
13191
  if (!loginState) {
12164
- await auth.loginByWebAuth((options?.fromCloudBaseLoginPage && !(0, tencet_cloud_js_1.isInternationalRegion)(options?.region))
12165
- ? {
12166
- getAuthUrl: (url) => {
12167
- // 国际站
12168
- const separator = url.includes('?') ? '&' : '?';
12169
- const urlWithParam = `${url}${separator}allowNoEnv=true`;
12170
- return `https://tcb.cloud.tencent.com/login?_redirect_uri=${encodeURIComponent(urlWithParam)}`;
12171
- },
12172
- }
12173
- : {
12174
- getAuthUrl: (url) => {
12175
- if ((0, tencet_cloud_js_1.isInternationalRegion)(options?.region)) {
12176
- url = url.replace('cloud.tencent.com', 'tencentcloud.com');
13192
+ const envMode = process.env.TCB_AUTH_MODE;
13193
+ const normalizedEnvMode = envMode === "web" || envMode === "device" ? envMode : undefined;
13194
+ const mode = options?.authMode || normalizedEnvMode || "device";
13195
+ const loginOptions = { flow: mode };
13196
+ if (mode === "web") {
13197
+ loginOptions.getAuthUrl =
13198
+ options?.fromCloudBaseLoginPage && !(0, tencet_cloud_js_1.isInternationalRegion)(options?.region)
13199
+ ? (url) => {
13200
+ const separator = url.includes("?") ? "&" : "?";
13201
+ const urlWithParam = `${url}${separator}allowNoEnv=true`;
13202
+ return `https://tcb.cloud.tencent.com/login?_redirect_uri=${encodeURIComponent(urlWithParam)}`;
12177
13203
  }
12178
- const separator = url.includes('?') ? '&' : '?';
12179
- return `${url}${separator}allowNoEnv=true`;
12180
- },
12181
- });
12182
- const loginState = await auth.getLoginState();
12183
- (0, logger_js_1.debug)("loginByWebAuth", loginState);
13204
+ : (url) => {
13205
+ if ((0, tencet_cloud_js_1.isInternationalRegion)(options?.region)) {
13206
+ url = url.replace("cloud.tencent.com", "tencentcloud.com");
13207
+ }
13208
+ const separator = url.includes("?") ? "&" : "?";
13209
+ return `${url}${separator}allowNoEnv=true`;
13210
+ };
13211
+ }
13212
+ else {
13213
+ if (options?.clientId) {
13214
+ loginOptions.client_id = options.clientId;
13215
+ }
13216
+ if (options?.onDeviceCode) {
13217
+ loginOptions.onDeviceCode = (info) => {
13218
+ setPendingAuthProgressState(info, mode);
13219
+ options.onDeviceCode?.(info);
13220
+ };
13221
+ }
13222
+ }
13223
+ (0, logger_js_1.debug)("beforeloginByWebAuth", { loginOptions });
13224
+ try {
13225
+ await auth.loginByWebAuth(loginOptions);
13226
+ resolveAuthProgressState();
13227
+ }
13228
+ catch (error) {
13229
+ rejectAuthProgressState(error);
13230
+ throw error;
13231
+ }
13232
+ const loginState = await peekLoginState({
13233
+ ignoreEnvVars: options?.ignoreEnvVars,
13234
+ });
13235
+ (0, logger_js_1.debug)("loginByWebAuth", { mode, hasLoginState: !!loginState });
12184
13236
  return loginState;
12185
13237
  }
12186
13238
  else {
13239
+ resolveAuthProgressState();
12187
13240
  return loginState;
12188
13241
  }
12189
13242
  }
13243
+ async function getLoginState(options) {
13244
+ return ensureLogin(options);
13245
+ }
12190
13246
  async function logout() {
12191
13247
  const result = await auth.logout();
13248
+ resetAuthProgressState();
12192
13249
  return result;
12193
13250
  }
12194
13251
 
@@ -13616,8 +14673,7 @@ function shouldRegisterTool(toolName) {
13616
14673
  // Cloud-incompatible tools that involve local file operations
13617
14674
  const cloudIncompatibleTools = [
13618
14675
  // Auth tools - local file uploads
13619
- 'login',
13620
- 'logout',
14676
+ 'auth',
13621
14677
  // Storage tools - local file uploads
13622
14678
  'uploadFile',
13623
14679
  // Hosting tools - local file uploads
@@ -13757,6 +14813,60 @@ function registerSQLDatabaseTools(server) {
13757
14813
  }
13758
14814
 
13759
14815
 
14816
+ /***/ }),
14817
+
14818
+ /***/ 9835:
14819
+ /***/ ((__unused_webpack_module, exports) => {
14820
+
14821
+
14822
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
14823
+ exports.ToolPayloadError = void 0;
14824
+ exports.buildJsonToolResult = buildJsonToolResult;
14825
+ exports.isToolPayloadError = isToolPayloadError;
14826
+ exports.toolPayloadErrorToResult = toolPayloadErrorToResult;
14827
+ exports.buildAuthNextStep = buildAuthNextStep;
14828
+ exports.throwToolPayloadError = throwToolPayloadError;
14829
+ function buildJsonToolResult(payload) {
14830
+ return {
14831
+ content: [
14832
+ {
14833
+ type: "text",
14834
+ text: JSON.stringify(payload, null, 2),
14835
+ },
14836
+ ],
14837
+ };
14838
+ }
14839
+ class ToolPayloadError extends Error {
14840
+ payload;
14841
+ constructor(payload) {
14842
+ super(typeof payload.message === "string" ? payload.message : "Tool payload error");
14843
+ this.name = "ToolPayloadError";
14844
+ this.payload = payload;
14845
+ }
14846
+ }
14847
+ exports.ToolPayloadError = ToolPayloadError;
14848
+ function isToolPayloadError(error) {
14849
+ return error instanceof ToolPayloadError;
14850
+ }
14851
+ function toolPayloadErrorToResult(error) {
14852
+ if (!isToolPayloadError(error)) {
14853
+ return null;
14854
+ }
14855
+ return buildJsonToolResult(error.payload);
14856
+ }
14857
+ function buildAuthNextStep(action, options) {
14858
+ return {
14859
+ tool: "auth",
14860
+ action,
14861
+ required_params: options?.requiredParams,
14862
+ suggested_args: options?.suggestedArgs ?? { action },
14863
+ };
14864
+ }
14865
+ function throwToolPayloadError(payload) {
14866
+ throw new ToolPayloadError(payload);
14867
+ }
14868
+
14869
+
13760
14870
  /***/ })
13761
14871
 
13762
14872
  /******/ });
@@ -13851,7 +14961,7 @@ var __webpack_exports__ = {};
13851
14961
  var exports = __webpack_exports__;
13852
14962
 
13853
14963
  Object.defineProperty(exports, "BJ", ({ value: true }));
13854
- exports.pk = exports.ZS = exports.vY = exports.q8 = exports.bM = exports.fW = exports._k = exports.T$ = exports.$n = exports.S = exports.bT = exports.ri = exports.BS = exports.R8 = exports.z3 = exports.pq = exports.R4 = exports.ps = exports.v7 = exports.S7 = exports.dD = exports.Gh = void 0;
14964
+ exports.j8 = exports.fO = exports.gk = exports.Yh = exports.JA = exports.xz = exports.RX = exports.pk = exports.ZS = exports.vY = exports.q8 = exports.bM = exports.fW = exports._k = exports.T$ = exports.$n = exports.S = exports.bT = exports.ri = exports.BS = exports.R8 = exports.z3 = exports.pq = exports.R4 = exports.ps = exports.v7 = exports.S7 = exports.dD = exports.Gh = void 0;
13855
14965
  exports.SJ = getInteractiveServerAsync;
13856
14966
  // CloudBase MCP Server Library
13857
14967
  var server_js_1 = __webpack_require__(1422);
@@ -13882,6 +14992,15 @@ var env_js_1 = __webpack_require__(622);
13882
14992
  Object.defineProperty(exports, "ZS", ({ enumerable: true, get: function () { return env_js_1.simplifyEnvList; } }));
13883
14993
  var setup_js_1 = __webpack_require__(6556);
13884
14994
  Object.defineProperty(exports, "pk", ({ enumerable: true, get: function () { return setup_js_1.RAW_IDE_FILE_MAPPINGS; } }));
14995
+ // Export runtime constants for multi-language support
14996
+ var functions_js_1 = __webpack_require__(5936);
14997
+ Object.defineProperty(exports, "RX", ({ enumerable: true, get: function () { return functions_js_1.SUPPORTED_RUNTIMES; } }));
14998
+ Object.defineProperty(exports, "xz", ({ enumerable: true, get: function () { return functions_js_1.ALL_SUPPORTED_RUNTIMES; } }));
14999
+ Object.defineProperty(exports, "JA", ({ enumerable: true, get: function () { return functions_js_1.DEFAULT_RUNTIME; } }));
15000
+ Object.defineProperty(exports, "Yh", ({ enumerable: true, get: function () { return functions_js_1.RECOMMENDED_RUNTIMES; } }));
15001
+ Object.defineProperty(exports, "gk", ({ enumerable: true, get: function () { return functions_js_1.formatRuntimeList; } }));
15002
+ Object.defineProperty(exports, "fO", ({ enumerable: true, get: function () { return functions_js_1.SUPPORTED_NODEJS_RUNTIMES; } }));
15003
+ Object.defineProperty(exports, "j8", ({ enumerable: true, get: function () { return functions_js_1.DEFAULT_NODEJS_RUNTIME; } }));
13885
15004
  /**
13886
15005
  * Get interactive server instance (CommonJS compatible)
13887
15006
  */
@@ -13894,7 +15013,13 @@ async function getInteractiveServerAsync() {
13894
15013
 
13895
15014
  })();
13896
15015
 
15016
+ const __webpack_exports__ALL_SUPPORTED_RUNTIMES = __webpack_exports__.xz;
15017
+ const __webpack_exports__DEFAULT_NODEJS_RUNTIME = __webpack_exports__.j8;
15018
+ const __webpack_exports__DEFAULT_RUNTIME = __webpack_exports__.JA;
13897
15019
  const __webpack_exports__RAW_IDE_FILE_MAPPINGS = __webpack_exports__.pk;
15020
+ const __webpack_exports__RECOMMENDED_RUNTIMES = __webpack_exports__.Yh;
15021
+ const __webpack_exports__SUPPORTED_NODEJS_RUNTIMES = __webpack_exports__.fO;
15022
+ const __webpack_exports__SUPPORTED_RUNTIMES = __webpack_exports__.RX;
13898
15023
  const __webpack_exports__StdioServerTransport = __webpack_exports__.S7;
13899
15024
  const __webpack_exports___esModule = __webpack_exports__.BJ;
13900
15025
  const __webpack_exports__createCloudBaseManagerWithOptions = __webpack_exports__.q8;
@@ -13902,6 +15027,7 @@ const __webpack_exports__createCloudBaseMcpServer = __webpack_exports__.Gh;
13902
15027
  const __webpack_exports__enableCloudMode = __webpack_exports__.S;
13903
15028
  const __webpack_exports__envManager = __webpack_exports__.vY;
13904
15029
  const __webpack_exports__error = __webpack_exports__.z3;
15030
+ const __webpack_exports__formatRuntimeList = __webpack_exports__.gk;
13905
15031
  const __webpack_exports__getCloudBaseManager = __webpack_exports__._k;
13906
15032
  const __webpack_exports__getCloudModeStatus = __webpack_exports__.$n;
13907
15033
  const __webpack_exports__getDefaultServer = __webpack_exports__.dD;
@@ -13918,4 +15044,4 @@ const __webpack_exports__shouldRegisterTool = __webpack_exports__.T$;
13918
15044
  const __webpack_exports__simplifyEnvList = __webpack_exports__.ZS;
13919
15045
  const __webpack_exports__telemetryReporter = __webpack_exports__.v7;
13920
15046
  const __webpack_exports__warn = __webpack_exports__.R8;
13921
- export { __webpack_exports__RAW_IDE_FILE_MAPPINGS as RAW_IDE_FILE_MAPPINGS, __webpack_exports__StdioServerTransport as StdioServerTransport, __webpack_exports___esModule as __esModule, __webpack_exports__createCloudBaseManagerWithOptions as createCloudBaseManagerWithOptions, __webpack_exports__createCloudBaseMcpServer as createCloudBaseMcpServer, __webpack_exports__enableCloudMode as enableCloudMode, __webpack_exports__envManager as envManager, __webpack_exports__error as error, __webpack_exports__getCloudBaseManager as getCloudBaseManager, __webpack_exports__getCloudModeStatus as getCloudModeStatus, __webpack_exports__getDefaultServer as getDefaultServer, __webpack_exports__getEnvId as getEnvId, __webpack_exports__getInteractiveServerAsync as getInteractiveServerAsync, __webpack_exports__getLoginState as getLoginState, __webpack_exports__info as info, __webpack_exports__isCloudMode as isCloudMode, __webpack_exports__logout as logout, __webpack_exports__reportToolCall as reportToolCall, __webpack_exports__reportToolkitLifecycle as reportToolkitLifecycle, __webpack_exports__resetCloudBaseManagerCache as resetCloudBaseManagerCache, __webpack_exports__shouldRegisterTool as shouldRegisterTool, __webpack_exports__simplifyEnvList as simplifyEnvList, __webpack_exports__telemetryReporter as telemetryReporter, __webpack_exports__warn as warn };
15047
+ export { __webpack_exports__ALL_SUPPORTED_RUNTIMES as ALL_SUPPORTED_RUNTIMES, __webpack_exports__DEFAULT_NODEJS_RUNTIME as DEFAULT_NODEJS_RUNTIME, __webpack_exports__DEFAULT_RUNTIME as DEFAULT_RUNTIME, __webpack_exports__RAW_IDE_FILE_MAPPINGS as RAW_IDE_FILE_MAPPINGS, __webpack_exports__RECOMMENDED_RUNTIMES as RECOMMENDED_RUNTIMES, __webpack_exports__SUPPORTED_NODEJS_RUNTIMES as SUPPORTED_NODEJS_RUNTIMES, __webpack_exports__SUPPORTED_RUNTIMES as SUPPORTED_RUNTIMES, __webpack_exports__StdioServerTransport as StdioServerTransport, __webpack_exports___esModule as __esModule, __webpack_exports__createCloudBaseManagerWithOptions as createCloudBaseManagerWithOptions, __webpack_exports__createCloudBaseMcpServer as createCloudBaseMcpServer, __webpack_exports__enableCloudMode as enableCloudMode, __webpack_exports__envManager as envManager, __webpack_exports__error as error, __webpack_exports__formatRuntimeList as formatRuntimeList, __webpack_exports__getCloudBaseManager as getCloudBaseManager, __webpack_exports__getCloudModeStatus as getCloudModeStatus, __webpack_exports__getDefaultServer as getDefaultServer, __webpack_exports__getEnvId as getEnvId, __webpack_exports__getInteractiveServerAsync as getInteractiveServerAsync, __webpack_exports__getLoginState as getLoginState, __webpack_exports__info as info, __webpack_exports__isCloudMode as isCloudMode, __webpack_exports__logout as logout, __webpack_exports__reportToolCall as reportToolCall, __webpack_exports__reportToolkitLifecycle as reportToolkitLifecycle, __webpack_exports__resetCloudBaseManagerCache as resetCloudBaseManagerCache, __webpack_exports__shouldRegisterTool as shouldRegisterTool, __webpack_exports__simplifyEnvList as simplifyEnvList, __webpack_exports__telemetryReporter as telemetryReporter, __webpack_exports__warn as warn };