@cloudbase/cloudbase-mcp 2.20.2 → 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 +287 -57
- package/dist/index.js +287 -57
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1703,7 +1703,7 @@ ${envIdSection}
|
|
|
1703
1703
|
## 环境信息
|
|
1704
1704
|
- 操作系统: ${os_1.default.type()} ${os_1.default.release()}
|
|
1705
1705
|
- Node.js版本: ${process.version}
|
|
1706
|
-
- MCP 版本:${process.env.npm_package_version || "2.
|
|
1706
|
+
- MCP 版本:${process.env.npm_package_version || "2.21.0" || 0}
|
|
1707
1707
|
- 系统架构: ${os_1.default.arch()}
|
|
1708
1708
|
- 时间: ${new Date().toISOString()}
|
|
1709
1709
|
- 请求ID: ${requestId}
|
|
@@ -1784,7 +1784,7 @@ function createWrappedHandler(name, handler, server) {
|
|
|
1784
1784
|
requestId: (typeof error === 'object' && error && 'requestId' in error) ? error.requestId : '',
|
|
1785
1785
|
ide: server.ide || process.env.INTEGRATION_IDE || ''
|
|
1786
1786
|
});
|
|
1787
|
-
const mcpVersion = true ? "2.
|
|
1787
|
+
const mcpVersion = true ? "2.21.0" : 0;
|
|
1788
1788
|
const requestIdSuffix = requestId ? `\n🆔 RequestId: ${requestId}` : '';
|
|
1789
1789
|
const enhancedErrorMessage = `${errorMessage}${requestIdSuffix}\n\n📦 CloudBase MCP v${mcpVersion}\n🔗 遇到问题?请复制以下链接到浏览器打开\n即可自动携带错误详情快速创建 GitHub Issue:\n${issueLink}`;
|
|
1790
1790
|
// 创建新的错误对象,保持原有的错误类型但更新消息
|
|
@@ -7349,7 +7349,7 @@ function registerStorageTools(server) {
|
|
|
7349
7349
|
// Tool 1: queryStorage - 查询存储信息(只读操作)
|
|
7350
7350
|
server.registerTool("queryStorage", {
|
|
7351
7351
|
title: "查询 CloudBase 存储信息",
|
|
7352
|
-
description: "查询 CloudBase 云存储信息,支持列出目录文件、获取文件信息、获取临时下载链接等只读操作。返回的文件信息包括文件名、大小、修改时间、下载链接等。注意:action=url 返回的 temporaryUrl 是临时签名链接,有效期由 maxAge 参数决定(默认1小时),不要当作永久公网地址使用。工具还会基于 DescribeEnvs 返回的 Storages[0].CdnDomain 推导出 publicUrl,⚠️ 警告:publicUrl 仅在存储桶 ACL 为公有读(所有用户可读)时才能被匿名访问;默认私有读写存储桶返回的 publicUrl 会 403,此时请继续使用 temporaryUrl 或先通过控制台/SDK
|
|
7352
|
+
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\") 设置。",
|
|
7353
7353
|
inputSchema: queryStorageInputSchema,
|
|
7354
7354
|
annotations: {
|
|
7355
7355
|
readOnlyHint: true,
|
|
@@ -7478,7 +7478,7 @@ function registerStorageTools(server) {
|
|
|
7478
7478
|
// Tool 2: manageStorage - 管理存储文件(写操作)
|
|
7479
7479
|
server.registerTool("manageStorage", {
|
|
7480
7480
|
title: "管理 CloudBase 存储文件",
|
|
7481
|
-
description: "管理 CloudBase 云存储文件,仅用于 COS/Storage 对象,不用于静态网站托管。支持上传文件/目录、下载文件/目录、删除文件/目录等操作。删除操作需要设置force=true进行确认,防止误删除重要文件。注意:上传后返回的 temporaryUrl 是临时签名链接,1小时后过期,不要当作永久公网地址写入配置或持久化存储。工具还会基于 DescribeEnvs 返回的 Storages[0].CdnDomain 推导 publicUrl,⚠️ 警告:publicUrl 仅在存储桶 ACL 为公有读(所有用户可读)时才能被匿名访问;默认私有读写存储桶返回的 publicUrl 会 403,此时请继续使用 temporaryUrl 或先通过控制台/SDK
|
|
7481
|
+
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\") 设置。",
|
|
7482
7482
|
inputSchema: manageStorageInputSchema,
|
|
7483
7483
|
annotations: {
|
|
7484
7484
|
readOnlyHint: false,
|
|
@@ -9275,7 +9275,7 @@ class TelemetryReporter {
|
|
|
9275
9275
|
const nodeVersion = process.version; // Node.js版本
|
|
9276
9276
|
const arch = os_1.default.arch(); // 系统架构
|
|
9277
9277
|
// 从构建时注入的版本号获取MCP版本信息
|
|
9278
|
-
const mcpVersion = process.env.npm_package_version || "2.
|
|
9278
|
+
const mcpVersion = process.env.npm_package_version || "2.21.0" || 0;
|
|
9279
9279
|
return {
|
|
9280
9280
|
userAgent: `${osType} ${osRelease} ${arch} ${nodeVersion} CloudBase-MCP/${mcpVersion}`,
|
|
9281
9281
|
deviceId: this.deviceId,
|
|
@@ -10993,8 +10993,8 @@ function registerPermissionTools(server) {
|
|
|
10993
10993
|
}
|
|
10994
10994
|
};
|
|
10995
10995
|
server.registerTool?.("queryPermissions", {
|
|
10996
|
-
title: "
|
|
10997
|
-
description: "
|
|
10996
|
+
title: "查询 CloudBase 权限与用户配置",
|
|
10997
|
+
description: "查询 CloudBase 权限与用户配置,支持查询资源权限(数据库/云函数/存储桶等)、角色列表/详情、应用用户列表/详情。\n\n示例:\n- 查询存储桶权限:`action=\"getResourcePermission\", resourceType=\"storage\", resourceId=\"bucket-name\"`",
|
|
10998
10998
|
inputSchema: {
|
|
10999
10999
|
action: zod_1.z.enum(QUERY_PERMISSION_ACTIONS),
|
|
11000
11000
|
resourceType: zod_1.z
|
|
@@ -11154,8 +11154,8 @@ function registerPermissionTools(server) {
|
|
|
11154
11154
|
}
|
|
11155
11155
|
}));
|
|
11156
11156
|
server.registerTool?.("managePermissions", {
|
|
11157
|
-
title: "
|
|
11158
|
-
description: "
|
|
11157
|
+
title: "管理 CloudBase 权限与用户配置",
|
|
11158
|
+
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`,请参考对应官方文档。",
|
|
11159
11159
|
inputSchema: {
|
|
11160
11160
|
action: zod_1.z.enum(MANAGE_PERMISSION_ACTIONS),
|
|
11161
11161
|
resourceType: zod_1.z
|
|
@@ -11649,14 +11649,28 @@ async function downloadFile(url, filePath, redirectCount = 0) {
|
|
|
11649
11649
|
.on("error", reject);
|
|
11650
11650
|
});
|
|
11651
11651
|
}
|
|
11652
|
-
// 解压ZIP
|
|
11652
|
+
// 解压ZIP文件(含 zip slip 防护)
|
|
11653
11653
|
async function extractZip(zipPath, extractPath) {
|
|
11654
11654
|
try {
|
|
11655
11655
|
// 创建解压目录
|
|
11656
11656
|
await fsPromises.mkdir(extractPath, { recursive: true });
|
|
11657
|
-
// 使用 adm-zip
|
|
11657
|
+
// 使用 adm-zip 库逐条目解压,防止 zip slip 路径穿越
|
|
11658
11658
|
const zip = new adm_zip_1.default(zipPath);
|
|
11659
|
-
zip.
|
|
11659
|
+
const entries = zip.getEntries();
|
|
11660
|
+
const resolvedExtractPath = path.resolve(extractPath);
|
|
11661
|
+
for (const entry of entries) {
|
|
11662
|
+
// 跳过目录条目,后面由 mkdir 自动创建
|
|
11663
|
+
if (entry.isDirectory)
|
|
11664
|
+
continue;
|
|
11665
|
+
const entryPath = path.resolve(resolvedExtractPath, entry.entryName);
|
|
11666
|
+
if (!entryPath.startsWith(resolvedExtractPath + path.sep)) {
|
|
11667
|
+
throw new Error(`解压失败: ZIP 文件中包含非法的路径 "${entry.entryName}",已安全拦截`);
|
|
11668
|
+
}
|
|
11669
|
+
// 确保目标目录存在
|
|
11670
|
+
await fsPromises.mkdir(path.dirname(entryPath), { recursive: true });
|
|
11671
|
+
// 写入文件
|
|
11672
|
+
await fsPromises.writeFile(entryPath, entry.getData());
|
|
11673
|
+
}
|
|
11660
11674
|
}
|
|
11661
11675
|
catch (error) {
|
|
11662
11676
|
throw new Error(`解压失败: ${error instanceof Error ? error.message : "未知错误"}`);
|
|
@@ -11831,7 +11845,7 @@ function registerSetupTools(server) {
|
|
|
11831
11845
|
server.registerTool("downloadTemplate", {
|
|
11832
11846
|
title: "下载项目模板",
|
|
11833
11847
|
description: `自动下载并部署CloudBase项目模板。
|
|
11834
|
-
**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.
|
|
11848
|
+
**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)`,
|
|
11835
11849
|
inputSchema: {
|
|
11836
11850
|
template: zod_1.z
|
|
11837
11851
|
.enum(["react", "vue", "miniprogram", "uniapp", "rules"])
|
|
@@ -12026,8 +12040,9 @@ exports.registerAppTools = registerAppTools;
|
|
|
12026
12040
|
const zod_1 = __webpack_require__(2971);
|
|
12027
12041
|
const cloudbase_manager_js_1 = __webpack_require__(3431);
|
|
12028
12042
|
const json_content_js_1 = __webpack_require__(4365);
|
|
12029
|
-
const
|
|
12030
|
-
const
|
|
12043
|
+
const cloud_mode_js_1 = __webpack_require__(9684);
|
|
12044
|
+
const QUERY_APP_ACTIONS = ["listApps", "getApp", "listAppVersions", "getAppVersion", "getBuildLog"];
|
|
12045
|
+
const MANAGE_APP_ACTIONS = ["deployApp", "getUploadUrl", "deleteApp", "deleteAppVersion"];
|
|
12031
12046
|
const APP_FRAMEWORKS = ["vue", "react", "next", "nuxt", "vite", "angular", "static"];
|
|
12032
12047
|
function buildEnvelope(data, message) {
|
|
12033
12048
|
return {
|
|
@@ -12046,18 +12061,37 @@ function buildErrorEnvelope(error) {
|
|
|
12046
12061
|
function getCloudAppService(cloudbase) {
|
|
12047
12062
|
return cloudbase.cloudAppService ?? cloudbase.getCloudAppService?.();
|
|
12048
12063
|
}
|
|
12064
|
+
function normalizeAccessUrlFromDomain(domain) {
|
|
12065
|
+
if (typeof domain !== "string" || !domain.trim())
|
|
12066
|
+
return {};
|
|
12067
|
+
const trimmed = domain.trim();
|
|
12068
|
+
const withProtocol = /^https?:\/\//i.test(trimmed) ? trimmed : `https://${trimmed}`;
|
|
12069
|
+
try {
|
|
12070
|
+
const url = new URL(withProtocol);
|
|
12071
|
+
url.hash = "";
|
|
12072
|
+
url.search = "";
|
|
12073
|
+
url.pathname = url.pathname === "/" ? "" : url.pathname.replace(/\/+$/, "");
|
|
12074
|
+
return {
|
|
12075
|
+
domain: url.host,
|
|
12076
|
+
accessUrl: url.toString().replace(/\/$/, ""),
|
|
12077
|
+
};
|
|
12078
|
+
}
|
|
12079
|
+
catch {
|
|
12080
|
+
return {};
|
|
12081
|
+
}
|
|
12082
|
+
}
|
|
12049
12083
|
function registerAppTools(server) {
|
|
12050
12084
|
const cloudBaseOptions = server.cloudBaseOptions;
|
|
12051
12085
|
const getManager = () => (0, cloudbase_manager_js_1.getCloudBaseManager)({ cloudBaseOptions });
|
|
12052
12086
|
server.registerTool?.("queryApps", {
|
|
12053
|
-
title: "查询
|
|
12054
|
-
description: "
|
|
12087
|
+
title: "查询 CloudBase 应用部署状态",
|
|
12088
|
+
description: "查询 CloudBase 应用部署的应用和版本。可查应用列表/详情、版本列表/详情;部署后用 getAppVersion 按 buildId 轮询构建状态;getBuildLog 可查询构建日志用于诊断失败原因。",
|
|
12055
12089
|
inputSchema: {
|
|
12056
12090
|
action: zod_1.z.enum(QUERY_APP_ACTIONS),
|
|
12057
12091
|
serviceName: zod_1.z
|
|
12058
12092
|
.string()
|
|
12059
12093
|
.optional()
|
|
12060
|
-
.describe("
|
|
12094
|
+
.describe("CloudBase 应用服务名。getApp / listAppVersions / getAppVersion / getBuildLog 时必填;重新部署后复用同一个 serviceName 查询版本历史。"),
|
|
12061
12095
|
searchKey: zod_1.z.string().optional().describe("按应用服务名模糊搜索关键词,仅 action=listApps 时使用。"),
|
|
12062
12096
|
pageNo: zod_1.z.number().optional().describe("分页页码,从 1 开始。"),
|
|
12063
12097
|
pageSize: zod_1.z.number().optional().describe("分页大小。"),
|
|
@@ -12068,14 +12102,18 @@ function registerAppTools(server) {
|
|
|
12068
12102
|
buildId: zod_1.z
|
|
12069
12103
|
.string()
|
|
12070
12104
|
.optional()
|
|
12071
|
-
.describe("构建 ID。getAppVersion 时可与 versionName 二选一;部署返回 BuildId 后可直接用它轮询状态。"),
|
|
12105
|
+
.describe("构建 ID。getAppVersion 时可与 versionName 二选一;部署返回 BuildId 后可直接用它轮询状态。getBuildLog 时必填。"),
|
|
12106
|
+
start: zod_1.z
|
|
12107
|
+
.number()
|
|
12108
|
+
.optional()
|
|
12109
|
+
.describe("构建日志偏移量,用于分页拉取后续日志。仅 action=getBuildLog 时使用,不传时从开头返回。"),
|
|
12072
12110
|
},
|
|
12073
12111
|
annotations: {
|
|
12074
12112
|
readOnlyHint: true,
|
|
12075
12113
|
openWorldHint: true,
|
|
12076
12114
|
category: "apps",
|
|
12077
12115
|
},
|
|
12078
|
-
}, async ({ action, serviceName, searchKey, pageNo, pageSize, versionName, buildId, }) => {
|
|
12116
|
+
}, async ({ action, serviceName, searchKey, pageNo, pageSize, versionName, buildId, start, }) => {
|
|
12079
12117
|
try {
|
|
12080
12118
|
const cloudbase = await getManager();
|
|
12081
12119
|
const appService = getCloudAppService(cloudbase);
|
|
@@ -12095,7 +12133,7 @@ function registerAppTools(server) {
|
|
|
12095
12133
|
apps: result.ServiceList ?? [],
|
|
12096
12134
|
total: result.Total ?? 0,
|
|
12097
12135
|
raw: result,
|
|
12098
|
-
}, "
|
|
12136
|
+
}, "CloudBase 应用列表查询成功"));
|
|
12099
12137
|
}
|
|
12100
12138
|
if (!serviceName) {
|
|
12101
12139
|
throw new Error(`action=${action} 时必须提供 serviceName`);
|
|
@@ -12110,7 +12148,7 @@ function registerAppTools(server) {
|
|
|
12110
12148
|
action,
|
|
12111
12149
|
serviceName,
|
|
12112
12150
|
app: result,
|
|
12113
|
-
}, "
|
|
12151
|
+
}, "CloudBase 应用详情查询成功"));
|
|
12114
12152
|
}
|
|
12115
12153
|
if (action === "listAppVersions") {
|
|
12116
12154
|
const result = await appService.describeAppVersionList({
|
|
@@ -12126,7 +12164,34 @@ function registerAppTools(server) {
|
|
|
12126
12164
|
versions: result.VersionList ?? [],
|
|
12127
12165
|
total: result.Total ?? 0,
|
|
12128
12166
|
raw: result,
|
|
12129
|
-
}, "
|
|
12167
|
+
}, "CloudBase 应用版本列表查询成功"));
|
|
12168
|
+
}
|
|
12169
|
+
if (action === "getBuildLog") {
|
|
12170
|
+
if (!buildId) {
|
|
12171
|
+
throw new Error("action=getBuildLog 时必须提供 buildId");
|
|
12172
|
+
}
|
|
12173
|
+
const result = await cloudbase.commonService("tcb", "2018-06-08").call({
|
|
12174
|
+
Action: "DescribeCloudBaseRunBuildLog",
|
|
12175
|
+
Param: {
|
|
12176
|
+
EnvId: cloudBaseOptions?.envId || process.env.CLOUDBASE_ENV_ID,
|
|
12177
|
+
ServiceName: serviceName,
|
|
12178
|
+
BuildId: buildId,
|
|
12179
|
+
Start: start ?? 0,
|
|
12180
|
+
},
|
|
12181
|
+
});
|
|
12182
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
12183
|
+
const logs = result.Response?.LogList || [];
|
|
12184
|
+
return (0, json_content_js_1.jsonContent)(buildEnvelope({
|
|
12185
|
+
action,
|
|
12186
|
+
serviceName,
|
|
12187
|
+
buildId,
|
|
12188
|
+
logs,
|
|
12189
|
+
total: result.Response?.Total || logs.length,
|
|
12190
|
+
nextStart: result.Response?.NextStart,
|
|
12191
|
+
raw: result,
|
|
12192
|
+
}, logs.length > 0
|
|
12193
|
+
? `查询到 ${logs.length} 条构建日志`
|
|
12194
|
+
: "暂无构建日志"));
|
|
12130
12195
|
}
|
|
12131
12196
|
const result = await appService.describeAppVersion({
|
|
12132
12197
|
deployType: "static-hosting",
|
|
@@ -12135,56 +12200,105 @@ function registerAppTools(server) {
|
|
|
12135
12200
|
buildId,
|
|
12136
12201
|
});
|
|
12137
12202
|
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
12138
|
-
|
|
12203
|
+
const isFailed = result.Status === "FAILED";
|
|
12204
|
+
const payload = {
|
|
12139
12205
|
action,
|
|
12140
12206
|
serviceName,
|
|
12207
|
+
status: result.Status,
|
|
12208
|
+
buildId: result.BuildId,
|
|
12209
|
+
failReason: result.FailReason,
|
|
12210
|
+
buildDuration: result.BuildDuration,
|
|
12141
12211
|
version: result,
|
|
12142
|
-
}
|
|
12212
|
+
};
|
|
12213
|
+
if (isFailed) {
|
|
12214
|
+
payload.nextStep = {
|
|
12215
|
+
action: "查询构建日志",
|
|
12216
|
+
tool: "queryApps",
|
|
12217
|
+
args: {
|
|
12218
|
+
action: "getBuildLog",
|
|
12219
|
+
serviceName,
|
|
12220
|
+
buildId: result.BuildId,
|
|
12221
|
+
},
|
|
12222
|
+
hint: `构建失败。调用 queryApps(action="getBuildLog", serviceName="${serviceName}", buildId="${result.BuildId}") 查看构建日志,诊断失败原因。`,
|
|
12223
|
+
};
|
|
12224
|
+
}
|
|
12225
|
+
return (0, json_content_js_1.jsonContent)(buildEnvelope(payload, `CloudBase 应用版本详情查询成功(状态: ${result.Status}${result.FailReason ? `, 失败原因: ${result.FailReason}` : ""}${isFailed ? ",可查询构建日志" : ""})`));
|
|
12143
12226
|
}
|
|
12144
12227
|
catch (error) {
|
|
12145
12228
|
return (0, json_content_js_1.jsonContent)(buildErrorEnvelope(error));
|
|
12146
12229
|
}
|
|
12147
12230
|
});
|
|
12148
12231
|
server.registerTool?.("manageApps", {
|
|
12149
|
-
title: "
|
|
12150
|
-
description: "
|
|
12232
|
+
title: "部署应用到 CloudBase(独立子域名)",
|
|
12233
|
+
description: "部署 Web 应用到 CloudBase(构建前后端,部署到独立子域名)。\n" +
|
|
12234
|
+
"action=getUploadUrl 获取预签名上传 URL(cloud mode 下使用),返回上传地址和 cosTimestamp。\n" +
|
|
12235
|
+
"action=deployApp 上传源码 ZIP 并触发远端构建部署管道:\n" +
|
|
12236
|
+
" 1. 远端 npm install(可通过 installCmd=\"\" 跳过)\n" +
|
|
12237
|
+
" 2. 远端 npm run build(可通过 buildCmd=\"\" 跳过)\n" +
|
|
12238
|
+
" 3. 远端 tcb hosting deploy\n" +
|
|
12239
|
+
"\n" +
|
|
12240
|
+
"域名格式:`<serviceName>-<envId>.webapps.tcloudbase.com`(每个 serviceName 一个独立子域名)\n" +
|
|
12241
|
+
"\n" +
|
|
12242
|
+
"✅ 推荐用法(新项目/需要独立域名的 Web 应用,首选此工具):\n" +
|
|
12243
|
+
" 新建项目首次部署时,传 framework=static, installCmd=\"\", buildCmd=\"\" 跳过远端构建,\n" +
|
|
12244
|
+
" 只执行 tcb hosting deploy。部署后获得独立子域名,支持版本管理。\n" +
|
|
12245
|
+
"\n" +
|
|
12246
|
+
"⚠️ 兼容性说明:\n" +
|
|
12247
|
+
"- 已有项目若之前用 manageHosting 部署过(域名格式:`<envId>-<appId>.tcloudbaseapp.com`),\n" +
|
|
12248
|
+
" 切换到 manageApps 会产生全新的 URL,老链接失效。请保持原部署方式不变。\n" +
|
|
12249
|
+
"- 如需判断:调用 queryHosting 检查是否已有托管文件。\n" +
|
|
12250
|
+
"\n" +
|
|
12251
|
+
"与 manageHosting 对比:\n" +
|
|
12252
|
+
"- manageApps(本工具,新项目首选):域名 `<serviceName>-<envId>.webapps.tcloudbase.com`,独立子域名,支持版本管理\n" +
|
|
12253
|
+
"- manageHosting(已有项目或 fallback):域名 `<envId>-<appId>.tcloudbaseapp.com/<path>`,共享环境域名\n" +
|
|
12254
|
+
"两者均可绑定自定义域名。\n" +
|
|
12255
|
+
"\n" +
|
|
12256
|
+
"⚠️ 如果 manageApps 构建失败,先用 queryApps(action=\"getBuildLog\") 查日志;仍不行再 fallback 到 manageHosting。",
|
|
12151
12257
|
inputSchema: {
|
|
12152
12258
|
action: zod_1.z.enum(MANAGE_APP_ACTIONS),
|
|
12153
12259
|
serviceName: zod_1.z
|
|
12154
12260
|
.string()
|
|
12155
|
-
.describe("
|
|
12261
|
+
.describe("CloudBase 应用服务名,会体现在域名中:`<serviceName>-<envId>.webapps.tcloudbase.com`。deployApp 时复用现有 serviceName 会新增一个部署版本并触发重新部署,而不是删除重建。首次部署请用新名称。"),
|
|
12156
12262
|
filePath: zod_1.z
|
|
12157
12263
|
.string()
|
|
12158
12264
|
.optional()
|
|
12159
|
-
.describe("
|
|
12265
|
+
.describe("要上传并部署的本地项目根目录绝对路径。本地模式下 deployApp 时必填;通常传源码所在目录(含 package.json 和源码),不是 dist 目录。构建产物目录请用 buildPath 指定。cloud mode 下无需传此参数,改用 cosTimestamp。"),
|
|
12266
|
+
cosTimestamp: zod_1.z
|
|
12267
|
+
.string()
|
|
12268
|
+
.optional()
|
|
12269
|
+
.describe("可选 COS 时间戳。传入此值则直接使用已上传的代码创建应用,跳过本地文件上传。需先调用 getUploadUrl 获取预签名 URL,上传 ZIP 包后再传此时间戳。cloud mode 下为必填;本地模式也可传此值代替 filePath。两个路径二选一:filePath(本地打包上传)或 cosTimestamp(预签名 URL 上传)。"),
|
|
12160
12270
|
appPath: zod_1.z
|
|
12161
12271
|
.string()
|
|
12162
12272
|
.optional()
|
|
12163
|
-
.describe("应用线上访问路径(hosting mount path),例如 /my-web-app
|
|
12273
|
+
.describe("应用线上访问路径(hosting mount path),例如 /my-web-app。不是本地目录路径;CloudApp 已有独立子域名,省略时默认为 /(根路径)。"),
|
|
12164
12274
|
buildPath: zod_1.z
|
|
12165
12275
|
.string()
|
|
12166
12276
|
.optional()
|
|
12167
|
-
.describe("构建产物目录,相对于 filePath,例如 dist 或 build
|
|
12277
|
+
.describe("构建产物目录,相对于 filePath,例如 dist 或 build。\n" +
|
|
12278
|
+
"⚠️ 传此值后远端构建系统会 cd 到此目录再执行 tcb hosting deploy,因此 deployCmd 会自动使用 .(当前目录)而非目录名,避免路径重复(如 dist/dist 错误)。\n" +
|
|
12279
|
+
"纯静态 HTML 如果在项目根目录可省略,但注意 deployCmd 默认用 dist。"),
|
|
12168
12280
|
framework: zod_1.z
|
|
12169
12281
|
.enum(APP_FRAMEWORKS)
|
|
12170
12282
|
.optional()
|
|
12171
|
-
.describe("前端框架类型。可选值:vue、react、next、nuxt、vite、angular、static
|
|
12283
|
+
.describe("前端框架类型。可选值:vue、react、next、nuxt、vite、angular、static。\n" +
|
|
12284
|
+
"即使传 static,仍会经过远端构建管道。如果本地已构建好,建议改用 manageHosting 直接上传,可完全跳过远端构建。"),
|
|
12172
12285
|
nodeJsVersion: zod_1.z
|
|
12173
12286
|
.string()
|
|
12174
12287
|
.optional()
|
|
12175
|
-
.describe("构建时使用的 Node.js 版本;不传时由
|
|
12288
|
+
.describe("构建时使用的 Node.js 版本;不传时由 CloudBase 使用默认值。"),
|
|
12176
12289
|
installCmd: zod_1.z
|
|
12177
12290
|
.string()
|
|
12178
12291
|
.optional()
|
|
12179
|
-
.describe("依赖安装命令,例如 npm install
|
|
12292
|
+
.describe("依赖安装命令,例如 npm install。不传时默认 npm install。本地已安装或无需安装可传空字符串 '' 跳过,但远端仍会执行 tcb hosting deploy。"),
|
|
12180
12293
|
buildCmd: zod_1.z
|
|
12181
12294
|
.string()
|
|
12182
12295
|
.optional()
|
|
12183
|
-
.describe("构建命令,例如 npm run build
|
|
12296
|
+
.describe("构建命令,例如 npm run build。不传时默认 npm run build。本地已构建好可传空字符串 '' 跳过构建步骤。若希望完全跳过远端管道,请改用 manageHosting。"),
|
|
12184
12297
|
deployCmd: zod_1.z
|
|
12185
12298
|
.string()
|
|
12186
12299
|
.optional()
|
|
12187
|
-
.describe("
|
|
12300
|
+
.describe("自定义部署命令。通常无需填写,默认自动生成 tcb hosting deploy 命令。" +
|
|
12301
|
+
"有 buildPath 时远端已 cd 到该目录,默认用 . 作为源码路径;无 buildPath 时默认用 dist。"),
|
|
12188
12302
|
ignore: zod_1.z.array(zod_1.z.string()).optional().describe("上传时忽略的文件/目录 glob 模式,例如 **/node_modules/**。"),
|
|
12189
12303
|
versionName: zod_1.z
|
|
12190
12304
|
.string()
|
|
@@ -12198,48 +12312,155 @@ function registerAppTools(server) {
|
|
|
12198
12312
|
openWorldHint: true,
|
|
12199
12313
|
category: "apps",
|
|
12200
12314
|
},
|
|
12201
|
-
}, async ({ action, serviceName, filePath, appPath, buildPath, framework, nodeJsVersion, installCmd, buildCmd, deployCmd, ignore, versionName, }) => {
|
|
12315
|
+
}, async ({ action, serviceName, filePath, cosTimestamp, appPath, buildPath, framework, nodeJsVersion, installCmd, buildCmd, deployCmd, ignore, versionName, }) => {
|
|
12202
12316
|
try {
|
|
12203
12317
|
const cloudbase = await getManager();
|
|
12204
12318
|
const appService = getCloudAppService(cloudbase);
|
|
12205
12319
|
if (!appService) {
|
|
12206
12320
|
throw new Error("当前 manager 未提供 cloudAppService");
|
|
12207
12321
|
}
|
|
12208
|
-
|
|
12209
|
-
|
|
12210
|
-
|
|
12322
|
+
// getUploadUrl — 获取预签名上传 URL(cloud mode 专用)
|
|
12323
|
+
if (action === "getUploadUrl") {
|
|
12324
|
+
if (!serviceName) {
|
|
12325
|
+
throw new Error("action=getUploadUrl 时必须提供 serviceName");
|
|
12211
12326
|
}
|
|
12212
|
-
const
|
|
12327
|
+
const cosInfoResult = await appService.describeCosInfo({
|
|
12213
12328
|
deployType: "static-hosting",
|
|
12214
12329
|
serviceName,
|
|
12215
|
-
localPath: filePath,
|
|
12216
|
-
ignore,
|
|
12217
12330
|
});
|
|
12218
|
-
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger,
|
|
12331
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, cosInfoResult);
|
|
12332
|
+
const defaultIgnore = ["node_modules/**", ".git/**", ".DS_Store", "**/.DS_Store"];
|
|
12333
|
+
// eslint-disable-next-line max-len
|
|
12334
|
+
const zipCmd = "zip -r upload.zip . -x 'node_modules/**' -x '.git/**' -x '.DS_Store' -x '**/.DS_Store'";
|
|
12335
|
+
const followupArgs = {
|
|
12336
|
+
action: "deployApp",
|
|
12337
|
+
serviceName,
|
|
12338
|
+
cosTimestamp: cosInfoResult.UnixTimestamp,
|
|
12339
|
+
};
|
|
12340
|
+
return (0, json_content_js_1.jsonContent)(buildEnvelope({
|
|
12341
|
+
action,
|
|
12342
|
+
serviceName,
|
|
12343
|
+
uploadUrl: cosInfoResult.UploadUrl,
|
|
12344
|
+
uploadHeaders: cosInfoResult.UploadHeaders,
|
|
12345
|
+
cosTimestamp: cosInfoResult.UnixTimestamp,
|
|
12346
|
+
method: "PUT",
|
|
12347
|
+
ignore: defaultIgnore,
|
|
12348
|
+
zipCommand: zipCmd,
|
|
12349
|
+
nextAction: {
|
|
12350
|
+
action: "上传代码到预签名 URL",
|
|
12351
|
+
hint: "请先在本地打包项目代码(排除 node_modules/.git),再将其上传到预签名 URL,然后调用 deployApp 触发构建",
|
|
12352
|
+
details: [
|
|
12353
|
+
`1. 打包: ${zipCmd}`,
|
|
12354
|
+
`2. 上传: curl -X PUT -T upload.zip '${cosInfoResult.UploadUrl}'`,
|
|
12355
|
+
`3. 触发构建: manageApps(action="deployApp", serviceName="${serviceName}", cosTimestamp="${cosInfoResult.UnixTimestamp}")`,
|
|
12356
|
+
],
|
|
12357
|
+
followup: {
|
|
12358
|
+
tool: "manageApps",
|
|
12359
|
+
args: followupArgs,
|
|
12360
|
+
},
|
|
12361
|
+
},
|
|
12362
|
+
}, "预签名上传 URL 获取成功。请上传代码后调用 deployApp 触发构建。"));
|
|
12363
|
+
}
|
|
12364
|
+
if (action === "deployApp") {
|
|
12365
|
+
// cloud mode 下必须有 cosTimestamp;本地模式必须有 filePath
|
|
12366
|
+
if ((0, cloud_mode_js_1.isCloudMode)()) {
|
|
12367
|
+
if (!cosTimestamp) {
|
|
12368
|
+
throw new Error("cloud mode 下 deployApp 需要 cosTimestamp 参数。请先调用 getUploadUrl 获取预签名上传 URL。" +
|
|
12369
|
+
"上传代码后再用 cosTimestamp 调用 deployApp。");
|
|
12370
|
+
}
|
|
12371
|
+
}
|
|
12372
|
+
else if (!filePath && !cosTimestamp) {
|
|
12373
|
+
throw new Error("action=deployApp 时必须提供 filePath(本地模式)或 cosTimestamp(cloud mode)。");
|
|
12374
|
+
}
|
|
12375
|
+
// 上传代码到 COS(仅本地模式需要,cloud mode 用 cosTimestamp 跳过)
|
|
12376
|
+
let cosTs = cosTimestamp;
|
|
12377
|
+
if (filePath && !cosTs) {
|
|
12378
|
+
const uploadResult = await appService.uploadCode({
|
|
12379
|
+
deployType: "static-hosting",
|
|
12380
|
+
serviceName,
|
|
12381
|
+
localPath: filePath,
|
|
12382
|
+
ignore,
|
|
12383
|
+
});
|
|
12384
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, uploadResult);
|
|
12385
|
+
cosTs = uploadResult.cosTimestamp;
|
|
12386
|
+
}
|
|
12387
|
+
// 构建命令智能默认值
|
|
12388
|
+
const resolvedInstallCmd = installCmd ?? "npm install";
|
|
12389
|
+
const resolvedBuildCmd = buildCmd ?? "npm run build";
|
|
12390
|
+
const resolvedDeployPath = appPath || "/";
|
|
12391
|
+
const resolvedBuildPath = buildPath || "";
|
|
12392
|
+
// ⚠️ 远端构建系统在有 buildPath 时 cd 到此目录再执行 tcb hosting deploy
|
|
12393
|
+
// 部署命令用 "." 避免 dist/dist 重复。framework=static 无构建步骤,用根目录
|
|
12394
|
+
const resolvedDeployCmd = deployCmd || (resolvedBuildPath || framework === "static"
|
|
12395
|
+
? `tcb hosting deploy . ${resolvedDeployPath}`
|
|
12396
|
+
: `tcb hosting deploy dist ${resolvedDeployPath}`);
|
|
12397
|
+
// 触发远端构建
|
|
12219
12398
|
const result = await appService.createApp({
|
|
12220
12399
|
deployType: "static-hosting",
|
|
12221
12400
|
serviceName,
|
|
12222
12401
|
buildType: "ZIP",
|
|
12223
12402
|
staticConfig: {
|
|
12224
|
-
appPath,
|
|
12225
|
-
buildPath,
|
|
12403
|
+
appPath: resolvedDeployPath,
|
|
12404
|
+
buildPath: resolvedBuildPath,
|
|
12226
12405
|
framework,
|
|
12227
12406
|
nodeJsVersion,
|
|
12228
|
-
cosTimestamp:
|
|
12407
|
+
cosTimestamp: cosTs,
|
|
12229
12408
|
staticCmd: {
|
|
12230
|
-
installCmd,
|
|
12231
|
-
buildCmd,
|
|
12232
|
-
deployCmd,
|
|
12409
|
+
installCmd: resolvedInstallCmd,
|
|
12410
|
+
buildCmd: resolvedBuildCmd,
|
|
12411
|
+
deployCmd: resolvedDeployCmd,
|
|
12233
12412
|
},
|
|
12234
12413
|
},
|
|
12235
12414
|
});
|
|
12236
12415
|
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
12416
|
+
const { BuildId, VersionName } = result;
|
|
12417
|
+
let appInfo;
|
|
12418
|
+
let domain;
|
|
12419
|
+
let accessUrl;
|
|
12420
|
+
let accessUrlLookupWarning;
|
|
12421
|
+
try {
|
|
12422
|
+
appInfo = await appService.describeAppInfo({
|
|
12423
|
+
deployType: "static-hosting",
|
|
12424
|
+
serviceName,
|
|
12425
|
+
});
|
|
12426
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, appInfo);
|
|
12427
|
+
({ domain, accessUrl } = normalizeAccessUrlFromDomain(appInfo?.Domain));
|
|
12428
|
+
}
|
|
12429
|
+
catch (error) {
|
|
12430
|
+
accessUrlLookupWarning = error instanceof Error ? error.message : String(error);
|
|
12431
|
+
}
|
|
12237
12432
|
return (0, json_content_js_1.jsonContent)(buildEnvelope({
|
|
12238
12433
|
action,
|
|
12239
12434
|
serviceName,
|
|
12240
|
-
|
|
12435
|
+
versionName: VersionName,
|
|
12436
|
+
buildId: BuildId,
|
|
12437
|
+
domain,
|
|
12438
|
+
accessUrl,
|
|
12439
|
+
accessUrlSource: accessUrl ? "describeAppInfo.Domain" : undefined,
|
|
12440
|
+
accessUrlLookupWarning,
|
|
12441
|
+
app: appInfo,
|
|
12442
|
+
upload: { cosTimestamp: cosTs },
|
|
12241
12443
|
deployment: result,
|
|
12242
|
-
|
|
12444
|
+
buildConfig: {
|
|
12445
|
+
installCmd: resolvedInstallCmd,
|
|
12446
|
+
buildCmd: resolvedBuildCmd,
|
|
12447
|
+
deployCmd: resolvedDeployCmd,
|
|
12448
|
+
},
|
|
12449
|
+
nextStep: {
|
|
12450
|
+
action: "轮询构建状态",
|
|
12451
|
+
tool: "queryApps",
|
|
12452
|
+
args: {
|
|
12453
|
+
action: "getAppVersion",
|
|
12454
|
+
serviceName,
|
|
12455
|
+
buildId: BuildId,
|
|
12456
|
+
},
|
|
12457
|
+
hint: accessUrl
|
|
12458
|
+
? `调用 queryApps(action="getAppVersion", serviceName="${serviceName}", buildId="${BuildId}") 轮询构建状态,直到 status 变为 SUCCESS 或 FAILED。构建成功后,后续记录部署时必须使用本结果的 accessUrl=${accessUrl},不要自行拼接域名。若状态为 FAILED,可继续调用 queryApps(action="getBuildLog", serviceName="${serviceName}", buildId="${BuildId}") 查看构建日志诊断失败原因。`
|
|
12459
|
+
: `调用 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}") 查看构建日志诊断失败原因。`,
|
|
12460
|
+
},
|
|
12461
|
+
}, accessUrl
|
|
12462
|
+
? "CloudBase 应用构建已触发,已返回真实 accessUrl;请通过 queryApps 轮询构建状态。"
|
|
12463
|
+
: "CloudBase 应用构建已触发,请通过 queryApps 轮询构建状态,并用 getApp 读取真实域名。"));
|
|
12243
12464
|
}
|
|
12244
12465
|
if (action === "deleteApp") {
|
|
12245
12466
|
const result = await appService.deleteApp({
|
|
@@ -12251,7 +12472,7 @@ function registerAppTools(server) {
|
|
|
12251
12472
|
action,
|
|
12252
12473
|
serviceName,
|
|
12253
12474
|
raw: result,
|
|
12254
|
-
}, "
|
|
12475
|
+
}, "CloudBase 应用删除成功"));
|
|
12255
12476
|
}
|
|
12256
12477
|
if (!versionName) {
|
|
12257
12478
|
throw new Error("action=deleteAppVersion 时必须提供 versionName");
|
|
@@ -12267,7 +12488,7 @@ function registerAppTools(server) {
|
|
|
12267
12488
|
serviceName,
|
|
12268
12489
|
versionName,
|
|
12269
12490
|
raw: result,
|
|
12270
|
-
}, "
|
|
12491
|
+
}, "CloudBase 应用版本删除成功"));
|
|
12271
12492
|
}
|
|
12272
12493
|
catch (error) {
|
|
12273
12494
|
return (0, json_content_js_1.jsonContent)(buildErrorEnvelope(error));
|
|
@@ -13071,6 +13292,16 @@ async function resolveHostingStaticDomain(cloudbase, logger) {
|
|
|
13071
13292
|
return undefined;
|
|
13072
13293
|
}
|
|
13073
13294
|
}
|
|
13295
|
+
async function assertHostingUploadEnvironmentReady(cloudbase, cloudBaseOptions, logger) {
|
|
13296
|
+
const envId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
13297
|
+
const envInfo = await cloudbase.env.getEnvInfo();
|
|
13298
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(logger, envInfo);
|
|
13299
|
+
const staticStorage = envInfo.EnvInfo?.StaticStorages?.[0];
|
|
13300
|
+
if (staticStorage?.Bucket) {
|
|
13301
|
+
return;
|
|
13302
|
+
}
|
|
13303
|
+
throw new Error(`当前环境 ${envId} 未发现静态托管资源配置,无法上传文件。请先确认 MCP 已绑定到已开通静态托管的 CloudBase 环境;如需切换环境,请调用 auth(action="set_env", envId="目标环境ID") 后重试。`);
|
|
13304
|
+
}
|
|
13074
13305
|
function buildFailureResult(action, error) {
|
|
13075
13306
|
return (0, tool_result_js_1.buildJsonToolResult)({
|
|
13076
13307
|
success: false,
|
|
@@ -13255,7 +13486,7 @@ function registerHostingTools(server) {
|
|
|
13255
13486
|
});
|
|
13256
13487
|
server.registerTool('manageHosting', {
|
|
13257
13488
|
title: '管理 CloudBase 静态托管',
|
|
13258
|
-
description: '管理 CloudBase 静态托管的变更操作。action=upload
|
|
13489
|
+
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。',
|
|
13259
13490
|
inputSchema: manageHostingInputSchema,
|
|
13260
13491
|
annotations: {
|
|
13261
13492
|
readOnlyHint: false,
|
|
@@ -13276,6 +13507,7 @@ function registerHostingTools(server) {
|
|
|
13276
13507
|
}
|
|
13277
13508
|
let result;
|
|
13278
13509
|
try {
|
|
13510
|
+
await assertHostingUploadEnvironmentReady(cloudbase, cloudBaseOptions, server.logger);
|
|
13279
13511
|
result = await cloudbase.hosting.uploadFiles({
|
|
13280
13512
|
localPath: input.localPath,
|
|
13281
13513
|
cloudPath: input.cloudPath,
|
|
@@ -14841,8 +15073,6 @@ function shouldRegisterTool(toolName) {
|
|
|
14841
15073
|
'manageCloudRun',
|
|
14842
15074
|
// Download tools - local file downloads
|
|
14843
15075
|
'manageStorage',
|
|
14844
|
-
// Apps tools - deployApp reads local filePath for code upload
|
|
14845
|
-
'manageApps',
|
|
14846
15076
|
];
|
|
14847
15077
|
const shouldRegister = !cloudIncompatibleTools.includes(toolName);
|
|
14848
15078
|
if (!shouldRegister) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudbase/cloudbase-mcp",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.21.0",
|
|
4
4
|
"packageManager": "pnpm@10.8.0",
|
|
5
5
|
"description": "腾讯云开发 MCP Server,通过AI提示词和MCP协议+云开发,让开发更智能、更高效,当你在Cursor/ VSCode GitHub Copilot/WinSurf/CodeBuddy/Augment Code/Claude Code等AI编程工具里写代码时,它能自动帮你生成可直接部署的前后端应用+小程序,并一键发布到腾讯云开发 CloudBase。",
|
|
6
6
|
"main": "./dist/index.cjs",
|