@cloudbase/cloudbase-mcp 2.8.0 → 2.10.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
@@ -142,7 +142,7 @@ function registerEnvTools(server) {
142
142
  // Get CLAUDE.md prompt content (skip for CodeBuddy IDE)
143
143
  let promptContent = "";
144
144
  const currentIde = server.ide || process.env.INTEGRATION_IDE;
145
- if (currentIde !== "CodeBuddy") {
145
+ if (currentIde !== "CodeBuddy" && process.env.CLOUDBASE_GUIDE_PROMPT !== "false") {
146
146
  try {
147
147
  promptContent = await (0, rag_js_1.getClaudePrompt)();
148
148
  }
@@ -245,7 +245,7 @@ function registerEnvTools(server) {
245
245
  });
246
246
  // Use commonService to call DescribeEnvs with filter parameters
247
247
  // Filter parameters match the reference conditions provided by user
248
- result = await cloudbaseList.commonService("tcb").call({
248
+ result = await cloudbaseList.commonService("tcb", "2018-06-08").call({
249
249
  Action: "DescribeEnvs",
250
250
  Param: {
251
251
  EnvTypes: ["weda", "baas"], // Include weda and baas (normal) environments
@@ -328,7 +328,7 @@ function registerEnvTools(server) {
328
328
  let responseText = JSON.stringify(result, null, 2);
329
329
  // For info action, append CLAUDE.md prompt content (skip for CodeBuddy IDE)
330
330
  const currentIde = server.ide || process.env.INTEGRATION_IDE;
331
- if (action === "info" && currentIde !== "CodeBuddy") {
331
+ if (action === "info" && currentIde !== "CodeBuddy" && process.env.CLOUDBASE_GUIDE_PROMPT !== "false") {
332
332
  try {
333
333
  const promptContent = await (0, rag_js_1.getClaudePrompt)();
334
334
  if (promptContent) {
@@ -431,7 +431,6 @@ const cloudbase_manager_js_1 = __webpack_require__(3431);
431
431
  const CATEGORY = "cloud-api";
432
432
  const ALLOWED_SERVICES = [
433
433
  "tcb",
434
- "flexdb",
435
434
  "scf",
436
435
  "sts",
437
436
  "cam",
@@ -454,7 +453,7 @@ function registerCapiTools(server) {
454
453
  inputSchema: {
455
454
  service: zod_1.z
456
455
  .enum(ALLOWED_SERVICES)
457
- .describe("选择要访问的服务,必须先查看规则/技能确认是否可用。可选:tcb、flexdb、scf、sts、cam、lowcode、cdn、vpc。"),
456
+ .describe("选择要访问的服务,必须先查看规则/技能确认是否可用。可选:tcb、scf、sts、cam、lowcode、cdn、vpc。"),
458
457
  action: zod_1.z
459
458
  .string()
460
459
  .min(1)
@@ -563,7 +562,7 @@ ${envIdSection}
563
562
  ## 环境信息
564
563
  - 操作系统: ${os_1.default.type()} ${os_1.default.release()}
565
564
  - Node.js版本: ${process.version}
566
- - MCP 版本:${process.env.npm_package_version || "2.8.0" || 0}
565
+ - MCP 版本:${process.env.npm_package_version || "2.10.0" || 0}
567
566
  - 系统架构: ${os_1.default.arch()}
568
567
  - 时间: ${new Date().toISOString()}
569
568
  - 请求ID: ${requestId}
@@ -773,6 +772,7 @@ const invite_code_js_1 = __webpack_require__(4760);
773
772
  const security_rule_js_1 = __webpack_require__(7862);
774
773
  const cloud_mode_js_1 = __webpack_require__(9684);
775
774
  const logger_js_1 = __webpack_require__(3039);
775
+ const tencet_cloud_js_1 = __webpack_require__(5018);
776
776
  const tool_wrapper_js_1 = __webpack_require__(1363);
777
777
  // 默认插件列表
778
778
  const DEFAULT_PLUGINS = [
@@ -792,7 +792,11 @@ const DEFAULT_PLUGINS = [
792
792
  "capi",
793
793
  ];
794
794
  function registerDatabase(server) {
795
- (0, databaseNoSQL_js_1.registerDatabaseTools)(server);
795
+ // Skip NoSQL database tools for international region (Singapore) as it doesn't support NoSQL DB
796
+ const region = server.cloudBaseOptions?.region || process.env.TCB_REGION;
797
+ if (!(0, tencet_cloud_js_1.isInternationalRegion)(region)) {
798
+ (0, databaseNoSQL_js_1.registerDatabaseTools)(server);
799
+ }
796
800
  (0, databaseSQL_js_1.registerSQLDatabaseTools)(server);
797
801
  (0, dataModel_js_1.registerDataModelTools)(server);
798
802
  }
@@ -1197,7 +1201,7 @@ class InteractiveServer {
1197
1201
  IsVisible: false,
1198
1202
  Channels: ["dcloud", "iotenable", "tem", "scene_module"],
1199
1203
  };
1200
- envResult = await sessionData.manager.commonService("tcb").call({
1204
+ envResult = await sessionData.manager.commonService("tcb", "2018-06-08").call({
1201
1205
  Action: "DescribeEnvs",
1202
1206
  Param: queryParams,
1203
1207
  });
@@ -4227,7 +4231,10 @@ async function getCloudBaseManager(options = {}) {
4227
4231
  return createCloudBaseManagerWithOptions(cloudBaseOptions);
4228
4232
  }
4229
4233
  try {
4230
- const loginState = await (0, auth_js_1.getLoginState)();
4234
+ // Get region from environment variable for auth URL
4235
+ // Note: At this point, cloudBaseOptions is undefined (checked above), so only use env var
4236
+ const region = process.env.TCB_REGION;
4237
+ const loginState = await (0, auth_js_1.getLoginState)({ region });
4231
4238
  const { envId: loginEnvId, secretId, secretKey, token } = loginState;
4232
4239
  let finalEnvId;
4233
4240
  if (requireEnvId) {
@@ -4252,12 +4259,17 @@ async function getCloudBaseManager(options = {}) {
4252
4259
  }
4253
4260
  // envId priority: envManager.cachedEnvId > envManager.getEnvId() > loginState.envId > undefined
4254
4261
  // Note: envManager.cachedEnvId has highest priority as it reflects user's latest environment switch
4262
+ // Region priority: process.env.TCB_REGION > undefined (use SDK default)
4263
+ // At this point, cloudBaseOptions is undefined (checked above), so only use env var if present
4264
+ // Reuse region variable declared above (line 259) for CloudBase initialization
4255
4265
  const manager = new manager_node_1.default({
4256
4266
  secretId,
4257
4267
  secretKey,
4258
4268
  envId: finalEnvId || loginEnvId,
4259
4269
  token,
4260
4270
  proxy: process.env.http_proxy,
4271
+ region,
4272
+ // REGION 国际站需要指定 region
4261
4273
  });
4262
4274
  return manager;
4263
4275
  }
@@ -4267,15 +4279,18 @@ async function getCloudBaseManager(options = {}) {
4267
4279
  }
4268
4280
  }
4269
4281
  /**
4270
- * 使用传入的 CloudBase 配置创建 manager,不使用缓存
4271
- * @param cloudBaseOptions 传入的 CloudBase 配置选项
4272
- * @returns CloudBase manager 实例
4282
+ * Create a manager with the provided CloudBase options, without using cache
4283
+ * @param cloudBaseOptions Provided CloudBase options
4284
+ * @returns CloudBase manager instance
4273
4285
  */
4274
4286
  function createCloudBaseManagerWithOptions(cloudBaseOptions) {
4275
- (0, logger_js_1.debug)('使用传入的 CloudBase 配置创建 manager:', cloudBaseOptions);
4287
+ (0, logger_js_1.debug)('Create manager with provided CloudBase options:', cloudBaseOptions);
4288
+ // Region priority: cloudBaseOptions.region > process.env.TCB_REGION > undefined (use SDK default)
4289
+ const region = cloudBaseOptions.region ?? process.env.TCB_REGION ?? undefined;
4276
4290
  const manager = new manager_node_1.default({
4277
4291
  ...cloudBaseOptions,
4278
4292
  proxy: cloudBaseOptions.proxy || process.env.http_proxy,
4293
+ region
4279
4294
  });
4280
4295
  return manager;
4281
4296
  }
@@ -4484,9 +4499,14 @@ async function _promptAndSetEnvironmentId(autoSelectSingle, options) {
4484
4499
  }
4485
4500
  // 1. 确保用户已登录
4486
4501
  (0, logger_js_1.debug)("[interactive] Step 1: Checking login state...");
4502
+ // Get region from server options or environment variable for auth URL
4503
+ // Note: serverCloudBaseOptions will be declared later (line 282), so we get it here first
4504
+ const serverCloudBaseOptionsForAuth = server?.cloudBaseOptions;
4505
+ const region = serverCloudBaseOptionsForAuth?.region || process.env.TCB_REGION;
4487
4506
  const loginState = await (0, auth_js_1.getLoginState)({
4488
4507
  fromCloudBaseLoginPage: options?.loginFromCloudBaseLoginPage,
4489
4508
  ignoreEnvVars: options?.ignoreEnvVars,
4509
+ region,
4490
4510
  });
4491
4511
  (0, logger_js_1.debug)("[interactive] Login state:", {
4492
4512
  hasLoginState: !!loginState,
@@ -4518,6 +4538,14 @@ async function _promptAndSetEnvironmentId(autoSelectSingle, options) {
4518
4538
  cloudBaseOptions: serverCloudBaseOptions,
4519
4539
  });
4520
4540
  (0, logger_js_1.debug)("[interactive] CloudBase manager obtained");
4541
+ // If envId is already set, return directly
4542
+ const envId = serverCloudBaseOptions?.envId || process.env.CLOUDBASE_ENV_ID;
4543
+ if (envId) {
4544
+ return {
4545
+ selectedEnvId: envId,
4546
+ cancelled: false,
4547
+ };
4548
+ }
4521
4549
  // Step 2.1: Check and initialize TCB service if needed
4522
4550
  // Check if retry is requested (from interactive server session data)
4523
4551
  // Ensure server is resolved if it's a Promise (CLI mode)
@@ -4591,7 +4619,7 @@ async function _promptAndSetEnvironmentId(autoSelectSingle, options) {
4591
4619
  let queryEnvSuccess = false;
4592
4620
  let queryEnvError;
4593
4621
  try {
4594
- // Use commonService to call DescribeEnvs with filter parameters
4622
+ // Use Service to call DescribeEnvs with filter parameters
4595
4623
  // Filter parameters match the reference conditions provided by user
4596
4624
  const queryParams = {
4597
4625
  EnvTypes: ["weda", "baas"], // Include weda and baas (normal) environments
@@ -4599,7 +4627,7 @@ async function _promptAndSetEnvironmentId(autoSelectSingle, options) {
4599
4627
  Channels: ["dcloud", "iotenable", "tem", "scene_module"], // Filter special channels
4600
4628
  };
4601
4629
  (0, logger_js_1.debug)("[interactive] DescribeEnvs params:", queryParams);
4602
- envResult = await cloudbase.commonService("tcb").call({
4630
+ envResult = await cloudbase.commonService("tcb", "2018-06-08").call({
4603
4631
  Action: "DescribeEnvs",
4604
4632
  Param: queryParams,
4605
4633
  });
@@ -4727,7 +4755,7 @@ async function _promptAndSetEnvironmentId(autoSelectSingle, options) {
4727
4755
  // Sometimes creation is async and env might not be immediately available
4728
4756
  (0, logger_js_1.debug)("[interactive] Verifying created environment exists in list...");
4729
4757
  try {
4730
- const verifyResult = await cloudbase.commonService("tcb").call({
4758
+ const verifyResult = await cloudbase.commonService("tcb", "2018-06-08").call({
4731
4759
  Action: "DescribeEnvs",
4732
4760
  Param: {
4733
4761
  EnvTypes: ["weda", "baas"],
@@ -4912,6 +4940,15 @@ async function _promptAndSetEnvironmentId(autoSelectSingle, options) {
4912
4940
  accountInfo.uin = String(loginState.uin);
4913
4941
  (0, logger_js_1.debug)("[interactive] Using UIN from loginState:", { uin: accountInfo.uin });
4914
4942
  }
4943
+ // Attach region from server options or environment variable fallback
4944
+ // Reuse serverCloudBaseOptions declared earlier (line 278)
4945
+ const currentServerCloudBaseOptions = server?.cloudBaseOptions;
4946
+ if (currentServerCloudBaseOptions?.region) {
4947
+ accountInfo.region = currentServerCloudBaseOptions.region;
4948
+ }
4949
+ else if (process.env.TCB_REGION) {
4950
+ accountInfo.region = process.env.TCB_REGION;
4951
+ }
4915
4952
  // Report display_env_selection event
4916
4953
  await telemetry_js_1.telemetryReporter.report('toolkit_env_setup', {
4917
4954
  step: 'display_env_selection',
@@ -5230,9 +5267,10 @@ checkIndex: 检查索引是否存在`),
5230
5267
  title: "修改 NoSQL 数据库结构",
5231
5268
  description: "修改 NoSQL 数据库结构",
5232
5269
  inputSchema: {
5233
- action: zod_1.z.enum(["createCollection", "updateCollection"])
5270
+ action: zod_1.z.enum(["createCollection", "updateCollection", "deleteCollection"])
5234
5271
  .describe(`createCollection: 创建集合
5235
- updateCollection: 更新集合`),
5272
+ updateCollection: 更新集合
5273
+ deleteCollection: 删除集合`),
5236
5274
  collectionName: zod_1.z.string().describe("集合名称"),
5237
5275
  updateOptions: zod_1.z
5238
5276
  .object({
@@ -5259,68 +5297,74 @@ updateCollection: 更新集合`),
5259
5297
  },
5260
5298
  annotations: {
5261
5299
  readOnlyHint: false,
5262
- destructiveHint: false,
5300
+ destructiveHint: true,
5263
5301
  idempotentHint: false,
5264
5302
  openWorldHint: true,
5265
5303
  category: CATEGORY,
5266
5304
  },
5267
5305
  }, async ({ action, collectionName, updateOptions }) => {
5268
- try {
5269
- const cloudbase = await getManager();
5270
- if (action === "createCollection") {
5271
- const result = await cloudbase.database.createCollection(collectionName);
5272
- (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
5273
- return {
5274
- content: [
5275
- {
5276
- type: "text",
5277
- text: JSON.stringify({
5278
- success: true,
5279
- requestId: result.RequestId,
5280
- action,
5281
- message: "云开发数据库集合创建成功",
5282
- }, null, 2),
5283
- },
5284
- ],
5285
- };
5286
- }
5287
- if (action === "updateCollection") {
5288
- if (!updateOptions) {
5289
- throw new Error("更新集合时必须提供 options");
5290
- }
5291
- const result = await cloudbase.database.updateCollection(collectionName, updateOptions);
5292
- (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
5293
- return {
5294
- content: [
5295
- {
5296
- type: "text",
5297
- text: JSON.stringify({
5298
- success: true,
5299
- requestId: result.RequestId,
5300
- action,
5301
- message: "云开发数据库集合更新成功",
5302
- }, null, 2),
5303
- },
5304
- ],
5305
- };
5306
- }
5307
- throw new Error(`不支持的操作类型: ${action}`);
5306
+ const cloudbase = await getManager();
5307
+ if (action === "createCollection") {
5308
+ const result = await cloudbase.database.createCollection(collectionName);
5309
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
5310
+ return {
5311
+ content: [
5312
+ {
5313
+ type: "text",
5314
+ text: JSON.stringify({
5315
+ success: true,
5316
+ requestId: result.RequestId,
5317
+ action,
5318
+ message: "云开发数据库集合创建成功",
5319
+ }, null, 2),
5320
+ },
5321
+ ],
5322
+ };
5308
5323
  }
5309
- catch (error) {
5324
+ if (action === "updateCollection") {
5325
+ if (!updateOptions) {
5326
+ throw new Error("更新集合时必须提供 options");
5327
+ }
5328
+ const result = await cloudbase.database.updateCollection(collectionName, updateOptions);
5329
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
5310
5330
  return {
5311
5331
  content: [
5312
5332
  {
5313
5333
  type: "text",
5314
5334
  text: JSON.stringify({
5315
- success: false,
5335
+ success: true,
5336
+ requestId: result.RequestId,
5316
5337
  action,
5317
- error: error.message,
5318
- message: "集合创建/更新操作失败",
5338
+ message: "云开发数据库集合更新成功",
5319
5339
  }, null, 2),
5320
5340
  },
5321
5341
  ],
5322
5342
  };
5323
5343
  }
5344
+ if (action === "deleteCollection") {
5345
+ const result = await cloudbase.database.deleteCollection(collectionName);
5346
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
5347
+ const body = {
5348
+ success: true,
5349
+ requestId: result.RequestId,
5350
+ action,
5351
+ message: result.Exists === false
5352
+ ? "集合不存在"
5353
+ : "云开发数据库集合删除成功",
5354
+ };
5355
+ if (result.Exists === false) {
5356
+ body.exists = false;
5357
+ }
5358
+ return {
5359
+ content: [
5360
+ {
5361
+ type: "text",
5362
+ text: JSON.stringify(body, null, 2),
5363
+ },
5364
+ ],
5365
+ };
5366
+ }
5367
+ throw new Error(`不支持的操作类型: ${action}`);
5324
5368
  });
5325
5369
  // readNoSqlDatabaseContent
5326
5370
  server.registerTool?.("readNoSqlDatabaseContent", {
@@ -5349,53 +5393,36 @@ updateCollection: 更新集合`),
5349
5393
  category: CATEGORY,
5350
5394
  },
5351
5395
  }, async ({ collectionName, query, projection, sort, limit, offset }) => {
5352
- try {
5353
- const cloudbase = await getManager();
5354
- const instanceId = await getDatabaseInstanceId(getManager);
5355
- // 兼容对象和字符串
5356
- const toJSONString = (v) => typeof v === "object" && v !== null ? JSON.stringify(v) : v;
5357
- const result = await cloudbase.commonService("flexdb").call({
5358
- Action: "Query",
5359
- Param: {
5360
- TableName: collectionName,
5361
- MgoQuery: toJSONString(query),
5362
- MgoProjection: toJSONString(projection),
5363
- MgoSort: toJSONString(sort),
5364
- MgoLimit: limit ?? 100, // 默认返回100条,避免底层SDK缺参报错
5365
- MgoOffset: offset,
5366
- Tag: instanceId,
5396
+ const cloudbase = await getManager();
5397
+ const instanceId = await getDatabaseInstanceId(getManager);
5398
+ const toJSONString = (v) => typeof v === "object" && v !== null ? JSON.stringify(v) : v;
5399
+ const result = await cloudbase.commonService("tcb", "2018-06-08").call({
5400
+ Action: "QueryRecords",
5401
+ Param: {
5402
+ TableName: collectionName,
5403
+ MgoQuery: toJSONString(query),
5404
+ MgoProjection: toJSONString(projection),
5405
+ MgoSort: toJSONString(sort),
5406
+ MgoLimit: limit ?? 100,
5407
+ MgoOffset: offset,
5408
+ Tag: instanceId,
5409
+ },
5410
+ });
5411
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
5412
+ return {
5413
+ content: [
5414
+ {
5415
+ type: "text",
5416
+ text: JSON.stringify({
5417
+ success: true,
5418
+ requestId: result.RequestId,
5419
+ data: result.Data,
5420
+ pager: result.Pager,
5421
+ message: "文档查询成功",
5422
+ }, null, 2),
5367
5423
  },
5368
- });
5369
- (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
5370
- return {
5371
- content: [
5372
- {
5373
- type: "text",
5374
- text: JSON.stringify({
5375
- success: true,
5376
- requestId: result.RequestId,
5377
- data: result.Data,
5378
- pager: result.Pager,
5379
- message: "文档查询成功",
5380
- }, null, 2),
5381
- },
5382
- ],
5383
- };
5384
- }
5385
- catch (error) {
5386
- return {
5387
- content: [
5388
- {
5389
- type: "text",
5390
- text: JSON.stringify({
5391
- success: false,
5392
- error: error.message,
5393
- message: "文档查询失败",
5394
- }, null, 2),
5395
- },
5396
- ],
5397
- };
5398
- }
5424
+ ],
5425
+ };
5399
5426
  });
5400
5427
  // writeNoSqlDatabaseContent
5401
5428
  server.registerTool?.("writeNoSqlDatabaseContent", {
@@ -5403,9 +5430,7 @@ updateCollection: 更新集合`),
5403
5430
  description: "修改 NoSQL 数据库数据记录",
5404
5431
  inputSchema: {
5405
5432
  action: zod_1.z.enum(["insert", "update", "delete"])
5406
- .describe(`createCollection: 创建数据
5407
- updateCollection: 更新数据
5408
- deleteCollection: 删除数据`),
5433
+ .describe(`insert: 插入数据(新增文档)\nupdate: 更新数据\ndelete: 删除数据`),
5409
5434
  collectionName: zod_1.z.string().describe("集合名称"),
5410
5435
  documents: zod_1.z
5411
5436
  .array(zod_1.z.object({}).passthrough())
@@ -5504,98 +5529,70 @@ deleteCollection: 删除数据`),
5504
5529
  });
5505
5530
  }
5506
5531
  async function insertDocuments({ collectionName, documents, getManager, logger, }) {
5507
- try {
5508
- const cloudbase = await getManager();
5509
- const instanceId = await getDatabaseInstanceId(getManager);
5510
- // 将对象数组序列化为字符串数组
5511
- const docsAsStrings = documents.map((doc) => JSON.stringify(doc));
5512
- const result = await cloudbase.commonService("flexdb").call({
5513
- Action: "PutItem",
5514
- Param: {
5515
- TableName: collectionName,
5516
- MgoDocs: docsAsStrings,
5517
- Tag: instanceId,
5518
- },
5519
- });
5520
- (0, cloudbase_manager_js_1.logCloudBaseResult)(logger, result);
5521
- return JSON.stringify({
5522
- success: true,
5523
- requestId: result.RequestId,
5524
- insertedIds: result.InsertedIds,
5525
- message: "文档插入成功",
5526
- }, null, 2);
5527
- }
5528
- catch (error) {
5529
- return JSON.stringify({
5530
- success: false,
5531
- error: error.message,
5532
- message: "文档插入失败",
5533
- }, null, 2);
5534
- }
5532
+ const cloudbase = await getManager();
5533
+ const instanceId = await getDatabaseInstanceId(getManager);
5534
+ const docsAsStrings = documents.map((doc) => JSON.stringify(doc));
5535
+ const result = await cloudbase.commonService("tcb", "2018-06-08").call({
5536
+ Action: "PutItem",
5537
+ Param: {
5538
+ TableName: collectionName,
5539
+ MgoDocs: docsAsStrings,
5540
+ Tag: instanceId,
5541
+ },
5542
+ });
5543
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(logger, result);
5544
+ return JSON.stringify({
5545
+ success: true,
5546
+ requestId: result.RequestId,
5547
+ insertedIds: result.InsertedIds,
5548
+ message: "文档插入成功",
5549
+ }, null, 2);
5535
5550
  }
5536
5551
  async function updateDocuments({ collectionName, query, update, isMulti, upsert, getManager, logger, }) {
5537
- try {
5538
- const cloudbase = await getManager();
5539
- const instanceId = await getDatabaseInstanceId(getManager);
5540
- const toJSONString = (v) => typeof v === "object" && v !== null ? JSON.stringify(v) : v;
5541
- const result = await cloudbase.commonService("flexdb").call({
5542
- Action: "UpdateItem",
5543
- Param: {
5544
- TableName: collectionName,
5545
- MgoQuery: toJSONString(query),
5546
- MgoUpdate: toJSONString(update),
5547
- MgoIsMulti: isMulti,
5548
- MgoUpsert: upsert,
5549
- Tag: instanceId,
5550
- },
5551
- });
5552
- (0, cloudbase_manager_js_1.logCloudBaseResult)(logger, result);
5553
- return JSON.stringify({
5554
- success: true,
5555
- requestId: result.RequestId,
5556
- modifiedCount: result.ModifiedNum,
5557
- matchedCount: result.MatchedNum,
5558
- upsertedId: result.UpsertedId,
5559
- message: "文档更新成功",
5560
- }, null, 2);
5561
- }
5562
- catch (error) {
5563
- return JSON.stringify({
5564
- success: false,
5565
- error: error.message,
5566
- message: "文档更新失败",
5567
- }, null, 2);
5568
- }
5552
+ const cloudbase = await getManager();
5553
+ const instanceId = await getDatabaseInstanceId(getManager);
5554
+ const toJSONString = (v) => typeof v === "object" && v !== null ? JSON.stringify(v) : v;
5555
+ const result = await cloudbase.commonService("tcb", "2018-06-08").call({
5556
+ Action: "UpdateItem",
5557
+ Param: {
5558
+ TableName: collectionName,
5559
+ MgoQuery: toJSONString(query),
5560
+ MgoUpdate: toJSONString(update),
5561
+ MgoIsMulti: isMulti,
5562
+ MgoUpsert: upsert,
5563
+ Tag: instanceId,
5564
+ },
5565
+ });
5566
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(logger, result);
5567
+ return JSON.stringify({
5568
+ success: true,
5569
+ requestId: result.RequestId,
5570
+ modifiedCount: result.ModifiedNum,
5571
+ matchedCount: result.MatchedNum,
5572
+ upsertedId: result.UpsertedId,
5573
+ message: "文档更新成功",
5574
+ }, null, 2);
5569
5575
  }
5570
5576
  async function deleteDocuments({ collectionName, query, isMulti, getManager, logger, }) {
5571
- try {
5572
- const cloudbase = await getManager();
5573
- const instanceId = await getDatabaseInstanceId(getManager);
5574
- const toJSONString = (v) => typeof v === "object" && v !== null ? JSON.stringify(v) : v;
5575
- const result = await cloudbase.commonService("flexdb").call({
5576
- Action: "DeleteItem",
5577
- Param: {
5578
- TableName: collectionName,
5579
- MgoQuery: toJSONString(query),
5580
- MgoIsMulti: isMulti,
5581
- Tag: instanceId,
5582
- },
5583
- });
5584
- (0, cloudbase_manager_js_1.logCloudBaseResult)(logger, result);
5585
- return JSON.stringify({
5586
- success: true,
5587
- requestId: result.RequestId,
5588
- deleted: result.Deleted,
5589
- message: "文档删除成功",
5590
- }, null, 2);
5591
- }
5592
- catch (error) {
5593
- return JSON.stringify({
5594
- success: false,
5595
- error: error.message,
5596
- message: "文档删除失败",
5597
- }, null, 2);
5598
- }
5577
+ const cloudbase = await getManager();
5578
+ const instanceId = await getDatabaseInstanceId(getManager);
5579
+ const toJSONString = (v) => typeof v === "object" && v !== null ? JSON.stringify(v) : v;
5580
+ const result = await cloudbase.commonService("tcb", "2018-06-08").call({
5581
+ Action: "DeleteItem",
5582
+ Param: {
5583
+ TableName: collectionName,
5584
+ MgoQuery: toJSONString(query),
5585
+ MgoIsMulti: isMulti,
5586
+ Tag: instanceId,
5587
+ },
5588
+ });
5589
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(logger, result);
5590
+ return JSON.stringify({
5591
+ success: true,
5592
+ requestId: result.RequestId,
5593
+ deleted: result.Deleted,
5594
+ message: "文档删除成功",
5595
+ }, null, 2);
5599
5596
  }
5600
5597
 
5601
5598
 
@@ -6148,12 +6145,12 @@ function registerDataModelTools(server) {
6148
6145
  // 数据模型查询工具
6149
6146
  server.registerTool?.("manageDataModel", {
6150
6147
  title: "数据模型管理",
6151
- description: "数据模型查询工具,支持查询和列表数据模型(只读操作)。list操作返回基础信息(不含Schema),get操作返回详细信息(含简化的Schema,包括字段列表、格式、关联关系等),docs操作生成SDK使用文档",
6148
+ description: "数据模型查询工具,支持查询和列表数据模型(只读操作)。通过 action 参数区分操作类型:list=获取模型列表(不含Schema,可选 names 参数过滤),get=查询单个模型详情(含Schema字段列表、格式、关联关系等,需要提供 name 参数),docs=生成SDK使用文档(需要提供 name 参数)",
6152
6149
  inputSchema: {
6153
6150
  action: zod_1.z
6154
6151
  .enum(["get", "list", "docs"])
6155
- .describe("操作类型:get=查询单个模型(含Schema字段列表、格式、关联关系),list=获取模型列表(不含Schema),docs=生成SDK使用文档"),
6156
- name: zod_1.z.string().optional().describe("模型名称(get操作时必填)"),
6152
+ .describe("操作类型:get=查询单个模型(含Schema字段列表、格式、关联关系,需要提供 name 参数),list=获取模型列表(不含Schema,可选 names 参数过滤),docs=生成SDK使用文档(需要提供 name 参数)"),
6153
+ name: zod_1.z.string().optional().describe("要查询的数据模型名称。当 action='get' 或 action='docs' 时,此参数为必填项,必须提供已存在的数据模型名称。可通过 action='list' 操作获取可用的模型名称列表"),
6157
6154
  names: zod_1.z
6158
6155
  .array(zod_1.z.string())
6159
6156
  .optional()
@@ -6165,289 +6162,271 @@ function registerDataModelTools(server) {
6165
6162
  category: "database",
6166
6163
  },
6167
6164
  }, async ({ action, name, names, }) => {
6168
- try {
6169
- const cloudbase = await getManager();
6170
- let currentEnvId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
6171
- let result;
6172
- switch (action) {
6173
- case "get":
6174
- if (!name) {
6175
- throw new Error("获取数据模型需要提供模型名称");
6176
- }
6177
- try {
6178
- result = await cloudbase.commonService("lowcode").call({
6179
- Action: "DescribeBasicDataSource",
6180
- Param: {
6181
- EnvId: currentEnvId,
6182
- Name: name,
6183
- },
6184
- });
6185
- (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
6186
- // 只保留基础字段,过滤掉冗余信息,并简化Schema
6187
- let simplifiedSchema = null;
6188
- // 解析并简化Schema
6189
- if (result.Data.Schema) {
6190
- try {
6191
- const schema = JSON.parse(result.Data.Schema);
6192
- const properties = schema.properties || {};
6193
- // 提取用户定义的字段(排除系统字段)
6194
- const userFields = Object.keys(properties)
6195
- .filter((key) => !properties[key]["x-system"]) // 排除系统字段
6196
- .map((key) => {
6197
- const field = properties[key];
6198
- return parseFieldStructure(field, key, schema);
6199
- });
6200
- // 提取关联关系
6201
- const relations = userFields
6202
- .filter((field) => field.linkage)
6203
- .map((field) => ({
6204
- field: field.name,
6205
- type: field.format,
6206
- title: field.title,
6207
- targetModel: field.linkage.parentDataSourceName,
6208
- foreignKey: field.linkage.parentFieldKey,
6209
- displayField: field.linkage.parentFieldTitle,
6210
- }));
6211
- simplifiedSchema = {
6212
- userFields,
6213
- relations,
6214
- totalFields: Object.keys(properties).length,
6215
- userFieldsCount: userFields.length,
6216
- };
6217
- }
6218
- catch (e) {
6219
- simplifiedSchema = { error: "Schema解析失败" };
6220
- }
6165
+ const cloudbase = await getManager();
6166
+ let currentEnvId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
6167
+ let result;
6168
+ switch (action) {
6169
+ case "get":
6170
+ if (!name) {
6171
+ throw new Error("获取数据模型需要提供模型名称");
6172
+ }
6173
+ try {
6174
+ result = await cloudbase.commonService("lowcode").call({
6175
+ Action: "DescribeBasicDataSource",
6176
+ Param: {
6177
+ EnvId: currentEnvId,
6178
+ Name: name,
6179
+ },
6180
+ });
6181
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
6182
+ // 只保留基础字段,过滤掉冗余信息,并简化Schema
6183
+ let simplifiedSchema = null;
6184
+ // 解析并简化Schema
6185
+ if (result.Data.Schema) {
6186
+ try {
6187
+ const schema = JSON.parse(result.Data.Schema);
6188
+ const properties = schema.properties || {};
6189
+ // 提取用户定义的字段(排除系统字段)
6190
+ const userFields = Object.keys(properties)
6191
+ .filter((key) => !properties[key]["x-system"]) // 排除系统字段
6192
+ .map((key) => {
6193
+ const field = properties[key];
6194
+ return parseFieldStructure(field, key, schema);
6195
+ });
6196
+ // 提取关联关系
6197
+ const relations = userFields
6198
+ .filter((field) => field.linkage)
6199
+ .map((field) => ({
6200
+ field: field.name,
6201
+ type: field.format,
6202
+ title: field.title,
6203
+ targetModel: field.linkage.parentDataSourceName,
6204
+ foreignKey: field.linkage.parentFieldKey,
6205
+ displayField: field.linkage.parentFieldTitle,
6206
+ }));
6207
+ simplifiedSchema = {
6208
+ userFields,
6209
+ relations,
6210
+ totalFields: Object.keys(properties).length,
6211
+ userFieldsCount: userFields.length,
6212
+ };
6221
6213
  }
6222
- // 尝试生成Mermaid图表
6223
- let mermaidDiagram = null;
6224
- if (result.Data.Schema &&
6225
- jsonSchemaToMermaid &&
6226
- simplifiedSchema &&
6227
- !simplifiedSchema.error) {
6228
- try {
6229
- const mainSchema = JSON.parse(result.Data.Schema);
6230
- const schemasMap = {
6231
- [name]: mainSchema,
6232
- };
6233
- // 获取关联模型的 schema
6234
- if (simplifiedSchema.relations &&
6235
- simplifiedSchema.relations.length > 0) {
6236
- const relatedModelNames = [
6237
- ...new Set(simplifiedSchema.relations.map((rel) => rel.targetModel)),
6238
- ];
6239
- for (const relatedModelName of relatedModelNames) {
6240
- try {
6241
- const relatedResult = await cloudbase
6242
- .commonService("lowcode")
6243
- .call({
6244
- Action: "DescribeBasicDataSource",
6245
- Param: {
6246
- EnvId: currentEnvId,
6247
- Name: relatedModelName,
6248
- },
6249
- });
6250
- if (relatedResult.Data && relatedResult.Data.Schema) {
6251
- schemasMap[relatedModelName] = JSON.parse(relatedResult.Data.Schema);
6252
- }
6253
- }
6254
- catch (e) {
6255
- console.warn(`获取关联模型 ${relatedModelName} schema 失败:`, e);
6214
+ catch (e) {
6215
+ simplifiedSchema = { error: "Schema解析失败" };
6216
+ }
6217
+ }
6218
+ // 尝试生成Mermaid图表
6219
+ let mermaidDiagram = null;
6220
+ if (result.Data.Schema &&
6221
+ jsonSchemaToMermaid &&
6222
+ simplifiedSchema &&
6223
+ !simplifiedSchema.error) {
6224
+ try {
6225
+ const mainSchema = JSON.parse(result.Data.Schema);
6226
+ const schemasMap = {
6227
+ [name]: mainSchema,
6228
+ };
6229
+ // 获取关联模型的 schema
6230
+ if (simplifiedSchema.relations &&
6231
+ simplifiedSchema.relations.length > 0) {
6232
+ const relatedModelNames = [
6233
+ ...new Set(simplifiedSchema.relations.map((rel) => rel.targetModel)),
6234
+ ];
6235
+ for (const relatedModelName of relatedModelNames) {
6236
+ try {
6237
+ const relatedResult = await cloudbase
6238
+ .commonService("lowcode")
6239
+ .call({
6240
+ Action: "DescribeBasicDataSource",
6241
+ Param: {
6242
+ EnvId: currentEnvId,
6243
+ Name: relatedModelName,
6244
+ },
6245
+ });
6246
+ if (relatedResult.Data && relatedResult.Data.Schema) {
6247
+ schemasMap[relatedModelName] = JSON.parse(relatedResult.Data.Schema);
6256
6248
  }
6257
6249
  }
6250
+ catch (e) {
6251
+ console.warn(`获取关联模型 ${relatedModelName} 的 schema 失败:`, e);
6252
+ }
6258
6253
  }
6259
- // 调用 jsonSchemaToMermaid,传入正确的参数格式
6260
- mermaidDiagram = jsonSchemaToMermaid(schemasMap);
6261
- }
6262
- catch (e) {
6263
- console.warn("生成Mermaid图表失败:", e);
6264
6254
  }
6255
+ // 调用 jsonSchemaToMermaid,传入正确的参数格式
6256
+ mermaidDiagram = jsonSchemaToMermaid(schemasMap);
6265
6257
  }
6266
- const simplifiedModel = {
6267
- DbInstanceType: result.Data.DbInstanceType,
6268
- Title: result.Data.Title,
6269
- Description: result.Data.Description,
6270
- Name: result.Data.Name,
6271
- UpdatedAt: result.Data.UpdatedAt,
6272
- Schema: simplifiedSchema,
6273
- mermaid: mermaidDiagram,
6274
- };
6275
- return {
6276
- content: [
6277
- {
6278
- type: "text",
6279
- text: JSON.stringify({
6280
- success: true,
6281
- action: "get",
6282
- data: simplifiedModel,
6283
- message: "获取数据模型成功",
6284
- }, null, 2),
6285
- },
6286
- ],
6287
- };
6288
- }
6289
- catch (error) {
6290
- if (error.original?.Code === "ResourceNotFound") {
6291
- return {
6292
- content: [
6293
- {
6294
- type: "text",
6295
- text: JSON.stringify({
6296
- success: false,
6297
- action: "get",
6298
- error: "ResourceNotFound",
6299
- message: `数据模型 ${name} 不存在`,
6300
- }, null, 2),
6301
- },
6302
- ],
6303
- };
6258
+ catch (e) {
6259
+ console.warn("生成Mermaid图表失败:", e);
6304
6260
  }
6305
- throw error;
6306
6261
  }
6307
- case "list":
6308
- // 构建请求参数
6309
- const listParams = {
6310
- EnvId: currentEnvId,
6311
- PageIndex: 1,
6312
- PageSize: 1000,
6313
- QuerySystemModel: true, // 查询系统模型
6314
- QueryConnector: 0, // 0 表示数据模型
6262
+ const simplifiedModel = {
6263
+ DbInstanceType: result.Data.DbInstanceType,
6264
+ Title: result.Data.Title,
6265
+ Description: result.Data.Description,
6266
+ Name: result.Data.Name,
6267
+ UpdatedAt: result.Data.UpdatedAt,
6268
+ Schema: simplifiedSchema,
6269
+ mermaid: mermaidDiagram,
6315
6270
  };
6316
- // 只有当 names 参数存在且不为空时才添加过滤条件
6317
- if (names && names.length > 0) {
6318
- listParams.DataSourceNames = names;
6319
- }
6320
- result = await cloudbase.commonService("lowcode").call({
6321
- Action: "DescribeDataSourceList",
6322
- Param: listParams,
6323
- });
6324
- (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
6325
- const models = result.Data?.Rows || [];
6326
- // 只保留基础字段,list操作不返回Schema
6327
- const simplifiedModels = models.map((model) => ({
6328
- DbInstanceType: model.DbInstanceType,
6329
- Title: model.Title,
6330
- Description: model.Description,
6331
- Name: model.Name,
6332
- UpdatedAt: model.UpdatedAt,
6333
- }));
6334
6271
  return {
6335
6272
  content: [
6336
6273
  {
6337
6274
  type: "text",
6338
6275
  text: JSON.stringify({
6339
6276
  success: true,
6340
- action: "list",
6341
- data: simplifiedModels,
6342
- count: simplifiedModels.length,
6343
- message: "获取数据模型列表成功",
6277
+ action: "get",
6278
+ data: simplifiedModel,
6279
+ message: "获取数据模型成功",
6344
6280
  }, null, 2),
6345
6281
  },
6346
6282
  ],
6347
6283
  };
6348
- case "docs":
6349
- if (!name) {
6350
- throw new Error("生成SDK文档需要提供模型名称");
6351
- }
6352
- try {
6353
- // 先获取模型信息
6354
- result = await cloudbase.commonService("lowcode").call({
6355
- Action: "DescribeBasicDataSource",
6356
- Param: {
6357
- EnvId: currentEnvId,
6358
- Name: name,
6359
- },
6360
- });
6361
- (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
6362
- if (!result.Data) {
6363
- throw new Error(`数据模型 ${name} 不存在`);
6364
- }
6365
- // 解析Schema获取字段信息
6366
- let userFields = [];
6367
- let relations = [];
6368
- if (result.Data.Schema) {
6369
- try {
6370
- const schema = JSON.parse(result.Data.Schema);
6371
- const properties = schema.properties || {};
6372
- // 提取用户定义的字段
6373
- userFields = Object.keys(properties)
6374
- .filter((key) => !properties[key]["x-system"])
6375
- .map((key) => {
6376
- const field = properties[key];
6377
- return parseFieldStructure(field, key, schema);
6378
- });
6379
- // 提取关联关系
6380
- relations = userFields
6381
- .filter((field) => field.linkage)
6382
- .map((field) => ({
6383
- field: field.name,
6384
- type: field.format,
6385
- title: field.title,
6386
- targetModel: field.linkage.parentDataSourceName,
6387
- foreignKey: field.linkage.parentFieldKey,
6388
- displayField: field.linkage.parentFieldTitle,
6389
- }));
6390
- }
6391
- catch (e) {
6392
- // Schema解析失败,使用空数组
6393
- console.error("Schema解析失败", e);
6394
- }
6395
- }
6396
- // 生成SDK使用文档
6397
- const docs = generateSDKDocs(result.Data.Name, result.Data.Title, userFields, relations);
6284
+ }
6285
+ catch (error) {
6286
+ if (error.original?.Code === "ResourceNotFound") {
6398
6287
  return {
6399
6288
  content: [
6400
6289
  {
6401
6290
  type: "text",
6402
6291
  text: JSON.stringify({
6403
- success: true,
6404
- action: "docs",
6405
- modelName: name,
6406
- modelTitle: result.Data.Title,
6407
- docs,
6408
- message: "SDK使用文档生成成功",
6292
+ success: false,
6293
+ action: "get",
6294
+ error: "ResourceNotFound",
6295
+ message: `数据模型 ${name} 不存在`,
6409
6296
  }, null, 2),
6410
6297
  },
6411
6298
  ],
6412
6299
  };
6413
6300
  }
6414
- catch (error) {
6415
- if (error.original?.Code === "ResourceNotFound") {
6416
- return {
6417
- content: [
6418
- {
6419
- type: "text",
6420
- text: JSON.stringify({
6421
- success: false,
6422
- action: "docs",
6423
- error: "ResourceNotFound",
6424
- message: `数据模型 ${name} 不存在`,
6425
- }, null, 2),
6426
- },
6427
- ],
6428
- };
6301
+ throw error;
6302
+ }
6303
+ case "list":
6304
+ // 构建请求参数
6305
+ const listParams = {
6306
+ EnvId: currentEnvId,
6307
+ PageIndex: 1,
6308
+ PageSize: 1000,
6309
+ QuerySystemModel: true, // 查询系统模型
6310
+ QueryConnector: 0, // 0 表示数据模型
6311
+ };
6312
+ // 只有当 names 参数存在且不为空时才添加过滤条件
6313
+ if (names && names.length > 0) {
6314
+ listParams.DataSourceNames = names;
6315
+ }
6316
+ result = await cloudbase.commonService("lowcode").call({
6317
+ Action: "DescribeDataSourceList",
6318
+ Param: listParams,
6319
+ });
6320
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
6321
+ const models = result.Data?.Rows || [];
6322
+ // 只保留基础字段,list操作不返回Schema
6323
+ const simplifiedModels = models.map((model) => ({
6324
+ DbInstanceType: model.DbInstanceType,
6325
+ Title: model.Title,
6326
+ Description: model.Description,
6327
+ Name: model.Name,
6328
+ UpdatedAt: model.UpdatedAt,
6329
+ }));
6330
+ return {
6331
+ content: [
6332
+ {
6333
+ type: "text",
6334
+ text: JSON.stringify({
6335
+ success: true,
6336
+ action: "list",
6337
+ data: simplifiedModels,
6338
+ count: simplifiedModels.length,
6339
+ message: "获取数据模型列表成功",
6340
+ }, null, 2),
6341
+ },
6342
+ ],
6343
+ };
6344
+ case "docs":
6345
+ if (!name) {
6346
+ throw new Error("生成SDK文档需要提供模型名称");
6347
+ }
6348
+ try {
6349
+ // 先获取模型信息
6350
+ result = await cloudbase.commonService("lowcode").call({
6351
+ Action: "DescribeBasicDataSource",
6352
+ Param: {
6353
+ EnvId: currentEnvId,
6354
+ Name: name,
6355
+ },
6356
+ });
6357
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
6358
+ if (!result.Data) {
6359
+ throw new Error(`数据模型 ${name} 不存在`);
6360
+ }
6361
+ // 解析Schema获取字段信息
6362
+ let userFields = [];
6363
+ let relations = [];
6364
+ if (result.Data.Schema) {
6365
+ try {
6366
+ const schema = JSON.parse(result.Data.Schema);
6367
+ const properties = schema.properties || {};
6368
+ // 提取用户定义的字段
6369
+ userFields = Object.keys(properties)
6370
+ .filter((key) => !properties[key]["x-system"])
6371
+ .map((key) => {
6372
+ const field = properties[key];
6373
+ return parseFieldStructure(field, key, schema);
6374
+ });
6375
+ // 提取关联关系
6376
+ relations = userFields
6377
+ .filter((field) => field.linkage)
6378
+ .map((field) => ({
6379
+ field: field.name,
6380
+ type: field.format,
6381
+ title: field.title,
6382
+ targetModel: field.linkage.parentDataSourceName,
6383
+ foreignKey: field.linkage.parentFieldKey,
6384
+ displayField: field.linkage.parentFieldTitle,
6385
+ }));
6386
+ }
6387
+ catch (e) {
6388
+ // Schema解析失败,使用空数组
6389
+ console.error("Schema解析失败", e);
6429
6390
  }
6430
- throw error;
6431
6391
  }
6432
- default:
6433
- throw new Error(`不支持的操作类型: ${action}`);
6434
- }
6435
- }
6436
- catch (error) {
6437
- return {
6438
- content: [
6439
- {
6440
- type: "text",
6441
- text: JSON.stringify({
6442
- success: false,
6443
- action,
6444
- error: error.message || error.original?.Message || "未知错误",
6445
- code: error.original?.Code,
6446
- message: "数据模型操作失败",
6447
- }, null, 2),
6448
- },
6449
- ],
6450
- };
6392
+ // 生成SDK使用文档
6393
+ const docs = generateSDKDocs(result.Data.Name, result.Data.Title, userFields, relations);
6394
+ return {
6395
+ content: [
6396
+ {
6397
+ type: "text",
6398
+ text: JSON.stringify({
6399
+ success: true,
6400
+ action: "docs",
6401
+ modelName: name,
6402
+ modelTitle: result.Data.Title,
6403
+ docs,
6404
+ message: "SDK使用文档生成成功",
6405
+ }, null, 2),
6406
+ },
6407
+ ],
6408
+ };
6409
+ }
6410
+ catch (error) {
6411
+ if (error.original?.Code === "ResourceNotFound") {
6412
+ return {
6413
+ content: [
6414
+ {
6415
+ type: "text",
6416
+ text: JSON.stringify({
6417
+ success: false,
6418
+ action: "docs",
6419
+ error: "ResourceNotFound",
6420
+ message: `数据模型 ${name} 不存在`,
6421
+ }, null, 2),
6422
+ },
6423
+ ],
6424
+ };
6425
+ }
6426
+ throw error;
6427
+ }
6428
+ default:
6429
+ throw new Error(`不支持的操作类型: ${action}`);
6451
6430
  }
6452
6431
  });
6453
6432
  // modifyDataModel - 数据模型修改工具(创建/更新)
@@ -6520,126 +6499,108 @@ classDiagram
6520
6499
  category: "database",
6521
6500
  },
6522
6501
  }, async ({ mermaidDiagram, action = "create", publish = false, dbInstanceType = "MYSQL", }) => {
6523
- try {
6524
- const cloudbase = await getManager();
6525
- let currentEnvId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
6526
- // 使用mermaidToJsonSchema转换Mermaid图表
6527
- const schemas = mermaidToJsonSchema(mermaidDiagram);
6528
- if (!schemas || Object.keys(schemas).length === 0) {
6529
- return {
6530
- content: [
6531
- {
6532
- type: "text",
6533
- text: JSON.stringify({
6534
- success: false,
6535
- error: "No schemas generated from Mermaid diagram",
6536
- message: "无法从Mermaid图表生成数据模型Schema",
6537
- }, null, 2),
6538
- },
6539
- ],
6540
- };
6541
- }
6542
- // 创建数据模型列表
6543
- const createDataModelList = Object.entries(schemas).map(([name, schema]) => {
6544
- return {
6545
- CreateSource: "cloudbase_create",
6546
- Creator: null,
6547
- DbLinkName: null,
6548
- Description: schema.description ||
6549
- `${schema.title || name}数据模型`,
6550
- Schema: JSON.stringify(createBackendSchemaParams(schema)),
6551
- Title: schema.title || name,
6552
- Name: name,
6553
- TableNameRule: "only_name",
6554
- };
6555
- });
6556
- // 调用批量创建数据模型API
6557
- const result = await cloudbase.commonService("lowcode").call({
6558
- Action: "BatchCreateDataModelList",
6559
- Param: {
6560
- CreateDataModelList: createDataModelList,
6561
- Creator: null,
6562
- DbInstanceType: dbInstanceType,
6563
- EnvId: currentEnvId,
6564
- },
6565
- });
6566
- (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
6567
- const taskId = result.Data?.TaskId;
6568
- if (!taskId) {
6569
- return {
6570
- content: [
6571
- {
6572
- type: "text",
6573
- text: JSON.stringify({
6574
- success: false,
6575
- requestId: result.RequestId,
6576
- error: "No TaskId returned",
6577
- message: "创建任务失败,未返回任务ID",
6578
- }, null, 2),
6579
- },
6580
- ],
6581
- };
6582
- }
6583
- // 轮询任务状态直至完成或超时
6584
- const maxWaitTime = 30000; // 30秒超时
6585
- const startTime = Date.now();
6586
- let status = "init";
6587
- let statusResult = null;
6588
- while (status === "init" && Date.now() - startTime < maxWaitTime) {
6589
- await new Promise((resolve) => setTimeout(resolve, 2000)); // 等待2秒
6590
- statusResult = await cloudbase.commonService("lowcode").call({
6591
- Action: "QueryModelTaskStatus",
6592
- Param: {
6593
- EnvId: currentEnvId,
6594
- TaskId: taskId,
6595
- },
6596
- });
6597
- (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, statusResult);
6598
- status = statusResult.Data?.Status || "init";
6599
- }
6600
- // 返回最终结果
6601
- const models = Object.keys(schemas);
6602
- const successModels = statusResult?.Data?.SuccessResourceIdList || [];
6603
- const failedModels = models.filter((model) => !successModels.includes(model));
6502
+ const cloudbase = await getManager();
6503
+ let currentEnvId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
6504
+ const schemas = mermaidToJsonSchema(mermaidDiagram);
6505
+ if (!schemas || Object.keys(schemas).length === 0) {
6604
6506
  return {
6605
6507
  content: [
6606
6508
  {
6607
6509
  type: "text",
6608
6510
  text: JSON.stringify({
6609
- success: status === "success",
6610
- requestId: result.RequestId,
6611
- taskId: taskId,
6612
- models: models,
6613
- successModels: successModels,
6614
- failedModels: failedModels,
6615
- status: status,
6616
- action: action,
6617
- message: status === "success"
6618
- ? `数据模型${action === "create" ? "创建" : "更新"}成功,共处理${models.length}个模型`
6619
- : status === "init"
6620
- ? `任务超时,任务ID: ${taskId},请稍后手动查询状态`
6621
- : `数据模型${action === "create" ? "创建" : "更新"}失败`,
6622
- taskResult: statusResult?.Data,
6511
+ success: false,
6512
+ error: "No schemas generated from Mermaid diagram",
6513
+ message: "无法从Mermaid图表生成数据模型Schema",
6623
6514
  }, null, 2),
6624
6515
  },
6625
6516
  ],
6626
6517
  };
6627
6518
  }
6628
- catch (error) {
6519
+ // 创建数据模型列表
6520
+ const createDataModelList = Object.entries(schemas).map(([name, schema]) => {
6521
+ return {
6522
+ CreateSource: "cloudbase_create",
6523
+ Creator: null,
6524
+ DbLinkName: null,
6525
+ Description: schema.description ||
6526
+ `${schema.title || name}数据模型`,
6527
+ Schema: JSON.stringify(createBackendSchemaParams(schema)),
6528
+ Title: schema.title || name,
6529
+ Name: name,
6530
+ TableNameRule: "only_name",
6531
+ };
6532
+ });
6533
+ // 调用批量创建数据模型API
6534
+ const result = await cloudbase.commonService("lowcode").call({
6535
+ Action: "BatchCreateDataModelList",
6536
+ Param: {
6537
+ CreateDataModelList: createDataModelList,
6538
+ Creator: null,
6539
+ DbInstanceType: dbInstanceType,
6540
+ EnvId: currentEnvId,
6541
+ },
6542
+ });
6543
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
6544
+ const taskId = result.Data?.TaskId;
6545
+ if (!taskId) {
6629
6546
  return {
6630
6547
  content: [
6631
6548
  {
6632
6549
  type: "text",
6633
6550
  text: JSON.stringify({
6634
6551
  success: false,
6635
- error: error.message || error.original?.Message || "未知错误",
6636
- code: error.original?.Code,
6637
- message: "数据模型修改操作失败",
6552
+ requestId: result.RequestId,
6553
+ error: "No TaskId returned",
6554
+ message: "创建任务失败,未返回任务ID",
6638
6555
  }, null, 2),
6639
6556
  },
6640
6557
  ],
6641
6558
  };
6642
6559
  }
6560
+ // 轮询任务状态直至完成或超时
6561
+ const maxWaitTime = 30000; // 30秒超时
6562
+ const startTime = Date.now();
6563
+ let status = "init";
6564
+ let statusResult = null;
6565
+ while (status === "init" && Date.now() - startTime < maxWaitTime) {
6566
+ await new Promise((resolve) => setTimeout(resolve, 2000)); // 等待2秒
6567
+ statusResult = await cloudbase.commonService("lowcode").call({
6568
+ Action: "QueryModelTaskStatus",
6569
+ Param: {
6570
+ EnvId: currentEnvId,
6571
+ TaskId: taskId,
6572
+ },
6573
+ });
6574
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, statusResult);
6575
+ status = statusResult.Data?.Status || "init";
6576
+ }
6577
+ // 返回最终结果
6578
+ const models = Object.keys(schemas);
6579
+ const successModels = statusResult?.Data?.SuccessResourceIdList || [];
6580
+ const failedModels = models.filter((model) => !successModels.includes(model));
6581
+ return {
6582
+ content: [
6583
+ {
6584
+ type: "text",
6585
+ text: JSON.stringify({
6586
+ success: status === "success",
6587
+ requestId: result.RequestId,
6588
+ taskId: taskId,
6589
+ models: models,
6590
+ successModels: successModels,
6591
+ failedModels: failedModels,
6592
+ status: status,
6593
+ action: action,
6594
+ message: status === "success"
6595
+ ? `数据模型${action === "create" ? "创建" : "更新"}成功,共处理${models.length}个模型`
6596
+ : status === "init"
6597
+ ? `任务超时,任务ID: ${taskId},请稍后手动查询状态`
6598
+ : `数据模型${action === "create" ? "创建" : "更新"}失败`,
6599
+ taskResult: statusResult?.Data,
6600
+ }, null, 2),
6601
+ },
6602
+ ],
6603
+ };
6643
6604
  });
6644
6605
  }
6645
6606
 
@@ -7454,41 +7415,25 @@ function registerInviteCodeTools(server) {
7454
7415
  ]
7455
7416
  };
7456
7417
  }
7457
- try {
7458
- const manager = await getManager();
7459
- const EnvId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
7460
- const result = await manager.commonService().call({
7461
- Action: 'ActivateInviteCode',
7462
- Param: { InviteCode, EnvId }
7463
- });
7464
- (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
7465
- return {
7466
- content: [
7467
- {
7468
- type: "text",
7469
- text: JSON.stringify({
7470
- ErrorCode: result?.ErrorCode || '',
7471
- ErrorMsg: result?.ErrorMsg || '',
7472
- RequestId: result?.RequestId || ''
7473
- }, null, 2)
7474
- }
7475
- ]
7476
- };
7477
- }
7478
- catch (e) {
7479
- return {
7480
- content: [
7481
- {
7482
- type: "text",
7483
- text: JSON.stringify({
7484
- ErrorCode: e.code || 'Exception',
7485
- ErrorMsg: '激活失败:' + e.message,
7486
- RequestId: e.RequestId || ''
7487
- }, null, 2)
7488
- }
7489
- ]
7490
- };
7491
- }
7418
+ const manager = await getManager();
7419
+ const EnvId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
7420
+ const result = await manager.commonService().call({
7421
+ Action: 'ActivateInviteCode',
7422
+ Param: { InviteCode, EnvId }
7423
+ });
7424
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
7425
+ return {
7426
+ content: [
7427
+ {
7428
+ type: "text",
7429
+ text: JSON.stringify({
7430
+ ErrorCode: result?.ErrorCode || '',
7431
+ ErrorMsg: result?.ErrorMsg || '',
7432
+ RequestId: result?.RequestId || ''
7433
+ }, null, 2)
7434
+ }
7435
+ ]
7436
+ };
7492
7437
  });
7493
7438
  }
7494
7439
 
@@ -7533,94 +7478,78 @@ function registerStorageTools(server) {
7533
7478
  category: "storage"
7534
7479
  }
7535
7480
  }, async (args) => {
7536
- try {
7537
- const input = args;
7538
- const manager = await getManager();
7539
- if (!manager) {
7540
- throw new Error("Failed to initialize CloudBase manager. Please check your credentials and environment configuration.");
7541
- }
7542
- const storageService = manager.storage;
7543
- switch (input.action) {
7544
- case 'list': {
7545
- const result = await storageService.listDirectoryFiles(input.cloudPath);
7546
- return {
7547
- content: [
7548
- {
7549
- type: "text",
7550
- text: JSON.stringify({
7551
- success: true,
7552
- data: {
7553
- action: 'list',
7554
- cloudPath: input.cloudPath,
7555
- files: result || [],
7556
- totalCount: result?.length || 0
7557
- },
7558
- message: `Successfully listed ${result?.length || 0} files in directory '${input.cloudPath}'`
7559
- }, null, 2)
7560
- }
7561
- ]
7562
- };
7563
- }
7564
- case 'info': {
7565
- const result = await storageService.getFileInfo(input.cloudPath);
7566
- return {
7567
- content: [
7568
- {
7569
- type: "text",
7570
- text: JSON.stringify({
7571
- success: true,
7572
- data: {
7573
- action: 'info',
7574
- cloudPath: input.cloudPath,
7575
- fileInfo: result
7576
- },
7577
- message: `Successfully retrieved file info for '${input.cloudPath}'`
7578
- }, null, 2)
7579
- }
7580
- ]
7581
- };
7582
- }
7583
- case 'url': {
7584
- const result = await storageService.getTemporaryUrl([{
7585
- cloudPath: input.cloudPath,
7586
- maxAge: input.maxAge || 3600
7587
- }]);
7588
- return {
7589
- content: [
7590
- {
7591
- type: "text",
7592
- text: JSON.stringify({
7593
- success: true,
7594
- data: {
7595
- action: 'url',
7596
- cloudPath: input.cloudPath,
7597
- temporaryUrl: result[0]?.url || "",
7598
- expireTime: `${input.maxAge || 3600}秒`,
7599
- fileId: result[0]?.fileId || ""
7600
- },
7601
- message: `Successfully generated temporary URL for '${input.cloudPath}'`
7602
- }, null, 2)
7603
- }
7604
- ]
7605
- };
7606
- }
7607
- default:
7608
- throw new Error(`Unsupported action: ${input.action}`);
7481
+ const input = args;
7482
+ const manager = await getManager();
7483
+ if (!manager) {
7484
+ throw new Error("Failed to initialize CloudBase manager. Please check your credentials and environment configuration.");
7485
+ }
7486
+ const storageService = manager.storage;
7487
+ switch (input.action) {
7488
+ case 'list': {
7489
+ const result = await storageService.listDirectoryFiles(input.cloudPath);
7490
+ return {
7491
+ content: [
7492
+ {
7493
+ type: "text",
7494
+ text: JSON.stringify({
7495
+ success: true,
7496
+ data: {
7497
+ action: 'list',
7498
+ cloudPath: input.cloudPath,
7499
+ files: result || [],
7500
+ totalCount: result?.length || 0
7501
+ },
7502
+ message: `Successfully listed ${result?.length || 0} files in directory '${input.cloudPath}'`
7503
+ }, null, 2)
7504
+ }
7505
+ ]
7506
+ };
7507
+ }
7508
+ case 'info': {
7509
+ const result = await storageService.getFileInfo(input.cloudPath);
7510
+ return {
7511
+ content: [
7512
+ {
7513
+ type: "text",
7514
+ text: JSON.stringify({
7515
+ success: true,
7516
+ data: {
7517
+ action: 'info',
7518
+ cloudPath: input.cloudPath,
7519
+ fileInfo: result
7520
+ },
7521
+ message: `Successfully retrieved file info for '${input.cloudPath}'`
7522
+ }, null, 2)
7523
+ }
7524
+ ]
7525
+ };
7526
+ }
7527
+ case 'url': {
7528
+ const result = await storageService.getTemporaryUrl([{
7529
+ cloudPath: input.cloudPath,
7530
+ maxAge: input.maxAge || 3600
7531
+ }]);
7532
+ return {
7533
+ content: [
7534
+ {
7535
+ type: "text",
7536
+ text: JSON.stringify({
7537
+ success: true,
7538
+ data: {
7539
+ action: 'url',
7540
+ cloudPath: input.cloudPath,
7541
+ temporaryUrl: result[0]?.url || "",
7542
+ expireTime: `${input.maxAge || 3600}秒`,
7543
+ fileId: result[0]?.fileId || ""
7544
+ },
7545
+ message: `Successfully generated temporary URL for '${input.cloudPath}'`
7546
+ }, null, 2)
7547
+ }
7548
+ ]
7549
+ };
7609
7550
  }
7610
- }
7611
- catch (error) {
7612
- return {
7613
- content: [
7614
- {
7615
- type: "text",
7616
- text: JSON.stringify({
7617
- success: false,
7618
- error: error.message || 'Unknown error occurred',
7619
- message: `Failed to query storage information. Please check your permissions and parameters.`
7620
- }, null, 2)
7621
- }
7622
- ]
7623
- };
7551
+ default:
7552
+ throw new Error(`Unsupported action: ${input.action}`);
7624
7553
  }
7625
7554
  });
7626
7555
  // Tool 2: manageStorage - 管理存储文件(写操作)
@@ -7636,156 +7565,153 @@ function registerStorageTools(server) {
7636
7565
  category: "storage"
7637
7566
  }
7638
7567
  }, async (args) => {
7639
- try {
7640
- const input = args;
7641
- const manager = await getManager();
7642
- if (!manager) {
7643
- throw new Error("Failed to initialize CloudBase manager. Please check your credentials and environment configuration.");
7644
- }
7645
- const storageService = manager.storage;
7646
- switch (input.action) {
7647
- case 'upload': {
7648
- if (input.isDirectory) {
7649
- // 上传目录
7650
- await storageService.uploadDirectory({
7651
- localPath: input.localPath,
7652
- cloudPath: input.cloudPath,
7653
- onProgress: (progressData) => {
7654
- console.log("Upload directory progress:", progressData);
7655
- }
7656
- });
7657
- }
7658
- else {
7659
- // 上传文件
7660
- await storageService.uploadFile({
7661
- localPath: input.localPath,
7662
- cloudPath: input.cloudPath,
7663
- onProgress: (progressData) => {
7664
- console.log("Upload file progress:", progressData);
7665
- }
7666
- });
7667
- }
7668
- // 获取文件临时下载地址
7669
- const fileUrls = await storageService.getTemporaryUrl([{
7670
- cloudPath: input.cloudPath,
7671
- maxAge: 3600 // 临时链接有效期1小时
7672
- }]);
7673
- return {
7674
- content: [
7675
- {
7676
- type: "text",
7677
- text: JSON.stringify({
7678
- success: true,
7679
- data: {
7680
- action: 'upload',
7681
- localPath: input.localPath,
7682
- cloudPath: input.cloudPath,
7683
- isDirectory: input.isDirectory,
7684
- temporaryUrl: fileUrls[0]?.url || "",
7685
- expireTime: "1小时"
7686
- },
7687
- message: `Successfully uploaded ${input.isDirectory ? 'directory' : 'file'} from '${input.localPath}' to '${input.cloudPath}'`
7688
- }, null, 2)
7689
- }
7690
- ]
7691
- };
7568
+ const input = args;
7569
+ const manager = await getManager();
7570
+ if (!manager) {
7571
+ throw new Error("Failed to initialize CloudBase manager. Please check your credentials and environment configuration.");
7572
+ }
7573
+ const storageService = manager.storage;
7574
+ switch (input.action) {
7575
+ case 'upload': {
7576
+ if (input.isDirectory) {
7577
+ await storageService.uploadDirectory({
7578
+ localPath: input.localPath,
7579
+ cloudPath: input.cloudPath,
7580
+ onProgress: (progressData) => {
7581
+ console.log("Upload directory progress:", progressData);
7582
+ }
7583
+ });
7692
7584
  }
7693
- case 'download': {
7694
- if (input.isDirectory) {
7695
- // 下载目录
7696
- await storageService.downloadDirectory({
7697
- cloudPath: input.cloudPath,
7698
- localPath: input.localPath
7699
- });
7700
- }
7701
- else {
7702
- // 下载文件
7703
- await storageService.downloadFile({
7704
- cloudPath: input.cloudPath,
7705
- localPath: input.localPath
7706
- });
7707
- }
7708
- return {
7709
- content: [
7710
- {
7711
- type: "text",
7712
- text: JSON.stringify({
7713
- success: true,
7714
- data: {
7715
- action: 'download',
7716
- cloudPath: input.cloudPath,
7717
- localPath: input.localPath,
7718
- isDirectory: input.isDirectory
7719
- },
7720
- message: `Successfully downloaded ${input.isDirectory ? 'directory' : 'file'} from '${input.cloudPath}' to '${input.localPath}'`
7721
- }, null, 2)
7722
- }
7723
- ]
7724
- };
7585
+ else {
7586
+ await storageService.uploadFile({
7587
+ localPath: input.localPath,
7588
+ cloudPath: input.cloudPath,
7589
+ onProgress: (progressData) => {
7590
+ console.log("Upload file progress:", progressData);
7591
+ }
7592
+ });
7725
7593
  }
7726
- case 'delete': {
7727
- if (!input.force) {
7728
- return {
7729
- content: [
7730
- {
7731
- type: "text",
7732
- text: JSON.stringify({
7733
- success: false,
7734
- error: "Delete operation requires confirmation",
7735
- message: "Please set force: true to confirm deletion. This action cannot be undone."
7736
- }, null, 2)
7737
- }
7738
- ]
7739
- };
7740
- }
7741
- if (input.isDirectory) {
7742
- // 删除目录
7743
- await storageService.deleteDirectory(input.cloudPath);
7744
- }
7745
- else {
7746
- // 删除文件
7747
- await storageService.deleteFile([input.cloudPath]);
7748
- }
7594
+ const fileUrls = await storageService.getTemporaryUrl([{
7595
+ cloudPath: input.cloudPath,
7596
+ maxAge: 3600
7597
+ }]);
7598
+ return {
7599
+ content: [
7600
+ {
7601
+ type: "text",
7602
+ text: JSON.stringify({
7603
+ success: true,
7604
+ data: {
7605
+ action: 'upload',
7606
+ localPath: input.localPath,
7607
+ cloudPath: input.cloudPath,
7608
+ isDirectory: input.isDirectory,
7609
+ temporaryUrl: fileUrls[0]?.url || "",
7610
+ expireTime: "1小时"
7611
+ },
7612
+ message: `Successfully uploaded ${input.isDirectory ? 'directory' : 'file'} from '${input.localPath}' to '${input.cloudPath}'`
7613
+ }, null, 2)
7614
+ }
7615
+ ]
7616
+ };
7617
+ }
7618
+ case 'download': {
7619
+ if (input.isDirectory) {
7620
+ await storageService.downloadDirectory({
7621
+ cloudPath: input.cloudPath,
7622
+ localPath: input.localPath
7623
+ });
7624
+ }
7625
+ else {
7626
+ await storageService.downloadFile({
7627
+ cloudPath: input.cloudPath,
7628
+ localPath: input.localPath
7629
+ });
7630
+ }
7631
+ return {
7632
+ content: [
7633
+ {
7634
+ type: "text",
7635
+ text: JSON.stringify({
7636
+ success: true,
7637
+ data: {
7638
+ action: 'download',
7639
+ cloudPath: input.cloudPath,
7640
+ localPath: input.localPath,
7641
+ isDirectory: input.isDirectory
7642
+ },
7643
+ message: `Successfully downloaded ${input.isDirectory ? 'directory' : 'file'} from '${input.cloudPath}' to '${input.localPath}'`
7644
+ }, null, 2)
7645
+ }
7646
+ ]
7647
+ };
7648
+ }
7649
+ case 'delete': {
7650
+ if (!input.force) {
7749
7651
  return {
7750
7652
  content: [
7751
7653
  {
7752
7654
  type: "text",
7753
7655
  text: JSON.stringify({
7754
- success: true,
7755
- data: {
7756
- action: 'delete',
7757
- cloudPath: input.cloudPath,
7758
- isDirectory: input.isDirectory,
7759
- deleted: true
7760
- },
7761
- message: `Successfully deleted ${input.isDirectory ? 'directory' : 'file'} '${input.cloudPath}'`
7656
+ success: false,
7657
+ error: "Delete operation requires confirmation",
7658
+ message: "Please set force: true to confirm deletion. This action cannot be undone."
7762
7659
  }, null, 2)
7763
7660
  }
7764
7661
  ]
7765
7662
  };
7766
7663
  }
7767
- default:
7768
- throw new Error(`Unsupported action: ${input.action}`);
7664
+ if (input.isDirectory) {
7665
+ await storageService.deleteDirectory(input.cloudPath);
7666
+ }
7667
+ else {
7668
+ await storageService.deleteFile([input.cloudPath]);
7669
+ }
7670
+ return {
7671
+ content: [
7672
+ {
7673
+ type: "text",
7674
+ text: JSON.stringify({
7675
+ success: true,
7676
+ data: {
7677
+ action: 'delete',
7678
+ cloudPath: input.cloudPath,
7679
+ isDirectory: input.isDirectory,
7680
+ deleted: true
7681
+ },
7682
+ message: `Successfully deleted ${input.isDirectory ? 'directory' : 'file'} '${input.cloudPath}'`
7683
+ }, null, 2)
7684
+ }
7685
+ ]
7686
+ };
7769
7687
  }
7770
- }
7771
- catch (error) {
7772
- return {
7773
- content: [
7774
- {
7775
- type: "text",
7776
- text: JSON.stringify({
7777
- success: false,
7778
- error: error.message || 'Unknown error occurred',
7779
- message: `Failed to manage storage. Please check your permissions and parameters.`
7780
- }, null, 2)
7781
- }
7782
- ]
7783
- };
7688
+ default:
7689
+ throw new Error(`Unsupported action: ${input.action}`);
7784
7690
  }
7785
7691
  });
7786
7692
  }
7787
7693
 
7788
7694
 
7695
+ /***/ }),
7696
+
7697
+ /***/ 5018:
7698
+ /***/ ((__unused_webpack_module, exports) => {
7699
+
7700
+
7701
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
7702
+ exports.isInternationalRegion = void 0;
7703
+ exports.isValidRegion = isValidRegion;
7704
+ const REGION = {
7705
+ SHANGHAI: 'ap-shanghai',
7706
+ SINGAPORE: 'ap-singapore',
7707
+ };
7708
+ const isInternationalRegion = (region) => region === REGION.SINGAPORE;
7709
+ exports.isInternationalRegion = isInternationalRegion;
7710
+ function isValidRegion(region) {
7711
+ return Object.values(REGION).includes(region);
7712
+ }
7713
+
7714
+
7789
7715
  /***/ }),
7790
7716
 
7791
7717
  /***/ 5023:
@@ -7934,113 +7860,97 @@ function registerCloudRunTools(server) {
7934
7860
  category: "cloudrun"
7935
7861
  }
7936
7862
  }, async (args) => {
7937
- try {
7938
- const input = args;
7939
- const manager = await getManager();
7940
- if (!manager) {
7941
- throw new Error("Failed to initialize CloudBase manager. Please check your credentials and environment configuration.");
7942
- }
7943
- const cloudrunService = manager.cloudrun;
7944
- switch (input.action) {
7945
- case 'list': {
7946
- const listParams = {
7947
- pageSize: input.pageSize,
7948
- pageNum: input.pageNum,
7949
- };
7950
- if (input.serverName) {
7951
- listParams.serverName = input.serverName;
7952
- }
7953
- if (input.serverType) {
7954
- listParams.serverType = input.serverType;
7955
- }
7956
- const result = await cloudrunService.list(listParams);
7957
- return {
7958
- content: [
7959
- {
7960
- type: "text",
7961
- text: JSON.stringify({
7962
- success: true,
7963
- data: {
7964
- services: result.ServerList || [],
7965
- pagination: {
7966
- total: result.Total || 0,
7967
- pageSize: input.pageSize,
7968
- pageNum: input.pageNum,
7969
- totalPages: Math.ceil((result.Total || 0) / (input.pageSize || 10))
7970
- }
7971
- },
7972
- message: `Found ${result.ServerList?.length || 0} CloudRun services`
7973
- }, null, 2)
7974
- }
7975
- ]
7976
- };
7863
+ const input = args;
7864
+ const manager = await getManager();
7865
+ if (!manager) {
7866
+ throw new Error("Failed to initialize CloudBase manager. Please check your credentials and environment configuration.");
7867
+ }
7868
+ const cloudrunService = manager.cloudrun;
7869
+ switch (input.action) {
7870
+ case 'list': {
7871
+ const listParams = {
7872
+ pageSize: input.pageSize,
7873
+ pageNum: input.pageNum,
7874
+ };
7875
+ if (input.serverName) {
7876
+ listParams.serverName = input.serverName;
7977
7877
  }
7978
- case 'detail': {
7979
- const serverName = input.detailServerName || input.serverName;
7980
- const result = await cloudrunService.detail({ serverName });
7981
- if (!result) {
7982
- return {
7983
- content: [
7984
- {
7985
- type: "text",
7986
- text: JSON.stringify({
7987
- success: false,
7988
- error: `Service '${serverName}' not found`,
7989
- message: "Please check the service name and try again."
7990
- }, null, 2)
7991
- }
7992
- ]
7993
- };
7994
- }
7995
- return {
7996
- content: [
7997
- {
7998
- type: "text",
7999
- text: JSON.stringify({
8000
- success: true,
8001
- data: {
8002
- service: result
8003
- },
8004
- message: `Retrieved details for service '${serverName}'`
8005
- }, null, 2)
8006
- }
8007
- ]
8008
- };
7878
+ if (input.serverType) {
7879
+ listParams.serverType = input.serverType;
8009
7880
  }
8010
- case 'templates': {
8011
- const result = await cloudrunService.getTemplates();
7881
+ const result = await cloudrunService.list(listParams);
7882
+ return {
7883
+ content: [
7884
+ {
7885
+ type: "text",
7886
+ text: JSON.stringify({
7887
+ success: true,
7888
+ data: {
7889
+ services: result.ServerList || [],
7890
+ pagination: {
7891
+ total: result.Total || 0,
7892
+ pageSize: input.pageSize,
7893
+ pageNum: input.pageNum,
7894
+ totalPages: Math.ceil((result.Total || 0) / (input.pageSize || 10))
7895
+ }
7896
+ },
7897
+ message: `Found ${result.ServerList?.length || 0} CloudRun services`
7898
+ }, null, 2)
7899
+ }
7900
+ ]
7901
+ };
7902
+ }
7903
+ case 'detail': {
7904
+ const serverName = input.detailServerName || input.serverName;
7905
+ const result = await cloudrunService.detail({ serverName });
7906
+ if (!result) {
8012
7907
  return {
8013
7908
  content: [
8014
7909
  {
8015
7910
  type: "text",
8016
7911
  text: JSON.stringify({
8017
- success: true,
8018
- data: {
8019
- templates: result || []
8020
- },
8021
- message: `Found ${result?.length || 0} available templates`
7912
+ success: false,
7913
+ error: `Service '${serverName}' not found`,
7914
+ message: "Please check the service name and try again."
8022
7915
  }, null, 2)
8023
7916
  }
8024
7917
  ]
8025
7918
  };
8026
7919
  }
8027
- default:
8028
- throw new Error(`Unsupported action: ${input.action}`);
7920
+ return {
7921
+ content: [
7922
+ {
7923
+ type: "text",
7924
+ text: JSON.stringify({
7925
+ success: true,
7926
+ data: {
7927
+ service: result
7928
+ },
7929
+ message: `Retrieved details for service '${serverName}'`
7930
+ }, null, 2)
7931
+ }
7932
+ ]
7933
+ };
8029
7934
  }
8030
- }
8031
- catch (error) {
8032
- return {
8033
- content: [
8034
- {
8035
- type: "text",
8036
- text: JSON.stringify({
8037
- success: false,
8038
- error: error.message || 'Unknown error occurred',
8039
- message: "Failed to query CloudRun information. Please check your permissions and try again."
8040
- }, null, 2)
8041
- }
8042
- ]
8043
- };
7935
+ case 'templates': {
7936
+ const result = await cloudrunService.getTemplates();
7937
+ return {
7938
+ content: [
7939
+ {
7940
+ type: "text",
7941
+ text: JSON.stringify({
7942
+ success: true,
7943
+ data: {
7944
+ templates: result || []
7945
+ },
7946
+ message: `Found ${result?.length || 0} available templates`
7947
+ }, null, 2)
7948
+ }
7949
+ ]
7950
+ };
7951
+ }
7952
+ default:
7953
+ throw new Error(`Unsupported action: ${input.action}`);
8044
7954
  }
8045
7955
  });
8046
7956
  // Track local running processes for CloudRun function services
@@ -8058,62 +7968,60 @@ function registerCloudRunTools(server) {
8058
7968
  category: "cloudrun"
8059
7969
  }
8060
7970
  }, async (args) => {
8061
- try {
8062
- const input = args;
8063
- const manager = await getManager();
8064
- if (!manager) {
8065
- throw new Error("Failed to initialize CloudBase manager. Please check your credentials and environment configuration.");
8066
- }
8067
- const cloudrunService = manager.cloudrun;
8068
- let targetPath;
8069
- // Validate and normalize path for operations that require it
8070
- if (input.targetPath) {
8071
- targetPath = validateAndNormalizePath(input.targetPath);
8072
- }
8073
- switch (input.action) {
8074
- case 'createAgent': {
8075
- if (!targetPath) {
8076
- throw new Error("targetPath is required for createAgent operation");
8077
- }
8078
- if (!input.agentConfig) {
8079
- throw new Error("agentConfig is required for createAgent operation");
8080
- }
8081
- const { agentName, botTag, description, template = 'blank' } = input.agentConfig;
8082
- // Generate BotId
8083
- const botId = botTag ? `ibot-${agentName}-${botTag}` : `ibot-${agentName}-${Date.now()}`;
8084
- // Create Agent using CloudBase Manager
8085
- const agentResult = await manager.agent.createFunctionAgent(targetPath, {
8086
- Name: agentName,
8087
- BotId: botId,
8088
- Introduction: description || `Agent created by ${agentName}`,
8089
- Avatar: undefined
8090
- });
8091
- // Create project directory
8092
- const projectDir = path_1.default.join(targetPath, input.serverName);
8093
- if (!fs_1.default.existsSync(projectDir)) {
8094
- fs_1.default.mkdirSync(projectDir, { recursive: true });
7971
+ const input = args;
7972
+ const manager = await getManager();
7973
+ if (!manager) {
7974
+ throw new Error("Failed to initialize CloudBase manager. Please check your credentials and environment configuration.");
7975
+ }
7976
+ const cloudrunService = manager.cloudrun;
7977
+ let targetPath;
7978
+ if (input.targetPath) {
7979
+ targetPath = validateAndNormalizePath(input.targetPath);
7980
+ }
7981
+ switch (input.action) {
7982
+ case 'createAgent': {
7983
+ if (!targetPath) {
7984
+ throw new Error("targetPath is required for createAgent operation");
7985
+ }
7986
+ if (!input.agentConfig) {
7987
+ throw new Error("agentConfig is required for createAgent operation");
7988
+ }
7989
+ const { agentName, botTag, description, template = 'blank' } = input.agentConfig;
7990
+ // Generate BotId
7991
+ const botId = botTag ? `ibot-${agentName}-${botTag}` : `ibot-${agentName}-${Date.now()}`;
7992
+ // Create Agent using CloudBase Manager
7993
+ const agentResult = await manager.agent.createFunctionAgent(targetPath, {
7994
+ Name: agentName,
7995
+ BotId: botId,
7996
+ Introduction: description || `Agent created by ${agentName}`,
7997
+ Avatar: undefined
7998
+ });
7999
+ // Create project directory
8000
+ const projectDir = path_1.default.join(targetPath, input.serverName);
8001
+ if (!fs_1.default.existsSync(projectDir)) {
8002
+ fs_1.default.mkdirSync(projectDir, { recursive: true });
8003
+ }
8004
+ // Generate package.json
8005
+ const packageJson = {
8006
+ name: input.serverName,
8007
+ version: "1.0.0",
8008
+ description: description || `Agent created by ${agentName}`,
8009
+ main: "index.js",
8010
+ scripts: {
8011
+ "dev": "tcb cloudrun run --runMode=agent -w",
8012
+ "deploy": "tcb cloudrun deploy",
8013
+ "start": "node index.js"
8014
+ },
8015
+ dependencies: {
8016
+ "@cloudbase/aiagent-framework": "^1.0.0-beta.10"
8017
+ },
8018
+ devDependencies: {
8019
+ "@cloudbase/cli": "^2.6.16"
8095
8020
  }
8096
- // Generate package.json
8097
- const packageJson = {
8098
- name: input.serverName,
8099
- version: "1.0.0",
8100
- description: description || `Agent created by ${agentName}`,
8101
- main: "index.js",
8102
- scripts: {
8103
- "dev": "tcb cloudrun run --runMode=agent -w",
8104
- "deploy": "tcb cloudrun deploy",
8105
- "start": "node index.js"
8106
- },
8107
- dependencies: {
8108
- "@cloudbase/aiagent-framework": "^1.0.0-beta.10"
8109
- },
8110
- devDependencies: {
8111
- "@cloudbase/cli": "^2.6.16"
8112
- }
8113
- };
8114
- fs_1.default.writeFileSync(path_1.default.join(projectDir, 'package.json'), JSON.stringify(packageJson, null, 2));
8115
- // Generate index.js with Agent template
8116
- const indexJsContent = `const { IBot } = require("@cloudbase/aiagent-framework");
8021
+ };
8022
+ fs_1.default.writeFileSync(path_1.default.join(projectDir, 'package.json'), JSON.stringify(packageJson, null, 2));
8023
+ // Generate index.js with Agent template
8024
+ const indexJsContent = `const { IBot } = require("@cloudbase/aiagent-framework");
8117
8025
  const { BotRunner } = require("@cloudbase/aiagent-framework");
8118
8026
 
8119
8027
  const ANSWER = "你好,我是一个智能体,但我只会说这一句话。";
@@ -8158,18 +8066,18 @@ exports.main = function (event, context) {
8158
8066
  return BotRunner.run(event, context, new MyBot(context));
8159
8067
  };
8160
8068
  `;
8161
- fs_1.default.writeFileSync(path_1.default.join(projectDir, 'index.js'), indexJsContent);
8162
- // Generate cloudbaserc.json
8163
- const currentEnvId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
8164
- const cloudbasercContent = {
8165
- envId: currentEnvId,
8166
- cloudrun: {
8167
- name: input.serverName
8168
- }
8169
- };
8170
- fs_1.default.writeFileSync(path_1.default.join(projectDir, 'cloudbaserc.json'), JSON.stringify(cloudbasercContent, null, 2));
8171
- // Generate README.md
8172
- const readmeContent = `# ${agentName} Agent
8069
+ fs_1.default.writeFileSync(path_1.default.join(projectDir, 'index.js'), indexJsContent);
8070
+ // Generate cloudbaserc.json
8071
+ const currentEnvId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
8072
+ const cloudbasercContent = {
8073
+ envId: currentEnvId,
8074
+ cloudrun: {
8075
+ name: input.serverName
8076
+ }
8077
+ };
8078
+ fs_1.default.writeFileSync(path_1.default.join(projectDir, 'cloudbaserc.json'), JSON.stringify(cloudbasercContent, null, 2));
8079
+ // Generate README.md
8080
+ const readmeContent = `# ${agentName} Agent
8173
8081
 
8174
8082
  这是一个基于函数型云托管的 AI 智能体。
8175
8083
 
@@ -8214,230 +8122,230 @@ for await (let x of res.textStream) {
8214
8122
  </script>
8215
8123
  \`\`\`
8216
8124
  `;
8217
- fs_1.default.writeFileSync(path_1.default.join(projectDir, 'README.md'), readmeContent);
8218
- return {
8219
- content: [
8220
- {
8221
- type: "text",
8222
- text: JSON.stringify({
8223
- success: true,
8224
- data: {
8225
- agentName: agentName,
8226
- botId: botId,
8227
- projectDir: projectDir,
8228
- serverName: input.serverName,
8229
- template: template,
8230
- filesCreated: ['package.json', 'index.js', 'cloudbaserc.json', 'README.md']
8231
- },
8232
- message: `Successfully created Agent '${agentName}' with BotId '${botId}' in ${projectDir}`
8233
- }, null, 2)
8234
- }
8235
- ]
8236
- };
8125
+ fs_1.default.writeFileSync(path_1.default.join(projectDir, 'README.md'), readmeContent);
8126
+ return {
8127
+ content: [
8128
+ {
8129
+ type: "text",
8130
+ text: JSON.stringify({
8131
+ success: true,
8132
+ data: {
8133
+ agentName: agentName,
8134
+ botId: botId,
8135
+ projectDir: projectDir,
8136
+ serverName: input.serverName,
8137
+ template: template,
8138
+ filesCreated: ['package.json', 'index.js', 'cloudbaserc.json', 'README.md']
8139
+ },
8140
+ message: `Successfully created Agent '${agentName}' with BotId '${botId}' in ${projectDir}`
8141
+ }, null, 2)
8142
+ }
8143
+ ]
8144
+ };
8145
+ }
8146
+ case 'deploy': {
8147
+ if (!targetPath) {
8148
+ throw new Error("targetPath is required for deploy operation");
8237
8149
  }
8238
- case 'deploy': {
8239
- if (!targetPath) {
8240
- throw new Error("targetPath is required for deploy operation");
8241
- }
8242
- // Determine service type - use input.serverType if provided, otherwise auto-detect
8243
- let serverType;
8244
- if (input.serverType) {
8245
- serverType = input.serverType;
8150
+ // Determine service type - use input.serverType if provided, otherwise auto-detect
8151
+ let serverType;
8152
+ if (input.serverType) {
8153
+ serverType = input.serverType;
8154
+ }
8155
+ else {
8156
+ try {
8157
+ // First try to get existing service details
8158
+ const details = await cloudrunService.detail({ serverName: input.serverName });
8159
+ serverType = details.BaseInfo?.ServerType || 'container';
8246
8160
  }
8247
- else {
8248
- try {
8249
- // First try to get existing service details
8250
- const details = await cloudrunService.detail({ serverName: input.serverName });
8251
- serverType = details.BaseInfo?.ServerType || 'container';
8161
+ catch (e) {
8162
+ // If service doesn't exist, determine by project structure
8163
+ const dockerfilePath = path_1.default.join(targetPath, 'Dockerfile');
8164
+ if (fs_1.default.existsSync(dockerfilePath)) {
8165
+ serverType = 'container';
8252
8166
  }
8253
- catch (e) {
8254
- // If service doesn't exist, determine by project structure
8255
- const dockerfilePath = path_1.default.join(targetPath, 'Dockerfile');
8256
- if (fs_1.default.existsSync(dockerfilePath)) {
8257
- serverType = 'container';
8258
- }
8259
- else {
8260
- // Check if it's a Node.js function project (has package.json with specific structure)
8261
- const packageJsonPath = path_1.default.join(targetPath, 'package.json');
8262
- if (fs_1.default.existsSync(packageJsonPath)) {
8263
- try {
8264
- const packageJson = JSON.parse(fs_1.default.readFileSync(packageJsonPath, 'utf8'));
8265
- // If it has function-specific dependencies or scripts, treat as function
8266
- if (packageJson.dependencies?.['@cloudbase/aiagent-framework'] ||
8267
- packageJson.scripts?.['dev']?.includes('cloudrun run')) {
8268
- serverType = 'function';
8269
- }
8270
- else {
8271
- serverType = 'container';
8272
- }
8167
+ else {
8168
+ // Check if it's a Node.js function project (has package.json with specific structure)
8169
+ const packageJsonPath = path_1.default.join(targetPath, 'package.json');
8170
+ if (fs_1.default.existsSync(packageJsonPath)) {
8171
+ try {
8172
+ const packageJson = JSON.parse(fs_1.default.readFileSync(packageJsonPath, 'utf8'));
8173
+ // If it has function-specific dependencies or scripts, treat as function
8174
+ if (packageJson.dependencies?.['@cloudbase/aiagent-framework'] ||
8175
+ packageJson.scripts?.['dev']?.includes('cloudrun run')) {
8176
+ serverType = 'function';
8273
8177
  }
8274
- catch (parseError) {
8178
+ else {
8275
8179
  serverType = 'container';
8276
8180
  }
8277
8181
  }
8278
- else {
8279
- // No package.json, default to container
8182
+ catch (parseError) {
8280
8183
  serverType = 'container';
8281
8184
  }
8282
8185
  }
8186
+ else {
8187
+ // No package.json, default to container
8188
+ serverType = 'container';
8189
+ }
8283
8190
  }
8284
8191
  }
8285
- const deployParams = {
8286
- serverName: input.serverName,
8287
- targetPath: targetPath,
8288
- force: input.force,
8289
- serverType: serverType,
8290
- };
8291
- // Add server configuration if provided
8292
- if (input.serverConfig) {
8293
- deployParams.serverConfig = input.serverConfig;
8294
- }
8295
- const result = await cloudrunService.deploy(deployParams);
8296
- // Generate cloudbaserc.json configuration file
8297
- const currentEnvId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
8298
- const cloudbasercPath = path_1.default.join(targetPath, 'cloudbaserc.json');
8299
- const cloudbasercContent = {
8300
- envId: currentEnvId,
8301
- cloudrun: {
8302
- name: input.serverName
8303
- }
8304
- };
8305
- try {
8306
- fs_1.default.writeFileSync(cloudbasercPath, JSON.stringify(cloudbasercContent, null, 2));
8307
- }
8308
- catch (error) {
8309
- // Ignore cloudbaserc.json creation errors
8192
+ }
8193
+ const deployParams = {
8194
+ serverName: input.serverName,
8195
+ targetPath: targetPath,
8196
+ force: input.force,
8197
+ serverType: serverType,
8198
+ };
8199
+ // Add server configuration if provided
8200
+ if (input.serverConfig) {
8201
+ deployParams.serverConfig = input.serverConfig;
8202
+ }
8203
+ const result = await cloudrunService.deploy(deployParams);
8204
+ // Generate cloudbaserc.json configuration file
8205
+ const currentEnvId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
8206
+ const cloudbasercPath = path_1.default.join(targetPath, 'cloudbaserc.json');
8207
+ const cloudbasercContent = {
8208
+ envId: currentEnvId,
8209
+ cloudrun: {
8210
+ name: input.serverName
8310
8211
  }
8311
- // Send deployment notification to CodeBuddy IDE
8212
+ };
8213
+ try {
8214
+ fs_1.default.writeFileSync(cloudbasercPath, JSON.stringify(cloudbasercContent, null, 2));
8215
+ }
8216
+ catch (error) {
8217
+ // Ignore cloudbaserc.json creation errors
8218
+ }
8219
+ // Send deployment notification to CodeBuddy IDE
8220
+ try {
8221
+ // Query service details to get access URL
8222
+ let serviceUrl = "";
8312
8223
  try {
8313
- // Query service details to get access URL
8314
- let serviceUrl = "";
8315
- try {
8316
- const serviceDetails = await cloudrunService.detail({ serverName: input.serverName });
8317
- // Extract access URL from service details
8318
- // Priority: DefaultDomainName > CustomDomainName > PublicDomain > InternalDomain
8319
- const details = serviceDetails; // Use any to access dynamic properties
8320
- if (details?.BaseInfo?.DefaultDomainName) {
8321
- // DefaultDomainName is already a complete URL (e.g., https://...)
8322
- serviceUrl = details.BaseInfo.DefaultDomainName;
8323
- }
8324
- else if (details?.BaseInfo?.CustomDomainName) {
8325
- // CustomDomainName might be a domain without protocol
8326
- const customDomain = details.BaseInfo.CustomDomainName;
8327
- serviceUrl = customDomain.startsWith('http') ? customDomain : `https://${customDomain}`;
8328
- }
8329
- else if (details?.BaseInfo?.PublicDomain) {
8330
- serviceUrl = `https://${details.BaseInfo.PublicDomain}`;
8331
- }
8332
- else if (details?.BaseInfo?.InternalDomain) {
8333
- serviceUrl = `https://${details.BaseInfo.InternalDomain}`;
8334
- }
8335
- else if (details?.AccessInfo?.PublicDomain) {
8336
- serviceUrl = `https://${details.AccessInfo.PublicDomain}`;
8337
- }
8338
- else {
8339
- serviceUrl = ""; // URL not available
8340
- }
8224
+ const serviceDetails = await cloudrunService.detail({ serverName: input.serverName });
8225
+ // Extract access URL from service details
8226
+ // Priority: DefaultDomainName > CustomDomainName > PublicDomain > InternalDomain
8227
+ const details = serviceDetails; // Use any to access dynamic properties
8228
+ if (details?.BaseInfo?.DefaultDomainName) {
8229
+ // DefaultDomainName is already a complete URL (e.g., https://...)
8230
+ serviceUrl = details.BaseInfo.DefaultDomainName;
8341
8231
  }
8342
- catch (detailErr) {
8343
- // If query fails, continue with empty URL
8344
- serviceUrl = "";
8232
+ else if (details?.BaseInfo?.CustomDomainName) {
8233
+ // CustomDomainName might be a domain without protocol
8234
+ const customDomain = details.BaseInfo.CustomDomainName;
8235
+ serviceUrl = customDomain.startsWith('http') ? customDomain : `https://${customDomain}`;
8236
+ }
8237
+ else if (details?.BaseInfo?.PublicDomain) {
8238
+ serviceUrl = `https://${details.BaseInfo.PublicDomain}`;
8239
+ }
8240
+ else if (details?.BaseInfo?.InternalDomain) {
8241
+ serviceUrl = `https://${details.BaseInfo.InternalDomain}`;
8242
+ }
8243
+ else if (details?.AccessInfo?.PublicDomain) {
8244
+ serviceUrl = `https://${details.AccessInfo.PublicDomain}`;
8245
+ }
8246
+ else {
8247
+ serviceUrl = ""; // URL not available
8345
8248
  }
8346
- // Extract project name from targetPath
8347
- const projectName = path_1.default.basename(targetPath);
8348
- // Build console URL
8349
- const consoleUrl = `https://tcb.cloud.tencent.com/dev?envId=${currentEnvId}#/platform-run/service/detail?serverName=${input.serverName}&tabId=overview&envId=${currentEnvId}`;
8350
- // Send notification
8351
- await (0, notification_js_1.sendDeployNotification)(server, {
8352
- deployType: 'cloudrun',
8353
- url: serviceUrl,
8354
- projectId: currentEnvId,
8355
- projectName: projectName,
8356
- consoleUrl: consoleUrl
8357
- });
8358
8249
  }
8359
- catch (notifyErr) {
8360
- // Notification failure should not affect deployment flow
8361
- // Error is already logged in sendDeployNotification
8250
+ catch (detailErr) {
8251
+ // If query fails, continue with empty URL
8252
+ serviceUrl = "";
8362
8253
  }
8363
- return {
8364
- content: [
8365
- {
8366
- type: "text",
8367
- text: JSON.stringify({
8368
- success: true,
8369
- data: {
8370
- serviceName: input.serverName,
8371
- status: 'deployed',
8372
- deployPath: targetPath,
8373
- serverType: serverType,
8374
- cloudbasercGenerated: true
8375
- },
8376
- message: `Successfully deployed ${serverType} service '${input.serverName}' from ${targetPath}`
8377
- }, null, 2)
8378
- }
8379
- ]
8380
- };
8254
+ // Extract project name from targetPath
8255
+ const projectName = path_1.default.basename(targetPath);
8256
+ // Build console URL
8257
+ const consoleUrl = `https://tcb.cloud.tencent.com/dev?envId=${currentEnvId}#/platform-run/service/detail?serverName=${input.serverName}&tabId=overview&envId=${currentEnvId}`;
8258
+ // Send notification
8259
+ await (0, notification_js_1.sendDeployNotification)(server, {
8260
+ deployType: 'cloudrun',
8261
+ url: serviceUrl,
8262
+ projectId: currentEnvId,
8263
+ projectName: projectName,
8264
+ consoleUrl: consoleUrl
8265
+ });
8381
8266
  }
8382
- case 'run': {
8383
- if (!targetPath) {
8384
- throw new Error("targetPath is required for run operation");
8385
- }
8386
- // Do not support container services locally: basic heuristic - if Dockerfile exists, treat as container
8387
- const dockerfilePath = path_1.default.join(targetPath, 'Dockerfile');
8388
- if (fs_1.default.existsSync(dockerfilePath)) {
8389
- throw new Error("Local run is only supported for function-type CloudRun services. Container services are not supported.");
8390
- }
8391
- // Check if this is an Agent project
8392
- const isAgent = checkIfAgentProject(targetPath);
8393
- const runMode = input.runOptions?.runMode || (isAgent ? 'agent' : 'normal');
8394
- // Check if service is already running and verify process exists
8395
- if (runningProcesses.has(input.serverName)) {
8396
- const existingPid = runningProcesses.get(input.serverName);
8397
- try {
8398
- // Check if process actually exists
8399
- process.kill(existingPid, 0);
8400
- return {
8401
- content: [
8402
- {
8403
- type: "text",
8404
- text: JSON.stringify({
8405
- success: true,
8406
- data: {
8407
- serviceName: input.serverName,
8408
- status: 'running',
8409
- pid: existingPid,
8410
- cwd: targetPath
8411
- },
8412
- message: `Service '${input.serverName}' is already running locally (pid=${existingPid})`
8413
- }, null, 2)
8414
- }
8415
- ]
8416
- };
8417
- }
8418
- catch (error) {
8419
- // Process doesn't exist, remove from tracking
8420
- runningProcesses.delete(input.serverName);
8267
+ catch (notifyErr) {
8268
+ // Notification failure should not affect deployment flow
8269
+ // Error is already logged in sendDeployNotification
8270
+ }
8271
+ return {
8272
+ content: [
8273
+ {
8274
+ type: "text",
8275
+ text: JSON.stringify({
8276
+ success: true,
8277
+ data: {
8278
+ serviceName: input.serverName,
8279
+ status: 'deployed',
8280
+ deployPath: targetPath,
8281
+ serverType: serverType,
8282
+ cloudbasercGenerated: true
8283
+ },
8284
+ message: `Successfully deployed ${serverType} service '${input.serverName}' from ${targetPath}`
8285
+ }, null, 2)
8421
8286
  }
8287
+ ]
8288
+ };
8289
+ }
8290
+ case 'run': {
8291
+ if (!targetPath) {
8292
+ throw new Error("targetPath is required for run operation");
8293
+ }
8294
+ // Do not support container services locally: basic heuristic - if Dockerfile exists, treat as container
8295
+ const dockerfilePath = path_1.default.join(targetPath, 'Dockerfile');
8296
+ if (fs_1.default.existsSync(dockerfilePath)) {
8297
+ throw new Error("Local run is only supported for function-type CloudRun services. Container services are not supported.");
8298
+ }
8299
+ // Check if this is an Agent project
8300
+ const isAgent = checkIfAgentProject(targetPath);
8301
+ const runMode = input.runOptions?.runMode || (isAgent ? 'agent' : 'normal');
8302
+ // Check if service is already running and verify process exists
8303
+ if (runningProcesses.has(input.serverName)) {
8304
+ const existingPid = runningProcesses.get(input.serverName);
8305
+ try {
8306
+ // Check if process actually exists
8307
+ process.kill(existingPid, 0);
8308
+ return {
8309
+ content: [
8310
+ {
8311
+ type: "text",
8312
+ text: JSON.stringify({
8313
+ success: true,
8314
+ data: {
8315
+ serviceName: input.serverName,
8316
+ status: 'running',
8317
+ pid: existingPid,
8318
+ cwd: targetPath
8319
+ },
8320
+ message: `Service '${input.serverName}' is already running locally (pid=${existingPid})`
8321
+ }, null, 2)
8322
+ }
8323
+ ]
8324
+ };
8422
8325
  }
8423
- const runPort = input.runOptions?.port ?? 3000;
8424
- const extraEnv = input.runOptions?.envParams ?? {};
8425
- // Set environment variables for functions-framework
8426
- const env = {
8427
- ...process.env,
8428
- PORT: String(runPort),
8429
- ...extraEnv,
8430
- // Add functions-framework specific environment variables
8431
- ENABLE_CORS: 'true',
8432
- ALLOWED_ORIGINS: '*'
8433
- };
8434
- // Choose execution method based on run mode
8435
- let child;
8436
- let command;
8437
- if (runMode === 'agent') {
8438
- // For Agent mode, use a different approach since functions-framework doesn't support Agent mode
8439
- // We'll use a custom script that sets up the Agent environment
8440
- command = `node -e "
8326
+ catch (error) {
8327
+ // Process doesn't exist, remove from tracking
8328
+ runningProcesses.delete(input.serverName);
8329
+ }
8330
+ }
8331
+ const runPort = input.runOptions?.port ?? 3000;
8332
+ const extraEnv = input.runOptions?.envParams ?? {};
8333
+ // Set environment variables for functions-framework
8334
+ const env = {
8335
+ ...process.env,
8336
+ PORT: String(runPort),
8337
+ ...extraEnv,
8338
+ // Add functions-framework specific environment variables
8339
+ ENABLE_CORS: 'true',
8340
+ ALLOWED_ORIGINS: '*'
8341
+ };
8342
+ // Choose execution method based on run mode
8343
+ let child;
8344
+ let command;
8345
+ if (runMode === 'agent') {
8346
+ // For Agent mode, use a different approach since functions-framework doesn't support Agent mode
8347
+ // We'll use a custom script that sets up the Agent environment
8348
+ command = `node -e "
8441
8349
  const { runCLI } = require('@cloudbase/functions-framework');
8442
8350
  process.env.PORT = '${runPort}';
8443
8351
  process.env.ENABLE_CORS = 'true';
@@ -8446,16 +8354,16 @@ for await (let x of res.textStream) {
8446
8354
  ${Object.entries(extraEnv).map(([key, value]) => `process.env.${key} = '${value}';`).join('\n')}
8447
8355
  runCLI();
8448
8356
  "`;
8449
- child = (0, child_process_1.spawn)(process.execPath, ['-e', command], {
8450
- cwd: targetPath,
8451
- env,
8452
- stdio: ['ignore', 'pipe', 'pipe'],
8453
- detached: true
8454
- });
8455
- }
8456
- else {
8457
- // Normal function mode
8458
- command = `node -e "
8357
+ child = (0, child_process_1.spawn)(process.execPath, ['-e', command], {
8358
+ cwd: targetPath,
8359
+ env,
8360
+ stdio: ['ignore', 'pipe', 'pipe'],
8361
+ detached: true
8362
+ });
8363
+ }
8364
+ else {
8365
+ // Normal function mode
8366
+ command = `node -e "
8459
8367
  const { runCLI } = require('@cloudbase/functions-framework');
8460
8368
  process.env.PORT = '${runPort}';
8461
8369
  process.env.ENABLE_CORS = 'true';
@@ -8463,182 +8371,167 @@ for await (let x of res.textStream) {
8463
8371
  ${Object.entries(extraEnv).map(([key, value]) => `process.env.${key} = '${value}';`).join('\n')}
8464
8372
  runCLI();
8465
8373
  "`;
8466
- child = (0, child_process_1.spawn)(process.execPath, ['-e', command], {
8467
- cwd: targetPath,
8468
- env,
8469
- stdio: ['ignore', 'pipe', 'pipe'],
8470
- detached: true
8471
- });
8472
- }
8473
- // Handle process exit to clean up tracking
8474
- child.on('exit', (code, signal) => {
8475
- runningProcesses.delete(input.serverName);
8476
- });
8477
- child.on('error', (error) => {
8478
- runningProcesses.delete(input.serverName);
8374
+ child = (0, child_process_1.spawn)(process.execPath, ['-e', command], {
8375
+ cwd: targetPath,
8376
+ env,
8377
+ stdio: ['ignore', 'pipe', 'pipe'],
8378
+ detached: true
8479
8379
  });
8480
- child.unref();
8481
- if (typeof child.pid !== 'number') {
8482
- throw new Error('Failed to start local process: PID is undefined.');
8483
- }
8484
- runningProcesses.set(input.serverName, child.pid);
8485
- return {
8486
- content: [
8487
- {
8488
- type: "text",
8489
- text: JSON.stringify({
8490
- success: true,
8491
- data: {
8492
- serviceName: input.serverName,
8493
- status: 'running',
8494
- pid: child.pid,
8495
- port: runPort,
8496
- runMode: runMode,
8497
- isAgent: isAgent,
8498
- command: command,
8499
- cwd: targetPath
8500
- },
8501
- message: `Started local run for ${runMode} service '${input.serverName}' on port ${runPort} (pid=${child.pid})`
8502
- }, null, 2)
8503
- }
8504
- ]
8505
- };
8506
8380
  }
8507
- case 'download': {
8508
- if (!targetPath) {
8509
- throw new Error("targetPath is required for download operation");
8510
- }
8511
- const result = await cloudrunService.download({
8512
- serverName: input.serverName,
8513
- targetPath: targetPath,
8514
- });
8515
- // Generate cloudbaserc.json configuration file
8516
- const currentEnvId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
8517
- const cloudbasercPath = path_1.default.join(targetPath, 'cloudbaserc.json');
8518
- const cloudbasercContent = {
8519
- envId: currentEnvId,
8520
- cloudrun: {
8521
- name: input.serverName
8381
+ // Handle process exit to clean up tracking
8382
+ child.on('exit', (code, signal) => {
8383
+ runningProcesses.delete(input.serverName);
8384
+ });
8385
+ child.on('error', (error) => {
8386
+ runningProcesses.delete(input.serverName);
8387
+ });
8388
+ child.unref();
8389
+ if (typeof child.pid !== 'number') {
8390
+ throw new Error('Failed to start local process: PID is undefined.');
8391
+ }
8392
+ runningProcesses.set(input.serverName, child.pid);
8393
+ return {
8394
+ content: [
8395
+ {
8396
+ type: "text",
8397
+ text: JSON.stringify({
8398
+ success: true,
8399
+ data: {
8400
+ serviceName: input.serverName,
8401
+ status: 'running',
8402
+ pid: child.pid,
8403
+ port: runPort,
8404
+ runMode: runMode,
8405
+ isAgent: isAgent,
8406
+ command: command,
8407
+ cwd: targetPath
8408
+ },
8409
+ message: `Started local run for ${runMode} service '${input.serverName}' on port ${runPort} (pid=${child.pid})`
8410
+ }, null, 2)
8522
8411
  }
8523
- };
8524
- try {
8525
- fs_1.default.writeFileSync(cloudbasercPath, JSON.stringify(cloudbasercContent, null, 2));
8526
- }
8527
- catch (error) {
8528
- // Ignore cloudbaserc.json creation errors
8529
- }
8530
- return {
8531
- content: [
8532
- {
8533
- type: "text",
8534
- text: JSON.stringify({
8535
- success: true,
8536
- data: {
8537
- serviceName: input.serverName,
8538
- downloadPath: targetPath,
8539
- filesCount: 0,
8540
- cloudbasercGenerated: true
8541
- },
8542
- message: `Successfully downloaded service '${input.serverName}' to ${targetPath}`
8543
- }, null, 2)
8544
- }
8545
- ]
8546
- };
8412
+ ]
8413
+ };
8414
+ }
8415
+ case 'download': {
8416
+ if (!targetPath) {
8417
+ throw new Error("targetPath is required for download operation");
8547
8418
  }
8548
- case 'delete': {
8549
- if (!input.force) {
8550
- return {
8551
- content: [
8552
- {
8553
- type: "text",
8554
- text: JSON.stringify({
8555
- success: false,
8556
- error: "Delete operation requires confirmation",
8557
- message: "Please set force: true to confirm deletion of the service. This action cannot be undone."
8558
- }, null, 2)
8559
- }
8560
- ]
8561
- };
8419
+ const result = await cloudrunService.download({
8420
+ serverName: input.serverName,
8421
+ targetPath: targetPath,
8422
+ });
8423
+ // Generate cloudbaserc.json configuration file
8424
+ const currentEnvId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
8425
+ const cloudbasercPath = path_1.default.join(targetPath, 'cloudbaserc.json');
8426
+ const cloudbasercContent = {
8427
+ envId: currentEnvId,
8428
+ cloudrun: {
8429
+ name: input.serverName
8562
8430
  }
8563
- const result = await cloudrunService.delete({
8564
- serverName: input.serverName,
8565
- });
8566
- return {
8567
- content: [
8568
- {
8569
- type: "text",
8570
- text: JSON.stringify({
8571
- success: true,
8572
- data: {
8573
- serviceName: input.serverName,
8574
- status: 'deleted'
8575
- },
8576
- message: `Successfully deleted service '${input.serverName}'`
8577
- }, null, 2)
8578
- }
8579
- ]
8580
- };
8431
+ };
8432
+ try {
8433
+ fs_1.default.writeFileSync(cloudbasercPath, JSON.stringify(cloudbasercContent, null, 2));
8581
8434
  }
8582
- case 'init': {
8583
- if (!targetPath) {
8584
- throw new Error("targetPath is required for init operation");
8585
- }
8586
- const result = await cloudrunService.init({
8587
- serverName: input.serverName,
8588
- targetPath: targetPath,
8589
- template: input.template,
8590
- });
8591
- // Generate cloudbaserc.json configuration file
8592
- const currentEnvId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
8593
- const cloudbasercPath = path_1.default.join(targetPath, input.serverName, 'cloudbaserc.json');
8594
- const cloudbasercContent = {
8595
- envId: currentEnvId,
8596
- cloudrun: {
8597
- name: input.serverName
8435
+ catch (error) {
8436
+ // Ignore cloudbaserc.json creation errors
8437
+ }
8438
+ return {
8439
+ content: [
8440
+ {
8441
+ type: "text",
8442
+ text: JSON.stringify({
8443
+ success: true,
8444
+ data: {
8445
+ serviceName: input.serverName,
8446
+ downloadPath: targetPath,
8447
+ filesCount: 0,
8448
+ cloudbasercGenerated: true
8449
+ },
8450
+ message: `Successfully downloaded service '${input.serverName}' to ${targetPath}`
8451
+ }, null, 2)
8598
8452
  }
8599
- };
8600
- try {
8601
- fs_1.default.writeFileSync(cloudbasercPath, JSON.stringify(cloudbasercContent, null, 2));
8602
- }
8603
- catch (error) {
8604
- // Ignore cloudbaserc.json creation errors
8605
- }
8453
+ ]
8454
+ };
8455
+ }
8456
+ case 'delete': {
8457
+ if (!input.force) {
8606
8458
  return {
8607
8459
  content: [
8608
8460
  {
8609
8461
  type: "text",
8610
8462
  text: JSON.stringify({
8611
- success: true,
8612
- data: {
8613
- serviceName: input.serverName,
8614
- template: input.template,
8615
- initPath: targetPath,
8616
- projectDir: result.projectDir || path_1.default.join(targetPath, input.serverName),
8617
- cloudbasercGenerated: true
8618
- },
8619
- message: `Successfully initialized service '${input.serverName}' with template '${input.template}' at ${targetPath}`
8463
+ success: false,
8464
+ error: "Delete operation requires confirmation",
8465
+ message: "Please set force: true to confirm deletion of the service. This action cannot be undone."
8620
8466
  }, null, 2)
8621
8467
  }
8622
8468
  ]
8623
8469
  };
8624
8470
  }
8625
- default:
8626
- throw new Error(`Unsupported action: ${input.action}`);
8471
+ const result = await cloudrunService.delete({
8472
+ serverName: input.serverName,
8473
+ });
8474
+ return {
8475
+ content: [
8476
+ {
8477
+ type: "text",
8478
+ text: JSON.stringify({
8479
+ success: true,
8480
+ data: {
8481
+ serviceName: input.serverName,
8482
+ status: 'deleted'
8483
+ },
8484
+ message: `Successfully deleted service '${input.serverName}'`
8485
+ }, null, 2)
8486
+ }
8487
+ ]
8488
+ };
8627
8489
  }
8628
- }
8629
- catch (error) {
8630
- return {
8631
- content: [
8632
- {
8633
- type: "text",
8634
- text: JSON.stringify({
8635
- success: false,
8636
- error: error.message || 'Unknown error occurred',
8637
- message: `Failed to ${args.action} CloudRun service. Please check your permissions and parameters.`
8638
- }, null, 2)
8490
+ case 'init': {
8491
+ if (!targetPath) {
8492
+ throw new Error("targetPath is required for init operation");
8493
+ }
8494
+ const result = await cloudrunService.init({
8495
+ serverName: input.serverName,
8496
+ targetPath: targetPath,
8497
+ template: input.template,
8498
+ });
8499
+ // Generate cloudbaserc.json configuration file
8500
+ const currentEnvId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
8501
+ const cloudbasercPath = path_1.default.join(targetPath, input.serverName, 'cloudbaserc.json');
8502
+ const cloudbasercContent = {
8503
+ envId: currentEnvId,
8504
+ cloudrun: {
8505
+ name: input.serverName
8639
8506
  }
8640
- ]
8641
- };
8507
+ };
8508
+ try {
8509
+ fs_1.default.writeFileSync(cloudbasercPath, JSON.stringify(cloudbasercContent, null, 2));
8510
+ }
8511
+ catch (error) {
8512
+ // Ignore cloudbaserc.json creation errors
8513
+ }
8514
+ return {
8515
+ content: [
8516
+ {
8517
+ type: "text",
8518
+ text: JSON.stringify({
8519
+ success: true,
8520
+ data: {
8521
+ serviceName: input.serverName,
8522
+ template: input.template,
8523
+ initPath: targetPath,
8524
+ projectDir: result.projectDir || path_1.default.join(targetPath, input.serverName),
8525
+ cloudbasercGenerated: true
8526
+ },
8527
+ message: `Successfully initialized service '${input.serverName}' with template '${input.template}' at ${targetPath}`
8528
+ }, null, 2)
8529
+ }
8530
+ ]
8531
+ };
8532
+ }
8533
+ default:
8534
+ throw new Error(`Unsupported action: ${input.action}`);
8642
8535
  }
8643
8536
  });
8644
8537
  }
@@ -8713,7 +8606,7 @@ class TelemetryReporter {
8713
8606
  const nodeVersion = process.version; // Node.js版本
8714
8607
  const arch = os_1.default.arch(); // 系统架构
8715
8608
  // 从构建时注入的版本号获取MCP版本信息
8716
- const mcpVersion = process.env.npm_package_version || "2.8.0" || 0;
8609
+ const mcpVersion = process.env.npm_package_version || "2.10.0" || 0;
8717
8610
  return {
8718
8611
  userAgent: `${osType} ${osRelease} ${arch} ${nodeVersion} CloudBase-MCP/${mcpVersion}`,
8719
8612
  deviceId: this.deviceId,
@@ -9083,12 +8976,12 @@ function registerFunctionTools(server) {
9083
8976
  // getFunctionList - 获取云函数列表或详情(推荐)
9084
8977
  server.registerTool?.("getFunctionList", {
9085
8978
  title: "查询云函数列表或详情",
9086
- description: "获取云函数列表或单个函数详情,通过 action 参数区分操作类型",
8979
+ description: "获取云函数列表或单个函数详情。通过 action 参数区分操作类型:list=获取函数列表(默认,无需额外参数),detail=获取函数详情(需要提供 name 参数指定函数名称)",
9087
8980
  inputSchema: {
9088
- action: zod_1.z.enum(["list", "detail"]).optional().describe("操作类型:list=获取函数列表(默认),detail=获取函数详情"),
8981
+ action: zod_1.z.enum(["list", "detail"]).optional().describe("操作类型:list=获取函数列表(默认,无需额外参数),detail=获取函数详情(需要提供 name 参数)"),
9089
8982
  limit: zod_1.z.number().optional().describe("范围(list 操作时使用)"),
9090
8983
  offset: zod_1.z.number().optional().describe("偏移(list 操作时使用)"),
9091
- name: zod_1.z.string().optional().describe("函数名称(detail 操作时必需)"),
8984
+ name: zod_1.z.string().optional().describe("要查询的函数名称。当 action='detail' 时,此参数为必填项,必须提供已存在的函数名称。可通过 action='list' 操作获取可用的函数名称列表"),
9092
8985
  codeSecret: zod_1.z.string().optional().describe("代码保护密钥(detail 操作时使用)")
9093
8986
  },
9094
8987
  annotations: {
@@ -9328,17 +9221,30 @@ function registerFunctionTools(server) {
9328
9221
  }
9329
9222
  }, async ({ name, params }) => {
9330
9223
  // 使用闭包中的 cloudBaseOptions
9331
- const cloudbase = await getManager();
9332
- const result = await cloudbase.functions.invokeFunction(name, params);
9333
- (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
9334
- return {
9335
- content: [
9336
- {
9337
- type: "text",
9338
- text: JSON.stringify(result, null, 2)
9339
- }
9340
- ]
9341
- };
9224
+ try {
9225
+ const cloudbase = await getManager();
9226
+ const result = await cloudbase.functions.invokeFunction(name, params);
9227
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
9228
+ return {
9229
+ content: [
9230
+ {
9231
+ type: "text",
9232
+ text: JSON.stringify(result, null, 2)
9233
+ }
9234
+ ]
9235
+ };
9236
+ }
9237
+ catch (error) {
9238
+ const errorMessage = (error instanceof Error ? error.message : String(error));
9239
+ if (errorMessage.includes("Function not found") ||
9240
+ errorMessage.includes("函数不存在")) {
9241
+ throw new Error(`${errorMessage}\n\n` +
9242
+ `Tip: "invokeFunction" can only call deployed cloud functions. ` +
9243
+ `For database operations (such as creating collections), ` +
9244
+ `please use the appropriate database tools instead.`);
9245
+ }
9246
+ throw error;
9247
+ }
9342
9248
  });
9343
9249
  // getFunctionLogs - 获取云函数日志(新版,参数直接展开)
9344
9250
  server.registerTool?.("getFunctionLogs", {
@@ -10133,15 +10039,14 @@ function registerSetupTools(server) {
10133
10039
  title: "下载项目模板",
10134
10040
  description: `自动下载并部署CloudBase项目模板。⚠️ **MANDATORY FOR NEW PROJECTS** ⚠️
10135
10041
 
10136
- **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.8.0" : 0}),便于后续维护和版本追踪\n- 下载 rules 模板时,如果项目中已存在 README.md 文件,系统会自动保护该文件不被覆盖(除非设置 overwrite=true)`,
10042
+ **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.10.0" : 0}),便于后续维护和版本追踪\n- 下载 rules 模板时,如果项目中已存在 README.md 文件,系统会自动保护该文件不被覆盖(除非设置 overwrite=true)`,
10137
10043
  inputSchema: {
10138
10044
  template: zod_1.z
10139
10045
  .enum(["react", "vue", "miniprogram", "uniapp", "rules"])
10140
10046
  .describe("要下载的模板类型"),
10141
10047
  ide: zod_1.z
10142
10048
  .enum(IDE_TYPES)
10143
- .optional()
10144
- .describe("指定要下载的IDE类型。如果未指定,会根据 INTEGRATION_IDE 环境变量自动选择对应的IDE配置;如果环境变量也未设置,则必须传入此参数"),
10049
+ .describe("指定要下载的IDE类型。"),
10145
10050
  overwrite: zod_1.z
10146
10051
  .boolean()
10147
10052
  .optional()
@@ -10156,7 +10061,7 @@ function registerSetupTools(server) {
10156
10061
  },
10157
10062
  }, async ({ template, ide, overwrite = false, }) => {
10158
10063
  try {
10159
- const ideResolution = resolveDownloadTemplateIDE(ide, process.env.INTEGRATION_IDE);
10064
+ const ideResolution = resolveDownloadTemplateIDE(ide, undefined);
10160
10065
  if (!ideResolution.ok) {
10161
10066
  const supportedIDEs = ideResolution.supportedIDEs.join(", ");
10162
10067
  if (ideResolution.reason === "unmapped_integration_ide") {
@@ -11152,7 +11057,7 @@ async function checkAndInitTcbService(cloudbase, context) {
11152
11057
  uin: newContext.uin,
11153
11058
  tcbServiceChecked: newContext.tcbServiceChecked
11154
11059
  });
11155
- const checkResult = await cloudbase.commonService("tcb").call({
11060
+ const checkResult = await cloudbase.commonService("tcb", "2018-06-08").call({
11156
11061
  Action: "CheckTcbService",
11157
11062
  Param: {}
11158
11063
  });
@@ -11173,7 +11078,7 @@ async function checkAndInitTcbService(cloudbase, context) {
11173
11078
  (0, logger_js_1.debug)('[env-setup] TCB service not initialized, attempting to initialize...');
11174
11079
  (0, logger_js_1.debug)('[env-setup] InitTcb params:', { Source: "qcloud", Channel: "mcp" });
11175
11080
  try {
11176
- const initResult = await cloudbase.commonService("tcb").call({
11081
+ const initResult = await cloudbase.commonService("tcb", "2018-06-08").call({
11177
11082
  Action: "InitTcb",
11178
11083
  Param: {
11179
11084
  Source: "qcloud",
@@ -11261,7 +11166,7 @@ async function checkAndCreateFreeEnv(cloudbase, context) {
11261
11166
  (0, logger_js_1.debug)('[env-setup] DescribeUserPromotionalActivity params:', {
11262
11167
  Names: ["NewUser", "ReturningUser", "BaasFree"]
11263
11168
  });
11264
- const activityResult = await cloudbase.commonService("tcb").call({
11169
+ const activityResult = await cloudbase.commonService("tcb", "2018-06-08").call({
11265
11170
  Action: "DescribeUserPromotionalActivity",
11266
11171
  Param: {
11267
11172
  Names: ["NewUser", "ReturningUser", "BaasFree"]
@@ -11312,7 +11217,7 @@ async function checkAndCreateFreeEnv(cloudbase, context) {
11312
11217
  Source: "qcloud"
11313
11218
  };
11314
11219
  (0, logger_js_1.debug)('[env-setup] CreateFreeEnvByActivity params:', createParams);
11315
- const createResult = await cloudbase.commonService("tcb").call({
11220
+ const createResult = await cloudbase.commonService("tcb", "2018-06-08").call({
11316
11221
  Action: "CreateFreeEnvByActivity",
11317
11222
  Param: createParams
11318
11223
  });
@@ -11457,7 +11362,9 @@ async function checkAndCreateFreeEnv(cloudbase, context) {
11457
11362
  */
11458
11363
  async function getUinForTelemetry() {
11459
11364
  try {
11460
- const loginState = await (0, auth_js_1.getLoginState)();
11365
+ // Get region from environment variable for auth URL
11366
+ const region = process.env.TCB_REGION;
11367
+ const loginState = await (0, auth_js_1.getLoginState)({ region });
11461
11368
  // Try to extract UIN from loginState
11462
11369
  // Note: actual field name may vary, adjust based on actual response
11463
11370
  return loginState.uin || undefined;
@@ -12023,6 +11930,7 @@ exports.getLoginState = getLoginState;
12023
11930
  exports.logout = logout;
12024
11931
  const toolbox_1 = __webpack_require__(2090);
12025
11932
  const logger_js_1 = __webpack_require__(3039);
11933
+ const tencet_cloud_js_1 = __webpack_require__(5018);
12026
11934
  const auth = toolbox_1.AuthSupevisor.getInstance({});
12027
11935
  async function getLoginState(options) {
12028
11936
  const { TENCENTCLOUD_SECRETID, TENCENTCLOUD_SECRETKEY, TENCENTCLOUD_SESSIONTOKEN, } = process.env;
@@ -12040,9 +11948,10 @@ async function getLoginState(options) {
12040
11948
  }
12041
11949
  const loginState = await auth.getLoginState();
12042
11950
  if (!loginState) {
12043
- await auth.loginByWebAuth(options?.fromCloudBaseLoginPage
11951
+ await auth.loginByWebAuth((options?.fromCloudBaseLoginPage && !(0, tencet_cloud_js_1.isInternationalRegion)(options?.region))
12044
11952
  ? {
12045
11953
  getAuthUrl: (url) => {
11954
+ // 国际站
12046
11955
  const separator = url.includes('?') ? '&' : '?';
12047
11956
  const urlWithParam = `${url}${separator}allowNoEnv=true`;
12048
11957
  return `https://tcb.cloud.tencent.com/login?_redirect_uri=${encodeURIComponent(urlWithParam)}`;
@@ -12050,6 +11959,9 @@ async function getLoginState(options) {
12050
11959
  }
12051
11960
  : {
12052
11961
  getAuthUrl: (url) => {
11962
+ if ((0, tencet_cloud_js_1.isInternationalRegion)(options?.region)) {
11963
+ url = url.replace('cloud.tencent.com', 'tencentcloud.com');
11964
+ }
12053
11965
  const separator = url.includes('?') ? '&' : '?';
12054
11966
  return `${url}${separator}allowNoEnv=true`;
12055
11967
  },
@@ -12097,7 +12009,7 @@ function renderHeader(accountInfo, ide) {
12097
12009
  <img class="logo" src="https://7463-tcb-advanced-a656fc-1257967285.tcb.qcloud.la/mcp/cloudbase-logo.svg" alt="CloudBase Logo" />
12098
12010
  <span class="title">CloudBase</span>
12099
12011
  </div>
12100
- ${hasAccount ? `
12012
+ ${(hasAccount && accountInfo.region !== 'ap-singapore') ? /** 国际站不支持切 */ `
12101
12013
  <div class="header-right">
12102
12014
  <div class="account-section">
12103
12015
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
@@ -12105,6 +12017,7 @@ function renderHeader(accountInfo, ide) {
12105
12017
  <circle cx="12" cy="7" r="4"/>
12106
12018
  </svg>
12107
12019
  <span class="account-uin">${accountInfo.uin}</span>
12020
+ ${accountInfo.region ? `<span class="account-region">${accountInfo.region}</span>` : ''}
12108
12021
  ${!isCodeBuddy ? `
12109
12022
  <button class="btn-switch" onclick="switchAccount()" title="切换账号">
12110
12023
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
@@ -12393,90 +12306,70 @@ function registerSecurityRuleTools(server) {
12393
12306
  },
12394
12307
  }, async ({ resourceType, resourceId }) => {
12395
12308
  const envId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
12396
- try {
12397
- const cloudbase = await getManager();
12398
- let result;
12399
- if (resourceType === "noSqlDatabase") {
12400
- // 查询数据库安全规则
12401
- result = await cloudbase.commonService().call({
12402
- Action: "DescribeSafeRule",
12403
- Param: {
12404
- CollectionName: resourceId,
12405
- EnvId: envId,
12406
- },
12407
- });
12408
- (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
12409
- }
12410
- else if (resourceType === "function") {
12411
- // 查询云函数安全规则
12412
- result = await cloudbase.commonService().call({
12413
- Action: "DescribeSecurityRule",
12414
- Param: {
12415
- ResourceType: "FUNCTION",
12416
- EnvId: envId,
12417
- },
12418
- });
12419
- (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
12420
- }
12421
- else if (resourceType === "storage") {
12422
- // 查询存储安全规则
12423
- result = await cloudbase.commonService().call({
12424
- Action: "DescribeStorageSafeRule",
12425
- Param: {
12426
- Bucket: resourceId,
12427
- EnvId: envId,
12428
- },
12429
- });
12430
- (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
12431
- }
12432
- else if (resourceType === "sqlDatabase") {
12433
- // TODO: 考虑是否有支持指定其他 instance、schema 的需求
12434
- const instanceId = "default";
12435
- const schema = envId;
12436
- const tableName = resourceId;
12437
- result = await cloudbase.commonService("lowcode").call({
12438
- Action: "DescribeDataSourceBasicPolicy",
12439
- Param: {
12440
- EnvId: envId,
12441
- ResourceType: "table",
12442
- ResourceId: `${instanceId}#${schema}#${tableName}`,
12443
- RoleIdentityList: ["allUser"],
12444
- },
12445
- });
12446
- (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
12447
- }
12448
- else {
12449
- throw new Error(`不支持的资源类型: ${resourceType}`);
12450
- }
12451
- return {
12452
- content: [
12453
- {
12454
- type: "text",
12455
- text: JSON.stringify({
12456
- success: true,
12457
- aclTag: result.AclTag,
12458
- rule: result.Rule ?? null,
12459
- raw: result,
12460
- message: "安全规则读取成功",
12461
- }, null, 2),
12462
- },
12463
- ],
12464
- };
12309
+ const cloudbase = await getManager();
12310
+ let result;
12311
+ if (resourceType === "noSqlDatabase") {
12312
+ result = await cloudbase.commonService().call({
12313
+ Action: "DescribeSafeRule",
12314
+ Param: {
12315
+ CollectionName: resourceId,
12316
+ EnvId: envId,
12317
+ },
12318
+ });
12319
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
12320
+ }
12321
+ else if (resourceType === "function") {
12322
+ result = await cloudbase.commonService().call({
12323
+ Action: "DescribeSecurityRule",
12324
+ Param: {
12325
+ ResourceType: "FUNCTION",
12326
+ EnvId: envId,
12327
+ },
12328
+ });
12329
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
12330
+ }
12331
+ else if (resourceType === "storage") {
12332
+ result = await cloudbase.commonService().call({
12333
+ Action: "DescribeStorageSafeRule",
12334
+ Param: {
12335
+ Bucket: resourceId,
12336
+ EnvId: envId,
12337
+ },
12338
+ });
12339
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
12340
+ }
12341
+ else if (resourceType === "sqlDatabase") {
12342
+ const instanceId = "default";
12343
+ const schema = envId;
12344
+ const tableName = resourceId;
12345
+ result = await cloudbase.commonService("lowcode").call({
12346
+ Action: "DescribeDataSourceBasicPolicy",
12347
+ Param: {
12348
+ EnvId: envId,
12349
+ ResourceType: "table",
12350
+ ResourceId: `${instanceId}#${schema}#${tableName}`,
12351
+ RoleIdentityList: ["allUser"],
12352
+ },
12353
+ });
12354
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
12465
12355
  }
12466
- catch (error) {
12467
- return {
12468
- content: [
12469
- {
12470
- type: "text",
12471
- text: JSON.stringify({
12472
- success: false,
12473
- error: error.message,
12474
- message: "安全规则读取失败",
12475
- }, null, 2),
12476
- },
12477
- ],
12478
- };
12356
+ else {
12357
+ throw new Error(`不支持的资源类型: ${resourceType}`);
12479
12358
  }
12359
+ return {
12360
+ content: [
12361
+ {
12362
+ type: "text",
12363
+ text: JSON.stringify({
12364
+ success: true,
12365
+ aclTag: result.AclTag,
12366
+ rule: result.Rule ?? null,
12367
+ raw: result,
12368
+ message: "安全规则读取成功",
12369
+ }, null, 2),
12370
+ },
12371
+ ],
12372
+ };
12480
12373
  });
12481
12374
  // 写入安全规则 Tool
12482
12375
  server.registerTool?.(exports.WRITE_SECURITY_RULE, {
@@ -12503,154 +12396,138 @@ function registerSecurityRuleTools(server) {
12503
12396
  category: "security-rule",
12504
12397
  },
12505
12398
  }, async ({ resourceType, resourceId, aclTag, rule }) => {
12506
- try {
12507
- const cloudbase = await getManager();
12508
- const envId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
12509
- let result;
12510
- if (resourceType === "noSqlDatabase") {
12511
- if (aclTag === "CUSTOM") {
12512
- if (!rule)
12513
- throw new Error("noSQL 数据库自定义安全规则(CUSTOM)必须提供 rule 字段");
12514
- result = await cloudbase.commonService().call({
12515
- Action: "ModifySafeRule",
12516
- Param: {
12517
- CollectionName: resourceId,
12518
- EnvId: envId,
12519
- AclTag: aclTag,
12520
- Rule: rule,
12521
- },
12522
- });
12523
- (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
12524
- }
12525
- else {
12526
- result = await cloudbase.commonService().call({
12527
- Action: "ModifyDatabaseACL",
12528
- Param: {
12529
- CollectionName: resourceId,
12530
- EnvId: envId,
12531
- AclTag: aclTag,
12532
- },
12533
- });
12534
- (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
12535
- }
12536
- }
12537
- else if (resourceType === "function") {
12538
- if (aclTag !== "CUSTOM")
12539
- throw new Error("云函数安全规则仅支持 CUSTOM 权限类别");
12399
+ const cloudbase = await getManager();
12400
+ const envId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
12401
+ let result;
12402
+ if (resourceType === "noSqlDatabase") {
12403
+ if (aclTag === "CUSTOM") {
12540
12404
  if (!rule)
12541
- throw new Error("云函数自定义安全规则(CUSTOM)必须提供 rule 字段");
12405
+ throw new Error("noSQL 数据库自定义安全规则(CUSTOM)必须提供 rule 字段");
12542
12406
  result = await cloudbase.commonService().call({
12543
- Action: "ModifySecurityRule",
12407
+ Action: "ModifySafeRule",
12544
12408
  Param: {
12545
- AclTag: aclTag,
12409
+ CollectionName: resourceId,
12546
12410
  EnvId: envId,
12547
- ResourceType: "FUNCTION",
12411
+ AclTag: aclTag,
12548
12412
  Rule: rule,
12549
12413
  },
12550
12414
  });
12551
12415
  (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
12552
12416
  }
12553
- else if (resourceType === "storage") {
12554
- if (aclTag === "CUSTOM") {
12555
- if (!rule)
12556
- throw new Error("存储自定义安全规则(CUSTOM)必须提供 rule 字段");
12557
- result = await cloudbase.commonService().call({
12558
- Action: "ModifyStorageSafeRule",
12559
- Param: {
12560
- Bucket: resourceId,
12561
- EnvId: envId,
12562
- AclTag: aclTag,
12563
- Rule: rule,
12564
- },
12565
- });
12566
- (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
12567
- }
12568
- else {
12569
- result = await cloudbase.commonService().call({
12570
- Action: "ModifyStorageSafeRule",
12571
- Param: {
12572
- Bucket: resourceId,
12573
- EnvId: envId,
12574
- AclTag: aclTag,
12575
- },
12576
- });
12577
- (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
12578
- }
12417
+ else {
12418
+ result = await cloudbase.commonService().call({
12419
+ Action: "ModifyDatabaseACL",
12420
+ Param: {
12421
+ CollectionName: resourceId,
12422
+ EnvId: envId,
12423
+ AclTag: aclTag,
12424
+ },
12425
+ });
12426
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
12579
12427
  }
12580
- else if (resourceType === "sqlDatabase") {
12581
- if (aclTag === "CUSTOM") {
12582
- throw new Error("SQL 数据库不支持自定义安全规则(CUSTOM");
12583
- }
12584
- const schema = envId;
12585
- const tableName = resourceId;
12586
- const instanceId = "default";
12587
- const resource = `${instanceId}#${schema}#${tableName}`;
12588
- const resourceType = "table";
12589
- const effect = "allow";
12590
- const policyList = [
12591
- "allUser",
12592
- "anonymousUser",
12593
- "externalUser",
12594
- "internalUser",
12595
- ].map((roleIdentity) => ({
12596
- RoleIdentity: roleIdentity,
12597
- ResourceType: resourceType,
12598
- ResourceId: resource,
12599
- RowPermission: [],
12600
- Effect: effect,
12601
- }));
12602
- policyList[0].RowPermission = getRowPermission(aclTag);
12603
- result = await cloudbase.commonService("lowcode").call({
12604
- Action: "BatchCreateResourcePolicy",
12428
+ }
12429
+ else if (resourceType === "function") {
12430
+ if (aclTag !== "CUSTOM")
12431
+ throw new Error("云函数安全规则仅支持 CUSTOM 权限类别");
12432
+ if (!rule)
12433
+ throw new Error("云函数自定义安全规则(CUSTOM)必须提供 rule 字段");
12434
+ result = await cloudbase.commonService().call({
12435
+ Action: "ModifySecurityRule",
12436
+ Param: {
12437
+ AclTag: aclTag,
12438
+ EnvId: envId,
12439
+ ResourceType: "FUNCTION",
12440
+ Rule: rule,
12441
+ },
12442
+ });
12443
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
12444
+ }
12445
+ else if (resourceType === "storage") {
12446
+ if (aclTag === "CUSTOM") {
12447
+ if (!rule)
12448
+ throw new Error("存储自定义安全规则(CUSTOM)必须提供 rule 字段");
12449
+ result = await cloudbase.commonService().call({
12450
+ Action: "ModifyStorageSafeRule",
12605
12451
  Param: {
12452
+ Bucket: resourceId,
12606
12453
  EnvId: envId,
12607
- PolicyList: policyList,
12454
+ AclTag: aclTag,
12455
+ Rule: rule,
12608
12456
  },
12609
12457
  });
12610
12458
  (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
12611
- function getRowPermission(policy) {
12612
- return {
12613
- READONLY: [
12614
- { Key: "all", Value: "r" },
12615
- { Key: "me", Value: "rw" },
12616
- ],
12617
- PRIVATE: [{ Key: "me", Value: "rw" }],
12618
- ADMINWRITE: [{ Key: "all", Value: "r" }],
12619
- ADMINONLY: [],
12620
- }[policy];
12621
- }
12622
12459
  }
12623
12460
  else {
12624
- throw new Error(`不支持的资源类型: ${resourceType}`);
12625
- }
12626
- return {
12627
- content: [
12628
- {
12629
- type: "text",
12630
- text: JSON.stringify({
12631
- success: true,
12632
- requestId: result.RequestId,
12633
- raw: result,
12634
- message: "安全规则写入成功",
12635
- }, null, 2),
12461
+ result = await cloudbase.commonService().call({
12462
+ Action: "ModifyStorageSafeRule",
12463
+ Param: {
12464
+ Bucket: resourceId,
12465
+ EnvId: envId,
12466
+ AclTag: aclTag,
12636
12467
  },
12637
- ],
12638
- };
12468
+ });
12469
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
12470
+ }
12639
12471
  }
12640
- catch (error) {
12641
- return {
12642
- content: [
12643
- {
12644
- type: "text",
12645
- text: JSON.stringify({
12646
- success: false,
12647
- error: error.message,
12648
- message: "安全规则写入失败",
12649
- }, null, 2),
12650
- },
12651
- ],
12652
- };
12472
+ else if (resourceType === "sqlDatabase") {
12473
+ if (aclTag === "CUSTOM") {
12474
+ throw new Error("SQL 数据库不支持自定义安全规则(CUSTOM)");
12475
+ }
12476
+ const schema = envId;
12477
+ const tableName = resourceId;
12478
+ const instanceId = "default";
12479
+ const resource = `${instanceId}#${schema}#${tableName}`;
12480
+ const resourceType = "table";
12481
+ const effect = "allow";
12482
+ const policyList = [
12483
+ "allUser",
12484
+ "anonymousUser",
12485
+ "externalUser",
12486
+ "internalUser",
12487
+ ].map((roleIdentity) => ({
12488
+ RoleIdentity: roleIdentity,
12489
+ ResourceType: resourceType,
12490
+ ResourceId: resource,
12491
+ RowPermission: [],
12492
+ Effect: effect,
12493
+ }));
12494
+ policyList[0].RowPermission = getRowPermission(aclTag);
12495
+ result = await cloudbase.commonService("lowcode").call({
12496
+ Action: "BatchCreateResourcePolicy",
12497
+ Param: {
12498
+ EnvId: envId,
12499
+ PolicyList: policyList,
12500
+ },
12501
+ });
12502
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
12503
+ function getRowPermission(policy) {
12504
+ return {
12505
+ READONLY: [
12506
+ { Key: "all", Value: "r" },
12507
+ { Key: "me", Value: "rw" },
12508
+ ],
12509
+ PRIVATE: [{ Key: "me", Value: "rw" }],
12510
+ ADMINWRITE: [{ Key: "all", Value: "r" }],
12511
+ ADMINONLY: [],
12512
+ }[policy];
12513
+ }
12514
+ }
12515
+ else {
12516
+ throw new Error(`不支持的资源类型: ${resourceType}`);
12653
12517
  }
12518
+ return {
12519
+ content: [
12520
+ {
12521
+ type: "text",
12522
+ text: JSON.stringify({
12523
+ success: true,
12524
+ requestId: result.RequestId,
12525
+ raw: result,
12526
+ message: "安全规则写入成功",
12527
+ }, null, 2),
12528
+ },
12529
+ ],
12530
+ };
12654
12531
  });
12655
12532
  }
12656
12533
 
@@ -13333,64 +13210,44 @@ function registerDownloadTools(server) {
13333
13210
  category: "download"
13334
13211
  }
13335
13212
  }, async ({ url, relativePath }) => {
13336
- try {
13337
- // 验证相对路径安全性
13338
- if (!isPathSafe(relativePath)) {
13339
- return {
13340
- content: [
13341
- {
13342
- type: "text",
13343
- text: JSON.stringify({
13344
- success: false,
13345
- error: "不安全的相对路径",
13346
- message: "相对路径包含路径遍历操作(../)或绝对路径,出于安全考虑已拒绝",
13347
- suggestion: "请使用项目根目录下的相对路径,例如:'assets/images/logo.png'"
13348
- }, null, 2)
13349
- }
13350
- ]
13351
- };
13352
- }
13353
- // 计算最终下载路径
13354
- const targetPath = calculateDownloadPath(relativePath);
13355
- const projectRoot = getProjectRoot();
13356
- console.log(`📁 项目根目录: ${projectRoot}`);
13357
- console.log(`📁 相对路径: ${relativePath}`);
13358
- console.log(`📁 最终路径: ${targetPath}`);
13359
- // 下载文件到指定路径
13360
- const result = await downloadFileToPath(url, targetPath);
13361
- return {
13362
- content: [
13363
- {
13364
- type: "text",
13365
- text: JSON.stringify({
13366
- success: true,
13367
- filePath: result.filePath,
13368
- relativePath: relativePath,
13369
- contentType: result.contentType,
13370
- fileSize: result.fileSize,
13371
- projectRoot: projectRoot,
13372
- message: "文件下载成功到指定路径",
13373
- note: `文件已保存到项目目录: ${relativePath}`
13374
- }, null, 2)
13375
- }
13376
- ]
13377
- };
13378
- }
13379
- catch (error) {
13213
+ if (!isPathSafe(relativePath)) {
13380
13214
  return {
13381
13215
  content: [
13382
13216
  {
13383
13217
  type: "text",
13384
13218
  text: JSON.stringify({
13385
13219
  success: false,
13386
- error: error.message,
13387
- message: "文件下载失败",
13388
- suggestion: "请检查相对路径是否正确,确保不包含 ../ 等路径遍历操作"
13220
+ error: "不安全的相对路径",
13221
+ message: "相对路径包含路径遍历操作(../)或绝对路径,出于安全考虑已拒绝",
13222
+ suggestion: "请使用项目根目录下的相对路径,例如:'assets/images/logo.png'"
13389
13223
  }, null, 2)
13390
13224
  }
13391
13225
  ]
13392
13226
  };
13393
13227
  }
13228
+ const targetPath = calculateDownloadPath(relativePath);
13229
+ const projectRoot = getProjectRoot();
13230
+ console.log(`📁 项目根目录: ${projectRoot}`);
13231
+ console.log(`📁 相对路径: ${relativePath}`);
13232
+ console.log(`📁 最终路径: ${targetPath}`);
13233
+ const result = await downloadFileToPath(url, targetPath);
13234
+ return {
13235
+ content: [
13236
+ {
13237
+ type: "text",
13238
+ text: JSON.stringify({
13239
+ success: true,
13240
+ filePath: result.filePath,
13241
+ relativePath: relativePath,
13242
+ contentType: result.contentType,
13243
+ fileSize: result.fileSize,
13244
+ projectRoot: projectRoot,
13245
+ message: "文件下载成功到指定路径",
13246
+ note: `文件已保存到项目目录: ${relativePath}`
13247
+ }, null, 2)
13248
+ }
13249
+ ]
13250
+ };
13394
13251
  });
13395
13252
  }
13396
13253
 
@@ -13605,52 +13462,35 @@ function registerSQLDatabaseTools(server) {
13605
13462
  category: CATEGORY,
13606
13463
  },
13607
13464
  }, async ({ sql }) => {
13608
- try {
13609
- const cloudbase = await getManager();
13610
- const envId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
13611
- // TODO: 考虑是否有支持指定其他 instance、schema 的需求
13612
- const schemaId = envId;
13613
- const instanceId = "default";
13614
- const result = await cloudbase.commonService("tcb").call({
13615
- Action: "RunSql",
13616
- Param: {
13465
+ const cloudbase = await getManager();
13466
+ const envId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
13467
+ const schemaId = envId;
13468
+ const instanceId = "default";
13469
+ const result = await cloudbase.commonService("tcb", "2018-06-08").call({
13470
+ Action: "RunSql",
13471
+ Param: {
13472
+ EnvId: envId,
13473
+ Sql: sql,
13474
+ DbInstance: {
13617
13475
  EnvId: envId,
13618
- Sql: sql,
13619
- DbInstance: {
13620
- EnvId: envId,
13621
- InstanceId: instanceId,
13622
- Schema: schemaId,
13623
- },
13476
+ InstanceId: instanceId,
13477
+ Schema: schemaId,
13624
13478
  },
13625
- });
13626
- (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
13627
- return {
13628
- content: [
13629
- {
13630
- type: "text",
13631
- text: JSON.stringify({
13632
- success: true,
13633
- message: "SQL query executed successfully",
13634
- result,
13635
- }, null, 2),
13636
- },
13637
- ],
13638
- };
13639
- }
13640
- catch (error) {
13641
- return {
13642
- content: [
13643
- {
13644
- type: "text",
13645
- text: JSON.stringify({
13646
- success: false,
13647
- error: error.message,
13648
- message: "SQL query execution failed",
13649
- }, null, 2),
13650
- },
13651
- ],
13652
- };
13653
- }
13479
+ },
13480
+ });
13481
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
13482
+ return {
13483
+ content: [
13484
+ {
13485
+ type: "text",
13486
+ text: JSON.stringify({
13487
+ success: true,
13488
+ message: "SQL query executed successfully",
13489
+ result,
13490
+ }, null, 2),
13491
+ },
13492
+ ],
13493
+ };
13654
13494
  });
13655
13495
  // executeWriteSQL
13656
13496
  server.registerTool?.("executeWriteSQL", {
@@ -13669,52 +13509,35 @@ function registerSQLDatabaseTools(server) {
13669
13509
  category: CATEGORY,
13670
13510
  },
13671
13511
  }, async ({ sql }) => {
13672
- try {
13673
- const cloudbase = await getManager();
13674
- const envId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
13675
- // TODO: 考虑是否有支持指定其他 instance、schema 的需求
13676
- const schemaId = envId;
13677
- const instanceId = "default";
13678
- const result = await cloudbase.commonService("tcb").call({
13679
- Action: "RunSql",
13680
- Param: {
13512
+ const cloudbase = await getManager();
13513
+ const envId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
13514
+ const schemaId = envId;
13515
+ const instanceId = "default";
13516
+ const result = await cloudbase.commonService("tcb", "2018-06-08").call({
13517
+ Action: "RunSql",
13518
+ Param: {
13519
+ EnvId: envId,
13520
+ Sql: sql,
13521
+ DbInstance: {
13681
13522
  EnvId: envId,
13682
- Sql: sql,
13683
- DbInstance: {
13684
- EnvId: envId,
13685
- InstanceId: instanceId,
13686
- Schema: schemaId,
13687
- },
13523
+ InstanceId: instanceId,
13524
+ Schema: schemaId,
13688
13525
  },
13689
- });
13690
- (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
13691
- return {
13692
- content: [
13693
- {
13694
- type: "text",
13695
- text: JSON.stringify({
13696
- success: true,
13697
- message: `SQL statement executed successfully. If you just created a table, make sure to check its security rule is set to a proper value by using \`${security_rule_js_1.WRITE_SECURITY_RULE}\` and \`${security_rule_js_1.READ_SECURITY_RULE}\` tools.`,
13698
- result,
13699
- }, null, 2),
13700
- },
13701
- ],
13702
- };
13703
- }
13704
- catch (error) {
13705
- return {
13706
- content: [
13707
- {
13708
- type: "text",
13709
- text: JSON.stringify({
13710
- success: false,
13711
- error: error.message,
13712
- message: "SQL statement execution failed",
13713
- }, null, 2),
13714
- },
13715
- ],
13716
- };
13717
- }
13526
+ },
13527
+ });
13528
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
13529
+ return {
13530
+ content: [
13531
+ {
13532
+ type: "text",
13533
+ text: JSON.stringify({
13534
+ success: true,
13535
+ message: `SQL statement executed successfully. If you just created a table, make sure to check its security rule is set to a proper value by using \`${security_rule_js_1.WRITE_SECURITY_RULE}\` and \`${security_rule_js_1.READ_SECURITY_RULE}\` tools.`,
13536
+ result,
13537
+ }, null, 2),
13538
+ },
13539
+ ],
13540
+ };
13718
13541
  });
13719
13542
  }
13720
13543