@cloudbase/cloudbase-mcp 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,32 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { registerEnvTools } from "./tools/env.js";
4
+ import { registerFileTools } from "./tools/file.js";
5
+ import { registerDatabaseTools } from "./tools/database.js";
6
+ import { registerHostingTools } from "./tools/hosting.js";
7
+ // Create server instance
8
+ const server = new McpServer({
9
+ name: "cloudbase-mcp",
10
+ version: "1.0.0",
11
+ capabilities: {
12
+ resources: {},
13
+ tools: {},
14
+ },
15
+ });
16
+ // Register environment management tools
17
+ registerEnvTools(server);
18
+ // Register file management tools
19
+ registerFileTools(server);
20
+ // Register database management tools
21
+ registerDatabaseTools(server);
22
+ // Register hosting management tools
23
+ registerHostingTools(server);
24
+ async function main() {
25
+ const transport = new StdioServerTransport();
26
+ await server.connect(transport);
27
+ console.error("TencentCloudBase MCP Server running on stdio");
28
+ }
29
+ main().catch((error) => {
30
+ console.error("Fatal error in main():", error);
31
+ process.exit(1);
32
+ });
@@ -0,0 +1,657 @@
1
+ import { z } from "zod";
2
+ import CloudBase from "@cloudbase/manager-node";
3
+ // 初始化CloudBase
4
+ const cloudbase = new CloudBase({
5
+ secretId: process.env.TENCENTCLOUD_SECRETID,
6
+ secretKey: process.env.TENCENTCLOUD_SECRETKEY,
7
+ envId: process.env.CLOUDBASE_ENV_ID,
8
+ token: process.env.TENCENTCLOUD_SESSIONTOKEN
9
+ });
10
+ // 获取数据库实例ID
11
+ async function getDatabaseInstanceId() {
12
+ const { EnvInfo } = await cloudbase.env.getEnvInfo();
13
+ if (!EnvInfo?.Databases?.[0]?.InstanceId) {
14
+ throw new Error("无法获取数据库实例ID");
15
+ }
16
+ return EnvInfo.Databases[0].InstanceId;
17
+ }
18
+ export function registerDatabaseTools(server) {
19
+ // 创建云开发数据库集合
20
+ server.tool("createCollection", "创建一个新的云开发数据库集合", {
21
+ collectionName: z.string().describe("云开发数据库集合名称")
22
+ }, async ({ collectionName }) => {
23
+ try {
24
+ const result = await cloudbase.database.createCollection(collectionName);
25
+ return {
26
+ content: [
27
+ {
28
+ type: "text",
29
+ text: JSON.stringify({
30
+ success: true,
31
+ requestId: result.RequestId,
32
+ message: "云开发数据库集合创建成功"
33
+ }, null, 2)
34
+ }
35
+ ]
36
+ };
37
+ }
38
+ catch (error) {
39
+ return {
40
+ content: [
41
+ {
42
+ type: "text",
43
+ text: JSON.stringify({
44
+ success: false,
45
+ error: error.message,
46
+ message: "云开发数据库集合创建失败"
47
+ }, null, 2)
48
+ }
49
+ ]
50
+ };
51
+ }
52
+ });
53
+ // 检查云开发数据库集合是否存在
54
+ server.tool("checkCollectionExists", "检查云开发数据库集合是否存在", {
55
+ collectionName: z.string().describe("云开发数据库集合名称")
56
+ }, async ({ collectionName }) => {
57
+ try {
58
+ const result = await cloudbase.database.checkCollectionExists(collectionName);
59
+ return {
60
+ content: [
61
+ {
62
+ type: "text",
63
+ text: JSON.stringify({
64
+ success: true,
65
+ exists: result.Exists,
66
+ requestId: result.RequestId,
67
+ message: result.Exists ? "云开发数据库集合已存在" : "云开发数据库集合不存在"
68
+ }, null, 2)
69
+ }
70
+ ]
71
+ };
72
+ }
73
+ catch (error) {
74
+ return {
75
+ content: [
76
+ {
77
+ type: "text",
78
+ text: JSON.stringify({
79
+ success: false,
80
+ error: error.message,
81
+ message: "检查云开发数据库集合失败"
82
+ }, null, 2)
83
+ }
84
+ ]
85
+ };
86
+ }
87
+ });
88
+ // // 删除云开发数据库集合
89
+ // server.tool(
90
+ // "deleteCollection",
91
+ // "删除一个云开发数据库集合",
92
+ // {
93
+ // collectionName: z.string().describe("云开发数据库集合名称")
94
+ // },
95
+ // async ({ collectionName }) => {
96
+ // try {
97
+ // const result = await cloudbase.database.deleteCollection(collectionName);
98
+ // return {
99
+ // content: [
100
+ // {
101
+ // type: "text",
102
+ // text: JSON.stringify({
103
+ // success: true,
104
+ // requestId: result.RequestId,
105
+ // exists: result.Exists,
106
+ // message: "云开发数据库集合删除成功"
107
+ // }, null, 2)
108
+ // }
109
+ // ]
110
+ // };
111
+ // } catch (error: any) {
112
+ // return {
113
+ // content: [
114
+ // {
115
+ // type: "text",
116
+ // text: JSON.stringify({
117
+ // success: false,
118
+ // error: error.message,
119
+ // message: "云开发数据库集合删除失败"
120
+ // }, null, 2)
121
+ // }
122
+ // ]
123
+ // };
124
+ // }
125
+ // }
126
+ // );
127
+ // 更新云开发数据库集合(创建/删除索引)
128
+ server.tool("updateCollection", "更新云开发数据库集合配置(创建或删除索引)", {
129
+ collectionName: z.string().describe("云开发数据库集合名称"),
130
+ options: z.object({
131
+ CreateIndexes: z.array(z.object({
132
+ IndexName: z.string(),
133
+ MgoKeySchema: z.object({
134
+ MgoIsUnique: z.boolean(),
135
+ MgoIndexKeys: z.array(z.object({
136
+ Name: z.string(),
137
+ Direction: z.string()
138
+ }))
139
+ })
140
+ })).optional(),
141
+ DropIndexes: z.array(z.object({
142
+ IndexName: z.string()
143
+ })).optional()
144
+ }).describe("更新选项,支持创建和删除索引")
145
+ }, async ({ collectionName, options }) => {
146
+ try {
147
+ const result = await cloudbase.database.updateCollection(collectionName, options);
148
+ return {
149
+ content: [
150
+ {
151
+ type: "text",
152
+ text: JSON.stringify({
153
+ success: true,
154
+ requestId: result.RequestId,
155
+ message: "云开发数据库集合更新成功"
156
+ }, null, 2)
157
+ }
158
+ ]
159
+ };
160
+ }
161
+ catch (error) {
162
+ return {
163
+ content: [
164
+ {
165
+ type: "text",
166
+ text: JSON.stringify({
167
+ success: false,
168
+ error: error.message,
169
+ message: "云开发数据库集合更新失败"
170
+ }, null, 2)
171
+ }
172
+ ]
173
+ };
174
+ }
175
+ });
176
+ // 查询云开发数据库集合详情
177
+ server.tool("describeCollection", "获取云开发数据库集合的详细信息", {
178
+ collectionName: z.string().describe("云开发数据库集合名称")
179
+ }, async ({ collectionName }) => {
180
+ try {
181
+ const result = await cloudbase.database.describeCollection(collectionName);
182
+ return {
183
+ content: [
184
+ {
185
+ type: "text",
186
+ text: JSON.stringify({
187
+ success: true,
188
+ requestId: result.RequestId,
189
+ indexNum: result.IndexNum,
190
+ indexes: result.Indexes,
191
+ message: "获取云开发数据库集合信息成功"
192
+ }, null, 2)
193
+ }
194
+ ]
195
+ };
196
+ }
197
+ catch (error) {
198
+ return {
199
+ content: [
200
+ {
201
+ type: "text",
202
+ text: JSON.stringify({
203
+ success: false,
204
+ error: error.message,
205
+ message: "获取云开发数据库集合信息失败"
206
+ }, null, 2)
207
+ }
208
+ ]
209
+ };
210
+ }
211
+ });
212
+ // 获取云开发数据库集合列表
213
+ server.tool("listCollections", "获取云开发数据库集合列表", {
214
+ offset: z.number().optional().describe("偏移量"),
215
+ limit: z.number().optional().describe("返回数量限制")
216
+ }, async ({ offset, limit }) => {
217
+ try {
218
+ const result = await cloudbase.database.listCollections({
219
+ MgoOffset: offset,
220
+ MgoLimit: limit
221
+ });
222
+ return {
223
+ content: [
224
+ {
225
+ type: "text",
226
+ text: JSON.stringify({
227
+ success: true,
228
+ requestId: result.RequestId,
229
+ collections: result.Collections,
230
+ pager: result.Pager,
231
+ message: "获取云开发数据库集合列表成功"
232
+ }, null, 2)
233
+ }
234
+ ]
235
+ };
236
+ }
237
+ catch (error) {
238
+ return {
239
+ content: [
240
+ {
241
+ type: "text",
242
+ text: JSON.stringify({
243
+ success: false,
244
+ error: error.message,
245
+ message: "获取云开发数据库集合列表失败"
246
+ }, null, 2)
247
+ }
248
+ ]
249
+ };
250
+ }
251
+ });
252
+ // 检查索引是否存在
253
+ server.tool("checkIndexExists", "检查索引是否存在", {
254
+ collectionName: z.string().describe("云开发数据库集合名称"),
255
+ indexName: z.string().describe("索引名称")
256
+ }, async ({ collectionName, indexName }) => {
257
+ try {
258
+ const result = await cloudbase.database.checkIndexExists(collectionName, indexName);
259
+ return {
260
+ content: [
261
+ {
262
+ type: "text",
263
+ text: JSON.stringify({
264
+ success: true,
265
+ exists: result.Exists,
266
+ requestId: result.RequestId,
267
+ message: result.Exists ? "索引已存在" : "索引不存在"
268
+ }, null, 2)
269
+ }
270
+ ]
271
+ };
272
+ }
273
+ catch (error) {
274
+ return {
275
+ content: [
276
+ {
277
+ type: "text",
278
+ text: JSON.stringify({
279
+ success: false,
280
+ error: error.message,
281
+ message: "检查索引失败"
282
+ }, null, 2)
283
+ }
284
+ ]
285
+ };
286
+ }
287
+ });
288
+ // // 导入数据
289
+ // server.tool(
290
+ // "importData",
291
+ // "导入数据到云开发数据库集合中",
292
+ // {
293
+ // collectionName: z.string().describe("云开发数据库集合名称"),
294
+ // file: z.object({
295
+ // ObjectKey: z.string().optional().describe("对象存储中的文件路径"),
296
+ // FilePath: z.string().optional().describe("本地文件路径")
297
+ // }).describe("导入文件信息"),
298
+ // options: z.object({
299
+ // FileType: z.enum(["csv", "json"]).optional().describe("文件类型"),
300
+ // StopOnError: z.boolean().optional().describe("遇到错误时是否停止导入"),
301
+ // ConflictMode: z.enum(["insert", "upsert"]).optional().describe("冲突处理方式")
302
+ // }).optional().describe("导入选项")
303
+ // },
304
+ // async ({ collectionName, file, options }) => {
305
+ // try {
306
+ // const result = await cloudbase.database.import(collectionName, file, options);
307
+ // return {
308
+ // content: [
309
+ // {
310
+ // type: "text",
311
+ // text: JSON.stringify({
312
+ // success: true,
313
+ // requestId: result.RequestId,
314
+ // jobId: result.JobId,
315
+ // message: "数据导入任务创建成功"
316
+ // }, null, 2)
317
+ // }
318
+ // ]
319
+ // };
320
+ // } catch (error: any) {
321
+ // return {
322
+ // content: [
323
+ // {
324
+ // type: "text",
325
+ // text: JSON.stringify({
326
+ // success: false,
327
+ // error: error.message,
328
+ // message: "数据导入任务创建失败"
329
+ // }, null, 2)
330
+ // }
331
+ // ]
332
+ // };
333
+ // }
334
+ // }
335
+ // );
336
+ // // 导出数据
337
+ // server.tool(
338
+ // "exportData",
339
+ // "从云开发数据库集合中导出数据",
340
+ // {
341
+ // collectionName: z.string().describe("云开发数据库集合名称"),
342
+ // file: z.object({
343
+ // ObjectKey: z.string().describe("导出到对象存储的文件路径")
344
+ // }).describe("导出文件信息"),
345
+ // options: z.object({
346
+ // FileType: z.enum(["csv", "json"]).optional().describe("文件类型"),
347
+ // Query: z.string().optional().describe("查询条件(JSON字符串)"),
348
+ // Sort: z.string().optional().describe("排序条件(JSON字符串)"),
349
+ // Skip: z.number().optional().describe("跳过的记录数"),
350
+ // Limit: z.number().optional().describe("限制返回的记录数"),
351
+ // Fields: z.string().optional().describe("导出字段列表,以逗号分隔")
352
+ // }).optional().describe("导出选项")
353
+ // },
354
+ // async ({ collectionName, file, options }) => {
355
+ // try {
356
+ // const result = await cloudbase.database.export(collectionName, file, options);
357
+ // return {
358
+ // content: [
359
+ // {
360
+ // type: "text",
361
+ // text: JSON.stringify({
362
+ // success: true,
363
+ // requestId: result.RequestId,
364
+ // jobId: result.JobId,
365
+ // message: "数据导出任务创建成功"
366
+ // }, null, 2)
367
+ // }
368
+ // ]
369
+ // };
370
+ // } catch (error: any) {
371
+ // return {
372
+ // content: [
373
+ // {
374
+ // type: "text",
375
+ // text: JSON.stringify({
376
+ // success: false,
377
+ // error: error.message,
378
+ // message: "数据导出任务创建失败"
379
+ // }, null, 2)
380
+ // }
381
+ // ]
382
+ // };
383
+ // }
384
+ // }
385
+ // );
386
+ // // 查询迁移状态
387
+ // server.tool(
388
+ // "migrateStatus",
389
+ // "查询数据迁移(导入/导出)任务的状态",
390
+ // {
391
+ // jobId: z.number().describe("任务ID")
392
+ // },
393
+ // async ({ jobId }) => {
394
+ // try {
395
+ // const result = await cloudbase.database.migrateStatus(jobId);
396
+ // return {
397
+ // content: [
398
+ // {
399
+ // type: "text",
400
+ // text: JSON.stringify({
401
+ // success: true,
402
+ // requestId: result.RequestId,
403
+ // status: result.Status,
404
+ // recordSuccess: result.RecordSuccess,
405
+ // recordFail: result.RecordFail,
406
+ // errorMsg: result.ErrorMsg,
407
+ // fileUrl: result.FileUrl,
408
+ // message: "获取迁移状态成功"
409
+ // }, null, 2)
410
+ // }
411
+ // ]
412
+ // };
413
+ // } catch (error: any) {
414
+ // return {
415
+ // content: [
416
+ // {
417
+ // type: "text",
418
+ // text: JSON.stringify({
419
+ // success: false,
420
+ // error: error.message,
421
+ // message: "获取迁移状态失败"
422
+ // }, null, 2)
423
+ // }
424
+ // ]
425
+ // };
426
+ // }
427
+ // }
428
+ // );
429
+ // 查询数据分布
430
+ server.tool("distribution", "查询数据库中云开发数据库集合的数据分布情况", {}, async () => {
431
+ try {
432
+ const result = await cloudbase.database.distribution();
433
+ return {
434
+ content: [
435
+ {
436
+ type: "text",
437
+ text: JSON.stringify({
438
+ success: true,
439
+ requestId: result.RequestId,
440
+ collections: result.Collections,
441
+ message: "获取数据分布成功"
442
+ }, null, 2)
443
+ }
444
+ ]
445
+ };
446
+ }
447
+ catch (error) {
448
+ return {
449
+ content: [
450
+ {
451
+ type: "text",
452
+ text: JSON.stringify({
453
+ success: false,
454
+ error: error.message,
455
+ message: "获取数据分布失败"
456
+ }, null, 2)
457
+ }
458
+ ]
459
+ };
460
+ }
461
+ });
462
+ // 插入文档
463
+ server.tool("insertDocuments", "向云开发数据库集合中插入一个或多个文档", {
464
+ collectionName: z.string().describe("云开发数据库集合名称"),
465
+ documents: z.array(z.string()).describe("要插入的文档数组,每个文档都是JSON字符串")
466
+ }, async ({ collectionName, documents }) => {
467
+ try {
468
+ const instanceId = await getDatabaseInstanceId();
469
+ const result = await cloudbase.commonService('flexdb').call({
470
+ Action: 'PutItem',
471
+ Param: {
472
+ TableName: collectionName,
473
+ MgoDocs: documents,
474
+ Tag: instanceId
475
+ }
476
+ });
477
+ return {
478
+ content: [
479
+ {
480
+ type: "text",
481
+ text: JSON.stringify({
482
+ success: true,
483
+ requestId: result.RequestId,
484
+ insertedIds: result.InsertedIds,
485
+ message: "文档插入成功"
486
+ }, null, 2)
487
+ }
488
+ ]
489
+ };
490
+ }
491
+ catch (error) {
492
+ return {
493
+ content: [
494
+ {
495
+ type: "text",
496
+ text: JSON.stringify({
497
+ success: false,
498
+ error: error.message,
499
+ message: "文档插入失败"
500
+ }, null, 2)
501
+ }
502
+ ]
503
+ };
504
+ }
505
+ });
506
+ // 查询文档
507
+ server.tool("queryDocuments", "查询云开发数据库集合中的文档", {
508
+ collectionName: z.string().describe("云开发数据库集合名称"),
509
+ query: z.string().optional().describe("查询条件(JSON字符串)"),
510
+ projection: z.string().optional().describe("返回字段投影(JSON字符串)"),
511
+ sort: z.string().optional().describe("排序条件(JSON字符串)"),
512
+ limit: z.number().optional().describe("返回数量限制"),
513
+ offset: z.number().optional().describe("跳过的记录数")
514
+ }, async ({ collectionName, query, projection, sort, limit, offset }) => {
515
+ try {
516
+ const instanceId = await getDatabaseInstanceId();
517
+ const result = await cloudbase.commonService('flexdb').call({
518
+ Action: 'Query',
519
+ Param: {
520
+ TableName: collectionName,
521
+ MgoQuery: query,
522
+ MgoProjection: projection,
523
+ MgoSort: sort,
524
+ MgoLimit: limit,
525
+ MgoOffset: offset,
526
+ Tag: instanceId
527
+ }
528
+ });
529
+ return {
530
+ content: [
531
+ {
532
+ type: "text",
533
+ text: JSON.stringify({
534
+ success: true,
535
+ requestId: result.RequestId,
536
+ data: result.Data,
537
+ pager: result.Pager,
538
+ message: "文档查询成功"
539
+ }, null, 2)
540
+ }
541
+ ]
542
+ };
543
+ }
544
+ catch (error) {
545
+ return {
546
+ content: [
547
+ {
548
+ type: "text",
549
+ text: JSON.stringify({
550
+ success: false,
551
+ error: error.message,
552
+ message: "文档查询失败"
553
+ }, null, 2)
554
+ }
555
+ ]
556
+ };
557
+ }
558
+ });
559
+ // 更新文档
560
+ server.tool("updateDocuments", "更新云开发数据库集合中的文档", {
561
+ collectionName: z.string().describe("云开发数据库集合名称"),
562
+ query: z.string().describe("查询条件(JSON字符串)"),
563
+ update: z.string().describe("更新内容(JSON字符串)"),
564
+ isMulti: z.boolean().optional().describe("是否更新多条记录"),
565
+ upsert: z.boolean().optional().describe("是否在不存在时插入")
566
+ }, async ({ collectionName, query, update, isMulti, upsert }) => {
567
+ try {
568
+ const instanceId = await getDatabaseInstanceId();
569
+ const result = await cloudbase.commonService('flexdb').call({
570
+ Action: 'UpdateItem',
571
+ Param: {
572
+ TableName: collectionName,
573
+ MgoQuery: query,
574
+ MgoUpdate: update,
575
+ MgoIsMulti: isMulti,
576
+ MgoUpsert: upsert,
577
+ Tag: instanceId
578
+ }
579
+ });
580
+ return {
581
+ content: [
582
+ {
583
+ type: "text",
584
+ text: JSON.stringify({
585
+ success: true,
586
+ requestId: result.RequestId,
587
+ modifiedCount: result.ModifiedNum,
588
+ matchedCount: result.MatchedNum,
589
+ upsertedId: result.UpsertedId,
590
+ message: "文档更新成功"
591
+ }, null, 2)
592
+ }
593
+ ]
594
+ };
595
+ }
596
+ catch (error) {
597
+ return {
598
+ content: [
599
+ {
600
+ type: "text",
601
+ text: JSON.stringify({
602
+ success: false,
603
+ error: error.message,
604
+ message: "文档更新失败"
605
+ }, null, 2)
606
+ }
607
+ ]
608
+ };
609
+ }
610
+ });
611
+ // 删除文档
612
+ server.tool("deleteDocuments", "删除云开发数据库集合中的文档", {
613
+ collectionName: z.string().describe("云开发数据库集合名称"),
614
+ query: z.string().describe("查询条件(JSON字符串)"),
615
+ isMulti: z.boolean().optional().describe("是否删除多条记录")
616
+ }, async ({ collectionName, query, isMulti }) => {
617
+ try {
618
+ const instanceId = await getDatabaseInstanceId();
619
+ const result = await cloudbase.commonService('flexdb').call({
620
+ Action: 'DeleteItem',
621
+ Param: {
622
+ TableName: collectionName,
623
+ MgoQuery: query,
624
+ MgoIsMulti: isMulti,
625
+ Tag: instanceId
626
+ }
627
+ });
628
+ return {
629
+ content: [
630
+ {
631
+ type: "text",
632
+ text: JSON.stringify({
633
+ success: true,
634
+ requestId: result.RequestId,
635
+ deleted: result.Deleted,
636
+ message: "文档删除成功"
637
+ }, null, 2)
638
+ }
639
+ ]
640
+ };
641
+ }
642
+ catch (error) {
643
+ return {
644
+ content: [
645
+ {
646
+ type: "text",
647
+ text: JSON.stringify({
648
+ success: false,
649
+ error: error.message,
650
+ message: "文档删除失败"
651
+ }, null, 2)
652
+ }
653
+ ]
654
+ };
655
+ }
656
+ });
657
+ }