@cloudbase/cloudbase-mcp 2.20.1 → 2.21.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/cli.cjs +3 -3
- package/dist/index.cjs +311 -81
- package/dist/index.js +311 -81
- package/package.json +2 -1
package/dist/index.cjs
CHANGED
|
@@ -2854,8 +2854,8 @@ function registerEnvTools(server) {
|
|
|
2854
2854
|
});
|
|
2855
2855
|
// envQuery - 环境查询(合并 listEnvs + getEnvInfo + getEnvAuthDomains)
|
|
2856
2856
|
server.registerTool?.("envQuery", {
|
|
2857
|
-
title: "环境查询",
|
|
2858
|
-
description: "
|
|
2857
|
+
title: "CloudBase 环境查询",
|
|
2858
|
+
description: "查询 CloudBase 环境相关信息,支持查询环境列表、指定环境详情和安全域名。(原工具名:listEnvs/getEnvInfo/getEnvAuthDomains,为兼容旧AI规则可继续使用这些名称)当 action=list 时,会按 DescribeEnvs 语义做列表/筛选,标准返回字段为 EnvId、Alias、Status、EnvType、Region、PackageId、PackageName、IsDefault,并支持通过 fields 白名单裁剪这些字段;aliasExact=true 时会按别名精确筛选,避免把前缀相近的环境误当作候选;即使传入 envId,action=list 也只返回摘要,不会返回完整资源明细或 expiry。如需查询某个已知 EnvId 对应环境的详细信息(包括资源字段和计费信息),必须使用 action=info 并传入目标环境的 envId 参数。action=info 会在可用时补充 BillingInfo(如 ExpireTime、PayMode、IsAutoRenew 等计费字段)。",
|
|
2859
2859
|
inputSchema: {
|
|
2860
2860
|
action: zod_1.z
|
|
2861
2861
|
.enum(["list", "info", "domains"])
|
|
@@ -3059,8 +3059,8 @@ function registerEnvTools(server) {
|
|
|
3059
3059
|
});
|
|
3060
3060
|
// envDomainManagement - 环境域名管理(合并 createEnvDomain + deleteEnvDomain)
|
|
3061
3061
|
server.registerTool?.("envDomainManagement", {
|
|
3062
|
-
title: "环境域名管理(安全域名 / CORS 白名单)",
|
|
3063
|
-
description: "
|
|
3062
|
+
title: "CloudBase 环境域名管理(安全域名 / CORS 白名单)",
|
|
3063
|
+
description: "管理 CloudBase 环境的安全域名(安全域名 / CORS 白名单),支持添加和删除操作。(原工具名:createEnvDomain/deleteEnvDomain,为兼容旧AI规则可继续使用这些名称)当浏览器 Web 应用需要从本地 Vite / dev server 直接访问 CloudBase 资源时,应先用 envQuery(action=domains) 检查当前实际浏览器 origin 对应的 host:port 是否已在白名单中,再按该实际值添加。新增或删除后通常需要继续轮询 envQuery(action=domains) 确认状态收敛;安全域名一般约 10 分钟生效。⚠️ 重要:此工具仅用于 CORS/请求来源验证,不涉及 SSL 证书。如需绑定自定义域名供公网 HTTPS 访问,请使用 manageGateway(action=\"bindCustomDomain\")。",
|
|
3064
3064
|
inputSchema: {
|
|
3065
3065
|
action: zod_1.z
|
|
3066
3066
|
.enum(["create", "delete"])
|
|
@@ -28555,8 +28555,8 @@ function registerAppAuthTools(server) {
|
|
|
28555
28555
|
};
|
|
28556
28556
|
};
|
|
28557
28557
|
server.registerTool?.("queryAppAuth", {
|
|
28558
|
-
title: "
|
|
28559
|
-
description: "应用侧认证配置只读入口。用于查询登录方式、provider、publishable key、API key、client 配置和静态域名等认证准备状态。⚠️ 本工具为管理端配置查询工具,不执行用户登录。当任务要求编写客户端登录代码时(例如「用 JS SDK 登录」),应先通过本工具确认配置状态,再在项目代码中编写 @cloudbase/js-sdk 客户端登录代码(如 auth.signInWithPassword()),而非使用本工具完成登录。若业务要接受普通用户名样式标识符,先查询 action=getLoginConfig;若 usernamePassword=false,下一步应立即调用 manageAppAuth(action=patchLoginStrategy, patch={ usernamePassword: true }),不要直接写 email 登录 API。",
|
|
28558
|
+
title: "查询 CloudBase 应用认证配置",
|
|
28559
|
+
description: "CloudBase 应用侧认证配置只读入口。用于查询登录方式、provider、publishable key、API key、client 配置和静态域名等认证准备状态。⚠️ 本工具为管理端配置查询工具,不执行用户登录。当任务要求编写客户端登录代码时(例如「用 JS SDK 登录」),应先通过本工具确认配置状态,再在项目代码中编写 @cloudbase/js-sdk 客户端登录代码(如 auth.signInWithPassword()),而非使用本工具完成登录。若业务要接受普通用户名样式标识符,先查询 action=getLoginConfig;若 usernamePassword=false,下一步应立即调用 manageAppAuth(action=patchLoginStrategy, patch={ usernamePassword: true }),不要直接写 email 登录 API。",
|
|
28560
28560
|
inputSchema: {
|
|
28561
28561
|
action: zod_1.z.enum(QUERY_APP_AUTH_ACTIONS),
|
|
28562
28562
|
providerId: zod_1.z.string().optional().describe("provider 标识,如 email、google"),
|
|
@@ -28666,8 +28666,8 @@ function registerAppAuthTools(server) {
|
|
|
28666
28666
|
}
|
|
28667
28667
|
}));
|
|
28668
28668
|
server.registerTool?.("manageAppAuth", {
|
|
28669
|
-
title: "
|
|
28670
|
-
description: "应用侧认证配置写入口。用于修改登录方式、provider、client 配置,确保 publishable key,以及创建或删除 API key、自定义登录密钥。⚠️ 本工具为管理端配置工具,不执行用户登录。当任务要求编写客户端登录代码时(例如「用 JS SDK 登录」),应先通过本工具完成配置(如启用 usernamePassword、获取 publishable key),再在项目代码中编写 @cloudbase/js-sdk 客户端登录代码(如 auth.signInWithPassword()),而非使用本工具完成登录。若前端要接受普通用户名样式标识符,应先执行 action=patchLoginStrategy 并传入 patch={ usernamePassword: true },再实现对应前端登录逻辑。",
|
|
28669
|
+
title: "管理 CloudBase 应用认证配置",
|
|
28670
|
+
description: "CloudBase 应用侧认证配置写入口。用于修改登录方式、provider、client 配置,确保 publishable key,以及创建或删除 API key、自定义登录密钥。⚠️ 本工具为管理端配置工具,不执行用户登录。当任务要求编写客户端登录代码时(例如「用 JS SDK 登录」),应先通过本工具完成配置(如启用 usernamePassword、获取 publishable key),再在项目代码中编写 @cloudbase/js-sdk 客户端登录代码(如 auth.signInWithPassword()),而非使用本工具完成登录。若前端要接受普通用户名样式标识符,应先执行 action=patchLoginStrategy 并传入 patch={ usernamePassword: true },再实现对应前端登录逻辑。",
|
|
28671
28671
|
inputSchema: {
|
|
28672
28672
|
action: zod_1.z.enum(MANAGE_APP_AUTH_ACTIONS),
|
|
28673
28673
|
patch: zod_1.z
|
|
@@ -38664,8 +38664,8 @@ function registerAgentTools(server) {
|
|
|
38664
38664
|
const cloudBaseOptions = server.cloudBaseOptions;
|
|
38665
38665
|
const getManager = () => (0, cloudbase_manager_js_1.getCloudBaseManager)({ cloudBaseOptions });
|
|
38666
38666
|
server.registerTool?.("queryAgents", {
|
|
38667
|
-
title: "查询 Agent",
|
|
38668
|
-
description: "Agent 域统一只读入口。支持列表、详情与日志查询。",
|
|
38667
|
+
title: "查询 CloudBase Agent",
|
|
38668
|
+
description: "CloudBase Agent 域统一只读入口。支持列表、详情与日志查询。",
|
|
38669
38669
|
inputSchema: {
|
|
38670
38670
|
action: zod_1.z.enum(QUERY_AGENT_ACTIONS),
|
|
38671
38671
|
agentId: zod_1.z.string().optional(),
|
|
@@ -38727,8 +38727,8 @@ function registerAgentTools(server) {
|
|
|
38727
38727
|
}
|
|
38728
38728
|
});
|
|
38729
38729
|
server.registerTool?.("manageAgents", {
|
|
38730
|
-
title: "管理 Agent",
|
|
38731
|
-
description: "Agent 域统一写入口。支持创建、更新和删除远端 Agent。",
|
|
38730
|
+
title: "管理 CloudBase Agent",
|
|
38731
|
+
description: "CloudBase Agent 域统一写入口。支持创建、更新和删除远端 Agent。",
|
|
38732
38732
|
inputSchema: {
|
|
38733
38733
|
action: zod_1.z.enum(MANAGE_AGENT_ACTIONS),
|
|
38734
38734
|
agentId: zod_1.z.string().optional(),
|
|
@@ -89822,8 +89822,8 @@ function registerFunctionTools(server) {
|
|
|
89822
89822
|
}
|
|
89823
89823
|
};
|
|
89824
89824
|
server.registerTool?.("queryFunctions", {
|
|
89825
|
-
title: "
|
|
89826
|
-
description: "
|
|
89825
|
+
title: "查询 CloudBase 云函数",
|
|
89826
|
+
description: "CloudBase 云函数统一只读入口。通过更自解释的 action 查询 CloudBase 云函数列表、函数详情、执行日志、层、触发器和代码下载地址。" +
|
|
89827
89827
|
"\n\n**分页说明**:`listFunctions`、`listLayers` 支持 `limit` 和 `offset` 参数。" +
|
|
89828
89828
|
"\n- `limit`: 分页数量,默认值由后端决定" +
|
|
89829
89829
|
"\n- `offset`: 分页偏移,从 0 开始" +
|
|
@@ -89883,8 +89883,8 @@ function registerFunctionTools(server) {
|
|
|
89883
89883
|
},
|
|
89884
89884
|
}, async (input) => withEnvelope(() => handleQueryFunctions(input)));
|
|
89885
89885
|
server.registerTool?.("manageFunctions", {
|
|
89886
|
-
title: "
|
|
89887
|
-
description: "
|
|
89886
|
+
title: "管理 CloudBase 云函数",
|
|
89887
|
+
description: "CloudBase 云函数统一写入口。支持创建函数、更新代码、更新配置、调用函数、管理定时跑 / 定时任务 / scheduled job 的 timer 触发器和层绑定。" +
|
|
89888
89888
|
"如果要创建 cron 定时任务,先用 createFunction 创建函数,再用 createFunctionTrigger 创建 timer 触发器(支持7段cron表达式),deleteFunctionTrigger 删除触发器。" +
|
|
89889
89889
|
"危险操作需要显式 confirm=true。",
|
|
89890
89890
|
inputSchema: {
|
|
@@ -115910,8 +115910,9 @@ exports.registerAppTools = registerAppTools;
|
|
|
115910
115910
|
const zod_1 = __webpack_require__(21614);
|
|
115911
115911
|
const cloudbase_manager_js_1 = __webpack_require__(3431);
|
|
115912
115912
|
const json_content_js_1 = __webpack_require__(4365);
|
|
115913
|
-
const
|
|
115914
|
-
const
|
|
115913
|
+
const cloud_mode_js_1 = __webpack_require__(89684);
|
|
115914
|
+
const QUERY_APP_ACTIONS = ["listApps", "getApp", "listAppVersions", "getAppVersion", "getBuildLog"];
|
|
115915
|
+
const MANAGE_APP_ACTIONS = ["deployApp", "getUploadUrl", "deleteApp", "deleteAppVersion"];
|
|
115915
115916
|
const APP_FRAMEWORKS = ["vue", "react", "next", "nuxt", "vite", "angular", "static"];
|
|
115916
115917
|
function buildEnvelope(data, message) {
|
|
115917
115918
|
return {
|
|
@@ -115930,18 +115931,37 @@ function buildErrorEnvelope(error) {
|
|
|
115930
115931
|
function getCloudAppService(cloudbase) {
|
|
115931
115932
|
return cloudbase.cloudAppService ?? cloudbase.getCloudAppService?.();
|
|
115932
115933
|
}
|
|
115934
|
+
function normalizeAccessUrlFromDomain(domain) {
|
|
115935
|
+
if (typeof domain !== "string" || !domain.trim())
|
|
115936
|
+
return {};
|
|
115937
|
+
const trimmed = domain.trim();
|
|
115938
|
+
const withProtocol = /^https?:\/\//i.test(trimmed) ? trimmed : `https://${trimmed}`;
|
|
115939
|
+
try {
|
|
115940
|
+
const url = new URL(withProtocol);
|
|
115941
|
+
url.hash = "";
|
|
115942
|
+
url.search = "";
|
|
115943
|
+
url.pathname = url.pathname === "/" ? "" : url.pathname.replace(/\/+$/, "");
|
|
115944
|
+
return {
|
|
115945
|
+
domain: url.host,
|
|
115946
|
+
accessUrl: url.toString().replace(/\/$/, ""),
|
|
115947
|
+
};
|
|
115948
|
+
}
|
|
115949
|
+
catch {
|
|
115950
|
+
return {};
|
|
115951
|
+
}
|
|
115952
|
+
}
|
|
115933
115953
|
function registerAppTools(server) {
|
|
115934
115954
|
const cloudBaseOptions = server.cloudBaseOptions;
|
|
115935
115955
|
const getManager = () => (0, cloudbase_manager_js_1.getCloudBaseManager)({ cloudBaseOptions });
|
|
115936
115956
|
server.registerTool?.("queryApps", {
|
|
115937
|
-
title: "查询
|
|
115938
|
-
description: "
|
|
115957
|
+
title: "查询 CloudBase 应用部署状态",
|
|
115958
|
+
description: "查询 CloudBase 应用部署的应用和版本。可查应用列表/详情、版本列表/详情;部署后用 getAppVersion 按 buildId 轮询构建状态;getBuildLog 可查询构建日志用于诊断失败原因。",
|
|
115939
115959
|
inputSchema: {
|
|
115940
115960
|
action: zod_1.z.enum(QUERY_APP_ACTIONS),
|
|
115941
115961
|
serviceName: zod_1.z
|
|
115942
115962
|
.string()
|
|
115943
115963
|
.optional()
|
|
115944
|
-
.describe("
|
|
115964
|
+
.describe("CloudBase 应用服务名。getApp / listAppVersions / getAppVersion / getBuildLog 时必填;重新部署后复用同一个 serviceName 查询版本历史。"),
|
|
115945
115965
|
searchKey: zod_1.z.string().optional().describe("按应用服务名模糊搜索关键词,仅 action=listApps 时使用。"),
|
|
115946
115966
|
pageNo: zod_1.z.number().optional().describe("分页页码,从 1 开始。"),
|
|
115947
115967
|
pageSize: zod_1.z.number().optional().describe("分页大小。"),
|
|
@@ -115952,14 +115972,18 @@ function registerAppTools(server) {
|
|
|
115952
115972
|
buildId: zod_1.z
|
|
115953
115973
|
.string()
|
|
115954
115974
|
.optional()
|
|
115955
|
-
.describe("构建 ID。getAppVersion 时可与 versionName 二选一;部署返回 BuildId 后可直接用它轮询状态。"),
|
|
115975
|
+
.describe("构建 ID。getAppVersion 时可与 versionName 二选一;部署返回 BuildId 后可直接用它轮询状态。getBuildLog 时必填。"),
|
|
115976
|
+
start: zod_1.z
|
|
115977
|
+
.number()
|
|
115978
|
+
.optional()
|
|
115979
|
+
.describe("构建日志偏移量,用于分页拉取后续日志。仅 action=getBuildLog 时使用,不传时从开头返回。"),
|
|
115956
115980
|
},
|
|
115957
115981
|
annotations: {
|
|
115958
115982
|
readOnlyHint: true,
|
|
115959
115983
|
openWorldHint: true,
|
|
115960
115984
|
category: "apps",
|
|
115961
115985
|
},
|
|
115962
|
-
}, async ({ action, serviceName, searchKey, pageNo, pageSize, versionName, buildId, }) => {
|
|
115986
|
+
}, async ({ action, serviceName, searchKey, pageNo, pageSize, versionName, buildId, start, }) => {
|
|
115963
115987
|
try {
|
|
115964
115988
|
const cloudbase = await getManager();
|
|
115965
115989
|
const appService = getCloudAppService(cloudbase);
|
|
@@ -115979,7 +116003,7 @@ function registerAppTools(server) {
|
|
|
115979
116003
|
apps: result.ServiceList ?? [],
|
|
115980
116004
|
total: result.Total ?? 0,
|
|
115981
116005
|
raw: result,
|
|
115982
|
-
}, "
|
|
116006
|
+
}, "CloudBase 应用列表查询成功"));
|
|
115983
116007
|
}
|
|
115984
116008
|
if (!serviceName) {
|
|
115985
116009
|
throw new Error(`action=${action} 时必须提供 serviceName`);
|
|
@@ -115994,7 +116018,7 @@ function registerAppTools(server) {
|
|
|
115994
116018
|
action,
|
|
115995
116019
|
serviceName,
|
|
115996
116020
|
app: result,
|
|
115997
|
-
}, "
|
|
116021
|
+
}, "CloudBase 应用详情查询成功"));
|
|
115998
116022
|
}
|
|
115999
116023
|
if (action === "listAppVersions") {
|
|
116000
116024
|
const result = await appService.describeAppVersionList({
|
|
@@ -116010,7 +116034,34 @@ function registerAppTools(server) {
|
|
|
116010
116034
|
versions: result.VersionList ?? [],
|
|
116011
116035
|
total: result.Total ?? 0,
|
|
116012
116036
|
raw: result,
|
|
116013
|
-
}, "
|
|
116037
|
+
}, "CloudBase 应用版本列表查询成功"));
|
|
116038
|
+
}
|
|
116039
|
+
if (action === "getBuildLog") {
|
|
116040
|
+
if (!buildId) {
|
|
116041
|
+
throw new Error("action=getBuildLog 时必须提供 buildId");
|
|
116042
|
+
}
|
|
116043
|
+
const result = await cloudbase.commonService("tcb", "2018-06-08").call({
|
|
116044
|
+
Action: "DescribeCloudBaseRunBuildLog",
|
|
116045
|
+
Param: {
|
|
116046
|
+
EnvId: cloudBaseOptions?.envId || process.env.CLOUDBASE_ENV_ID,
|
|
116047
|
+
ServiceName: serviceName,
|
|
116048
|
+
BuildId: buildId,
|
|
116049
|
+
Start: start ?? 0,
|
|
116050
|
+
},
|
|
116051
|
+
});
|
|
116052
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
116053
|
+
const logs = result.Response?.LogList || [];
|
|
116054
|
+
return (0, json_content_js_1.jsonContent)(buildEnvelope({
|
|
116055
|
+
action,
|
|
116056
|
+
serviceName,
|
|
116057
|
+
buildId,
|
|
116058
|
+
logs,
|
|
116059
|
+
total: result.Response?.Total || logs.length,
|
|
116060
|
+
nextStart: result.Response?.NextStart,
|
|
116061
|
+
raw: result,
|
|
116062
|
+
}, logs.length > 0
|
|
116063
|
+
? `查询到 ${logs.length} 条构建日志`
|
|
116064
|
+
: "暂无构建日志"));
|
|
116014
116065
|
}
|
|
116015
116066
|
const result = await appService.describeAppVersion({
|
|
116016
116067
|
deployType: "static-hosting",
|
|
@@ -116019,56 +116070,105 @@ function registerAppTools(server) {
|
|
|
116019
116070
|
buildId,
|
|
116020
116071
|
});
|
|
116021
116072
|
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
116022
|
-
|
|
116073
|
+
const isFailed = result.Status === "FAILED";
|
|
116074
|
+
const payload = {
|
|
116023
116075
|
action,
|
|
116024
116076
|
serviceName,
|
|
116077
|
+
status: result.Status,
|
|
116078
|
+
buildId: result.BuildId,
|
|
116079
|
+
failReason: result.FailReason,
|
|
116080
|
+
buildDuration: result.BuildDuration,
|
|
116025
116081
|
version: result,
|
|
116026
|
-
}
|
|
116082
|
+
};
|
|
116083
|
+
if (isFailed) {
|
|
116084
|
+
payload.nextStep = {
|
|
116085
|
+
action: "查询构建日志",
|
|
116086
|
+
tool: "queryApps",
|
|
116087
|
+
args: {
|
|
116088
|
+
action: "getBuildLog",
|
|
116089
|
+
serviceName,
|
|
116090
|
+
buildId: result.BuildId,
|
|
116091
|
+
},
|
|
116092
|
+
hint: `构建失败。调用 queryApps(action="getBuildLog", serviceName="${serviceName}", buildId="${result.BuildId}") 查看构建日志,诊断失败原因。`,
|
|
116093
|
+
};
|
|
116094
|
+
}
|
|
116095
|
+
return (0, json_content_js_1.jsonContent)(buildEnvelope(payload, `CloudBase 应用版本详情查询成功(状态: ${result.Status}${result.FailReason ? `, 失败原因: ${result.FailReason}` : ""}${isFailed ? ",可查询构建日志" : ""})`));
|
|
116027
116096
|
}
|
|
116028
116097
|
catch (error) {
|
|
116029
116098
|
return (0, json_content_js_1.jsonContent)(buildErrorEnvelope(error));
|
|
116030
116099
|
}
|
|
116031
116100
|
});
|
|
116032
116101
|
server.registerTool?.("manageApps", {
|
|
116033
|
-
title: "
|
|
116034
|
-
description: "
|
|
116102
|
+
title: "部署应用到 CloudBase(独立子域名)",
|
|
116103
|
+
description: "部署 Web 应用到 CloudBase(构建前后端,部署到独立子域名)。\n" +
|
|
116104
|
+
"action=getUploadUrl 获取预签名上传 URL(cloud mode 下使用),返回上传地址和 cosTimestamp。\n" +
|
|
116105
|
+
"action=deployApp 上传源码 ZIP 并触发远端构建部署管道:\n" +
|
|
116106
|
+
" 1. 远端 npm install(可通过 installCmd=\"\" 跳过)\n" +
|
|
116107
|
+
" 2. 远端 npm run build(可通过 buildCmd=\"\" 跳过)\n" +
|
|
116108
|
+
" 3. 远端 tcb hosting deploy\n" +
|
|
116109
|
+
"\n" +
|
|
116110
|
+
"域名格式:`<serviceName>-<envId>.webapps.tcloudbase.com`(每个 serviceName 一个独立子域名)\n" +
|
|
116111
|
+
"\n" +
|
|
116112
|
+
"✅ 推荐用法(新项目/需要独立域名的 Web 应用,首选此工具):\n" +
|
|
116113
|
+
" 新建项目首次部署时,传 framework=static, installCmd=\"\", buildCmd=\"\" 跳过远端构建,\n" +
|
|
116114
|
+
" 只执行 tcb hosting deploy。部署后获得独立子域名,支持版本管理。\n" +
|
|
116115
|
+
"\n" +
|
|
116116
|
+
"⚠️ 兼容性说明:\n" +
|
|
116117
|
+
"- 已有项目若之前用 manageHosting 部署过(域名格式:`<envId>-<appId>.tcloudbaseapp.com`),\n" +
|
|
116118
|
+
" 切换到 manageApps 会产生全新的 URL,老链接失效。请保持原部署方式不变。\n" +
|
|
116119
|
+
"- 如需判断:调用 queryHosting 检查是否已有托管文件。\n" +
|
|
116120
|
+
"\n" +
|
|
116121
|
+
"与 manageHosting 对比:\n" +
|
|
116122
|
+
"- manageApps(本工具,新项目首选):域名 `<serviceName>-<envId>.webapps.tcloudbase.com`,独立子域名,支持版本管理\n" +
|
|
116123
|
+
"- manageHosting(已有项目或 fallback):域名 `<envId>-<appId>.tcloudbaseapp.com/<path>`,共享环境域名\n" +
|
|
116124
|
+
"两者均可绑定自定义域名。\n" +
|
|
116125
|
+
"\n" +
|
|
116126
|
+
"⚠️ 如果 manageApps 构建失败,先用 queryApps(action=\"getBuildLog\") 查日志;仍不行再 fallback 到 manageHosting。",
|
|
116035
116127
|
inputSchema: {
|
|
116036
116128
|
action: zod_1.z.enum(MANAGE_APP_ACTIONS),
|
|
116037
116129
|
serviceName: zod_1.z
|
|
116038
116130
|
.string()
|
|
116039
|
-
.describe("
|
|
116131
|
+
.describe("CloudBase 应用服务名,会体现在域名中:`<serviceName>-<envId>.webapps.tcloudbase.com`。deployApp 时复用现有 serviceName 会新增一个部署版本并触发重新部署,而不是删除重建。首次部署请用新名称。"),
|
|
116040
116132
|
filePath: zod_1.z
|
|
116041
116133
|
.string()
|
|
116042
116134
|
.optional()
|
|
116043
|
-
.describe("
|
|
116135
|
+
.describe("要上传并部署的本地项目根目录绝对路径。本地模式下 deployApp 时必填;通常传源码所在目录(含 package.json 和源码),不是 dist 目录。构建产物目录请用 buildPath 指定。cloud mode 下无需传此参数,改用 cosTimestamp。"),
|
|
116136
|
+
cosTimestamp: zod_1.z
|
|
116137
|
+
.string()
|
|
116138
|
+
.optional()
|
|
116139
|
+
.describe("可选 COS 时间戳。传入此值则直接使用已上传的代码创建应用,跳过本地文件上传。需先调用 getUploadUrl 获取预签名 URL,上传 ZIP 包后再传此时间戳。cloud mode 下为必填;本地模式也可传此值代替 filePath。两个路径二选一:filePath(本地打包上传)或 cosTimestamp(预签名 URL 上传)。"),
|
|
116044
116140
|
appPath: zod_1.z
|
|
116045
116141
|
.string()
|
|
116046
116142
|
.optional()
|
|
116047
|
-
.describe("应用线上访问路径(hosting mount path),例如 /my-web-app
|
|
116143
|
+
.describe("应用线上访问路径(hosting mount path),例如 /my-web-app。不是本地目录路径;CloudApp 已有独立子域名,省略时默认为 /(根路径)。"),
|
|
116048
116144
|
buildPath: zod_1.z
|
|
116049
116145
|
.string()
|
|
116050
116146
|
.optional()
|
|
116051
|
-
.describe("构建产物目录,相对于 filePath,例如 dist 或 build
|
|
116147
|
+
.describe("构建产物目录,相对于 filePath,例如 dist 或 build。\n" +
|
|
116148
|
+
"⚠️ 传此值后远端构建系统会 cd 到此目录再执行 tcb hosting deploy,因此 deployCmd 会自动使用 .(当前目录)而非目录名,避免路径重复(如 dist/dist 错误)。\n" +
|
|
116149
|
+
"纯静态 HTML 如果在项目根目录可省略,但注意 deployCmd 默认用 dist。"),
|
|
116052
116150
|
framework: zod_1.z
|
|
116053
116151
|
.enum(APP_FRAMEWORKS)
|
|
116054
116152
|
.optional()
|
|
116055
|
-
.describe("前端框架类型。可选值:vue、react、next、nuxt、vite、angular、static
|
|
116153
|
+
.describe("前端框架类型。可选值:vue、react、next、nuxt、vite、angular、static。\n" +
|
|
116154
|
+
"即使传 static,仍会经过远端构建管道。如果本地已构建好,建议改用 manageHosting 直接上传,可完全跳过远端构建。"),
|
|
116056
116155
|
nodeJsVersion: zod_1.z
|
|
116057
116156
|
.string()
|
|
116058
116157
|
.optional()
|
|
116059
|
-
.describe("构建时使用的 Node.js 版本;不传时由
|
|
116158
|
+
.describe("构建时使用的 Node.js 版本;不传时由 CloudBase 使用默认值。"),
|
|
116060
116159
|
installCmd: zod_1.z
|
|
116061
116160
|
.string()
|
|
116062
116161
|
.optional()
|
|
116063
|
-
.describe("依赖安装命令,例如 npm install
|
|
116162
|
+
.describe("依赖安装命令,例如 npm install。不传时默认 npm install。本地已安装或无需安装可传空字符串 '' 跳过,但远端仍会执行 tcb hosting deploy。"),
|
|
116064
116163
|
buildCmd: zod_1.z
|
|
116065
116164
|
.string()
|
|
116066
116165
|
.optional()
|
|
116067
|
-
.describe("构建命令,例如 npm run build
|
|
116166
|
+
.describe("构建命令,例如 npm run build。不传时默认 npm run build。本地已构建好可传空字符串 '' 跳过构建步骤。若希望完全跳过远端管道,请改用 manageHosting。"),
|
|
116068
116167
|
deployCmd: zod_1.z
|
|
116069
116168
|
.string()
|
|
116070
116169
|
.optional()
|
|
116071
|
-
.describe("
|
|
116170
|
+
.describe("自定义部署命令。通常无需填写,默认自动生成 tcb hosting deploy 命令。" +
|
|
116171
|
+
"有 buildPath 时远端已 cd 到该目录,默认用 . 作为源码路径;无 buildPath 时默认用 dist。"),
|
|
116072
116172
|
ignore: zod_1.z.array(zod_1.z.string()).optional().describe("上传时忽略的文件/目录 glob 模式,例如 **/node_modules/**。"),
|
|
116073
116173
|
versionName: zod_1.z
|
|
116074
116174
|
.string()
|
|
@@ -116082,48 +116182,155 @@ function registerAppTools(server) {
|
|
|
116082
116182
|
openWorldHint: true,
|
|
116083
116183
|
category: "apps",
|
|
116084
116184
|
},
|
|
116085
|
-
}, async ({ action, serviceName, filePath, appPath, buildPath, framework, nodeJsVersion, installCmd, buildCmd, deployCmd, ignore, versionName, }) => {
|
|
116185
|
+
}, async ({ action, serviceName, filePath, cosTimestamp, appPath, buildPath, framework, nodeJsVersion, installCmd, buildCmd, deployCmd, ignore, versionName, }) => {
|
|
116086
116186
|
try {
|
|
116087
116187
|
const cloudbase = await getManager();
|
|
116088
116188
|
const appService = getCloudAppService(cloudbase);
|
|
116089
116189
|
if (!appService) {
|
|
116090
116190
|
throw new Error("当前 manager 未提供 cloudAppService");
|
|
116091
116191
|
}
|
|
116092
|
-
|
|
116093
|
-
|
|
116094
|
-
|
|
116192
|
+
// getUploadUrl — 获取预签名上传 URL(cloud mode 专用)
|
|
116193
|
+
if (action === "getUploadUrl") {
|
|
116194
|
+
if (!serviceName) {
|
|
116195
|
+
throw new Error("action=getUploadUrl 时必须提供 serviceName");
|
|
116095
116196
|
}
|
|
116096
|
-
const
|
|
116197
|
+
const cosInfoResult = await appService.describeCosInfo({
|
|
116097
116198
|
deployType: "static-hosting",
|
|
116098
116199
|
serviceName,
|
|
116099
|
-
localPath: filePath,
|
|
116100
|
-
ignore,
|
|
116101
116200
|
});
|
|
116102
|
-
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger,
|
|
116201
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, cosInfoResult);
|
|
116202
|
+
const defaultIgnore = ["node_modules/**", ".git/**", ".DS_Store", "**/.DS_Store"];
|
|
116203
|
+
// eslint-disable-next-line max-len
|
|
116204
|
+
const zipCmd = "zip -r upload.zip . -x 'node_modules/**' -x '.git/**' -x '.DS_Store' -x '**/.DS_Store'";
|
|
116205
|
+
const followupArgs = {
|
|
116206
|
+
action: "deployApp",
|
|
116207
|
+
serviceName,
|
|
116208
|
+
cosTimestamp: cosInfoResult.UnixTimestamp,
|
|
116209
|
+
};
|
|
116210
|
+
return (0, json_content_js_1.jsonContent)(buildEnvelope({
|
|
116211
|
+
action,
|
|
116212
|
+
serviceName,
|
|
116213
|
+
uploadUrl: cosInfoResult.UploadUrl,
|
|
116214
|
+
uploadHeaders: cosInfoResult.UploadHeaders,
|
|
116215
|
+
cosTimestamp: cosInfoResult.UnixTimestamp,
|
|
116216
|
+
method: "PUT",
|
|
116217
|
+
ignore: defaultIgnore,
|
|
116218
|
+
zipCommand: zipCmd,
|
|
116219
|
+
nextAction: {
|
|
116220
|
+
action: "上传代码到预签名 URL",
|
|
116221
|
+
hint: "请先在本地打包项目代码(排除 node_modules/.git),再将其上传到预签名 URL,然后调用 deployApp 触发构建",
|
|
116222
|
+
details: [
|
|
116223
|
+
`1. 打包: ${zipCmd}`,
|
|
116224
|
+
`2. 上传: curl -X PUT -T upload.zip '${cosInfoResult.UploadUrl}'`,
|
|
116225
|
+
`3. 触发构建: manageApps(action="deployApp", serviceName="${serviceName}", cosTimestamp="${cosInfoResult.UnixTimestamp}")`,
|
|
116226
|
+
],
|
|
116227
|
+
followup: {
|
|
116228
|
+
tool: "manageApps",
|
|
116229
|
+
args: followupArgs,
|
|
116230
|
+
},
|
|
116231
|
+
},
|
|
116232
|
+
}, "预签名上传 URL 获取成功。请上传代码后调用 deployApp 触发构建。"));
|
|
116233
|
+
}
|
|
116234
|
+
if (action === "deployApp") {
|
|
116235
|
+
// cloud mode 下必须有 cosTimestamp;本地模式必须有 filePath
|
|
116236
|
+
if ((0, cloud_mode_js_1.isCloudMode)()) {
|
|
116237
|
+
if (!cosTimestamp) {
|
|
116238
|
+
throw new Error("cloud mode 下 deployApp 需要 cosTimestamp 参数。请先调用 getUploadUrl 获取预签名上传 URL。" +
|
|
116239
|
+
"上传代码后再用 cosTimestamp 调用 deployApp。");
|
|
116240
|
+
}
|
|
116241
|
+
}
|
|
116242
|
+
else if (!filePath && !cosTimestamp) {
|
|
116243
|
+
throw new Error("action=deployApp 时必须提供 filePath(本地模式)或 cosTimestamp(cloud mode)。");
|
|
116244
|
+
}
|
|
116245
|
+
// 上传代码到 COS(仅本地模式需要,cloud mode 用 cosTimestamp 跳过)
|
|
116246
|
+
let cosTs = cosTimestamp;
|
|
116247
|
+
if (filePath && !cosTs) {
|
|
116248
|
+
const uploadResult = await appService.uploadCode({
|
|
116249
|
+
deployType: "static-hosting",
|
|
116250
|
+
serviceName,
|
|
116251
|
+
localPath: filePath,
|
|
116252
|
+
ignore,
|
|
116253
|
+
});
|
|
116254
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, uploadResult);
|
|
116255
|
+
cosTs = uploadResult.cosTimestamp;
|
|
116256
|
+
}
|
|
116257
|
+
// 构建命令智能默认值
|
|
116258
|
+
const resolvedInstallCmd = installCmd ?? "npm install";
|
|
116259
|
+
const resolvedBuildCmd = buildCmd ?? "npm run build";
|
|
116260
|
+
const resolvedDeployPath = appPath || "/";
|
|
116261
|
+
const resolvedBuildPath = buildPath || "";
|
|
116262
|
+
// ⚠️ 远端构建系统在有 buildPath 时 cd 到此目录再执行 tcb hosting deploy
|
|
116263
|
+
// 部署命令用 "." 避免 dist/dist 重复。framework=static 无构建步骤,用根目录
|
|
116264
|
+
const resolvedDeployCmd = deployCmd || (resolvedBuildPath || framework === "static"
|
|
116265
|
+
? `tcb hosting deploy . ${resolvedDeployPath}`
|
|
116266
|
+
: `tcb hosting deploy dist ${resolvedDeployPath}`);
|
|
116267
|
+
// 触发远端构建
|
|
116103
116268
|
const result = await appService.createApp({
|
|
116104
116269
|
deployType: "static-hosting",
|
|
116105
116270
|
serviceName,
|
|
116106
116271
|
buildType: "ZIP",
|
|
116107
116272
|
staticConfig: {
|
|
116108
|
-
appPath,
|
|
116109
|
-
buildPath,
|
|
116273
|
+
appPath: resolvedDeployPath,
|
|
116274
|
+
buildPath: resolvedBuildPath,
|
|
116110
116275
|
framework,
|
|
116111
116276
|
nodeJsVersion,
|
|
116112
|
-
cosTimestamp:
|
|
116277
|
+
cosTimestamp: cosTs,
|
|
116113
116278
|
staticCmd: {
|
|
116114
|
-
installCmd,
|
|
116115
|
-
buildCmd,
|
|
116116
|
-
deployCmd,
|
|
116279
|
+
installCmd: resolvedInstallCmd,
|
|
116280
|
+
buildCmd: resolvedBuildCmd,
|
|
116281
|
+
deployCmd: resolvedDeployCmd,
|
|
116117
116282
|
},
|
|
116118
116283
|
},
|
|
116119
116284
|
});
|
|
116120
116285
|
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
116286
|
+
const { BuildId, VersionName } = result;
|
|
116287
|
+
let appInfo;
|
|
116288
|
+
let domain;
|
|
116289
|
+
let accessUrl;
|
|
116290
|
+
let accessUrlLookupWarning;
|
|
116291
|
+
try {
|
|
116292
|
+
appInfo = await appService.describeAppInfo({
|
|
116293
|
+
deployType: "static-hosting",
|
|
116294
|
+
serviceName,
|
|
116295
|
+
});
|
|
116296
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, appInfo);
|
|
116297
|
+
({ domain, accessUrl } = normalizeAccessUrlFromDomain(appInfo?.Domain));
|
|
116298
|
+
}
|
|
116299
|
+
catch (error) {
|
|
116300
|
+
accessUrlLookupWarning = error instanceof Error ? error.message : String(error);
|
|
116301
|
+
}
|
|
116121
116302
|
return (0, json_content_js_1.jsonContent)(buildEnvelope({
|
|
116122
116303
|
action,
|
|
116123
116304
|
serviceName,
|
|
116124
|
-
|
|
116305
|
+
versionName: VersionName,
|
|
116306
|
+
buildId: BuildId,
|
|
116307
|
+
domain,
|
|
116308
|
+
accessUrl,
|
|
116309
|
+
accessUrlSource: accessUrl ? "describeAppInfo.Domain" : undefined,
|
|
116310
|
+
accessUrlLookupWarning,
|
|
116311
|
+
app: appInfo,
|
|
116312
|
+
upload: { cosTimestamp: cosTs },
|
|
116125
116313
|
deployment: result,
|
|
116126
|
-
|
|
116314
|
+
buildConfig: {
|
|
116315
|
+
installCmd: resolvedInstallCmd,
|
|
116316
|
+
buildCmd: resolvedBuildCmd,
|
|
116317
|
+
deployCmd: resolvedDeployCmd,
|
|
116318
|
+
},
|
|
116319
|
+
nextStep: {
|
|
116320
|
+
action: "轮询构建状态",
|
|
116321
|
+
tool: "queryApps",
|
|
116322
|
+
args: {
|
|
116323
|
+
action: "getAppVersion",
|
|
116324
|
+
serviceName,
|
|
116325
|
+
buildId: BuildId,
|
|
116326
|
+
},
|
|
116327
|
+
hint: accessUrl
|
|
116328
|
+
? `调用 queryApps(action="getAppVersion", serviceName="${serviceName}", buildId="${BuildId}") 轮询构建状态,直到 status 变为 SUCCESS 或 FAILED。构建成功后,后续记录部署时必须使用本结果的 accessUrl=${accessUrl},不要自行拼接域名。若状态为 FAILED,可继续调用 queryApps(action="getBuildLog", serviceName="${serviceName}", buildId="${BuildId}") 查看构建日志诊断失败原因。`
|
|
116329
|
+
: `调用 queryApps(action="getAppVersion", serviceName="${serviceName}", buildId="${BuildId}") 轮询构建状态,直到 status 变为 SUCCESS 或 FAILED;再调用 queryApps(action="getApp", serviceName="${serviceName}") 读取 app.Domain 作为 accessUrl,不能自行拼接域名。若状态为 FAILED,可继续调用 queryApps(action="getBuildLog", serviceName="${serviceName}", buildId="${BuildId}") 查看构建日志诊断失败原因。`,
|
|
116330
|
+
},
|
|
116331
|
+
}, accessUrl
|
|
116332
|
+
? "CloudBase 应用构建已触发,已返回真实 accessUrl;请通过 queryApps 轮询构建状态。"
|
|
116333
|
+
: "CloudBase 应用构建已触发,请通过 queryApps 轮询构建状态,并用 getApp 读取真实域名。"));
|
|
116127
116334
|
}
|
|
116128
116335
|
if (action === "deleteApp") {
|
|
116129
116336
|
const result = await appService.deleteApp({
|
|
@@ -116135,7 +116342,7 @@ function registerAppTools(server) {
|
|
|
116135
116342
|
action,
|
|
116136
116343
|
serviceName,
|
|
116137
116344
|
raw: result,
|
|
116138
|
-
}, "
|
|
116345
|
+
}, "CloudBase 应用删除成功"));
|
|
116139
116346
|
}
|
|
116140
116347
|
if (!versionName) {
|
|
116141
116348
|
throw new Error("action=deleteAppVersion 时必须提供 versionName");
|
|
@@ -116151,7 +116358,7 @@ function registerAppTools(server) {
|
|
|
116151
116358
|
serviceName,
|
|
116152
116359
|
versionName,
|
|
116153
116360
|
raw: result,
|
|
116154
|
-
}, "
|
|
116361
|
+
}, "CloudBase 应用版本删除成功"));
|
|
116155
116362
|
}
|
|
116156
116363
|
catch (error) {
|
|
116157
116364
|
return (0, json_content_js_1.jsonContent)(buildErrorEnvelope(error));
|
|
@@ -117772,6 +117979,16 @@ async function resolveHostingStaticDomain(cloudbase, logger) {
|
|
|
117772
117979
|
return undefined;
|
|
117773
117980
|
}
|
|
117774
117981
|
}
|
|
117982
|
+
async function assertHostingUploadEnvironmentReady(cloudbase, cloudBaseOptions, logger) {
|
|
117983
|
+
const envId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
117984
|
+
const envInfo = await cloudbase.env.getEnvInfo();
|
|
117985
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(logger, envInfo);
|
|
117986
|
+
const staticStorage = envInfo.EnvInfo?.StaticStorages?.[0];
|
|
117987
|
+
if (staticStorage?.Bucket) {
|
|
117988
|
+
return;
|
|
117989
|
+
}
|
|
117990
|
+
throw new Error(`当前环境 ${envId} 未发现静态托管资源配置,无法上传文件。请先确认 MCP 已绑定到已开通静态托管的 CloudBase 环境;如需切换环境,请调用 auth(action="set_env", envId="目标环境ID") 后重试。`);
|
|
117991
|
+
}
|
|
117775
117992
|
function buildFailureResult(action, error) {
|
|
117776
117993
|
return (0, tool_result_js_1.buildJsonToolResult)({
|
|
117777
117994
|
success: false,
|
|
@@ -117816,7 +118033,7 @@ function registerHostingTools(server) {
|
|
|
117816
118033
|
const cloudBaseOptions = server.cloudBaseOptions;
|
|
117817
118034
|
const getManager = () => (0, cloudbase_manager_js_1.getCloudBaseManager)({ cloudBaseOptions });
|
|
117818
118035
|
server.registerTool('queryHosting', {
|
|
117819
|
-
title: '
|
|
118036
|
+
title: '查询 CloudBase 静态托管',
|
|
117820
118037
|
description: '查询 CloudBase 静态托管的只读信息。适合 AI 先做发现再决定下一步:action=websiteConfig 查询首页/错误页/路由规则与站点域名信息;action=status 查询托管服务状态;action=findFiles 按前缀查找文件;action=listFiles 列出全部托管文件;action=domainStatus 查询自定义域名的当前状态与配置。该工具不会产生任何副作用。',
|
|
117821
118038
|
inputSchema: queryHostingInputSchema,
|
|
117822
118039
|
annotations: {
|
|
@@ -117955,8 +118172,8 @@ function registerHostingTools(server) {
|
|
|
117955
118172
|
}
|
|
117956
118173
|
});
|
|
117957
118174
|
server.registerTool('manageHosting', {
|
|
117958
|
-
title: '
|
|
117959
|
-
description: '管理 CloudBase 静态托管的变更操作。action=upload
|
|
118175
|
+
title: '管理 CloudBase 静态托管',
|
|
118176
|
+
description: '管理 CloudBase 静态托管的变更操作。action=upload 上传本地构建产物到共享域名(域名格式:<envId>-<appId>.tcloudbaseapp.com/<cloudPath>);action=delete 删除托管文件或目录(必须 confirm=true);action=setWebsiteDocument 设置首页/错误页/路由规则;action=enableService 开通静态托管;action=bindDomain / unbindDomain / updateDomain 管理自定义域名;action=downloadFile / downloadDirectory 下载托管内容到本地。⚠️ 新项目部署优先使用 manageApps(部署到独立子域名),本工具适合已有老项目继续使用或作为 manageApps 的 fallback。manageApps 与 manageHosting 域名不同,切换会导致老链接失效。若任务只是查看配置、文件或域名状态,请改用 queryHosting。',
|
|
117960
118177
|
inputSchema: manageHostingInputSchema,
|
|
117961
118178
|
annotations: {
|
|
117962
118179
|
readOnlyHint: false,
|
|
@@ -117977,6 +118194,7 @@ function registerHostingTools(server) {
|
|
|
117977
118194
|
}
|
|
117978
118195
|
let result;
|
|
117979
118196
|
try {
|
|
118197
|
+
await assertHostingUploadEnvironmentReady(cloudbase, cloudBaseOptions, server.logger);
|
|
117980
118198
|
result = await cloudbase.hosting.uploadFiles({
|
|
117981
118199
|
localPath: input.localPath,
|
|
117982
118200
|
cloudPath: input.cloudPath,
|
|
@@ -134931,7 +135149,7 @@ class TelemetryReporter {
|
|
|
134931
135149
|
const nodeVersion = process.version; // Node.js版本
|
|
134932
135150
|
const arch = os_1.default.arch(); // 系统架构
|
|
134933
135151
|
// 从构建时注入的版本号获取MCP版本信息
|
|
134934
|
-
const mcpVersion = process.env.npm_package_version || "2.
|
|
135152
|
+
const mcpVersion = process.env.npm_package_version || "2.21.0" || 0;
|
|
134935
135153
|
return {
|
|
134936
135154
|
userAgent: `${osType} ${osRelease} ${arch} ${nodeVersion} CloudBase-MCP/${mcpVersion}`,
|
|
134937
135155
|
deviceId: this.deviceId,
|
|
@@ -193536,7 +193754,7 @@ ${envIdSection}
|
|
|
193536
193754
|
## 环境信息
|
|
193537
193755
|
- 操作系统: ${os_1.default.type()} ${os_1.default.release()}
|
|
193538
193756
|
- Node.js版本: ${process.version}
|
|
193539
|
-
- MCP 版本:${process.env.npm_package_version || "2.
|
|
193757
|
+
- MCP 版本:${process.env.npm_package_version || "2.21.0" || 0}
|
|
193540
193758
|
- 系统架构: ${os_1.default.arch()}
|
|
193541
193759
|
- 时间: ${new Date().toISOString()}
|
|
193542
193760
|
- 请求ID: ${requestId}
|
|
@@ -193617,7 +193835,7 @@ function createWrappedHandler(name, handler, server) {
|
|
|
193617
193835
|
requestId: (typeof error === 'object' && error && 'requestId' in error) ? error.requestId : '',
|
|
193618
193836
|
ide: server.ide || process.env.INTEGRATION_IDE || ''
|
|
193619
193837
|
});
|
|
193620
|
-
const mcpVersion = true ? "2.
|
|
193838
|
+
const mcpVersion = true ? "2.21.0" : 0;
|
|
193621
193839
|
const requestIdSuffix = requestId ? `\n🆔 RequestId: ${requestId}` : '';
|
|
193622
193840
|
const enhancedErrorMessage = `${errorMessage}${requestIdSuffix}\n\n📦 CloudBase MCP v${mcpVersion}\n🔗 遇到问题?请复制以下链接到浏览器打开\n即可自动携带错误详情快速创建 GitHub Issue:\n${issueLink}`;
|
|
193623
193841
|
// 创建新的错误对象,保持原有的错误类型但更新消息
|
|
@@ -208620,8 +208838,8 @@ function registerPermissionTools(server) {
|
|
|
208620
208838
|
}
|
|
208621
208839
|
};
|
|
208622
208840
|
server.registerTool?.("queryPermissions", {
|
|
208623
|
-
title: "
|
|
208624
|
-
description: "
|
|
208841
|
+
title: "查询 CloudBase 权限与用户配置",
|
|
208842
|
+
description: "查询 CloudBase 权限与用户配置,支持查询资源权限(数据库/云函数/存储桶等)、角色列表/详情、应用用户列表/详情。\n\n示例:\n- 查询存储桶权限:`action=\"getResourcePermission\", resourceType=\"storage\", resourceId=\"bucket-name\"`",
|
|
208625
208843
|
inputSchema: {
|
|
208626
208844
|
action: zod_1.z.enum(QUERY_PERMISSION_ACTIONS),
|
|
208627
208845
|
resourceType: zod_1.z
|
|
@@ -208781,8 +208999,8 @@ function registerPermissionTools(server) {
|
|
|
208781
208999
|
}
|
|
208782
209000
|
}));
|
|
208783
209001
|
server.registerTool?.("managePermissions", {
|
|
208784
|
-
title: "
|
|
208785
|
-
description: "
|
|
209002
|
+
title: "管理 CloudBase 权限与用户配置",
|
|
209003
|
+
description: "管理 CloudBase 权限与用户配置,支持修改资源权限(数据库/云函数/存储桶等)、角色管理、成员与策略增删、应用用户 CRUD。\n\n示例:\n- 设置存储桶为私有:`action=\"updateResourcePermission\", resourceType=\"storage\", resourceId=\"bucket-name\", permission=\"PRIVATE\"`\n- 创建角色:`action=\"createRole\", roleName=\"admin\", roleIdentity=\"admin\"`\n\n注意:`createUser` / `updateUser` 是环境侧应用用户管理能力,适合测试账号、管理员或预置用户,不应替代浏览器里的 Web SDK 注册表单。前端用户名密码注册应使用 `auth.signUp({ username, password })`,登录应使用 `auth.signInWithPassword({ username, password })`。`securityRule` 的详细语义取决于 `resourceType`,请参考对应官方文档。",
|
|
208786
209004
|
inputSchema: {
|
|
208787
209005
|
action: zod_1.z.enum(MANAGE_PERMISSION_ACTIONS),
|
|
208788
209006
|
resourceType: zod_1.z
|
|
@@ -209394,14 +209612,28 @@ async function downloadFile(url, filePath, redirectCount = 0) {
|
|
|
209394
209612
|
.on("error", reject);
|
|
209395
209613
|
});
|
|
209396
209614
|
}
|
|
209397
|
-
// 解压ZIP
|
|
209615
|
+
// 解压ZIP文件(含 zip slip 防护)
|
|
209398
209616
|
async function extractZip(zipPath, extractPath) {
|
|
209399
209617
|
try {
|
|
209400
209618
|
// 创建解压目录
|
|
209401
209619
|
await fsPromises.mkdir(extractPath, { recursive: true });
|
|
209402
|
-
// 使用 adm-zip
|
|
209620
|
+
// 使用 adm-zip 库逐条目解压,防止 zip slip 路径穿越
|
|
209403
209621
|
const zip = new adm_zip_1.default(zipPath);
|
|
209404
|
-
zip.
|
|
209622
|
+
const entries = zip.getEntries();
|
|
209623
|
+
const resolvedExtractPath = path.resolve(extractPath);
|
|
209624
|
+
for (const entry of entries) {
|
|
209625
|
+
// 跳过目录条目,后面由 mkdir 自动创建
|
|
209626
|
+
if (entry.isDirectory)
|
|
209627
|
+
continue;
|
|
209628
|
+
const entryPath = path.resolve(resolvedExtractPath, entry.entryName);
|
|
209629
|
+
if (!entryPath.startsWith(resolvedExtractPath + path.sep)) {
|
|
209630
|
+
throw new Error(`解压失败: ZIP 文件中包含非法的路径 "${entry.entryName}",已安全拦截`);
|
|
209631
|
+
}
|
|
209632
|
+
// 确保目标目录存在
|
|
209633
|
+
await fsPromises.mkdir(path.dirname(entryPath), { recursive: true });
|
|
209634
|
+
// 写入文件
|
|
209635
|
+
await fsPromises.writeFile(entryPath, entry.getData());
|
|
209636
|
+
}
|
|
209405
209637
|
}
|
|
209406
209638
|
catch (error) {
|
|
209407
209639
|
throw new Error(`解压失败: ${error instanceof Error ? error.message : "未知错误"}`);
|
|
@@ -209576,7 +209808,7 @@ function registerSetupTools(server) {
|
|
|
209576
209808
|
server.registerTool("downloadTemplate", {
|
|
209577
209809
|
title: "下载项目模板",
|
|
209578
209810
|
description: `自动下载并部署CloudBase项目模板。
|
|
209579
|
-
**Note**: Call this tool when the user requests to create a new project using a CloudBase template.\n\n支持的模板:\n- react: React + CloudBase 全栈应用模板\n- vue: Vue + CloudBase 全栈应用模板\n- miniprogram: 微信小程序 + 云开发模板 \n- uniapp: UniApp + CloudBase 跨端应用模板\n- rules: 只包含AI编辑器配置文件(包含Cursor、WindSurf、CodeBuddy等所有主流编辑器配置),适合在已有项目中补充AI编辑器配置\n\n支持的IDE类型:\n- all: 下载所有IDE配置\n- cursor: Cursor AI编辑器\n- 其他IDE类型见下方列表\n\n注意:如果未传入 ide 参数且无法从环境变量检测到 IDE,将提示错误并要求传入 ide 参数\n- windsurf: WindSurf AI编辑器\n- codebuddy: CodeBuddy AI编辑器\n- claude-code: Claude Code AI编辑器\n- cline: Cline AI编辑器\n- gemini-cli: Gemini CLI\n- opencode: OpenCode AI编辑器\n- qwen-code: 通义灵码\n- baidu-comate: 百度Comate\n- openai-codex-cli: OpenAI Codex CLI\n- augment-code: Augment Code\n- github-copilot: GitHub Copilot\n- roocode: RooCode AI编辑器\n- tongyi-lingma: 通义灵码\n- trae: Trae AI编辑器\n- qoder: Qoder AI编辑器\n- antigravity: Google Antigravity AI编辑器\n- vscode: Visual Studio Code\n- kiro: Kiro AI编辑器\n- aider: Aider AI编辑器\n\n特别说明:\n- rules 模板会自动包含当前 mcp 版本号信息(版本号:${ true ? "2.
|
|
209811
|
+
**Note**: Call this tool when the user requests to create a new project using a CloudBase template.\n\n支持的模板:\n- react: React + CloudBase 全栈应用模板\n- vue: Vue + CloudBase 全栈应用模板\n- miniprogram: 微信小程序 + 云开发模板 \n- uniapp: UniApp + CloudBase 跨端应用模板\n- rules: 只包含AI编辑器配置文件(包含Cursor、WindSurf、CodeBuddy等所有主流编辑器配置),适合在已有项目中补充AI编辑器配置\n\n支持的IDE类型:\n- all: 下载所有IDE配置\n- cursor: Cursor AI编辑器\n- 其他IDE类型见下方列表\n\n注意:如果未传入 ide 参数且无法从环境变量检测到 IDE,将提示错误并要求传入 ide 参数\n- windsurf: WindSurf AI编辑器\n- codebuddy: CodeBuddy AI编辑器\n- claude-code: Claude Code AI编辑器\n- cline: Cline AI编辑器\n- gemini-cli: Gemini CLI\n- opencode: OpenCode AI编辑器\n- qwen-code: 通义灵码\n- baidu-comate: 百度Comate\n- openai-codex-cli: OpenAI Codex CLI\n- augment-code: Augment Code\n- github-copilot: GitHub Copilot\n- roocode: RooCode AI编辑器\n- tongyi-lingma: 通义灵码\n- trae: Trae AI编辑器\n- qoder: Qoder AI编辑器\n- antigravity: Google Antigravity AI编辑器\n- vscode: Visual Studio Code\n- kiro: Kiro AI编辑器\n- aider: Aider AI编辑器\n\n特别说明:\n- rules 模板会自动包含当前 mcp 版本号信息(版本号:${ true ? "2.21.0" : 0}),便于后续维护和版本追踪\n- 下载 rules 模板时,如果项目中已存在 README.md 文件,系统会自动保护该文件不被覆盖(除非设置 overwrite=true)`,
|
|
209580
209812
|
inputSchema: {
|
|
209581
209813
|
template: zod_1.z
|
|
209582
209814
|
.enum(["react", "vue", "miniprogram", "uniapp", "rules"])
|
|
@@ -227002,8 +227234,8 @@ function registerGatewayTools(server) {
|
|
|
227002
227234
|
}
|
|
227003
227235
|
};
|
|
227004
227236
|
server.registerTool?.("queryGateway", {
|
|
227005
|
-
title: "
|
|
227006
|
-
description: "
|
|
227237
|
+
title: "查询 CloudBase 网关",
|
|
227238
|
+
description: "CloudBase 网关统一只读入口。通过 action 查询网关域名、访问入口和目标暴露情况。",
|
|
227007
227239
|
inputSchema: {
|
|
227008
227240
|
action: zod_1.z
|
|
227009
227241
|
.enum(QUERY_GATEWAY_ACTIONS)
|
|
@@ -227025,8 +227257,8 @@ function registerGatewayTools(server) {
|
|
|
227025
227257
|
},
|
|
227026
227258
|
}, async (input) => withEnvelope(() => handleQueryGateway(input)));
|
|
227027
227259
|
server.registerTool?.("manageGateway", {
|
|
227028
|
-
title: "
|
|
227029
|
-
description: "
|
|
227260
|
+
title: "管理 CloudBase 网关",
|
|
227261
|
+
description: "CloudBase 网关统一写入口。通过 action 创建目标访问入口,后续承接更通用的网关配置能力。为已存在的 HTTP 云函数补默认域名访问时,通常使用 createAccess 并提供 targetType=\"function\"、targetName、type=\"HTTP\" 与期望 path。注意 createAccess 只创建网关入口,不会自动修改函数资源权限。⚠️ 如需绑定带 SSL 证书的自定义域名供公网 HTTPS 访问,使用 action=\"bindCustomDomain\"(需要 domain 和 certificateId 参数);如需配置 CORS/安全域名(无证书),请使用 envDomainManagement 工具。",
|
|
227030
227262
|
inputSchema: {
|
|
227031
227263
|
action: zod_1.z
|
|
227032
227264
|
.enum(MANAGE_GATEWAY_ACTIONS)
|
|
@@ -236871,8 +237103,6 @@ function shouldRegisterTool(toolName) {
|
|
|
236871
237103
|
'manageCloudRun',
|
|
236872
237104
|
// Download tools - local file downloads
|
|
236873
237105
|
'manageStorage',
|
|
236874
|
-
// Apps tools - deployApp reads local filePath for code upload
|
|
236875
|
-
'manageApps',
|
|
236876
237106
|
];
|
|
236877
237107
|
const shouldRegister = !cloudIncompatibleTools.includes(toolName);
|
|
236878
237108
|
if (!shouldRegister) {
|
|
@@ -250624,8 +250854,8 @@ function registerStorageTools(server) {
|
|
|
250624
250854
|
const getManager = () => (0, cloudbase_manager_js_1.getCloudBaseManager)({ cloudBaseOptions });
|
|
250625
250855
|
// Tool 1: queryStorage - 查询存储信息(只读操作)
|
|
250626
250856
|
server.registerTool("queryStorage", {
|
|
250627
|
-
title: "
|
|
250628
|
-
description: "
|
|
250857
|
+
title: "查询 CloudBase 存储信息",
|
|
250858
|
+
description: "查询 CloudBase 云存储信息,支持列出目录文件、获取文件信息、获取临时下载链接等只读操作。返回的文件信息包括文件名、大小、修改时间、下载链接等。注意:action=url 返回的 temporaryUrl 是临时签名链接,有效期由 maxAge 参数决定(默认1小时),不要当作永久公网地址使用。工具还会基于 DescribeEnvs 返回的 Storages[0].CdnDomain 推导出 publicUrl,⚠️ 警告:publicUrl 仅在存储桶 ACL 为公有读(所有用户可读)时才能被匿名访问;默认私有读写存储桶返回的 publicUrl 会 403,此时请继续使用 temporaryUrl 或先通过控制台/SDK 将目标路径设置为公有读。\n\n💡 存储桶 ACL 权限管理请使用 permissions 工具:queryPermissions(action=\"getResourcePermission\", resourceType=\"storage\", resourceId=\"bucket-name\") 查询,managePermissions(action=\"updateResourcePermission\", resourceType=\"storage\", resourceId=\"bucket-name\", permission=\"READONLY\") 设置。",
|
|
250629
250859
|
inputSchema: queryStorageInputSchema,
|
|
250630
250860
|
annotations: {
|
|
250631
250861
|
readOnlyHint: true,
|
|
@@ -250753,8 +250983,8 @@ function registerStorageTools(server) {
|
|
|
250753
250983
|
});
|
|
250754
250984
|
// Tool 2: manageStorage - 管理存储文件(写操作)
|
|
250755
250985
|
server.registerTool("manageStorage", {
|
|
250756
|
-
title: "
|
|
250757
|
-
description: "
|
|
250986
|
+
title: "管理 CloudBase 存储文件",
|
|
250987
|
+
description: "管理 CloudBase 云存储文件,仅用于 COS/Storage 对象,不用于静态网站托管。支持上传文件/目录、下载文件/目录、删除文件/目录等操作。删除操作需要设置force=true进行确认,防止误删除重要文件。注意:上传后返回的 temporaryUrl 是临时签名链接,1小时后过期,不要当作永久公网地址写入配置或持久化存储。工具还会基于 DescribeEnvs 返回的 Storages[0].CdnDomain 推导 publicUrl,⚠️ 警告:publicUrl 仅在存储桶 ACL 为公有读(所有用户可读)时才能被匿名访问;默认私有读写存储桶返回的 publicUrl 会 403,此时请继续使用 temporaryUrl 或先通过控制台/SDK 将目标路径设置为公有读。\n\n💡 存储桶 ACL 权限管理请使用 permissions 工具:queryPermissions(action=\"getResourcePermission\", resourceType=\"storage\", resourceId=\"bucket-name\") 查询,managePermissions(action=\"updateResourcePermission\", resourceType=\"storage\", resourceId=\"bucket-name\", permission=\"READONLY\") 设置。",
|
|
250758
250988
|
inputSchema: manageStorageInputSchema,
|
|
250759
250989
|
annotations: {
|
|
250760
250990
|
readOnlyHint: false,
|