@cloudbase/cloudbase-mcp 2.15.3 → 2.16.0-beta.1
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/README.md +31 -13
- package/dist/cli.cjs +3 -3
- package/dist/index.cjs +6047 -790
- package/dist/index.js +1752 -524
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -169,7 +169,21 @@ const DEFAULT_AUTH_ACTIONS = [
|
|
|
169
169
|
"start_auth",
|
|
170
170
|
"set_env",
|
|
171
171
|
"logout",
|
|
172
|
+
"get_temp_credentials",
|
|
172
173
|
];
|
|
174
|
+
function maskSensitiveValue(value) {
|
|
175
|
+
if (value.length <= 4) {
|
|
176
|
+
return "*".repeat(value.length);
|
|
177
|
+
}
|
|
178
|
+
return `${value.slice(0, 2)}******${value.slice(-2)}`;
|
|
179
|
+
}
|
|
180
|
+
function isTemporaryCredentialLoginState(loginState) {
|
|
181
|
+
const refreshToken = normalizeOptionalToolString(loginState.refreshToken);
|
|
182
|
+
const token = normalizeOptionalToolString(loginState.token);
|
|
183
|
+
const accessTokenExpired = typeof loginState.accessTokenExpired === "number" ||
|
|
184
|
+
typeof loginState.accessTokenExpired === "string";
|
|
185
|
+
return Boolean(token && (refreshToken || accessTokenExpired));
|
|
186
|
+
}
|
|
173
187
|
function getCurrentIde(server) {
|
|
174
188
|
return server.ide || process.env.INTEGRATION_IDE || "";
|
|
175
189
|
}
|
|
@@ -532,6 +546,14 @@ function registerEnvTools(server) {
|
|
|
532
546
|
.describe("action=logout 时确认操作,传 yes"),
|
|
533
547
|
}
|
|
534
548
|
: {}),
|
|
549
|
+
...(supportedAuthActions.includes("get_temp_credentials")
|
|
550
|
+
? {
|
|
551
|
+
reveal: zod_1.z
|
|
552
|
+
.boolean()
|
|
553
|
+
.optional()
|
|
554
|
+
.describe("action=get_temp_credentials 时可选。true=返回明文临时密钥;默认 false 仅返回脱敏结果"),
|
|
555
|
+
}
|
|
556
|
+
: {}),
|
|
535
557
|
},
|
|
536
558
|
annotations: {
|
|
537
559
|
readOnlyHint: false,
|
|
@@ -550,6 +572,7 @@ function registerEnvTools(server) {
|
|
|
550
572
|
const oauthCustom = normalizeOptionalToolBoolean(rawArgs.oauthCustom);
|
|
551
573
|
const envId = rawArgs.envId;
|
|
552
574
|
const confirm = rawArgs.confirm === "yes" ? "yes" : undefined;
|
|
575
|
+
const reveal = normalizeOptionalToolBoolean(rawArgs.reveal) === true;
|
|
553
576
|
const resolvedAuthOptions = resolveToolAuthOptions(server, {
|
|
554
577
|
authMode,
|
|
555
578
|
oauthEndpoint,
|
|
@@ -860,6 +883,58 @@ function registerEnvTools(server) {
|
|
|
860
883
|
message: "✅ 已退出登录",
|
|
861
884
|
});
|
|
862
885
|
}
|
|
886
|
+
if (action === "get_temp_credentials") {
|
|
887
|
+
const loginState = (await (0, auth_js_1.peekLoginState)());
|
|
888
|
+
if (!loginState) {
|
|
889
|
+
return (0, tool_result_js_1.buildJsonToolResult)({
|
|
890
|
+
ok: false,
|
|
891
|
+
code: "AUTH_REQUIRED",
|
|
892
|
+
message: "当前未登录,请先完成管理端认证后再获取临时密钥。",
|
|
893
|
+
next_step: buildAuthRequiredNextStep(server),
|
|
894
|
+
});
|
|
895
|
+
}
|
|
896
|
+
if (confirm !== "yes") {
|
|
897
|
+
return (0, tool_result_js_1.buildJsonToolResult)({
|
|
898
|
+
ok: false,
|
|
899
|
+
code: "INVALID_ARGS",
|
|
900
|
+
message: "action=get_temp_credentials 时必须显式传 confirm=\"yes\",以确认你要导出当前管理端临时密钥。",
|
|
901
|
+
next_step: (0, tool_result_js_1.buildAuthNextStep)("get_temp_credentials", {
|
|
902
|
+
suggestedArgs: { action: "get_temp_credentials", confirm: "yes" },
|
|
903
|
+
}),
|
|
904
|
+
});
|
|
905
|
+
}
|
|
906
|
+
if (!isTemporaryCredentialLoginState(loginState)) {
|
|
907
|
+
return (0, tool_result_js_1.buildJsonToolResult)({
|
|
908
|
+
ok: false,
|
|
909
|
+
code: "UNSUPPORTED_CREDENTIAL_TYPE",
|
|
910
|
+
message: "当前登录态不是可导出的临时密钥。仅支持通过 Web / device 登录得到的临时密钥,永久密钥登录不允许导出。",
|
|
911
|
+
});
|
|
912
|
+
}
|
|
913
|
+
const secretId = normalizeOptionalToolString(loginState.secretId);
|
|
914
|
+
const secretKey = normalizeOptionalToolString(loginState.secretKey);
|
|
915
|
+
const token = normalizeOptionalToolString(loginState.token);
|
|
916
|
+
if (!secretId || !secretKey || !token) {
|
|
917
|
+
return (0, tool_result_js_1.buildJsonToolResult)({
|
|
918
|
+
ok: false,
|
|
919
|
+
code: "INTERNAL_ERROR",
|
|
920
|
+
message: "当前登录态缺少完整的临时密钥字段,请重新登录后再试。",
|
|
921
|
+
});
|
|
922
|
+
}
|
|
923
|
+
return (0, tool_result_js_1.buildJsonToolResult)({
|
|
924
|
+
ok: true,
|
|
925
|
+
code: "TEMP_CREDENTIALS_READY",
|
|
926
|
+
message: reveal
|
|
927
|
+
? "当前管理端临时密钥已准备好,请注意避免泄露。"
|
|
928
|
+
: "当前管理端临时密钥已准备好,默认仅返回脱敏结果。",
|
|
929
|
+
env_id: normalizeOptionalToolString(loginState.envId) ?? null,
|
|
930
|
+
credentials: {
|
|
931
|
+
secretId: reveal ? secretId : maskSensitiveValue(secretId),
|
|
932
|
+
secretKey: reveal ? secretKey : maskSensitiveValue(secretKey),
|
|
933
|
+
token: reveal ? token : maskSensitiveValue(token),
|
|
934
|
+
masked: !reveal,
|
|
935
|
+
},
|
|
936
|
+
});
|
|
937
|
+
}
|
|
863
938
|
return (0, tool_result_js_1.buildJsonToolResult)({
|
|
864
939
|
ok: false,
|
|
865
940
|
code: "NOT_SUPPORTED",
|
|
@@ -1282,7 +1357,15 @@ function registerCapiTools(server) {
|
|
|
1282
1357
|
const getManager = () => (0, cloudbase_manager_js_1.getCloudBaseManager)({ cloudBaseOptions });
|
|
1283
1358
|
server.registerTool?.("callCloudApi", {
|
|
1284
1359
|
title: "调用云API",
|
|
1285
|
-
description: `通用的云 API 调用工具,主要用于 CloudBase / 腾讯云管控面与依赖资源相关 API 调用。调用前请先确认 service、Action 与 Param,避免猜测 Action 名称。如果你的目标是通过 HTTP 协议直接集成 auth/functions/cloudrun/storage/mysqldb 等 CloudBase 业务 API,请不要优先使用 callCloudApi,而应优先查看对应 OpenAPI / Swagger。现有 OpenAPI / Swagger 能力不是通用的管控面 Action 集合;管控面 API 请优先参考 CloudBase API 概览 ${CLOUDBASE_CONTROL_PLANE_DOC_URL} 与云开发依赖资源接口指引 ${CLOUDBASE_DEPENDENCY_API_DOC_URL}。对于 tcb
|
|
1360
|
+
description: `通用的云 API 调用工具,主要用于 CloudBase / 腾讯云管控面与依赖资源相关 API 调用。调用前请先确认 service、Action 与 Param,避免猜测 Action 名称。如果你的目标是通过 HTTP 协议直接集成 auth/functions/cloudrun/storage/mysqldb 等 CloudBase 业务 API,请不要优先使用 callCloudApi,而应优先查看对应 OpenAPI / Swagger。现有 OpenAPI / Swagger 能力不是通用的管控面 Action 集合;管控面 API 请优先参考 CloudBase API 概览 ${CLOUDBASE_CONTROL_PLANE_DOC_URL} 与云开发依赖资源接口指引 ${CLOUDBASE_DEPENDENCY_API_DOC_URL}。对于 tcb service,常用 Action 分类如下:
|
|
1361
|
+
|
|
1362
|
+
**环境管理**: \`CreateEnv\`、\`ModifyEnv\`、\`DescribeEnvs\`、\`DestroyEnv\`
|
|
1363
|
+
**用户管理**: \`CreateUser\`、\`ModifyUser\`、\`DescribeUserList\`、\`DeleteUsers\`
|
|
1364
|
+
**认证配置**: \`EditAuthConfig\`、\`DescribeAuthDomains\`
|
|
1365
|
+
**云函数**: \`DescribeFunctions\`、\`CreateFunction\`、\`UpdateFunctionCode\`、\`DeleteFunction\`
|
|
1366
|
+
**数据库**: \`CreateMySQLInstance\`、\`DescribeMySQLInstances\`、\`DestroyMySQLInstance\`
|
|
1367
|
+
|
|
1368
|
+
销毁环境时,常见做法是至少带上 \`EnvId\` 和 \`BypassCheck: true\`,如果环境已经处于隔离期再按文档补 \`IsForce: true\`。`,
|
|
1286
1369
|
inputSchema: {
|
|
1287
1370
|
service: zod_1.z
|
|
1288
1371
|
.enum(ALLOWED_SERVICES)
|
|
@@ -1290,7 +1373,7 @@ function registerCapiTools(server) {
|
|
|
1290
1373
|
action: zod_1.z
|
|
1291
1374
|
.string()
|
|
1292
1375
|
.min(1)
|
|
1293
|
-
.describe("具体 Action 名称,需符合对应服务的官方 API 定义。若不确定正确 Action
|
|
1376
|
+
.describe("具体 Action 名称,需符合对应服务的官方 API 定义。若不确定正确 Action,请先查官方文档;不要用近义词或历史命名进行猜测。tcb 常用 Action:环境管理 CreateEnv/ModifyEnv/DescribeEnvs/DestroyEnv、用户管理 CreateUser/ModifyUser/DescribeUserList/DeleteUsers、认证配置 EditAuthConfig、云函数 DescribeFunctions/CreateFunction、数据库 CreateMySQLInstance 等。"),
|
|
1294
1377
|
params: zod_1.z
|
|
1295
1378
|
.record(zod_1.z.any())
|
|
1296
1379
|
.optional()
|
|
@@ -1426,7 +1509,7 @@ ${envIdSection}
|
|
|
1426
1509
|
## 环境信息
|
|
1427
1510
|
- 操作系统: ${os_1.default.type()} ${os_1.default.release()}
|
|
1428
1511
|
- Node.js版本: ${process.version}
|
|
1429
|
-
- MCP 版本:${process.env.npm_package_version || "2.
|
|
1512
|
+
- MCP 版本:${process.env.npm_package_version || "2.16.0-beta.1" || 0}
|
|
1430
1513
|
- 系统架构: ${os_1.default.arch()}
|
|
1431
1514
|
- 时间: ${new Date().toISOString()}
|
|
1432
1515
|
- 请求ID: ${requestId}
|
|
@@ -1637,10 +1720,14 @@ const cloudrun_js_1 = __webpack_require__(5023);
|
|
|
1637
1720
|
const dataModel_js_1 = __webpack_require__(4052);
|
|
1638
1721
|
const gateway_js_1 = __webpack_require__(4319);
|
|
1639
1722
|
const invite_code_js_1 = __webpack_require__(4760);
|
|
1640
|
-
const
|
|
1723
|
+
const agents_js_1 = __webpack_require__(9527);
|
|
1724
|
+
const app_auth_js_1 = __webpack_require__(5313);
|
|
1725
|
+
const apps_js_1 = __webpack_require__(6817);
|
|
1726
|
+
const logs_js_1 = __webpack_require__(2322);
|
|
1727
|
+
const permissions_js_1 = __webpack_require__(6485);
|
|
1641
1728
|
const cloud_mode_js_1 = __webpack_require__(9684);
|
|
1642
1729
|
const logger_js_1 = __webpack_require__(3039);
|
|
1643
|
-
const
|
|
1730
|
+
const tencent_cloud_js_1 = __webpack_require__(1454);
|
|
1644
1731
|
const tool_result_js_1 = __webpack_require__(9835);
|
|
1645
1732
|
const tool_wrapper_js_1 = __webpack_require__(1363);
|
|
1646
1733
|
// 默认插件列表
|
|
@@ -1654,15 +1741,18 @@ const DEFAULT_PLUGINS = [
|
|
|
1654
1741
|
"rag",
|
|
1655
1742
|
"cloudrun",
|
|
1656
1743
|
"gateway",
|
|
1744
|
+
"app-auth",
|
|
1745
|
+
"permissions",
|
|
1746
|
+
"logs",
|
|
1747
|
+
"agents",
|
|
1657
1748
|
"download",
|
|
1658
|
-
"security-rule",
|
|
1659
1749
|
"invite-code",
|
|
1660
1750
|
"capi",
|
|
1661
1751
|
];
|
|
1662
1752
|
function registerDatabase(server) {
|
|
1663
1753
|
// Skip NoSQL database tools for international region (Singapore) as it doesn't support NoSQL DB
|
|
1664
1754
|
const region = server.cloudBaseOptions?.region || process.env.TCB_REGION;
|
|
1665
|
-
if (!(0,
|
|
1755
|
+
if (!(0, tencent_cloud_js_1.isInternationalRegion)(region)) {
|
|
1666
1756
|
(0, databaseNoSQL_js_1.registerDatabaseTools)(server);
|
|
1667
1757
|
}
|
|
1668
1758
|
(0, databaseSQL_js_1.registerSQLDatabaseTools)(server);
|
|
@@ -1679,15 +1769,28 @@ const AVAILABLE_PLUGINS = {
|
|
|
1679
1769
|
rag: { name: "rag", register: rag_js_1.registerRagTools },
|
|
1680
1770
|
download: { name: "download", register: download_js_1.registerDownloadTools },
|
|
1681
1771
|
gateway: { name: "gateway", register: gateway_js_1.registerGatewayTools },
|
|
1682
|
-
|
|
1683
|
-
"
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
},
|
|
1772
|
+
"app-auth": { name: "app-auth", register: app_auth_js_1.registerAppAuthTools },
|
|
1773
|
+
permissions: { name: "permissions", register: permissions_js_1.registerPermissionTools },
|
|
1774
|
+
logs: { name: "logs", register: logs_js_1.registerLogTools },
|
|
1775
|
+
agents: { name: "agents", register: agents_js_1.registerAgentTools },
|
|
1776
|
+
apps: { name: "apps", register: apps_js_1.registerAppTools },
|
|
1687
1777
|
"invite-code": { name: "invite-code", register: invite_code_js_1.registerInviteCodeTools },
|
|
1688
1778
|
cloudrun: { name: "cloudrun", register: cloudrun_js_1.registerCloudRunTools },
|
|
1689
1779
|
capi: { name: "capi", register: capi_js_1.registerCapiTools },
|
|
1690
1780
|
};
|
|
1781
|
+
const PLUGIN_ALIASES = {
|
|
1782
|
+
"access-control": "permissions",
|
|
1783
|
+
"auth-config": "app-auth",
|
|
1784
|
+
"security-rule": "permissions",
|
|
1785
|
+
"security-rules": "permissions",
|
|
1786
|
+
"secret-rule": "permissions",
|
|
1787
|
+
"secret-rules": "permissions",
|
|
1788
|
+
users: "permissions",
|
|
1789
|
+
};
|
|
1790
|
+
function normalizePluginName(name) {
|
|
1791
|
+
const normalized = name.trim().toLowerCase().replace(/\s+/g, "-");
|
|
1792
|
+
return PLUGIN_ALIASES[normalized] ?? normalized;
|
|
1793
|
+
}
|
|
1691
1794
|
/**
|
|
1692
1795
|
* Parse enabled plugins list
|
|
1693
1796
|
* @param pluginsEnabled Optional array of enabled plugin names (takes precedence over env var)
|
|
@@ -1710,12 +1813,19 @@ function parseEnabledPlugins(pluginsEnabled, pluginsDisabled) {
|
|
|
1710
1813
|
}
|
|
1711
1814
|
const allDisabledPlugins = new Set();
|
|
1712
1815
|
if (disabledEnv) {
|
|
1713
|
-
disabledEnv
|
|
1816
|
+
disabledEnv
|
|
1817
|
+
.split(",")
|
|
1818
|
+
.map((p) => normalizePluginName(p))
|
|
1819
|
+
.forEach((p) => allDisabledPlugins.add(p));
|
|
1714
1820
|
}
|
|
1715
1821
|
if (pluginsDisabled && pluginsDisabled.length > 0) {
|
|
1716
|
-
pluginsDisabled
|
|
1822
|
+
pluginsDisabled
|
|
1823
|
+
.map((p) => normalizePluginName(p))
|
|
1824
|
+
.forEach((p) => allDisabledPlugins.add(p));
|
|
1717
1825
|
}
|
|
1718
|
-
enabledPlugins =
|
|
1826
|
+
enabledPlugins = Array.from(new Set(enabledPlugins
|
|
1827
|
+
.map((p) => normalizePluginName(p))
|
|
1828
|
+
.filter((p) => !allDisabledPlugins.has(p))));
|
|
1719
1829
|
return enabledPlugins;
|
|
1720
1830
|
}
|
|
1721
1831
|
/**
|
|
@@ -1823,6 +1933,26 @@ Object.defineProperty(exports, "reportToolkitLifecycle", ({ enumerable: true, ge
|
|
|
1823
1933
|
Object.defineProperty(exports, "telemetryReporter", ({ enumerable: true, get: function () { return telemetry_js_1.telemetryReporter; } }));
|
|
1824
1934
|
|
|
1825
1935
|
|
|
1936
|
+
/***/ }),
|
|
1937
|
+
|
|
1938
|
+
/***/ 1454:
|
|
1939
|
+
/***/ ((__unused_webpack_module, exports) => {
|
|
1940
|
+
|
|
1941
|
+
|
|
1942
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
1943
|
+
exports.isInternationalRegion = void 0;
|
|
1944
|
+
exports.isValidRegion = isValidRegion;
|
|
1945
|
+
const REGION = {
|
|
1946
|
+
SHANGHAI: 'ap-shanghai',
|
|
1947
|
+
SINGAPORE: 'ap-singapore',
|
|
1948
|
+
};
|
|
1949
|
+
const isInternationalRegion = (region) => region === REGION.SINGAPORE;
|
|
1950
|
+
exports.isInternationalRegion = isInternationalRegion;
|
|
1951
|
+
function isValidRegion(region) {
|
|
1952
|
+
return Object.values(REGION).includes(region);
|
|
1953
|
+
}
|
|
1954
|
+
|
|
1955
|
+
|
|
1826
1956
|
/***/ }),
|
|
1827
1957
|
|
|
1828
1958
|
/***/ 1622:
|
|
@@ -1837,6 +1967,90 @@ module.exports = __WEBPACK_EXTERNAL_MODULE_open__;
|
|
|
1837
1967
|
|
|
1838
1968
|
module.exports = __WEBPACK_EXTERNAL_MODULE__cloudbase_toolbox_034e5bd0__;
|
|
1839
1969
|
|
|
1970
|
+
/***/ }),
|
|
1971
|
+
|
|
1972
|
+
/***/ 2322:
|
|
1973
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
1974
|
+
|
|
1975
|
+
|
|
1976
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
1977
|
+
exports.registerLogTools = registerLogTools;
|
|
1978
|
+
const zod_1 = __webpack_require__(2971);
|
|
1979
|
+
const cloudbase_manager_js_1 = __webpack_require__(3431);
|
|
1980
|
+
const json_content_js_1 = __webpack_require__(4365);
|
|
1981
|
+
const QUERY_LOG_ACTIONS = ["checkLogService", "searchLogs"];
|
|
1982
|
+
function buildEnvelope(data, message) {
|
|
1983
|
+
return {
|
|
1984
|
+
success: true,
|
|
1985
|
+
data,
|
|
1986
|
+
message,
|
|
1987
|
+
};
|
|
1988
|
+
}
|
|
1989
|
+
function buildErrorEnvelope(error) {
|
|
1990
|
+
return {
|
|
1991
|
+
success: false,
|
|
1992
|
+
data: {},
|
|
1993
|
+
message: error instanceof Error ? error.message : String(error),
|
|
1994
|
+
};
|
|
1995
|
+
}
|
|
1996
|
+
function registerLogTools(server) {
|
|
1997
|
+
const cloudBaseOptions = server.cloudBaseOptions;
|
|
1998
|
+
const getManager = () => (0, cloudbase_manager_js_1.getCloudBaseManager)({ cloudBaseOptions });
|
|
1999
|
+
server.registerTool?.("queryLogs", {
|
|
2000
|
+
title: "查询日志服务",
|
|
2001
|
+
description: "日志域统一只读入口。支持检查日志服务状态并搜索 CLS 日志。",
|
|
2002
|
+
inputSchema: {
|
|
2003
|
+
action: zod_1.z.enum(QUERY_LOG_ACTIONS),
|
|
2004
|
+
queryString: zod_1.z.string().optional(),
|
|
2005
|
+
service: zod_1.z.enum(["tcb", "tcbr"]).optional(),
|
|
2006
|
+
startTime: zod_1.z.string().optional(),
|
|
2007
|
+
endTime: zod_1.z.string().optional(),
|
|
2008
|
+
limit: zod_1.z.number().optional(),
|
|
2009
|
+
context: zod_1.z.string().optional(),
|
|
2010
|
+
sort: zod_1.z.enum(["asc", "desc"]).optional(),
|
|
2011
|
+
},
|
|
2012
|
+
annotations: {
|
|
2013
|
+
readOnlyHint: true,
|
|
2014
|
+
openWorldHint: true,
|
|
2015
|
+
category: "logs",
|
|
2016
|
+
},
|
|
2017
|
+
}, async ({ action, queryString, service, startTime, endTime, limit, context, sort, }) => {
|
|
2018
|
+
try {
|
|
2019
|
+
const cloudbase = await getManager();
|
|
2020
|
+
if (action === "checkLogService") {
|
|
2021
|
+
const enabled = await cloudbase.log.checkLogServiceEnabled();
|
|
2022
|
+
return (0, json_content_js_1.jsonContent)(buildEnvelope({
|
|
2023
|
+
action,
|
|
2024
|
+
enabled,
|
|
2025
|
+
}, enabled ? "日志服务已开通" : "日志服务未开通或仍在初始化中"));
|
|
2026
|
+
}
|
|
2027
|
+
if (!queryString) {
|
|
2028
|
+
throw new Error("action=searchLogs 时必须提供 queryString");
|
|
2029
|
+
}
|
|
2030
|
+
const result = await cloudbase.log.searchClsLog({
|
|
2031
|
+
queryString,
|
|
2032
|
+
StartTime: startTime ?? "1970-01-01 00:00:00",
|
|
2033
|
+
EndTime: endTime ?? "2099-12-31 23:59:59",
|
|
2034
|
+
Limit: limit ?? 20,
|
|
2035
|
+
Context: context,
|
|
2036
|
+
Sort: sort,
|
|
2037
|
+
service,
|
|
2038
|
+
});
|
|
2039
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
2040
|
+
return (0, json_content_js_1.jsonContent)(buildEnvelope({
|
|
2041
|
+
action,
|
|
2042
|
+
queryString,
|
|
2043
|
+
results: result.LogResults ?? null,
|
|
2044
|
+
raw: result,
|
|
2045
|
+
}, "日志检索成功"));
|
|
2046
|
+
}
|
|
2047
|
+
catch (error) {
|
|
2048
|
+
return (0, json_content_js_1.jsonContent)(buildErrorEnvelope(error));
|
|
2049
|
+
}
|
|
2050
|
+
});
|
|
2051
|
+
}
|
|
2052
|
+
|
|
2053
|
+
|
|
1840
2054
|
/***/ }),
|
|
1841
2055
|
|
|
1842
2056
|
/***/ 2344:
|
|
@@ -3257,7 +3471,13 @@ async function getCloudBaseManager(options = {}) {
|
|
|
3257
3471
|
* @returns CloudBase manager instance
|
|
3258
3472
|
*/
|
|
3259
3473
|
function createCloudBaseManagerWithOptions(cloudBaseOptions) {
|
|
3260
|
-
(0, logger_js_1.debug)('Create manager with provided CloudBase options:',
|
|
3474
|
+
(0, logger_js_1.debug)('Create manager with provided CloudBase options:', {
|
|
3475
|
+
envId: cloudBaseOptions.envId,
|
|
3476
|
+
region: cloudBaseOptions.region,
|
|
3477
|
+
hasSecretId: !!cloudBaseOptions.secretId,
|
|
3478
|
+
hasSecretKey: !!cloudBaseOptions.secretKey,
|
|
3479
|
+
hasToken: !!cloudBaseOptions.token,
|
|
3480
|
+
});
|
|
3261
3481
|
// Region priority: cloudBaseOptions.region > process.env.TCB_REGION > undefined (use SDK default)
|
|
3262
3482
|
const region = cloudBaseOptions.region ?? process.env.TCB_REGION ?? undefined;
|
|
3263
3483
|
const manager = new manager_node_1.default({
|
|
@@ -3329,6 +3549,8 @@ const cloudbase_manager_js_1 = __webpack_require__(3431);
|
|
|
3329
3549
|
const CATEGORY = "NoSQL database";
|
|
3330
3550
|
const COLLECTION_READY_TIMEOUT_MS = 10000;
|
|
3331
3551
|
const COLLECTION_READY_POLL_INTERVAL_MS = 500;
|
|
3552
|
+
/** Convert object values to JSON strings for API calls */
|
|
3553
|
+
const toJSONString = (v) => typeof v === "object" && v !== null ? JSON.stringify(v) : v;
|
|
3332
3554
|
// 获取数据库实例ID
|
|
3333
3555
|
async function getDatabaseInstanceId(getManager) {
|
|
3334
3556
|
const cloudbase = await getManager();
|
|
@@ -3359,6 +3581,53 @@ function normalizeNoSqlDocuments(data) {
|
|
|
3359
3581
|
}
|
|
3360
3582
|
return data.map((item) => parseNoSqlDocument(item));
|
|
3361
3583
|
}
|
|
3584
|
+
function normalizeSortDirection(value) {
|
|
3585
|
+
if (value === 1) {
|
|
3586
|
+
return 1;
|
|
3587
|
+
}
|
|
3588
|
+
if (value === -1) {
|
|
3589
|
+
return -1;
|
|
3590
|
+
}
|
|
3591
|
+
throw new Error(`非法 sort direction: ${String(value)},仅支持 1 / -1`);
|
|
3592
|
+
}
|
|
3593
|
+
function normalizeSortItem(value) {
|
|
3594
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
3595
|
+
throw new Error("sort 数组项必须是 { key, direction } 对象");
|
|
3596
|
+
}
|
|
3597
|
+
const { key, direction } = value;
|
|
3598
|
+
if (typeof key !== "string" || key.trim() === "") {
|
|
3599
|
+
throw new Error("sort.key 必须是非空字符串");
|
|
3600
|
+
}
|
|
3601
|
+
return {
|
|
3602
|
+
key,
|
|
3603
|
+
direction: normalizeSortDirection(direction),
|
|
3604
|
+
};
|
|
3605
|
+
}
|
|
3606
|
+
function normalizeSortInput(sort) {
|
|
3607
|
+
if (sort === undefined || sort === null) {
|
|
3608
|
+
return undefined;
|
|
3609
|
+
}
|
|
3610
|
+
let parsed = sort;
|
|
3611
|
+
if (typeof parsed === "string") {
|
|
3612
|
+
const trimmed = parsed.trim();
|
|
3613
|
+
if (!trimmed) {
|
|
3614
|
+
return undefined;
|
|
3615
|
+
}
|
|
3616
|
+
try {
|
|
3617
|
+
parsed = JSON.parse(trimmed);
|
|
3618
|
+
}
|
|
3619
|
+
catch {
|
|
3620
|
+
throw new Error("sort 必须是 sort 数组的 JSON 字符串");
|
|
3621
|
+
}
|
|
3622
|
+
}
|
|
3623
|
+
if (!Array.isArray(parsed)) {
|
|
3624
|
+
throw new Error('sort 仅支持数组 [{"key":"createdAt","direction":-1}] 或对应 JSON 字符串');
|
|
3625
|
+
}
|
|
3626
|
+
if (parsed.length === 0) {
|
|
3627
|
+
return undefined;
|
|
3628
|
+
}
|
|
3629
|
+
return JSON.stringify(parsed.map((item) => normalizeSortItem(item)));
|
|
3630
|
+
}
|
|
3362
3631
|
function withCollectionName(collectionName, payload) {
|
|
3363
3632
|
return {
|
|
3364
3633
|
...payload,
|
|
@@ -3703,7 +3972,7 @@ deleteCollection: 删除集合`),
|
|
|
3703
3972
|
zod_1.z.string(),
|
|
3704
3973
|
])
|
|
3705
3974
|
.optional()
|
|
3706
|
-
.describe("
|
|
3975
|
+
.describe('排序条件,仅支持数组 [{"key":"createdAt","direction":-1}] 或对应 JSON 字符串。'),
|
|
3707
3976
|
limit: zod_1.z.number().optional().describe("返回数量限制"),
|
|
3708
3977
|
offset: zod_1.z.number().optional().describe("跳过的记录数"),
|
|
3709
3978
|
},
|
|
@@ -3715,14 +3984,14 @@ deleteCollection: 删除集合`),
|
|
|
3715
3984
|
}, async ({ collectionName, query, projection, sort, limit, offset }) => {
|
|
3716
3985
|
const cloudbase = await getManager();
|
|
3717
3986
|
const instanceId = await getDatabaseInstanceId(getManager);
|
|
3718
|
-
const
|
|
3987
|
+
const normalizedSort = normalizeSortInput(sort);
|
|
3719
3988
|
const result = await cloudbase.commonService("tcb", "2018-06-08").call({
|
|
3720
3989
|
Action: "QueryRecords",
|
|
3721
3990
|
Param: {
|
|
3722
3991
|
TableName: collectionName,
|
|
3723
3992
|
MgoQuery: toJSONString(query),
|
|
3724
3993
|
MgoProjection: toJSONString(projection),
|
|
3725
|
-
MgoSort:
|
|
3994
|
+
MgoSort: normalizedSort,
|
|
3726
3995
|
MgoLimit: limit ?? 100,
|
|
3727
3996
|
MgoOffset: offset,
|
|
3728
3997
|
Tag: instanceId,
|
|
@@ -3751,7 +4020,7 @@ deleteCollection: 删除集合`),
|
|
|
3751
4020
|
// writeNoSqlDatabaseContent
|
|
3752
4021
|
server.registerTool?.("writeNoSqlDatabaseContent", {
|
|
3753
4022
|
title: "修改 NoSQL 数据库数据记录",
|
|
3754
|
-
description: "修改 NoSQL 数据库数据记录。可按 MongoDB updateOne/updateMany 的心智模型理解:部分更新必须使用 $set/$inc/$push 等更新操作符;如果直接传 { field: value }
|
|
4023
|
+
description: "修改 NoSQL 数据库数据记录。可按 MongoDB updateOne/updateMany 的心智模型理解:部分更新必须使用 $set/$inc/$push 等更新操作符;如果直接传 { field: value } 这类普通对象,底层会把它当作替换内容,存在覆盖整条文档的风险。更新嵌套对象中的某个字段时必须使用点号路径(如 { \"$set\": { \"address.city\": \"shenzhen\" } }),若写成 { \"$set\": { \"address\": { \"city\": \"shenzhen\" } } } 则整个 address 对象会被替换,同级其他字段将丢失。",
|
|
3755
4024
|
inputSchema: {
|
|
3756
4025
|
action: zod_1.z
|
|
3757
4026
|
.enum(["insert", "update", "delete"])
|
|
@@ -3768,7 +4037,7 @@ deleteCollection: 删除集合`),
|
|
|
3768
4037
|
update: zod_1.z
|
|
3769
4038
|
.union([zod_1.z.object({}).passthrough(), zod_1.z.string()])
|
|
3770
4039
|
.optional()
|
|
3771
|
-
.describe("更新内容(对象或字符串,推荐对象)(update 操作必填)。按 MongoDB 更新语义传入 MgoUpdate:部分更新请使用 $set/$inc/$unset/$push 等操作符,例如 { \"$set\": { \"status\": \"pending\" } };不要直接传 { \"status\": \"pending\" }
|
|
4040
|
+
.describe("更新内容(对象或字符串,推荐对象)(update 操作必填)。按 MongoDB 更新语义传入 MgoUpdate:部分更新请使用 $set/$inc/$unset/$push 等操作符,例如 { \"$set\": { \"status\": \"pending\" } };不要直接传 { \"status\": \"pending\" },否则可能替换整条文档。更新嵌套字段时必须用点号路径,如 { \"$set\": { \"address.city\": \"shenzhen\" } },不要写成 { \"$set\": { \"address\": { \"city\": \"shenzhen\" } } }(会替换整个 address 对象)。"),
|
|
3772
4041
|
isMulti: zod_1.z
|
|
3773
4042
|
.boolean()
|
|
3774
4043
|
.optional()
|
|
@@ -3879,7 +4148,6 @@ async function insertDocuments({ collectionName, documents, getManager, logger,
|
|
|
3879
4148
|
async function updateDocuments({ collectionName, query, update, isMulti, upsert, getManager, logger, }) {
|
|
3880
4149
|
const cloudbase = await getManager();
|
|
3881
4150
|
const instanceId = await getDatabaseInstanceId(getManager);
|
|
3882
|
-
const toJSONString = (v) => typeof v === "object" && v !== null ? JSON.stringify(v) : v;
|
|
3883
4151
|
const result = await cloudbase.commonService("tcb", "2018-06-08").call({
|
|
3884
4152
|
Action: "UpdateItem",
|
|
3885
4153
|
Param: {
|
|
@@ -3904,7 +4172,6 @@ async function updateDocuments({ collectionName, query, update, isMulti, upsert,
|
|
|
3904
4172
|
async function deleteDocuments({ collectionName, query, isMulti, getManager, logger, }) {
|
|
3905
4173
|
const cloudbase = await getManager();
|
|
3906
4174
|
const instanceId = await getDatabaseInstanceId(getManager);
|
|
3907
|
-
const toJSONString = (v) => typeof v === "object" && v !== null ? JSON.stringify(v) : v;
|
|
3908
4175
|
const result = await cloudbase.commonService("tcb", "2018-06-08").call({
|
|
3909
4176
|
Action: "DeleteItem",
|
|
3910
4177
|
Param: {
|
|
@@ -5620,32 +5887,41 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
|
5620
5887
|
exports.registerGatewayTools = registerGatewayTools;
|
|
5621
5888
|
const zod_1 = __webpack_require__(2971);
|
|
5622
5889
|
const cloudbase_manager_js_1 = __webpack_require__(3431);
|
|
5890
|
+
const json_content_js_1 = __webpack_require__(4365);
|
|
5623
5891
|
const QUERY_GATEWAY_ACTIONS = [
|
|
5624
5892
|
"getAccess",
|
|
5625
5893
|
"listDomains",
|
|
5894
|
+
"listRoutes",
|
|
5895
|
+
"getRoute",
|
|
5896
|
+
"listCustomDomains",
|
|
5626
5897
|
];
|
|
5627
5898
|
const MANAGE_GATEWAY_ACTIONS = [
|
|
5628
5899
|
"createAccess",
|
|
5900
|
+
"createRoute",
|
|
5901
|
+
"updateRoute",
|
|
5902
|
+
"deleteRoute",
|
|
5903
|
+
"bindCustomDomain",
|
|
5904
|
+
"deleteCustomDomain",
|
|
5905
|
+
"deleteAccess",
|
|
5906
|
+
"updatePathAuth",
|
|
5629
5907
|
];
|
|
5630
|
-
function jsonContent(body) {
|
|
5631
|
-
return {
|
|
5632
|
-
content: [
|
|
5633
|
-
{
|
|
5634
|
-
type: "text",
|
|
5635
|
-
text: JSON.stringify(body, null, 2),
|
|
5636
|
-
},
|
|
5637
|
-
],
|
|
5638
|
-
};
|
|
5639
|
-
}
|
|
5640
5908
|
function normalizeAccessPath(path) {
|
|
5641
5909
|
if (!path) {
|
|
5642
5910
|
return "/";
|
|
5643
5911
|
}
|
|
5644
5912
|
return path.startsWith("/") ? path : `/${path}`;
|
|
5645
5913
|
}
|
|
5914
|
+
function ensureGatewayEnvId(cloudBaseOptions) {
|
|
5915
|
+
const envId = cloudBaseOptions?.envId;
|
|
5916
|
+
if (!envId) {
|
|
5917
|
+
throw new Error("当前网关操作需要已绑定 envId");
|
|
5918
|
+
}
|
|
5919
|
+
return envId;
|
|
5920
|
+
}
|
|
5646
5921
|
function registerGatewayTools(server) {
|
|
5647
5922
|
const cloudBaseOptions = server.cloudBaseOptions;
|
|
5648
5923
|
const getManager = () => (0, cloudbase_manager_js_1.getCloudBaseManager)({ cloudBaseOptions });
|
|
5924
|
+
const getGatewayEnvId = () => ensureGatewayEnvId(cloudBaseOptions);
|
|
5649
5925
|
const buildEnvelope = (data, message, nextActions) => ({
|
|
5650
5926
|
success: true,
|
|
5651
5927
|
data,
|
|
@@ -5659,10 +5935,10 @@ function registerGatewayTools(server) {
|
|
|
5659
5935
|
});
|
|
5660
5936
|
const withEnvelope = async (handler) => {
|
|
5661
5937
|
try {
|
|
5662
|
-
return jsonContent(await handler());
|
|
5938
|
+
return (0, json_content_js_1.jsonContent)(await handler());
|
|
5663
5939
|
}
|
|
5664
5940
|
catch (error) {
|
|
5665
|
-
return jsonContent(buildErrorEnvelope(error));
|
|
5941
|
+
return (0, json_content_js_1.jsonContent)(buildErrorEnvelope(error));
|
|
5666
5942
|
}
|
|
5667
5943
|
};
|
|
5668
5944
|
const listGatewayDomains = async () => {
|
|
@@ -5679,6 +5955,63 @@ function registerGatewayTools(server) {
|
|
|
5679
5955
|
raw: result,
|
|
5680
5956
|
};
|
|
5681
5957
|
};
|
|
5958
|
+
const listHttpServiceRoutes = async (domain) => {
|
|
5959
|
+
const cloudbase = await getManager();
|
|
5960
|
+
const result = await cloudbase.env.describeHttpServiceRoute({
|
|
5961
|
+
EnvId: getGatewayEnvId(),
|
|
5962
|
+
...(domain
|
|
5963
|
+
? {
|
|
5964
|
+
Filters: [
|
|
5965
|
+
{
|
|
5966
|
+
Name: "Domain",
|
|
5967
|
+
Values: [domain],
|
|
5968
|
+
},
|
|
5969
|
+
],
|
|
5970
|
+
}
|
|
5971
|
+
: {}),
|
|
5972
|
+
});
|
|
5973
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
5974
|
+
return result;
|
|
5975
|
+
};
|
|
5976
|
+
const flattenRoutes = (result) => (result.Domains ?? []).flatMap((domainItem) => (domainItem.Routes ?? []).map((route) => ({
|
|
5977
|
+
Domain: domainItem.Domain,
|
|
5978
|
+
DomainType: domainItem.DomainType,
|
|
5979
|
+
AccessType: domainItem.AccessType,
|
|
5980
|
+
...route,
|
|
5981
|
+
})));
|
|
5982
|
+
const resolveRouteDomain = async (preferredDomain) => {
|
|
5983
|
+
if (preferredDomain) {
|
|
5984
|
+
return preferredDomain;
|
|
5985
|
+
}
|
|
5986
|
+
const routeInfo = await listHttpServiceRoutes();
|
|
5987
|
+
return routeInfo.OriginDomain;
|
|
5988
|
+
};
|
|
5989
|
+
const normalizeRoutePayload = async (route, fallback, domain) => {
|
|
5990
|
+
const path = normalizeAccessPath(route?.path ?? fallback.path);
|
|
5991
|
+
const serviceType = route?.serviceType ?? fallback.targetType;
|
|
5992
|
+
const serviceName = route?.serviceName ?? fallback.targetName;
|
|
5993
|
+
if (!serviceType || !serviceName) {
|
|
5994
|
+
throw new Error("route.serviceType 和 route.serviceName 为必填项");
|
|
5995
|
+
}
|
|
5996
|
+
return {
|
|
5997
|
+
EnvId: getGatewayEnvId(),
|
|
5998
|
+
Domain: {
|
|
5999
|
+
Domain: await resolveRouteDomain(domain),
|
|
6000
|
+
Routes: [
|
|
6001
|
+
{
|
|
6002
|
+
Path: path,
|
|
6003
|
+
UpstreamResourceType: serviceType === "function" ? "SCF" : "CBR",
|
|
6004
|
+
UpstreamResourceName: serviceName,
|
|
6005
|
+
EnableAuth: route?.auth !== undefined
|
|
6006
|
+
? route.auth
|
|
6007
|
+
: fallback.auth !== undefined
|
|
6008
|
+
? fallback.auth
|
|
6009
|
+
: undefined,
|
|
6010
|
+
},
|
|
6011
|
+
],
|
|
6012
|
+
},
|
|
6013
|
+
};
|
|
6014
|
+
};
|
|
5682
6015
|
const handleQueryGateway = async (input) => {
|
|
5683
6016
|
switch (input.action) {
|
|
5684
6017
|
case "listDomains": {
|
|
@@ -5696,6 +6029,36 @@ function registerGatewayTools(server) {
|
|
|
5696
6029
|
},
|
|
5697
6030
|
]);
|
|
5698
6031
|
}
|
|
6032
|
+
case "listCustomDomains": {
|
|
6033
|
+
const result = await listGatewayDomains();
|
|
6034
|
+
return buildEnvelope({
|
|
6035
|
+
action: input.action,
|
|
6036
|
+
domains: result.raw.ServiceSet ?? [],
|
|
6037
|
+
total: (result.raw.ServiceSet ?? []).length,
|
|
6038
|
+
raw: result.raw,
|
|
6039
|
+
}, `已获取 ${(result.raw.ServiceSet ?? []).length} 个自定义域名`);
|
|
6040
|
+
}
|
|
6041
|
+
case "listRoutes": {
|
|
6042
|
+
const result = await listHttpServiceRoutes();
|
|
6043
|
+
const routes = flattenRoutes(result);
|
|
6044
|
+
return buildEnvelope({
|
|
6045
|
+
action: input.action,
|
|
6046
|
+
routes,
|
|
6047
|
+
total: result.TotalCount ?? routes.length,
|
|
6048
|
+
raw: result,
|
|
6049
|
+
}, `已获取 ${result.TotalCount ?? routes.length} 条 HTTP 路由`);
|
|
6050
|
+
}
|
|
6051
|
+
case "getRoute": {
|
|
6052
|
+
const result = await listHttpServiceRoutes();
|
|
6053
|
+
const route = flattenRoutes(result).find((item) => (input.routeId && item.RouteId === input.routeId) ||
|
|
6054
|
+
(input.targetName && item.UpstreamResourceName === input.targetName)) ?? null;
|
|
6055
|
+
return buildEnvelope({
|
|
6056
|
+
action: input.action,
|
|
6057
|
+
routeId: input.routeId ?? null,
|
|
6058
|
+
route,
|
|
6059
|
+
raw: result,
|
|
6060
|
+
}, route ? "已获取路由详情" : "未找到对应路由");
|
|
6061
|
+
}
|
|
5699
6062
|
case "getAccess": {
|
|
5700
6063
|
if (!input.targetName) {
|
|
5701
6064
|
throw new Error("getAccess 操作时,targetName 参数是必需的");
|
|
@@ -5738,6 +6101,9 @@ function registerGatewayTools(server) {
|
|
|
5738
6101
|
const handleManageGateway = async (input) => {
|
|
5739
6102
|
switch (input.action) {
|
|
5740
6103
|
case "createAccess": {
|
|
6104
|
+
if (!input.targetName || !input.targetType) {
|
|
6105
|
+
throw new Error("action=createAccess 时必须提供 targetType 和 targetName");
|
|
6106
|
+
}
|
|
5741
6107
|
const cloudbase = await getManager();
|
|
5742
6108
|
const accessPath = normalizeAccessPath(input.path || `/${input.targetName}`);
|
|
5743
6109
|
const result = await cloudbase.access.createAccess({
|
|
@@ -5761,6 +6127,128 @@ function registerGatewayTools(server) {
|
|
|
5761
6127
|
},
|
|
5762
6128
|
]);
|
|
5763
6129
|
}
|
|
6130
|
+
case "createRoute": {
|
|
6131
|
+
const cloudbase = await getManager();
|
|
6132
|
+
const result = await cloudbase.env.createHttpServiceRoute((await normalizeRoutePayload(input.route, input, input.domain)));
|
|
6133
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
6134
|
+
return buildEnvelope({
|
|
6135
|
+
action: input.action,
|
|
6136
|
+
route: input.route ?? null,
|
|
6137
|
+
raw: result,
|
|
6138
|
+
}, "HTTP 路由创建成功");
|
|
6139
|
+
}
|
|
6140
|
+
case "updateRoute": {
|
|
6141
|
+
const cloudbase = await getManager();
|
|
6142
|
+
const result = await cloudbase.env.modifyHttpServiceRoute((await normalizeRoutePayload(input.route, input, input.domain)));
|
|
6143
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
6144
|
+
return buildEnvelope({
|
|
6145
|
+
action: input.action,
|
|
6146
|
+
route: input.route ?? null,
|
|
6147
|
+
raw: result,
|
|
6148
|
+
}, "HTTP 路由更新成功");
|
|
6149
|
+
}
|
|
6150
|
+
case "deleteRoute": {
|
|
6151
|
+
const routePath = input.route?.path ?? input.path;
|
|
6152
|
+
if (!routePath) {
|
|
6153
|
+
throw new Error("action=deleteRoute 时必须提供 route.path 或 path");
|
|
6154
|
+
}
|
|
6155
|
+
const cloudbase = await getManager();
|
|
6156
|
+
const domain = await resolveRouteDomain(input.domain);
|
|
6157
|
+
const result = await cloudbase.env.deleteHttpServiceRoute({
|
|
6158
|
+
EnvId: getGatewayEnvId(),
|
|
6159
|
+
Domain: domain,
|
|
6160
|
+
Paths: [normalizeAccessPath(routePath)],
|
|
6161
|
+
});
|
|
6162
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
6163
|
+
return buildEnvelope({
|
|
6164
|
+
action: input.action,
|
|
6165
|
+
domain,
|
|
6166
|
+
path: normalizeAccessPath(routePath),
|
|
6167
|
+
raw: result,
|
|
6168
|
+
}, "HTTP 路由删除成功");
|
|
6169
|
+
}
|
|
6170
|
+
case "bindCustomDomain": {
|
|
6171
|
+
if (!input.domain || !input.certificateId) {
|
|
6172
|
+
throw new Error("action=bindCustomDomain 时必须提供 domain 和 certificateId");
|
|
6173
|
+
}
|
|
6174
|
+
const cloudbase = await getManager();
|
|
6175
|
+
const result = await cloudbase.env.bindCustomDomain({
|
|
6176
|
+
EnvId: getGatewayEnvId(),
|
|
6177
|
+
Domain: {
|
|
6178
|
+
Domain: input.domain,
|
|
6179
|
+
CertId: input.certificateId,
|
|
6180
|
+
},
|
|
6181
|
+
});
|
|
6182
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
6183
|
+
return buildEnvelope({
|
|
6184
|
+
action: input.action,
|
|
6185
|
+
domain: input.domain,
|
|
6186
|
+
certificateId: input.certificateId,
|
|
6187
|
+
raw: result,
|
|
6188
|
+
}, "自定义域名绑定成功");
|
|
6189
|
+
}
|
|
6190
|
+
case "deleteCustomDomain": {
|
|
6191
|
+
if (!input.domain) {
|
|
6192
|
+
throw new Error("action=deleteCustomDomain 时必须提供 domain");
|
|
6193
|
+
}
|
|
6194
|
+
const cloudbase = await getManager();
|
|
6195
|
+
const result = await cloudbase.env.deleteCustomDomain({
|
|
6196
|
+
EnvId: getGatewayEnvId(),
|
|
6197
|
+
Domain: input.domain,
|
|
6198
|
+
});
|
|
6199
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
6200
|
+
return buildEnvelope({
|
|
6201
|
+
action: input.action,
|
|
6202
|
+
domain: input.domain,
|
|
6203
|
+
raw: result,
|
|
6204
|
+
}, "自定义域名删除成功");
|
|
6205
|
+
}
|
|
6206
|
+
case "deleteAccess": {
|
|
6207
|
+
const cloudbase = await getManager();
|
|
6208
|
+
const accessPath = input.path ? normalizeAccessPath(input.path) : undefined;
|
|
6209
|
+
const result = await cloudbase.access.deleteAccess({
|
|
6210
|
+
...(input.targetName ? { name: input.targetName } : {}),
|
|
6211
|
+
...(accessPath ? { path: accessPath } : {}),
|
|
6212
|
+
});
|
|
6213
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
6214
|
+
return buildEnvelope({
|
|
6215
|
+
action: input.action,
|
|
6216
|
+
targetName: input.targetName ?? null,
|
|
6217
|
+
path: accessPath ?? null,
|
|
6218
|
+
raw: result,
|
|
6219
|
+
}, "网关访问入口删除成功");
|
|
6220
|
+
}
|
|
6221
|
+
case "updatePathAuth": {
|
|
6222
|
+
if (!input.targetName && !input.path) {
|
|
6223
|
+
throw new Error("action=updatePathAuth 时至少需要提供 targetName 或 path");
|
|
6224
|
+
}
|
|
6225
|
+
if (input.auth === undefined) {
|
|
6226
|
+
throw new Error("action=updatePathAuth 时必须提供 auth");
|
|
6227
|
+
}
|
|
6228
|
+
const cloudbase = await getManager();
|
|
6229
|
+
const accessPath = input.path ? normalizeAccessPath(input.path) : undefined;
|
|
6230
|
+
const accessList = await cloudbase.access.getAccessList({
|
|
6231
|
+
...(input.targetName ? { name: input.targetName } : {}),
|
|
6232
|
+
...(accessPath ? { path: accessPath } : {}),
|
|
6233
|
+
});
|
|
6234
|
+
const apiIds = (accessList.APISet ?? []).map((item) => item.APIId).filter(Boolean);
|
|
6235
|
+
if (apiIds.length === 0) {
|
|
6236
|
+
throw new Error("未找到可更新鉴权状态的访问入口");
|
|
6237
|
+
}
|
|
6238
|
+
const result = await cloudbase.access.switchPathAuth({
|
|
6239
|
+
apiIds,
|
|
6240
|
+
auth: input.auth,
|
|
6241
|
+
});
|
|
6242
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
6243
|
+
return buildEnvelope({
|
|
6244
|
+
action: input.action,
|
|
6245
|
+
targetName: input.targetName ?? null,
|
|
6246
|
+
path: accessPath ?? null,
|
|
6247
|
+
auth: input.auth,
|
|
6248
|
+
apiIds,
|
|
6249
|
+
raw: result,
|
|
6250
|
+
}, "网关路径鉴权更新成功");
|
|
6251
|
+
}
|
|
5764
6252
|
default:
|
|
5765
6253
|
throw new Error(`不支持的操作类型: ${input.action}`);
|
|
5766
6254
|
}
|
|
@@ -5780,6 +6268,7 @@ function registerGatewayTools(server) {
|
|
|
5780
6268
|
.string()
|
|
5781
6269
|
.optional()
|
|
5782
6270
|
.describe("目标资源名称。getAccess 时必填"),
|
|
6271
|
+
routeId: zod_1.z.string().optional().describe("路由 ID。getRoute 时可选"),
|
|
5783
6272
|
},
|
|
5784
6273
|
annotations: {
|
|
5785
6274
|
readOnlyHint: true,
|
|
@@ -5794,11 +6283,25 @@ function registerGatewayTools(server) {
|
|
|
5794
6283
|
action: zod_1.z.enum(MANAGE_GATEWAY_ACTIONS).describe("写操作类型,例如 createAccess"),
|
|
5795
6284
|
targetType: zod_1.z
|
|
5796
6285
|
.enum(["function"])
|
|
6286
|
+
.optional()
|
|
5797
6287
|
.describe("目标资源类型。当前支持 function,后续可扩展"),
|
|
5798
|
-
targetName: zod_1.z.string().describe("目标资源名称"),
|
|
6288
|
+
targetName: zod_1.z.string().optional().describe("目标资源名称"),
|
|
5799
6289
|
path: zod_1.z.string().optional().describe("访问路径,默认 /{targetName}"),
|
|
5800
6290
|
type: zod_1.z.enum(["Event", "HTTP"]).optional().describe("函数接入类型"),
|
|
5801
6291
|
auth: zod_1.z.boolean().optional().describe("是否开启鉴权"),
|
|
6292
|
+
route: zod_1.z
|
|
6293
|
+
.object({
|
|
6294
|
+
routeId: zod_1.z.string().optional(),
|
|
6295
|
+
path: zod_1.z.string().optional(),
|
|
6296
|
+
serviceType: zod_1.z.string().optional(),
|
|
6297
|
+
serviceName: zod_1.z.string().optional(),
|
|
6298
|
+
auth: zod_1.z.boolean().optional(),
|
|
6299
|
+
})
|
|
6300
|
+
.optional()
|
|
6301
|
+
.describe("HTTP 路由配置对象"),
|
|
6302
|
+
domain: zod_1.z.string().optional().describe("自定义域名"),
|
|
6303
|
+
certificateId: zod_1.z.string().optional().describe("证书 ID"),
|
|
6304
|
+
accessName: zod_1.z.string().optional().describe("访问入口名称,保留字段"),
|
|
5802
6305
|
},
|
|
5803
6306
|
annotations: {
|
|
5804
6307
|
readOnlyHint: false,
|
|
@@ -5818,6 +6321,26 @@ function registerGatewayTools(server) {
|
|
|
5818
6321
|
|
|
5819
6322
|
module.exports = __WEBPACK_EXTERNAL_MODULE_net__;
|
|
5820
6323
|
|
|
6324
|
+
/***/ }),
|
|
6325
|
+
|
|
6326
|
+
/***/ 4365:
|
|
6327
|
+
/***/ ((__unused_webpack_module, exports) => {
|
|
6328
|
+
|
|
6329
|
+
|
|
6330
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
6331
|
+
exports.jsonContent = jsonContent;
|
|
6332
|
+
function jsonContent(body) {
|
|
6333
|
+
return {
|
|
6334
|
+
content: [
|
|
6335
|
+
{
|
|
6336
|
+
type: "text",
|
|
6337
|
+
text: JSON.stringify(body, null, 2),
|
|
6338
|
+
},
|
|
6339
|
+
],
|
|
6340
|
+
};
|
|
6341
|
+
}
|
|
6342
|
+
|
|
6343
|
+
|
|
5821
6344
|
/***/ }),
|
|
5822
6345
|
|
|
5823
6346
|
/***/ 4421:
|
|
@@ -6152,33 +6675,13 @@ function registerStorageTools(server) {
|
|
|
6152
6675
|
|
|
6153
6676
|
/***/ }),
|
|
6154
6677
|
|
|
6155
|
-
/***/
|
|
6156
|
-
/***/ ((__unused_webpack_module, exports)
|
|
6678
|
+
/***/ 5023:
|
|
6679
|
+
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
6157
6680
|
|
|
6158
6681
|
|
|
6159
|
-
|
|
6160
|
-
|
|
6161
|
-
|
|
6162
|
-
const REGION = {
|
|
6163
|
-
SHANGHAI: 'ap-shanghai',
|
|
6164
|
-
SINGAPORE: 'ap-singapore',
|
|
6165
|
-
};
|
|
6166
|
-
const isInternationalRegion = (region) => region === REGION.SINGAPORE;
|
|
6167
|
-
exports.isInternationalRegion = isInternationalRegion;
|
|
6168
|
-
function isValidRegion(region) {
|
|
6169
|
-
return Object.values(REGION).includes(region);
|
|
6170
|
-
}
|
|
6171
|
-
|
|
6172
|
-
|
|
6173
|
-
/***/ }),
|
|
6174
|
-
|
|
6175
|
-
/***/ 5023:
|
|
6176
|
-
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
6177
|
-
|
|
6178
|
-
|
|
6179
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6180
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
6181
|
-
};
|
|
6682
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6683
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
6684
|
+
};
|
|
6182
6685
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
6183
6686
|
exports.CLOUDRUN_ACCESS_TYPES = exports.CLOUDRUN_SERVICE_TYPES = void 0;
|
|
6184
6687
|
exports.registerCloudRunTools = registerCloudRunTools;
|
|
@@ -6187,6 +6690,7 @@ const fs_1 = __importDefault(__webpack_require__(4421));
|
|
|
6187
6690
|
const path_1 = __importDefault(__webpack_require__(2521));
|
|
6188
6691
|
const zod_1 = __webpack_require__(2971);
|
|
6189
6692
|
const cloudbase_manager_js_1 = __webpack_require__(3431);
|
|
6693
|
+
const logger_js_1 = __webpack_require__(3039);
|
|
6190
6694
|
const notification_js_1 = __webpack_require__(2720);
|
|
6191
6695
|
// CloudRun service types
|
|
6192
6696
|
exports.CLOUDRUN_SERVICE_TYPES = ['function', 'container'];
|
|
@@ -6289,9 +6793,10 @@ function checkIfAgentProject(projectPath) {
|
|
|
6289
6793
|
*/
|
|
6290
6794
|
function validateAndNormalizePath(inputPath) {
|
|
6291
6795
|
let normalizedPath = path_1.default.resolve(inputPath);
|
|
6292
|
-
//
|
|
6796
|
+
// Security check - ensure path is within current working directory
|
|
6293
6797
|
const cwd = process.cwd();
|
|
6294
|
-
|
|
6798
|
+
const prefix = cwd.endsWith(path_1.default.sep) ? cwd : cwd + path_1.default.sep;
|
|
6799
|
+
if (!normalizedPath.startsWith(prefix) && normalizedPath !== cwd) {
|
|
6295
6800
|
throw new Error(`Path must be within current working directory: ${cwd}`);
|
|
6296
6801
|
}
|
|
6297
6802
|
return normalizedPath;
|
|
@@ -6690,7 +7195,7 @@ for await (let x of res.textStream) {
|
|
|
6690
7195
|
fs_1.default.writeFileSync(cloudbasercPath, JSON.stringify(cloudbasercContent, null, 2));
|
|
6691
7196
|
}
|
|
6692
7197
|
catch (error) {
|
|
6693
|
-
|
|
7198
|
+
(0, logger_js_1.debug)('cloudbaserc.json creation skipped:', error instanceof Error ? error : new Error(String(error)));
|
|
6694
7199
|
}
|
|
6695
7200
|
// Send deployment notification to CodeBuddy IDE
|
|
6696
7201
|
try {
|
|
@@ -6817,39 +7322,34 @@ for await (let x of res.textStream) {
|
|
|
6817
7322
|
};
|
|
6818
7323
|
// Choose execution method based on run mode
|
|
6819
7324
|
let child;
|
|
6820
|
-
|
|
7325
|
+
const script = `const { runCLI } = require('@cloudbase/functions-framework'); runCLI();`;
|
|
6821
7326
|
if (runMode === 'agent') {
|
|
6822
|
-
|
|
6823
|
-
|
|
6824
|
-
|
|
6825
|
-
|
|
6826
|
-
|
|
6827
|
-
|
|
6828
|
-
|
|
6829
|
-
|
|
6830
|
-
|
|
6831
|
-
runCLI();
|
|
6832
|
-
"`;
|
|
6833
|
-
child = (0, child_process_1.spawn)(process.execPath, ['-e', command], {
|
|
7327
|
+
const childEnv = {
|
|
7328
|
+
...env,
|
|
7329
|
+
PORT: String(runPort),
|
|
7330
|
+
ENABLE_CORS: 'true',
|
|
7331
|
+
ALLOWED_ORIGINS: '*',
|
|
7332
|
+
RUN_MODE: 'agent',
|
|
7333
|
+
...extraEnv,
|
|
7334
|
+
};
|
|
7335
|
+
child = (0, child_process_1.spawn)(process.execPath, ['-e', script], {
|
|
6834
7336
|
cwd: targetPath,
|
|
6835
|
-
env,
|
|
7337
|
+
env: childEnv,
|
|
6836
7338
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
6837
7339
|
detached: true
|
|
6838
7340
|
});
|
|
6839
7341
|
}
|
|
6840
7342
|
else {
|
|
6841
|
-
|
|
6842
|
-
|
|
6843
|
-
|
|
6844
|
-
|
|
6845
|
-
|
|
6846
|
-
|
|
6847
|
-
|
|
6848
|
-
|
|
6849
|
-
"`;
|
|
6850
|
-
child = (0, child_process_1.spawn)(process.execPath, ['-e', command], {
|
|
7343
|
+
const childEnv = {
|
|
7344
|
+
...env,
|
|
7345
|
+
PORT: String(runPort),
|
|
7346
|
+
ENABLE_CORS: 'true',
|
|
7347
|
+
ALLOWED_ORIGINS: '*',
|
|
7348
|
+
...extraEnv,
|
|
7349
|
+
};
|
|
7350
|
+
child = (0, child_process_1.spawn)(process.execPath, ['-e', script], {
|
|
6851
7351
|
cwd: targetPath,
|
|
6852
|
-
env,
|
|
7352
|
+
env: childEnv,
|
|
6853
7353
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
6854
7354
|
detached: true
|
|
6855
7355
|
});
|
|
@@ -6879,7 +7379,7 @@ for await (let x of res.textStream) {
|
|
|
6879
7379
|
port: runPort,
|
|
6880
7380
|
runMode: runMode,
|
|
6881
7381
|
isAgent: isAgent,
|
|
6882
|
-
command:
|
|
7382
|
+
command: script,
|
|
6883
7383
|
cwd: targetPath
|
|
6884
7384
|
},
|
|
6885
7385
|
message: `Started local run for ${runMode} service '${input.serverName}' on port ${runPort} (pid=${child.pid})`
|
|
@@ -6909,7 +7409,7 @@ for await (let x of res.textStream) {
|
|
|
6909
7409
|
fs_1.default.writeFileSync(cloudbasercPath, JSON.stringify(cloudbasercContent, null, 2));
|
|
6910
7410
|
}
|
|
6911
7411
|
catch (error) {
|
|
6912
|
-
|
|
7412
|
+
(0, logger_js_1.debug)('cloudbaserc.json creation skipped:', error instanceof Error ? error : new Error(String(error)));
|
|
6913
7413
|
}
|
|
6914
7414
|
return {
|
|
6915
7415
|
content: [
|
|
@@ -6985,7 +7485,7 @@ for await (let x of res.textStream) {
|
|
|
6985
7485
|
fs_1.default.writeFileSync(cloudbasercPath, JSON.stringify(cloudbasercContent, null, 2));
|
|
6986
7486
|
}
|
|
6987
7487
|
catch (error) {
|
|
6988
|
-
|
|
7488
|
+
(0, logger_js_1.debug)('cloudbaserc.json creation skipped:', error instanceof Error ? error : new Error(String(error)));
|
|
6989
7489
|
}
|
|
6990
7490
|
return {
|
|
6991
7491
|
content: [
|
|
@@ -7013,6 +7513,290 @@ for await (let x of res.textStream) {
|
|
|
7013
7513
|
}
|
|
7014
7514
|
|
|
7015
7515
|
|
|
7516
|
+
/***/ }),
|
|
7517
|
+
|
|
7518
|
+
/***/ 5313:
|
|
7519
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
7520
|
+
|
|
7521
|
+
|
|
7522
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
7523
|
+
exports.registerAppAuthTools = registerAppAuthTools;
|
|
7524
|
+
const zod_1 = __webpack_require__(2971);
|
|
7525
|
+
const cloudbase_manager_js_1 = __webpack_require__(3431);
|
|
7526
|
+
const json_content_js_1 = __webpack_require__(4365);
|
|
7527
|
+
const QUERY_APP_AUTH_ACTIONS = [
|
|
7528
|
+
"getLoginConfig",
|
|
7529
|
+
"listProviders",
|
|
7530
|
+
"getProvider",
|
|
7531
|
+
"getClientConfig",
|
|
7532
|
+
"listApiKeyTokens",
|
|
7533
|
+
"getStaticDomain",
|
|
7534
|
+
];
|
|
7535
|
+
const MANAGE_APP_AUTH_ACTIONS = [
|
|
7536
|
+
"updateLoginConfig",
|
|
7537
|
+
"updateProvider",
|
|
7538
|
+
"updateClientConfig",
|
|
7539
|
+
"createApiKeyToken",
|
|
7540
|
+
"createCustomLoginKeys",
|
|
7541
|
+
];
|
|
7542
|
+
function buildEnvelope(data, message) {
|
|
7543
|
+
return {
|
|
7544
|
+
success: true,
|
|
7545
|
+
data,
|
|
7546
|
+
message,
|
|
7547
|
+
};
|
|
7548
|
+
}
|
|
7549
|
+
function buildErrorEnvelope(error) {
|
|
7550
|
+
return {
|
|
7551
|
+
success: false,
|
|
7552
|
+
data: {},
|
|
7553
|
+
message: error instanceof Error ? error.message : String(error),
|
|
7554
|
+
};
|
|
7555
|
+
}
|
|
7556
|
+
function normalizePlainObject(value, label) {
|
|
7557
|
+
if (value === undefined) {
|
|
7558
|
+
return undefined;
|
|
7559
|
+
}
|
|
7560
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
7561
|
+
throw new Error(`${label} 必须是对象`);
|
|
7562
|
+
}
|
|
7563
|
+
return value;
|
|
7564
|
+
}
|
|
7565
|
+
function extractLoginStrategyState(value) {
|
|
7566
|
+
const source = normalizePlainObject(value, "loginStrategy") ?? {};
|
|
7567
|
+
const data = normalizePlainObject(source.Data, "loginStrategy.Data") ?? source;
|
|
7568
|
+
return {
|
|
7569
|
+
PhoneNumberLogin: Boolean(data.PhoneNumberLogin ?? data.PhoneLogin ?? false),
|
|
7570
|
+
EmailLogin: Boolean(data.EmailLogin ?? false),
|
|
7571
|
+
AnonymousLogin: Boolean(data.AnonymousLogin ?? false),
|
|
7572
|
+
UserNameLogin: Boolean(data.UserNameLogin ?? data.UsernameLogin ?? false),
|
|
7573
|
+
...(data.SmsVerificationConfig ? { SmsVerificationConfig: data.SmsVerificationConfig } : {}),
|
|
7574
|
+
...(typeof data.Mfa === "boolean" ? { Mfa: data.Mfa } : {}),
|
|
7575
|
+
...(data.MfaConfig ? { MfaConfig: data.MfaConfig } : {}),
|
|
7576
|
+
...(data.PwdUpdateStrategy ? { PwdUpdateStrategy: data.PwdUpdateStrategy } : {}),
|
|
7577
|
+
};
|
|
7578
|
+
}
|
|
7579
|
+
function normalizeLoginConfigPatch(value) {
|
|
7580
|
+
const { PhoneLogin, UsernameLogin, ...rest } = value;
|
|
7581
|
+
return {
|
|
7582
|
+
...rest,
|
|
7583
|
+
...(typeof PhoneLogin === "boolean" ? { PhoneNumberLogin: PhoneLogin } : {}),
|
|
7584
|
+
...(typeof UsernameLogin === "boolean" ? { UserNameLogin: UsernameLogin } : {}),
|
|
7585
|
+
};
|
|
7586
|
+
}
|
|
7587
|
+
function registerAppAuthTools(server) {
|
|
7588
|
+
const cloudBaseOptions = server.cloudBaseOptions;
|
|
7589
|
+
const getManager = () => (0, cloudbase_manager_js_1.getCloudBaseManager)({ cloudBaseOptions });
|
|
7590
|
+
const withEnvelope = async (handler) => {
|
|
7591
|
+
try {
|
|
7592
|
+
return (0, json_content_js_1.jsonContent)(await handler());
|
|
7593
|
+
}
|
|
7594
|
+
catch (error) {
|
|
7595
|
+
return (0, json_content_js_1.jsonContent)(buildErrorEnvelope(error));
|
|
7596
|
+
}
|
|
7597
|
+
};
|
|
7598
|
+
const callControlPlaneAction = async (action, params) => {
|
|
7599
|
+
const cloudbase = await getManager();
|
|
7600
|
+
const service = cloudbase.commonService("tcb", "2018-06-08");
|
|
7601
|
+
const result = await service.call({
|
|
7602
|
+
Action: action,
|
|
7603
|
+
Param: params ?? {},
|
|
7604
|
+
});
|
|
7605
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
7606
|
+
return result;
|
|
7607
|
+
};
|
|
7608
|
+
server.registerTool?.("queryAppAuth", {
|
|
7609
|
+
title: "查询应用认证配置",
|
|
7610
|
+
description: "应用侧认证配置只读入口。用于查询登录方式、provider、publishable key、client 配置和静态域名等认证准备状态。",
|
|
7611
|
+
inputSchema: {
|
|
7612
|
+
action: zod_1.z.enum(QUERY_APP_AUTH_ACTIONS),
|
|
7613
|
+
providerId: zod_1.z.string().optional().describe("provider 标识,如 email、google"),
|
|
7614
|
+
},
|
|
7615
|
+
annotations: {
|
|
7616
|
+
readOnlyHint: true,
|
|
7617
|
+
openWorldHint: true,
|
|
7618
|
+
category: "auth",
|
|
7619
|
+
},
|
|
7620
|
+
}, async ({ action, providerId, }) => withEnvelope(async () => {
|
|
7621
|
+
const envId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
7622
|
+
const cloudbase = await getManager();
|
|
7623
|
+
switch (action) {
|
|
7624
|
+
case "getLoginConfig": {
|
|
7625
|
+
// Manager SDK v5 provides a dedicated helper for login config.
|
|
7626
|
+
const result = await cloudbase.env.getLoginConfigListV2();
|
|
7627
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
7628
|
+
return buildEnvelope({
|
|
7629
|
+
action,
|
|
7630
|
+
envId,
|
|
7631
|
+
loginConfig: result,
|
|
7632
|
+
}, "应用登录配置查询成功");
|
|
7633
|
+
}
|
|
7634
|
+
case "listProviders": {
|
|
7635
|
+
const result = await callControlPlaneAction("GetProviders", {
|
|
7636
|
+
EnvId: envId,
|
|
7637
|
+
});
|
|
7638
|
+
return buildEnvelope({
|
|
7639
|
+
action,
|
|
7640
|
+
envId,
|
|
7641
|
+
providers: result.Providers ?? result.ProviderList ?? result.Data ?? result,
|
|
7642
|
+
raw: result,
|
|
7643
|
+
}, "应用 provider 列表查询成功");
|
|
7644
|
+
}
|
|
7645
|
+
case "getProvider": {
|
|
7646
|
+
if (!providerId) {
|
|
7647
|
+
throw new Error("action=getProvider 时必须提供 providerId");
|
|
7648
|
+
}
|
|
7649
|
+
const result = await callControlPlaneAction("GetProviders", {
|
|
7650
|
+
EnvId: envId,
|
|
7651
|
+
});
|
|
7652
|
+
const providers = (result.Providers ??
|
|
7653
|
+
result.ProviderList ??
|
|
7654
|
+
result.Data ??
|
|
7655
|
+
[]);
|
|
7656
|
+
const provider = providers.find((item) => item.Id === providerId || item.id === providerId) ?? null;
|
|
7657
|
+
return buildEnvelope({
|
|
7658
|
+
action,
|
|
7659
|
+
envId,
|
|
7660
|
+
providerId,
|
|
7661
|
+
provider,
|
|
7662
|
+
raw: result,
|
|
7663
|
+
}, `应用 provider ${providerId} 查询成功`);
|
|
7664
|
+
}
|
|
7665
|
+
case "getClientConfig": {
|
|
7666
|
+
const result = await callControlPlaneAction("DescribeClient", {
|
|
7667
|
+
EnvId: envId,
|
|
7668
|
+
});
|
|
7669
|
+
return buildEnvelope({
|
|
7670
|
+
action,
|
|
7671
|
+
envId,
|
|
7672
|
+
clientConfig: result,
|
|
7673
|
+
}, "应用 client 配置查询成功");
|
|
7674
|
+
}
|
|
7675
|
+
case "listApiKeyTokens": {
|
|
7676
|
+
const result = await callControlPlaneAction("DescribeApiKeyTokens", {
|
|
7677
|
+
EnvId: envId,
|
|
7678
|
+
});
|
|
7679
|
+
return buildEnvelope({
|
|
7680
|
+
action,
|
|
7681
|
+
envId,
|
|
7682
|
+
apiKeyTokens: result.ApiKeyTokens ?? result.Data ?? result,
|
|
7683
|
+
raw: result,
|
|
7684
|
+
}, "应用 publishable key 列表查询成功");
|
|
7685
|
+
}
|
|
7686
|
+
case "getStaticDomain": {
|
|
7687
|
+
const result = await callControlPlaneAction("DescribeStaticDomain", {
|
|
7688
|
+
EnvId: envId,
|
|
7689
|
+
});
|
|
7690
|
+
return buildEnvelope({
|
|
7691
|
+
action,
|
|
7692
|
+
envId,
|
|
7693
|
+
staticDomain: result,
|
|
7694
|
+
}, "应用静态域名查询成功");
|
|
7695
|
+
}
|
|
7696
|
+
}
|
|
7697
|
+
}));
|
|
7698
|
+
server.registerTool?.("manageAppAuth", {
|
|
7699
|
+
title: "管理应用认证配置",
|
|
7700
|
+
description: "应用侧认证配置写入口。用于修改登录方式、provider、client 配置,创建 publishable key 和自定义登录密钥。",
|
|
7701
|
+
inputSchema: {
|
|
7702
|
+
action: zod_1.z.enum(MANAGE_APP_AUTH_ACTIONS),
|
|
7703
|
+
loginConfig: zod_1.z.record(zod_1.z.any()).optional().describe("updateLoginConfig 使用的登录配置对象"),
|
|
7704
|
+
providerId: zod_1.z.string().optional().describe("provider 标识,如 email、google"),
|
|
7705
|
+
config: zod_1.z.record(zod_1.z.any()).optional().describe("provider / client / api key 的配置对象"),
|
|
7706
|
+
},
|
|
7707
|
+
annotations: {
|
|
7708
|
+
readOnlyHint: false,
|
|
7709
|
+
destructiveHint: true,
|
|
7710
|
+
idempotentHint: false,
|
|
7711
|
+
openWorldHint: true,
|
|
7712
|
+
category: "auth",
|
|
7713
|
+
},
|
|
7714
|
+
}, async ({ action, loginConfig, providerId, config, }) => withEnvelope(async () => {
|
|
7715
|
+
const envId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
7716
|
+
const cloudbase = await getManager();
|
|
7717
|
+
switch (action) {
|
|
7718
|
+
case "updateLoginConfig": {
|
|
7719
|
+
const normalized = normalizePlainObject(loginConfig, "loginConfig");
|
|
7720
|
+
if (!normalized) {
|
|
7721
|
+
throw new Error("action=updateLoginConfig 时必须提供 loginConfig");
|
|
7722
|
+
}
|
|
7723
|
+
const current = await cloudbase.env.getLoginConfigListV2();
|
|
7724
|
+
const merged = {
|
|
7725
|
+
EnvId: envId,
|
|
7726
|
+
...extractLoginStrategyState(current),
|
|
7727
|
+
...normalizeLoginConfigPatch(normalized),
|
|
7728
|
+
};
|
|
7729
|
+
// Manager SDK v5 provides a dedicated helper for login config updates.
|
|
7730
|
+
const result = await cloudbase.env.updateLoginConfigV2(merged);
|
|
7731
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
7732
|
+
return buildEnvelope({
|
|
7733
|
+
action,
|
|
7734
|
+
envId,
|
|
7735
|
+
appliedLoginConfig: merged,
|
|
7736
|
+
raw: result,
|
|
7737
|
+
}, "应用登录配置更新成功");
|
|
7738
|
+
}
|
|
7739
|
+
case "updateProvider": {
|
|
7740
|
+
const normalized = normalizePlainObject(config, "config");
|
|
7741
|
+
if (!providerId) {
|
|
7742
|
+
throw new Error("action=updateProvider 时必须提供 providerId");
|
|
7743
|
+
}
|
|
7744
|
+
if (!normalized) {
|
|
7745
|
+
throw new Error("action=updateProvider 时必须提供 config");
|
|
7746
|
+
}
|
|
7747
|
+
const result = await callControlPlaneAction("ModifyProvider", {
|
|
7748
|
+
EnvId: envId,
|
|
7749
|
+
Id: providerId,
|
|
7750
|
+
...normalized,
|
|
7751
|
+
});
|
|
7752
|
+
return buildEnvelope({
|
|
7753
|
+
action,
|
|
7754
|
+
envId,
|
|
7755
|
+
providerId,
|
|
7756
|
+
raw: result,
|
|
7757
|
+
}, `应用 provider ${providerId} 更新成功`);
|
|
7758
|
+
}
|
|
7759
|
+
case "updateClientConfig": {
|
|
7760
|
+
const normalized = normalizePlainObject(config, "config");
|
|
7761
|
+
if (!normalized) {
|
|
7762
|
+
throw new Error("action=updateClientConfig 时必须提供 config");
|
|
7763
|
+
}
|
|
7764
|
+
const result = await callControlPlaneAction("ModifyClient", {
|
|
7765
|
+
EnvId: envId,
|
|
7766
|
+
...normalized,
|
|
7767
|
+
});
|
|
7768
|
+
return buildEnvelope({
|
|
7769
|
+
action,
|
|
7770
|
+
envId,
|
|
7771
|
+
raw: result,
|
|
7772
|
+
}, "应用 client 配置更新成功");
|
|
7773
|
+
}
|
|
7774
|
+
case "createApiKeyToken": {
|
|
7775
|
+
const normalized = normalizePlainObject(config, "config");
|
|
7776
|
+
const result = await callControlPlaneAction("CreateApiKeyToken", {
|
|
7777
|
+
EnvId: envId,
|
|
7778
|
+
...(normalized ?? {}),
|
|
7779
|
+
});
|
|
7780
|
+
return buildEnvelope({
|
|
7781
|
+
action,
|
|
7782
|
+
envId,
|
|
7783
|
+
raw: result,
|
|
7784
|
+
}, "应用 publishable key 创建成功");
|
|
7785
|
+
}
|
|
7786
|
+
case "createCustomLoginKeys": {
|
|
7787
|
+
const result = await cloudbase.env.createCustomLoginKeys();
|
|
7788
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
7789
|
+
return buildEnvelope({
|
|
7790
|
+
action,
|
|
7791
|
+
envId,
|
|
7792
|
+
raw: result,
|
|
7793
|
+
}, "自定义登录密钥创建成功");
|
|
7794
|
+
}
|
|
7795
|
+
}
|
|
7796
|
+
}));
|
|
7797
|
+
}
|
|
7798
|
+
|
|
7799
|
+
|
|
7016
7800
|
/***/ }),
|
|
7017
7801
|
|
|
7018
7802
|
/***/ 5814:
|
|
@@ -7082,7 +7866,7 @@ class TelemetryReporter {
|
|
|
7082
7866
|
const nodeVersion = process.version; // Node.js版本
|
|
7083
7867
|
const arch = os_1.default.arch(); // 系统架构
|
|
7084
7868
|
// 从构建时注入的版本号获取MCP版本信息
|
|
7085
|
-
const mcpVersion = process.env.npm_package_version || "2.
|
|
7869
|
+
const mcpVersion = process.env.npm_package_version || "2.16.0-beta.1" || 0;
|
|
7086
7870
|
return {
|
|
7087
7871
|
userAgent: `${osType} ${osRelease} ${arch} ${nodeVersion} CloudBase-MCP/${mcpVersion}`,
|
|
7088
7872
|
deviceId: this.deviceId,
|
|
@@ -7229,16 +8013,16 @@ class TelemetryReporter {
|
|
|
7229
8013
|
}
|
|
7230
8014
|
// 创建全局实例
|
|
7231
8015
|
exports.telemetryReporter = new TelemetryReporter();
|
|
7232
|
-
|
|
7233
|
-
|
|
7234
|
-
|
|
7235
|
-
|
|
7236
|
-
|
|
8016
|
+
/**
|
|
8017
|
+
* 解析环境ID
|
|
8018
|
+
* 优先级:传入配置 > envManager缓存 > 环境变量 > unknown
|
|
8019
|
+
*/
|
|
8020
|
+
function resolveEnvId(cloudBaseOptions) {
|
|
8021
|
+
let envId = 'unknown';
|
|
7237
8022
|
let envIdSource = 'unknown';
|
|
7238
8023
|
try {
|
|
7239
|
-
|
|
7240
|
-
|
|
7241
|
-
envId = params.cloudBaseOptions.envId;
|
|
8024
|
+
if (cloudBaseOptions?.envId) {
|
|
8025
|
+
envId = cloudBaseOptions.envId;
|
|
7242
8026
|
envIdSource = 'cloudBaseOptions';
|
|
7243
8027
|
}
|
|
7244
8028
|
else {
|
|
@@ -7256,20 +8040,26 @@ const reportToolCall = async (params) => {
|
|
|
7256
8040
|
envIdSource = 'default';
|
|
7257
8041
|
}
|
|
7258
8042
|
}
|
|
7259
|
-
(0, logger_js_1.debug)('[telemetry] 工具调用 envId 获取结果', {
|
|
7260
|
-
toolName: params.toolName,
|
|
7261
|
-
envId,
|
|
7262
|
-
envIdSource,
|
|
7263
|
-
hasCloudBaseOptions: !!params.cloudBaseOptions,
|
|
7264
|
-
cloudBaseOptionsEnvId: params.cloudBaseOptions?.envId || null
|
|
7265
|
-
});
|
|
7266
8043
|
}
|
|
7267
8044
|
catch (err) {
|
|
7268
|
-
// 忽略错误,使用 unknown
|
|
7269
8045
|
(0, logger_js_1.debug)('获取环境ID失败,遥测数据将使用 unknown', err instanceof Error ? err : new Error(String(err)));
|
|
7270
8046
|
envId = 'unknown';
|
|
7271
8047
|
envIdSource = 'error';
|
|
7272
8048
|
}
|
|
8049
|
+
return { envId, envIdSource };
|
|
8050
|
+
}
|
|
8051
|
+
// 便捷方法
|
|
8052
|
+
const reportToolCall = async (params) => {
|
|
8053
|
+
const { nodeVersion, osType, osRelease, arch, mcpVersion } = exports.telemetryReporter.getUserAgent();
|
|
8054
|
+
// 安全获取环境ID,优先使用传入的配置
|
|
8055
|
+
const { envId, envIdSource } = resolveEnvId(params.cloudBaseOptions);
|
|
8056
|
+
(0, logger_js_1.debug)('[telemetry] 工具调用 envId 获取结果', {
|
|
8057
|
+
toolName: params.toolName,
|
|
8058
|
+
envId,
|
|
8059
|
+
envIdSource,
|
|
8060
|
+
hasCloudBaseOptions: !!params.cloudBaseOptions,
|
|
8061
|
+
cloudBaseOptionsEnvId: params.cloudBaseOptions?.envId || null
|
|
8062
|
+
});
|
|
7273
8063
|
// 报告工具调用情况
|
|
7274
8064
|
const eventData = {
|
|
7275
8065
|
toolName: params.toolName,
|
|
@@ -7319,43 +8109,14 @@ exports.reportToolCall = reportToolCall;
|
|
|
7319
8109
|
const reportToolkitLifecycle = async (params) => {
|
|
7320
8110
|
const { nodeVersion, osType, osRelease, arch, mcpVersion } = exports.telemetryReporter.getUserAgent();
|
|
7321
8111
|
// 安全获取环境ID,优先使用传入的配置
|
|
7322
|
-
|
|
7323
|
-
|
|
7324
|
-
|
|
7325
|
-
|
|
7326
|
-
|
|
7327
|
-
|
|
7328
|
-
|
|
7329
|
-
|
|
7330
|
-
else {
|
|
7331
|
-
const cachedEnvId = (0, cloudbase_manager_js_1.getCachedEnvId)();
|
|
7332
|
-
if (cachedEnvId) {
|
|
7333
|
-
envId = cachedEnvId;
|
|
7334
|
-
envIdSource = 'envManager.cachedEnvId';
|
|
7335
|
-
}
|
|
7336
|
-
else if (process.env.CLOUDBASE_ENV_ID) {
|
|
7337
|
-
envId = process.env.CLOUDBASE_ENV_ID;
|
|
7338
|
-
envIdSource = 'process.env.CLOUDBASE_ENV_ID';
|
|
7339
|
-
}
|
|
7340
|
-
else {
|
|
7341
|
-
envId = 'unknown';
|
|
7342
|
-
envIdSource = 'default';
|
|
7343
|
-
}
|
|
7344
|
-
}
|
|
7345
|
-
(0, logger_js_1.debug)('[telemetry] 生命周期事件 envId 获取结果', {
|
|
7346
|
-
event: params.event,
|
|
7347
|
-
envId,
|
|
7348
|
-
envIdSource,
|
|
7349
|
-
hasCloudBaseOptions: !!params.cloudBaseOptions,
|
|
7350
|
-
cloudBaseOptionsEnvId: params.cloudBaseOptions?.envId || null
|
|
7351
|
-
});
|
|
7352
|
-
}
|
|
7353
|
-
catch (err) {
|
|
7354
|
-
// 忽略错误,使用 unknown
|
|
7355
|
-
(0, logger_js_1.debug)('获取环境ID失败,遥测数据将使用 unknown', err instanceof Error ? err : new Error(String(err)));
|
|
7356
|
-
envId = 'unknown';
|
|
7357
|
-
envIdSource = 'error';
|
|
7358
|
-
}
|
|
8112
|
+
const { envId, envIdSource } = resolveEnvId(params.cloudBaseOptions);
|
|
8113
|
+
(0, logger_js_1.debug)('[telemetry] 生命周期事件 envId 获取结果', {
|
|
8114
|
+
event: params.event,
|
|
8115
|
+
envId,
|
|
8116
|
+
envIdSource,
|
|
8117
|
+
hasCloudBaseOptions: !!params.cloudBaseOptions,
|
|
8118
|
+
cloudBaseOptionsEnvId: params.cloudBaseOptions?.envId || null
|
|
8119
|
+
});
|
|
7359
8120
|
// 报告 Toolkit 生命周期事件
|
|
7360
8121
|
const eventData = {
|
|
7361
8122
|
event: params.event,
|
|
@@ -7397,11 +8158,13 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
|
7397
8158
|
exports.MANAGE_FUNCTION_ACTIONS = exports.QUERY_FUNCTION_ACTIONS = exports.TRIGGER_CONFIG_EXAMPLES = exports.SUPPORTED_TRIGGER_TYPES = exports.DEFAULT_NODEJS_RUNTIME = exports.SUPPORTED_NODEJS_RUNTIMES = exports.RECOMMENDED_RUNTIMES = exports.DEFAULT_RUNTIME = exports.ALL_SUPPORTED_RUNTIMES = exports.SUPPORTED_RUNTIMES = void 0;
|
|
7398
8159
|
exports.formatRuntimeList = formatRuntimeList;
|
|
7399
8160
|
exports.shouldInstallDependencyForFunction = shouldInstallDependencyForFunction;
|
|
8161
|
+
exports.resolveEventFunctionRuntime = resolveEventFunctionRuntime;
|
|
7400
8162
|
exports.buildFunctionOperationErrorMessage = buildFunctionOperationErrorMessage;
|
|
7401
8163
|
exports.registerFunctionTools = registerFunctionTools;
|
|
7402
8164
|
const zod_1 = __webpack_require__(2971);
|
|
7403
8165
|
const cloudbase_manager_js_1 = __webpack_require__(3431);
|
|
7404
8166
|
const cloud_mode_js_1 = __webpack_require__(9684);
|
|
8167
|
+
const json_content_js_1 = __webpack_require__(4365);
|
|
7405
8168
|
const logger_js_1 = __webpack_require__(3039);
|
|
7406
8169
|
const fs_1 = __webpack_require__(4421);
|
|
7407
8170
|
const path_1 = __importDefault(__webpack_require__(2521));
|
|
@@ -7553,16 +8316,6 @@ const MANAGE_LAYER_SCHEMA = zod_1.z.object({
|
|
|
7553
8316
|
layerName: zod_1.z.string().describe("层名称"),
|
|
7554
8317
|
layerVersion: zod_1.z.number().describe("层版本号"),
|
|
7555
8318
|
});
|
|
7556
|
-
function jsonContent(body) {
|
|
7557
|
-
return {
|
|
7558
|
-
content: [
|
|
7559
|
-
{
|
|
7560
|
-
type: "text",
|
|
7561
|
-
text: JSON.stringify(body, null, 2),
|
|
7562
|
-
},
|
|
7563
|
-
],
|
|
7564
|
-
};
|
|
7565
|
-
}
|
|
7566
8319
|
function normalizeFunctionLayers(layers) {
|
|
7567
8320
|
if (!Array.isArray(layers)) {
|
|
7568
8321
|
return [];
|
|
@@ -7598,6 +8351,16 @@ function shouldInstallDependencyForFunction(functionType, hasPackageJson) {
|
|
|
7598
8351
|
}
|
|
7599
8352
|
return true;
|
|
7600
8353
|
}
|
|
8354
|
+
function resolveEventFunctionRuntime(runtime) {
|
|
8355
|
+
if (typeof runtime !== "string" || !runtime.trim()) {
|
|
8356
|
+
return exports.DEFAULT_RUNTIME;
|
|
8357
|
+
}
|
|
8358
|
+
const normalizedRuntime = runtime.replace(/\s+/g, "");
|
|
8359
|
+
if (exports.ALL_SUPPORTED_RUNTIMES.includes(normalizedRuntime)) {
|
|
8360
|
+
return normalizedRuntime;
|
|
8361
|
+
}
|
|
8362
|
+
throw new Error(`不支持的运行时环境: "${String(runtime)}"\n\n支持的运行时:\n${formatRuntimeList()}`);
|
|
8363
|
+
}
|
|
7601
8364
|
function buildFunctionOperationErrorMessage(operation, functionName, functionRootPath, error) {
|
|
7602
8365
|
const baseMessage = error instanceof Error ? error.message : String(error);
|
|
7603
8366
|
const suggestions = [];
|
|
@@ -7650,10 +8413,10 @@ function registerFunctionTools(server) {
|
|
|
7650
8413
|
});
|
|
7651
8414
|
const withEnvelope = async (handler) => {
|
|
7652
8415
|
try {
|
|
7653
|
-
return jsonContent(await handler());
|
|
8416
|
+
return (0, json_content_js_1.jsonContent)(await handler());
|
|
7654
8417
|
}
|
|
7655
8418
|
catch (error) {
|
|
7656
|
-
return jsonContent(buildErrorEnvelope(error));
|
|
8419
|
+
return (0, json_content_js_1.jsonContent)(buildErrorEnvelope(error));
|
|
7657
8420
|
}
|
|
7658
8421
|
};
|
|
7659
8422
|
const requireConfirm = (action, confirm) => {
|
|
@@ -7973,22 +8736,12 @@ function registerFunctionTools(server) {
|
|
|
7973
8736
|
const functionName = String(func.name);
|
|
7974
8737
|
(0, logger_js_1.debug)(`[createFunction] name=${functionName}, type=${String(func.type || "Event")}`);
|
|
7975
8738
|
if (func.type !== "HTTP") {
|
|
7976
|
-
|
|
7977
|
-
|
|
7978
|
-
|
|
7979
|
-
|
|
7980
|
-
|
|
7981
|
-
|
|
7982
|
-
func.runtime = normalizedRuntime;
|
|
7983
|
-
}
|
|
7984
|
-
else if (func.runtime.includes(" ")) {
|
|
7985
|
-
console.warn(`检测到 runtime 参数包含空格: "${func.runtime}",已自动移除空格`);
|
|
7986
|
-
func.runtime = normalizedRuntime;
|
|
7987
|
-
}
|
|
7988
|
-
}
|
|
7989
|
-
if (typeof func.runtime !== "string" ||
|
|
7990
|
-
!exports.ALL_SUPPORTED_RUNTIMES.includes(func.runtime)) {
|
|
7991
|
-
throw new Error(`不支持的运行时环境: "${String(func.runtime)}"\n\n支持的运行时:\n${formatRuntimeList()}`);
|
|
8739
|
+
const originalRuntime = typeof func.runtime === "string" ? func.runtime : undefined;
|
|
8740
|
+
func.runtime = resolveEventFunctionRuntime(func.runtime);
|
|
8741
|
+
if (typeof originalRuntime === "string" &&
|
|
8742
|
+
originalRuntime.includes(" ") &&
|
|
8743
|
+
originalRuntime.replace(/\s+/g, "") === func.runtime) {
|
|
8744
|
+
console.warn(`检测到 runtime 参数包含空格: "${originalRuntime}",已自动移除空格`);
|
|
7992
8745
|
}
|
|
7993
8746
|
}
|
|
7994
8747
|
const processedRootPath = processFunctionRootPath(input.functionRootPath, functionName);
|
|
@@ -8042,18 +8795,18 @@ function registerFunctionTools(server) {
|
|
|
8042
8795
|
reason: "交付前确认 HTTP 访问路径是否已存在并已生效",
|
|
8043
8796
|
});
|
|
8044
8797
|
nextActions.push({
|
|
8045
|
-
tool: "
|
|
8046
|
-
action: "
|
|
8798
|
+
tool: "queryPermissions",
|
|
8799
|
+
action: "getResourcePermission",
|
|
8047
8800
|
reason: "评测、浏览器或其他外部调用方可能以匿名身份访问;若直接报 EXCEED_AUTHORITY,应先读取当前函数安全规则",
|
|
8048
8801
|
});
|
|
8049
8802
|
nextActions.push({
|
|
8050
|
-
tool: "
|
|
8051
|
-
action: "
|
|
8803
|
+
tool: "managePermissions",
|
|
8804
|
+
action: "updateResourcePermission",
|
|
8052
8805
|
reason: "只有在确认需要匿名访问时,才按实际安全要求调整函数安全规则,例如处理 EXCEED_AUTHORITY",
|
|
8053
8806
|
});
|
|
8054
8807
|
}
|
|
8055
8808
|
const message = func.type === "HTTP"
|
|
8056
|
-
? `已创建 HTTP 函数 ${functionName}。如果后续需要通过 URL 访问,请显式调用 manageGateway(action="createAccess") 按实际路径和鉴权需求创建访问入口。评测或其他外部调用方可能会以匿名身份访问,而且失败后不一定会把 EXCEED_AUTHORITY 再反馈给 AI;交付前请主动确认访问路径和函数安全规则,若已出现 EXCEED_AUTHORITY,请先调用
|
|
8809
|
+
? `已创建 HTTP 函数 ${functionName}。如果后续需要通过 URL 访问,请显式调用 manageGateway(action="createAccess") 按实际路径和鉴权需求创建访问入口。评测或其他外部调用方可能会以匿名身份访问,而且失败后不一定会把 EXCEED_AUTHORITY 再反馈给 AI;交付前请主动确认访问路径和函数安全规则,若已出现 EXCEED_AUTHORITY,请先调用 queryPermissions(action="getResourcePermission", resourceType="function", resourceId="${functionName}") 查看当前规则,再按需要使用 managePermissions(action="updateResourcePermission") 调整权限。`
|
|
8057
8810
|
: `已创建函数 ${functionName}`;
|
|
8058
8811
|
return buildEnvelope({
|
|
8059
8812
|
action: input.action,
|
|
@@ -8451,15 +9204,410 @@ module.exports = __WEBPACK_EXTERNAL_MODULE_ws__;
|
|
|
8451
9204
|
|
|
8452
9205
|
/***/ }),
|
|
8453
9206
|
|
|
8454
|
-
/***/
|
|
8455
|
-
/***/ (
|
|
9207
|
+
/***/ 6485:
|
|
9208
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
8456
9209
|
|
|
8457
9210
|
|
|
8458
|
-
|
|
8459
|
-
|
|
8460
|
-
|
|
8461
|
-
|
|
8462
|
-
|
|
9211
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
9212
|
+
exports.registerPermissionTools = registerPermissionTools;
|
|
9213
|
+
const zod_1 = __webpack_require__(2971);
|
|
9214
|
+
const cloudbase_manager_js_1 = __webpack_require__(3431);
|
|
9215
|
+
const json_content_js_1 = __webpack_require__(4365);
|
|
9216
|
+
const QUERY_PERMISSION_ACTIONS = [
|
|
9217
|
+
"getResourcePermission",
|
|
9218
|
+
"listResourcePermissions",
|
|
9219
|
+
"listRoles",
|
|
9220
|
+
"getRole",
|
|
9221
|
+
"listUsers",
|
|
9222
|
+
"getUser",
|
|
9223
|
+
];
|
|
9224
|
+
const MANAGE_PERMISSION_ACTIONS = [
|
|
9225
|
+
"updateResourcePermission",
|
|
9226
|
+
"createRole",
|
|
9227
|
+
"updateRole",
|
|
9228
|
+
"deleteRoles",
|
|
9229
|
+
"addRoleMembers",
|
|
9230
|
+
"removeRoleMembers",
|
|
9231
|
+
"addRolePolicies",
|
|
9232
|
+
"removeRolePolicies",
|
|
9233
|
+
"createUser",
|
|
9234
|
+
"updateUser",
|
|
9235
|
+
"deleteUsers",
|
|
9236
|
+
];
|
|
9237
|
+
function buildEnvelope(data, message) {
|
|
9238
|
+
return {
|
|
9239
|
+
success: true,
|
|
9240
|
+
data,
|
|
9241
|
+
message,
|
|
9242
|
+
};
|
|
9243
|
+
}
|
|
9244
|
+
function buildErrorEnvelope(error) {
|
|
9245
|
+
return {
|
|
9246
|
+
success: false,
|
|
9247
|
+
data: {},
|
|
9248
|
+
message: error instanceof Error ? error.message : String(error),
|
|
9249
|
+
};
|
|
9250
|
+
}
|
|
9251
|
+
function mapResourceType(resourceType) {
|
|
9252
|
+
const resourceTypeMap = {
|
|
9253
|
+
noSqlDatabase: "collection",
|
|
9254
|
+
sqlDatabase: "table",
|
|
9255
|
+
function: "function",
|
|
9256
|
+
storage: "storage",
|
|
9257
|
+
};
|
|
9258
|
+
return resourceTypeMap[resourceType];
|
|
9259
|
+
}
|
|
9260
|
+
function normalizeRecordArray(value, label) {
|
|
9261
|
+
if (value === undefined) {
|
|
9262
|
+
return undefined;
|
|
9263
|
+
}
|
|
9264
|
+
if (!Array.isArray(value)) {
|
|
9265
|
+
throw new Error(`${label} 必须是数组`);
|
|
9266
|
+
}
|
|
9267
|
+
return value;
|
|
9268
|
+
}
|
|
9269
|
+
function registerPermissionTools(server) {
|
|
9270
|
+
const cloudBaseOptions = server.cloudBaseOptions;
|
|
9271
|
+
const getManager = () => (0, cloudbase_manager_js_1.getCloudBaseManager)({ cloudBaseOptions });
|
|
9272
|
+
const withEnvelope = async (handler) => {
|
|
9273
|
+
try {
|
|
9274
|
+
return (0, json_content_js_1.jsonContent)(await handler());
|
|
9275
|
+
}
|
|
9276
|
+
catch (error) {
|
|
9277
|
+
return (0, json_content_js_1.jsonContent)(buildErrorEnvelope(error));
|
|
9278
|
+
}
|
|
9279
|
+
};
|
|
9280
|
+
server.registerTool?.("queryPermissions", {
|
|
9281
|
+
title: "查询权限与用户配置",
|
|
9282
|
+
description: "权限域统一只读入口。支持查询资源权限、角色列表/详情、应用用户列表/详情。",
|
|
9283
|
+
inputSchema: {
|
|
9284
|
+
action: zod_1.z.enum(QUERY_PERMISSION_ACTIONS),
|
|
9285
|
+
resourceType: zod_1.z
|
|
9286
|
+
.enum(["noSqlDatabase", "sqlDatabase", "function", "storage"])
|
|
9287
|
+
.optional(),
|
|
9288
|
+
resourceId: zod_1.z.string().optional(),
|
|
9289
|
+
resourceIds: zod_1.z.array(zod_1.z.string()).optional(),
|
|
9290
|
+
roleId: zod_1.z.string().optional(),
|
|
9291
|
+
roleIdentity: zod_1.z.string().optional(),
|
|
9292
|
+
roleName: zod_1.z.string().optional(),
|
|
9293
|
+
uid: zod_1.z.string().optional(),
|
|
9294
|
+
username: zod_1.z.string().optional(),
|
|
9295
|
+
pageNo: zod_1.z.number().optional(),
|
|
9296
|
+
pageSize: zod_1.z.number().optional(),
|
|
9297
|
+
},
|
|
9298
|
+
annotations: {
|
|
9299
|
+
readOnlyHint: true,
|
|
9300
|
+
openWorldHint: true,
|
|
9301
|
+
category: "permissions",
|
|
9302
|
+
},
|
|
9303
|
+
}, async ({ action, resourceType, resourceId, resourceIds, roleId, roleIdentity, roleName, uid, username, pageNo, pageSize, }) => withEnvelope(async () => {
|
|
9304
|
+
const envId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
9305
|
+
const cloudbase = await getManager();
|
|
9306
|
+
switch (action) {
|
|
9307
|
+
case "getResourcePermission": {
|
|
9308
|
+
if (!resourceType || !resourceId) {
|
|
9309
|
+
throw new Error("action=getResourcePermission 时必须提供 resourceType 和 resourceId");
|
|
9310
|
+
}
|
|
9311
|
+
const result = await cloudbase.permission.describeResourcePermission({
|
|
9312
|
+
resourceType: mapResourceType(resourceType),
|
|
9313
|
+
resources: [resourceId],
|
|
9314
|
+
});
|
|
9315
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
9316
|
+
return buildEnvelope({
|
|
9317
|
+
action,
|
|
9318
|
+
envId,
|
|
9319
|
+
resourceType,
|
|
9320
|
+
resourceId,
|
|
9321
|
+
permissions: result.Data.PermissionList ?? [],
|
|
9322
|
+
raw: result,
|
|
9323
|
+
}, "资源权限查询成功");
|
|
9324
|
+
}
|
|
9325
|
+
case "listResourcePermissions": {
|
|
9326
|
+
if (!resourceType) {
|
|
9327
|
+
throw new Error("action=listResourcePermissions 时必须提供 resourceType");
|
|
9328
|
+
}
|
|
9329
|
+
const result = await cloudbase.permission.describeResourcePermission({
|
|
9330
|
+
resourceType: mapResourceType(resourceType),
|
|
9331
|
+
resources: resourceIds,
|
|
9332
|
+
});
|
|
9333
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
9334
|
+
return buildEnvelope({
|
|
9335
|
+
action,
|
|
9336
|
+
envId,
|
|
9337
|
+
resourceType,
|
|
9338
|
+
permissions: result.Data.PermissionList ?? [],
|
|
9339
|
+
total: result.Data.TotalCount ?? 0,
|
|
9340
|
+
raw: result,
|
|
9341
|
+
}, "资源权限列表查询成功");
|
|
9342
|
+
}
|
|
9343
|
+
case "listRoles": {
|
|
9344
|
+
const result = await cloudbase.permission.describeRoleList({
|
|
9345
|
+
pageNumber: pageNo ?? 1,
|
|
9346
|
+
pageSize: pageSize ?? 20,
|
|
9347
|
+
loadDetails: true,
|
|
9348
|
+
});
|
|
9349
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
9350
|
+
return buildEnvelope({
|
|
9351
|
+
action,
|
|
9352
|
+
envId,
|
|
9353
|
+
systemRoles: result.Data.SystemRoles ?? [],
|
|
9354
|
+
customRoles: result.Data.CustomRoles ?? [],
|
|
9355
|
+
total: result.Data.TotalCount ?? 0,
|
|
9356
|
+
raw: result,
|
|
9357
|
+
}, "角色列表查询成功");
|
|
9358
|
+
}
|
|
9359
|
+
case "getRole": {
|
|
9360
|
+
const result = await cloudbase.permission.describeRoleList({
|
|
9361
|
+
roleId,
|
|
9362
|
+
roleIdentity,
|
|
9363
|
+
roleName,
|
|
9364
|
+
pageNumber: 1,
|
|
9365
|
+
pageSize: 20,
|
|
9366
|
+
loadDetails: true,
|
|
9367
|
+
});
|
|
9368
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
9369
|
+
const roles = [
|
|
9370
|
+
...(result.Data.SystemRoles ?? []),
|
|
9371
|
+
...(result.Data.CustomRoles ?? []),
|
|
9372
|
+
];
|
|
9373
|
+
const role = roles.find((item) => (roleId && item.RoleId === roleId) ||
|
|
9374
|
+
(roleIdentity && item.RoleIdentity === roleIdentity) ||
|
|
9375
|
+
(roleName && item.RoleName === roleName)) ?? null;
|
|
9376
|
+
return buildEnvelope({
|
|
9377
|
+
action,
|
|
9378
|
+
envId,
|
|
9379
|
+
role,
|
|
9380
|
+
raw: result,
|
|
9381
|
+
}, "角色详情查询成功");
|
|
9382
|
+
}
|
|
9383
|
+
case "listUsers": {
|
|
9384
|
+
const result = await cloudbase.user.describeUserList({
|
|
9385
|
+
pageNo: pageNo ?? 1,
|
|
9386
|
+
pageSize: pageSize ?? 20,
|
|
9387
|
+
name: username,
|
|
9388
|
+
});
|
|
9389
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
9390
|
+
return buildEnvelope({
|
|
9391
|
+
action,
|
|
9392
|
+
envId,
|
|
9393
|
+
users: result.Data.UserList ?? [],
|
|
9394
|
+
total: result.Data.Total ?? 0,
|
|
9395
|
+
raw: result,
|
|
9396
|
+
}, "应用用户列表查询成功");
|
|
9397
|
+
}
|
|
9398
|
+
case "getUser": {
|
|
9399
|
+
if (!uid && !username) {
|
|
9400
|
+
throw new Error("action=getUser 时必须提供 uid 或 username");
|
|
9401
|
+
}
|
|
9402
|
+
const result = await cloudbase.user.describeUserList({
|
|
9403
|
+
pageNo: 1,
|
|
9404
|
+
pageSize: 20,
|
|
9405
|
+
name: username,
|
|
9406
|
+
});
|
|
9407
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
9408
|
+
const user = (result.Data.UserList ?? []).find((item) => (uid && item.Uid === uid) || (username && item.Name === username)) ?? null;
|
|
9409
|
+
return buildEnvelope({
|
|
9410
|
+
action,
|
|
9411
|
+
envId,
|
|
9412
|
+
user,
|
|
9413
|
+
raw: result,
|
|
9414
|
+
}, "应用用户详情查询成功");
|
|
9415
|
+
}
|
|
9416
|
+
}
|
|
9417
|
+
}));
|
|
9418
|
+
server.registerTool?.("managePermissions", {
|
|
9419
|
+
title: "管理权限与用户配置",
|
|
9420
|
+
description: "权限域统一写入口。支持修改资源权限、角色管理、成员与策略增删、应用用户 CRUD。",
|
|
9421
|
+
inputSchema: {
|
|
9422
|
+
action: zod_1.z.enum(MANAGE_PERMISSION_ACTIONS),
|
|
9423
|
+
resourceType: zod_1.z
|
|
9424
|
+
.enum(["noSqlDatabase", "sqlDatabase", "function", "storage"])
|
|
9425
|
+
.optional(),
|
|
9426
|
+
resourceId: zod_1.z.string().optional(),
|
|
9427
|
+
permission: zod_1.z
|
|
9428
|
+
.enum(["READONLY", "PRIVATE", "ADMINWRITE", "ADMINONLY", "CUSTOM"])
|
|
9429
|
+
.optional(),
|
|
9430
|
+
securityRule: zod_1.z.string().optional(),
|
|
9431
|
+
roleId: zod_1.z.string().optional(),
|
|
9432
|
+
roleIds: zod_1.z.array(zod_1.z.string()).optional(),
|
|
9433
|
+
roleName: zod_1.z.string().optional(),
|
|
9434
|
+
roleIdentity: zod_1.z.string().optional(),
|
|
9435
|
+
description: zod_1.z.string().optional(),
|
|
9436
|
+
memberUids: zod_1.z.array(zod_1.z.string()).optional(),
|
|
9437
|
+
policies: zod_1.z.array(zod_1.z.record(zod_1.z.any())).optional(),
|
|
9438
|
+
uid: zod_1.z.string().optional(),
|
|
9439
|
+
uids: zod_1.z.array(zod_1.z.string()).optional(),
|
|
9440
|
+
username: zod_1.z.string().optional(),
|
|
9441
|
+
password: zod_1.z.string().optional(),
|
|
9442
|
+
userStatus: zod_1.z.enum(["ACTIVE", "BLOCKED"]).optional(),
|
|
9443
|
+
},
|
|
9444
|
+
annotations: {
|
|
9445
|
+
readOnlyHint: false,
|
|
9446
|
+
destructiveHint: true,
|
|
9447
|
+
idempotentHint: false,
|
|
9448
|
+
openWorldHint: true,
|
|
9449
|
+
category: "permissions",
|
|
9450
|
+
},
|
|
9451
|
+
}, async ({ action, resourceType, resourceId, permission, securityRule, roleId, roleIds, roleName, roleIdentity, description, memberUids, policies, uid, uids, username, password, userStatus, }) => withEnvelope(async () => {
|
|
9452
|
+
const envId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
9453
|
+
const cloudbase = await getManager();
|
|
9454
|
+
const normalizedPolicies = normalizeRecordArray(policies, "policies");
|
|
9455
|
+
switch (action) {
|
|
9456
|
+
case "updateResourcePermission": {
|
|
9457
|
+
if (!resourceType || !resourceId || !permission) {
|
|
9458
|
+
throw new Error("action=updateResourcePermission 时必须提供 resourceType、resourceId 和 permission");
|
|
9459
|
+
}
|
|
9460
|
+
const result = await cloudbase.permission.modifyResourcePermission({
|
|
9461
|
+
resourceType: mapResourceType(resourceType),
|
|
9462
|
+
resource: resourceId,
|
|
9463
|
+
permission,
|
|
9464
|
+
securityRule,
|
|
9465
|
+
});
|
|
9466
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
9467
|
+
return buildEnvelope({
|
|
9468
|
+
action,
|
|
9469
|
+
envId,
|
|
9470
|
+
resourceType,
|
|
9471
|
+
resourceId,
|
|
9472
|
+
permission,
|
|
9473
|
+
raw: result,
|
|
9474
|
+
}, "资源权限更新成功");
|
|
9475
|
+
}
|
|
9476
|
+
case "createRole": {
|
|
9477
|
+
if (!roleName || !roleIdentity) {
|
|
9478
|
+
throw new Error("action=createRole 时必须提供 roleName 和 roleIdentity");
|
|
9479
|
+
}
|
|
9480
|
+
const result = await cloudbase.permission.createRole({
|
|
9481
|
+
roleName,
|
|
9482
|
+
roleIdentity,
|
|
9483
|
+
description,
|
|
9484
|
+
memberUids,
|
|
9485
|
+
policies: normalizedPolicies,
|
|
9486
|
+
});
|
|
9487
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
9488
|
+
return buildEnvelope({
|
|
9489
|
+
action,
|
|
9490
|
+
envId,
|
|
9491
|
+
roleName,
|
|
9492
|
+
raw: result,
|
|
9493
|
+
}, "角色创建成功");
|
|
9494
|
+
}
|
|
9495
|
+
case "updateRole":
|
|
9496
|
+
case "addRoleMembers":
|
|
9497
|
+
case "removeRoleMembers":
|
|
9498
|
+
case "addRolePolicies":
|
|
9499
|
+
case "removeRolePolicies": {
|
|
9500
|
+
if (!roleId) {
|
|
9501
|
+
throw new Error(`action=${action} 时必须提供 roleId`);
|
|
9502
|
+
}
|
|
9503
|
+
const result = await cloudbase.permission.modifyRole({
|
|
9504
|
+
roleId,
|
|
9505
|
+
...(action === "updateRole"
|
|
9506
|
+
? {
|
|
9507
|
+
roleName,
|
|
9508
|
+
description,
|
|
9509
|
+
addMemberUids: memberUids,
|
|
9510
|
+
addPolicies: normalizedPolicies,
|
|
9511
|
+
}
|
|
9512
|
+
: {}),
|
|
9513
|
+
...(action === "addRoleMembers" ? { addMemberUids: memberUids } : {}),
|
|
9514
|
+
...(action === "removeRoleMembers" ? { removeMemberUids: memberUids } : {}),
|
|
9515
|
+
...(action === "addRolePolicies" ? { addPolicies: normalizedPolicies } : {}),
|
|
9516
|
+
...(action === "removeRolePolicies"
|
|
9517
|
+
? { removePolicies: normalizedPolicies }
|
|
9518
|
+
: {}),
|
|
9519
|
+
});
|
|
9520
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
9521
|
+
return buildEnvelope({
|
|
9522
|
+
action,
|
|
9523
|
+
envId,
|
|
9524
|
+
roleId,
|
|
9525
|
+
raw: result,
|
|
9526
|
+
}, "角色更新成功");
|
|
9527
|
+
}
|
|
9528
|
+
case "deleteRoles": {
|
|
9529
|
+
if (!roleIds?.length) {
|
|
9530
|
+
throw new Error("action=deleteRoles 时必须提供 roleIds");
|
|
9531
|
+
}
|
|
9532
|
+
const result = await cloudbase.permission.deleteRoles({
|
|
9533
|
+
roleIds,
|
|
9534
|
+
});
|
|
9535
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
9536
|
+
return buildEnvelope({
|
|
9537
|
+
action,
|
|
9538
|
+
envId,
|
|
9539
|
+
roleIds,
|
|
9540
|
+
raw: result,
|
|
9541
|
+
}, "角色删除成功");
|
|
9542
|
+
}
|
|
9543
|
+
case "createUser": {
|
|
9544
|
+
if (!username || !password) {
|
|
9545
|
+
throw new Error("action=createUser 时必须提供 username 和 password");
|
|
9546
|
+
}
|
|
9547
|
+
const result = await cloudbase.user.createUser({
|
|
9548
|
+
name: username,
|
|
9549
|
+
password,
|
|
9550
|
+
userStatus,
|
|
9551
|
+
description,
|
|
9552
|
+
});
|
|
9553
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
9554
|
+
return buildEnvelope({
|
|
9555
|
+
action,
|
|
9556
|
+
envId,
|
|
9557
|
+
username,
|
|
9558
|
+
raw: result,
|
|
9559
|
+
}, "应用用户创建成功");
|
|
9560
|
+
}
|
|
9561
|
+
case "updateUser": {
|
|
9562
|
+
if (!uid) {
|
|
9563
|
+
throw new Error("action=updateUser 时必须提供 uid");
|
|
9564
|
+
}
|
|
9565
|
+
const result = await cloudbase.user.modifyUser({
|
|
9566
|
+
uid,
|
|
9567
|
+
name: username,
|
|
9568
|
+
password,
|
|
9569
|
+
userStatus,
|
|
9570
|
+
description,
|
|
9571
|
+
});
|
|
9572
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
9573
|
+
return buildEnvelope({
|
|
9574
|
+
action,
|
|
9575
|
+
envId,
|
|
9576
|
+
uid,
|
|
9577
|
+
raw: result,
|
|
9578
|
+
}, "应用用户更新成功");
|
|
9579
|
+
}
|
|
9580
|
+
case "deleteUsers": {
|
|
9581
|
+
if (!uids?.length) {
|
|
9582
|
+
throw new Error("action=deleteUsers 时必须提供 uids");
|
|
9583
|
+
}
|
|
9584
|
+
const result = await cloudbase.user.deleteUsers({
|
|
9585
|
+
uids,
|
|
9586
|
+
});
|
|
9587
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
9588
|
+
return buildEnvelope({
|
|
9589
|
+
action,
|
|
9590
|
+
envId,
|
|
9591
|
+
uids,
|
|
9592
|
+
raw: result,
|
|
9593
|
+
}, "应用用户删除成功");
|
|
9594
|
+
}
|
|
9595
|
+
}
|
|
9596
|
+
}));
|
|
9597
|
+
}
|
|
9598
|
+
|
|
9599
|
+
|
|
9600
|
+
/***/ }),
|
|
9601
|
+
|
|
9602
|
+
/***/ 6556:
|
|
9603
|
+
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
9604
|
+
|
|
9605
|
+
|
|
9606
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9607
|
+
if (k2 === undefined) k2 = k;
|
|
9608
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9609
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9610
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8463
9611
|
}
|
|
8464
9612
|
Object.defineProperty(o, k2, desc);
|
|
8465
9613
|
}) : (function(o, m, k, k2) {
|
|
@@ -8914,7 +10062,7 @@ function registerSetupTools(server) {
|
|
|
8914
10062
|
title: "下载项目模板",
|
|
8915
10063
|
description: `自动下载并部署CloudBase项目模板。⚠️ **MANDATORY FOR NEW PROJECTS** ⚠️
|
|
8916
10064
|
|
|
8917
|
-
**CRITICAL**: This tool MUST be called FIRST when starting a new project.\n\n支持的模板:\n- react: React + CloudBase 全栈应用模板\n- vue: Vue + CloudBase 全栈应用模板\n- miniprogram: 微信小程序 + 云开发模板 \n- uniapp: UniApp + CloudBase 跨端应用模板\n- rules: 只包含AI编辑器配置文件(包含Cursor、WindSurf、CodeBuddy等所有主流编辑器配置),适合在已有项目中补充AI编辑器配置\n\n支持的IDE类型:\n- all: 下载所有IDE配置\n- cursor: Cursor AI编辑器\n- 其他IDE类型见下方列表\n\n注意:如果未传入 ide 参数且无法从环境变量检测到 IDE,将提示错误并要求传入 ide 参数\n- windsurf: WindSurf AI编辑器\n- codebuddy: CodeBuddy AI编辑器\n- claude-code: Claude Code AI编辑器\n- cline: Cline AI编辑器\n- gemini-cli: Gemini CLI\n- opencode: OpenCode AI编辑器\n- qwen-code: 通义灵码\n- baidu-comate: 百度Comate\n- openai-codex-cli: OpenAI Codex CLI\n- augment-code: Augment Code\n- github-copilot: GitHub Copilot\n- roocode: RooCode AI编辑器\n- tongyi-lingma: 通义灵码\n- trae: Trae AI编辑器\n- qoder: Qoder AI编辑器\n- antigravity: Google Antigravity AI编辑器\n- vscode: Visual Studio Code\n- kiro: Kiro AI编辑器\n- aider: Aider AI编辑器\n\n特别说明:\n- rules 模板会自动包含当前 mcp 版本号信息(版本号:${ true ? "2.
|
|
10065
|
+
**CRITICAL**: This tool MUST be called FIRST when starting a new project.\n\n支持的模板:\n- react: React + CloudBase 全栈应用模板\n- vue: Vue + CloudBase 全栈应用模板\n- miniprogram: 微信小程序 + 云开发模板 \n- uniapp: UniApp + CloudBase 跨端应用模板\n- rules: 只包含AI编辑器配置文件(包含Cursor、WindSurf、CodeBuddy等所有主流编辑器配置),适合在已有项目中补充AI编辑器配置\n\n支持的IDE类型:\n- all: 下载所有IDE配置\n- cursor: Cursor AI编辑器\n- 其他IDE类型见下方列表\n\n注意:如果未传入 ide 参数且无法从环境变量检测到 IDE,将提示错误并要求传入 ide 参数\n- windsurf: WindSurf AI编辑器\n- codebuddy: CodeBuddy AI编辑器\n- claude-code: Claude Code AI编辑器\n- cline: Cline AI编辑器\n- gemini-cli: Gemini CLI\n- opencode: OpenCode AI编辑器\n- qwen-code: 通义灵码\n- baidu-comate: 百度Comate\n- openai-codex-cli: OpenAI Codex CLI\n- augment-code: Augment Code\n- github-copilot: GitHub Copilot\n- roocode: RooCode AI编辑器\n- tongyi-lingma: 通义灵码\n- trae: Trae AI编辑器\n- qoder: Qoder AI编辑器\n- antigravity: Google Antigravity AI编辑器\n- vscode: Visual Studio Code\n- kiro: Kiro AI编辑器\n- aider: Aider AI编辑器\n\n特别说明:\n- rules 模板会自动包含当前 mcp 版本号信息(版本号:${ true ? "2.16.0-beta.1" : 0}),便于后续维护和版本追踪\n- 下载 rules 模板时,如果项目中已存在 README.md 文件,系统会自动保护该文件不被覆盖(除非设置 overwrite=true)`,
|
|
8918
10066
|
inputSchema: {
|
|
8919
10067
|
template: zod_1.z
|
|
8920
10068
|
.enum(["react", "vue", "miniprogram", "uniapp", "rules"])
|
|
@@ -9098,6 +10246,228 @@ function registerSetupTools(server) {
|
|
|
9098
10246
|
|
|
9099
10247
|
module.exports = __WEBPACK_EXTERNAL_MODULE__cloudbase_manager_node_6a52ea40__;
|
|
9100
10248
|
|
|
10249
|
+
/***/ }),
|
|
10250
|
+
|
|
10251
|
+
/***/ 6817:
|
|
10252
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
10253
|
+
|
|
10254
|
+
|
|
10255
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
10256
|
+
exports.registerAppTools = registerAppTools;
|
|
10257
|
+
const zod_1 = __webpack_require__(2971);
|
|
10258
|
+
const cloudbase_manager_js_1 = __webpack_require__(3431);
|
|
10259
|
+
const json_content_js_1 = __webpack_require__(4365);
|
|
10260
|
+
const QUERY_APP_ACTIONS = ["listApps", "getApp", "listAppVersions", "getAppVersion"];
|
|
10261
|
+
const MANAGE_APP_ACTIONS = ["deployApp", "deleteApp", "deleteAppVersion"];
|
|
10262
|
+
function buildEnvelope(data, message) {
|
|
10263
|
+
return {
|
|
10264
|
+
success: true,
|
|
10265
|
+
data,
|
|
10266
|
+
message,
|
|
10267
|
+
};
|
|
10268
|
+
}
|
|
10269
|
+
function buildErrorEnvelope(error) {
|
|
10270
|
+
return {
|
|
10271
|
+
success: false,
|
|
10272
|
+
data: {},
|
|
10273
|
+
message: error instanceof Error ? error.message : String(error),
|
|
10274
|
+
};
|
|
10275
|
+
}
|
|
10276
|
+
function getCloudAppService(cloudbase) {
|
|
10277
|
+
return cloudbase.cloudAppService ?? cloudbase.getCloudAppService?.();
|
|
10278
|
+
}
|
|
10279
|
+
function registerAppTools(server) {
|
|
10280
|
+
const cloudBaseOptions = server.cloudBaseOptions;
|
|
10281
|
+
const getManager = () => (0, cloudbase_manager_js_1.getCloudBaseManager)({ cloudBaseOptions });
|
|
10282
|
+
server.registerTool?.("queryApps", {
|
|
10283
|
+
title: "查询 CloudApp",
|
|
10284
|
+
description: "CloudApp 域统一只读入口。支持应用、版本列表与版本详情查询。",
|
|
10285
|
+
inputSchema: {
|
|
10286
|
+
action: zod_1.z.enum(QUERY_APP_ACTIONS),
|
|
10287
|
+
serviceName: zod_1.z.string().optional(),
|
|
10288
|
+
searchKey: zod_1.z.string().optional(),
|
|
10289
|
+
pageNo: zod_1.z.number().optional(),
|
|
10290
|
+
pageSize: zod_1.z.number().optional(),
|
|
10291
|
+
versionName: zod_1.z.string().optional(),
|
|
10292
|
+
buildId: zod_1.z.string().optional(),
|
|
10293
|
+
},
|
|
10294
|
+
annotations: {
|
|
10295
|
+
readOnlyHint: true,
|
|
10296
|
+
openWorldHint: true,
|
|
10297
|
+
category: "apps",
|
|
10298
|
+
},
|
|
10299
|
+
}, async ({ action, serviceName, searchKey, pageNo, pageSize, versionName, buildId, }) => {
|
|
10300
|
+
try {
|
|
10301
|
+
const cloudbase = await getManager();
|
|
10302
|
+
const appService = getCloudAppService(cloudbase);
|
|
10303
|
+
if (!appService) {
|
|
10304
|
+
throw new Error("当前 manager 未提供 cloudAppService");
|
|
10305
|
+
}
|
|
10306
|
+
if (action === "listApps") {
|
|
10307
|
+
const result = await appService.describeAppList({
|
|
10308
|
+
deployType: "static-hosting",
|
|
10309
|
+
pageNo: pageNo ?? 1,
|
|
10310
|
+
pageSize: pageSize ?? 20,
|
|
10311
|
+
searchKey,
|
|
10312
|
+
});
|
|
10313
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
10314
|
+
return (0, json_content_js_1.jsonContent)(buildEnvelope({
|
|
10315
|
+
action,
|
|
10316
|
+
apps: result.ServiceList ?? [],
|
|
10317
|
+
total: result.Total ?? 0,
|
|
10318
|
+
raw: result,
|
|
10319
|
+
}, "CloudApp 列表查询成功"));
|
|
10320
|
+
}
|
|
10321
|
+
if (!serviceName) {
|
|
10322
|
+
throw new Error(`action=${action} 时必须提供 serviceName`);
|
|
10323
|
+
}
|
|
10324
|
+
if (action === "getApp") {
|
|
10325
|
+
const result = await appService.describeAppInfo({
|
|
10326
|
+
deployType: "static-hosting",
|
|
10327
|
+
serviceName,
|
|
10328
|
+
});
|
|
10329
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
10330
|
+
return (0, json_content_js_1.jsonContent)(buildEnvelope({
|
|
10331
|
+
action,
|
|
10332
|
+
serviceName,
|
|
10333
|
+
app: result,
|
|
10334
|
+
}, "CloudApp 详情查询成功"));
|
|
10335
|
+
}
|
|
10336
|
+
if (action === "listAppVersions") {
|
|
10337
|
+
const result = await appService.describeAppVersionList({
|
|
10338
|
+
deployType: "static-hosting",
|
|
10339
|
+
serviceName,
|
|
10340
|
+
pageNo: pageNo ?? 1,
|
|
10341
|
+
pageSize: pageSize ?? 20,
|
|
10342
|
+
});
|
|
10343
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
10344
|
+
return (0, json_content_js_1.jsonContent)(buildEnvelope({
|
|
10345
|
+
action,
|
|
10346
|
+
serviceName,
|
|
10347
|
+
versions: result.VersionList ?? [],
|
|
10348
|
+
total: result.Total ?? 0,
|
|
10349
|
+
raw: result,
|
|
10350
|
+
}, "CloudApp 版本列表查询成功"));
|
|
10351
|
+
}
|
|
10352
|
+
const result = await appService.describeAppVersion({
|
|
10353
|
+
deployType: "static-hosting",
|
|
10354
|
+
serviceName,
|
|
10355
|
+
versionName,
|
|
10356
|
+
buildId,
|
|
10357
|
+
});
|
|
10358
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
10359
|
+
return (0, json_content_js_1.jsonContent)(buildEnvelope({
|
|
10360
|
+
action,
|
|
10361
|
+
serviceName,
|
|
10362
|
+
version: result,
|
|
10363
|
+
}, "CloudApp 版本详情查询成功"));
|
|
10364
|
+
}
|
|
10365
|
+
catch (error) {
|
|
10366
|
+
return (0, json_content_js_1.jsonContent)(buildErrorEnvelope(error));
|
|
10367
|
+
}
|
|
10368
|
+
});
|
|
10369
|
+
server.registerTool?.("manageApps", {
|
|
10370
|
+
title: "管理 CloudApp",
|
|
10371
|
+
description: "CloudApp 域统一写入口。首轮仅支持静态部署、删除应用和删除版本。",
|
|
10372
|
+
inputSchema: {
|
|
10373
|
+
action: zod_1.z.enum(MANAGE_APP_ACTIONS),
|
|
10374
|
+
serviceName: zod_1.z.string(),
|
|
10375
|
+
localPath: zod_1.z.string().optional(),
|
|
10376
|
+
appPath: zod_1.z.string().optional(),
|
|
10377
|
+
buildPath: zod_1.z.string().optional(),
|
|
10378
|
+
framework: zod_1.z.string().optional(),
|
|
10379
|
+
nodeJsVersion: zod_1.z.string().optional(),
|
|
10380
|
+
installCmd: zod_1.z.string().optional(),
|
|
10381
|
+
buildCmd: zod_1.z.string().optional(),
|
|
10382
|
+
deployCmd: zod_1.z.string().optional(),
|
|
10383
|
+
ignore: zod_1.z.array(zod_1.z.string()).optional(),
|
|
10384
|
+
versionName: zod_1.z.string().optional(),
|
|
10385
|
+
},
|
|
10386
|
+
annotations: {
|
|
10387
|
+
readOnlyHint: false,
|
|
10388
|
+
destructiveHint: true,
|
|
10389
|
+
idempotentHint: false,
|
|
10390
|
+
openWorldHint: true,
|
|
10391
|
+
category: "apps",
|
|
10392
|
+
},
|
|
10393
|
+
}, async ({ action, serviceName, localPath, appPath, buildPath, framework, nodeJsVersion, installCmd, buildCmd, deployCmd, ignore, versionName, }) => {
|
|
10394
|
+
try {
|
|
10395
|
+
const cloudbase = await getManager();
|
|
10396
|
+
const appService = getCloudAppService(cloudbase);
|
|
10397
|
+
if (!appService) {
|
|
10398
|
+
throw new Error("当前 manager 未提供 cloudAppService");
|
|
10399
|
+
}
|
|
10400
|
+
if (action === "deployApp") {
|
|
10401
|
+
if (!localPath) {
|
|
10402
|
+
throw new Error("action=deployApp 时必须提供 localPath");
|
|
10403
|
+
}
|
|
10404
|
+
const uploadResult = await appService.uploadCode({
|
|
10405
|
+
deployType: "static-hosting",
|
|
10406
|
+
serviceName,
|
|
10407
|
+
localPath,
|
|
10408
|
+
ignore,
|
|
10409
|
+
});
|
|
10410
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, uploadResult);
|
|
10411
|
+
const result = await appService.createApp({
|
|
10412
|
+
deployType: "static-hosting",
|
|
10413
|
+
serviceName,
|
|
10414
|
+
buildType: "ZIP",
|
|
10415
|
+
staticConfig: {
|
|
10416
|
+
appPath,
|
|
10417
|
+
buildPath,
|
|
10418
|
+
framework,
|
|
10419
|
+
nodeJsVersion,
|
|
10420
|
+
cosTimestamp: uploadResult.cosTimestamp,
|
|
10421
|
+
staticCmd: {
|
|
10422
|
+
installCmd,
|
|
10423
|
+
buildCmd,
|
|
10424
|
+
deployCmd,
|
|
10425
|
+
},
|
|
10426
|
+
},
|
|
10427
|
+
});
|
|
10428
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
10429
|
+
return (0, json_content_js_1.jsonContent)(buildEnvelope({
|
|
10430
|
+
action,
|
|
10431
|
+
serviceName,
|
|
10432
|
+
upload: uploadResult,
|
|
10433
|
+
deployment: result,
|
|
10434
|
+
}, "CloudApp 部署成功"));
|
|
10435
|
+
}
|
|
10436
|
+
if (action === "deleteApp") {
|
|
10437
|
+
const result = await appService.deleteApp({
|
|
10438
|
+
deployType: "static-hosting",
|
|
10439
|
+
serviceName,
|
|
10440
|
+
});
|
|
10441
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
10442
|
+
return (0, json_content_js_1.jsonContent)(buildEnvelope({
|
|
10443
|
+
action,
|
|
10444
|
+
serviceName,
|
|
10445
|
+
raw: result,
|
|
10446
|
+
}, "CloudApp 删除成功"));
|
|
10447
|
+
}
|
|
10448
|
+
if (!versionName) {
|
|
10449
|
+
throw new Error("action=deleteAppVersion 时必须提供 versionName");
|
|
10450
|
+
}
|
|
10451
|
+
const result = await appService.deleteAppVersion({
|
|
10452
|
+
deployType: "static-hosting",
|
|
10453
|
+
serviceName,
|
|
10454
|
+
versionName,
|
|
10455
|
+
});
|
|
10456
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
10457
|
+
return (0, json_content_js_1.jsonContent)(buildEnvelope({
|
|
10458
|
+
action,
|
|
10459
|
+
serviceName,
|
|
10460
|
+
versionName,
|
|
10461
|
+
raw: result,
|
|
10462
|
+
}, "CloudApp 版本删除成功"));
|
|
10463
|
+
}
|
|
10464
|
+
catch (error) {
|
|
10465
|
+
return (0, json_content_js_1.jsonContent)(buildErrorEnvelope(error));
|
|
10466
|
+
}
|
|
10467
|
+
});
|
|
10468
|
+
}
|
|
10469
|
+
|
|
10470
|
+
|
|
9101
10471
|
/***/ }),
|
|
9102
10472
|
|
|
9103
10473
|
/***/ 6887:
|
|
@@ -9920,7 +11290,7 @@ exports.getLoginState = getLoginState;
|
|
|
9920
11290
|
exports.logout = logout;
|
|
9921
11291
|
const toolbox_1 = __webpack_require__(2090);
|
|
9922
11292
|
const logger_js_1 = __webpack_require__(3039);
|
|
9923
|
-
const
|
|
11293
|
+
const tencent_cloud_js_1 = __webpack_require__(1454);
|
|
9924
11294
|
const auth = toolbox_1.AuthSupervisor.getInstance({});
|
|
9925
11295
|
const authProgressState = {
|
|
9926
11296
|
status: "IDLE",
|
|
@@ -10109,7 +11479,7 @@ async function peekLoginState(options) {
|
|
|
10109
11479
|
return auth.getLoginState();
|
|
10110
11480
|
}
|
|
10111
11481
|
async function ensureLogin(options) {
|
|
10112
|
-
(0, logger_js_1.debug)("TENCENTCLOUD_SECRETID", {
|
|
11482
|
+
(0, logger_js_1.debug)("TENCENTCLOUD_SECRETID", { hasSecretId: !!process.env.TENCENTCLOUD_SECRETID });
|
|
10113
11483
|
const loginState = await peekLoginState({
|
|
10114
11484
|
ignoreEnvVars: options?.ignoreEnvVars,
|
|
10115
11485
|
});
|
|
@@ -10130,14 +11500,14 @@ async function ensureLogin(options) {
|
|
|
10130
11500
|
const loginOptions = { flow: mode };
|
|
10131
11501
|
if (mode === "web") {
|
|
10132
11502
|
loginOptions.getAuthUrl =
|
|
10133
|
-
options?.fromCloudBaseLoginPage && !(0,
|
|
11503
|
+
options?.fromCloudBaseLoginPage && !(0, tencent_cloud_js_1.isInternationalRegion)(options?.region)
|
|
10134
11504
|
? (url) => {
|
|
10135
11505
|
const separator = url.includes("?") ? "&" : "?";
|
|
10136
11506
|
const urlWithParam = `${url}${separator}allowNoEnv=true`;
|
|
10137
11507
|
return `https://tcb.cloud.tencent.com/login?_redirect_uri=${encodeURIComponent(urlWithParam)}`;
|
|
10138
11508
|
}
|
|
10139
11509
|
: (url) => {
|
|
10140
|
-
if ((0,
|
|
11510
|
+
if ((0, tencent_cloud_js_1.isInternationalRegion)(options?.region)) {
|
|
10141
11511
|
url = url.replace("cloud.tencent.com", "tencentcloud.com");
|
|
10142
11512
|
}
|
|
10143
11513
|
const separator = url.includes("?") ? "&" : "?";
|
|
@@ -10205,332 +11575,6 @@ module.exports = __WEBPACK_EXTERNAL_MODULE_dns__;
|
|
|
10205
11575
|
|
|
10206
11576
|
module.exports = __WEBPACK_EXTERNAL_MODULE_crypto__;
|
|
10207
11577
|
|
|
10208
|
-
/***/ }),
|
|
10209
|
-
|
|
10210
|
-
/***/ 7862:
|
|
10211
|
-
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
10212
|
-
|
|
10213
|
-
|
|
10214
|
-
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
10215
|
-
exports.WRITE_SECURITY_RULE = exports.READ_SECURITY_RULE = void 0;
|
|
10216
|
-
exports.normalizeCustomSecurityRule = normalizeCustomSecurityRule;
|
|
10217
|
-
exports.buildSecurityRuleErrorMessage = buildSecurityRuleErrorMessage;
|
|
10218
|
-
exports.registerSecurityRuleTools = registerSecurityRuleTools;
|
|
10219
|
-
const zod_1 = __webpack_require__(2971);
|
|
10220
|
-
const cloudbase_manager_js_1 = __webpack_require__(3431);
|
|
10221
|
-
exports.READ_SECURITY_RULE = "readSecurityRule";
|
|
10222
|
-
exports.WRITE_SECURITY_RULE = "writeSecurityRule";
|
|
10223
|
-
const FUNCTION_CUSTOM_RULE_EXAMPLE = JSON.stringify({
|
|
10224
|
-
"*": {
|
|
10225
|
-
invoke: true,
|
|
10226
|
-
},
|
|
10227
|
-
}, null, 2);
|
|
10228
|
-
function isPlainObject(value) {
|
|
10229
|
-
return (typeof value === "object" &&
|
|
10230
|
-
value !== null &&
|
|
10231
|
-
!Array.isArray(value));
|
|
10232
|
-
}
|
|
10233
|
-
function formatSecurityRuleInputHint(resourceType) {
|
|
10234
|
-
if (resourceType === "function") {
|
|
10235
|
-
return `函数自定义安全规则应传 JSON 对象或 JSON 字符串,例如 ${FUNCTION_CUSTOM_RULE_EXAMPLE}。`;
|
|
10236
|
-
}
|
|
10237
|
-
if (resourceType === "noSqlDatabase") {
|
|
10238
|
-
return "NoSQL 自定义安全规则应传 JSON 对象或 JSON 字符串,例如 {\"read\":\"true\",\"write\":\"true\"}。";
|
|
10239
|
-
}
|
|
10240
|
-
return "自定义安全规则应传 JSON 对象或 JSON 字符串,并与 readSecurityRule 返回的规则结构保持一致。";
|
|
10241
|
-
}
|
|
10242
|
-
function normalizeCustomSecurityRule(resourceType, rule) {
|
|
10243
|
-
if (rule === undefined) {
|
|
10244
|
-
throw new Error(`resourceType=${resourceType} 且 aclTag=CUSTOM 时必须提供 rule 字段`);
|
|
10245
|
-
}
|
|
10246
|
-
if (typeof rule === "string") {
|
|
10247
|
-
try {
|
|
10248
|
-
const parsed = JSON.parse(rule);
|
|
10249
|
-
if (!isPlainObject(parsed)) {
|
|
10250
|
-
throw new Error(`rule 必须是 JSON 对象,不支持 ${Array.isArray(parsed) ? "数组" : typeof parsed}。`);
|
|
10251
|
-
}
|
|
10252
|
-
return JSON.stringify(parsed);
|
|
10253
|
-
}
|
|
10254
|
-
catch (error) {
|
|
10255
|
-
const baseMessage = error instanceof Error ? error.message : "rule 不是合法的 JSON 字符串";
|
|
10256
|
-
throw new Error(`${baseMessage} ${formatSecurityRuleInputHint(resourceType)}`);
|
|
10257
|
-
}
|
|
10258
|
-
}
|
|
10259
|
-
if (!isPlainObject(rule)) {
|
|
10260
|
-
throw new Error(`rule 必须是 JSON 对象或 JSON 字符串。${formatSecurityRuleInputHint(resourceType)}`);
|
|
10261
|
-
}
|
|
10262
|
-
return JSON.stringify(rule);
|
|
10263
|
-
}
|
|
10264
|
-
function buildSecurityRuleErrorMessage(operation, resourceType, aclTag, error) {
|
|
10265
|
-
const baseMessage = error instanceof Error ? error.message : String(error);
|
|
10266
|
-
const suggestions = [];
|
|
10267
|
-
if (operation === "writeSecurityRule" && aclTag === "CUSTOM") {
|
|
10268
|
-
suggestions.push(formatSecurityRuleInputHint(resourceType));
|
|
10269
|
-
}
|
|
10270
|
-
if (/INVALID_VALUE|ModifySecurityRule|错误的值|JSON/i.test(baseMessage)) {
|
|
10271
|
-
suggestions.push("请先把 CUSTOM 规则整理成 JSON 对象,再传给 writeSecurityRule。");
|
|
10272
|
-
}
|
|
10273
|
-
if (suggestions.length === 0) {
|
|
10274
|
-
suggestions.push("请检查 resourceType、aclTag 和 rule 是否与官方安全规则格式一致后重试。");
|
|
10275
|
-
}
|
|
10276
|
-
return `[${operation}] 调用失败: ${baseMessage}\n建议:${suggestions.join(" ")}`;
|
|
10277
|
-
}
|
|
10278
|
-
/**
|
|
10279
|
-
* 注册安全规则相关 Tool
|
|
10280
|
-
* @param server MCP Server 实例
|
|
10281
|
-
*/
|
|
10282
|
-
function registerSecurityRuleTools(server) {
|
|
10283
|
-
const cloudBaseOptions = server.cloudBaseOptions;
|
|
10284
|
-
const getManager = () => (0, cloudbase_manager_js_1.getCloudBaseManager)({ cloudBaseOptions });
|
|
10285
|
-
// 读取安全规则 Tool
|
|
10286
|
-
server.registerTool?.(exports.READ_SECURITY_RULE, {
|
|
10287
|
-
title: "读取安全规则",
|
|
10288
|
-
description: `读取指定资源(noSQL 数据库、SQL 数据库、云函数、存储桶)的安全规则和权限类别。\n\n安全规则文档:\n- 云函数安全规则:https://docs.cloudbase.net/cloud-function/security-rules\n- 存储安全规则:https://docs.cloudbase.net/storage/security-rules\n- 文档型数据库安全规则:https://docs.cloudbase.net/database/security-rules`,
|
|
10289
|
-
inputSchema: {
|
|
10290
|
-
resourceType: zod_1.z
|
|
10291
|
-
.enum(["noSqlDatabase", "sqlDatabase", "function", "storage"])
|
|
10292
|
-
.describe("资源类型:noSqlDatabase=noSQL 数据库,sqlDatabase=SQL 数据库,function=云函数,storage=存储桶"),
|
|
10293
|
-
resourceId: zod_1.z
|
|
10294
|
-
.string()
|
|
10295
|
-
.describe("资源唯一标识。noSQL 数据库为集合名,SQL 数据库为表名,云函数为函数名,存储为桶名(完整格式如 '6169-xxx-1257473911',可通过 envQuery action=info 获取 EnvInfo.Storages[].Bucket)。"),
|
|
10296
|
-
},
|
|
10297
|
-
annotations: {
|
|
10298
|
-
readOnlyHint: true,
|
|
10299
|
-
openWorldHint: true,
|
|
10300
|
-
category: "security-rule",
|
|
10301
|
-
},
|
|
10302
|
-
}, async ({ resourceType, resourceId }) => {
|
|
10303
|
-
const envId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
10304
|
-
const cloudbase = await getManager();
|
|
10305
|
-
let result;
|
|
10306
|
-
if (resourceType === "noSqlDatabase") {
|
|
10307
|
-
result = await cloudbase.commonService().call({
|
|
10308
|
-
Action: "DescribeSafeRule",
|
|
10309
|
-
Param: {
|
|
10310
|
-
CollectionName: resourceId,
|
|
10311
|
-
EnvId: envId,
|
|
10312
|
-
},
|
|
10313
|
-
});
|
|
10314
|
-
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
10315
|
-
}
|
|
10316
|
-
else if (resourceType === "function") {
|
|
10317
|
-
result = await cloudbase.commonService().call({
|
|
10318
|
-
Action: "DescribeSecurityRule",
|
|
10319
|
-
Param: {
|
|
10320
|
-
ResourceType: "FUNCTION",
|
|
10321
|
-
EnvId: envId,
|
|
10322
|
-
},
|
|
10323
|
-
});
|
|
10324
|
-
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
10325
|
-
}
|
|
10326
|
-
else if (resourceType === "storage") {
|
|
10327
|
-
result = await cloudbase.commonService().call({
|
|
10328
|
-
Action: "DescribeStorageSafeRule",
|
|
10329
|
-
Param: {
|
|
10330
|
-
Bucket: resourceId,
|
|
10331
|
-
EnvId: envId,
|
|
10332
|
-
},
|
|
10333
|
-
});
|
|
10334
|
-
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
10335
|
-
}
|
|
10336
|
-
else if (resourceType === "sqlDatabase") {
|
|
10337
|
-
const instanceId = "default";
|
|
10338
|
-
const schema = envId;
|
|
10339
|
-
const tableName = resourceId;
|
|
10340
|
-
result = await cloudbase.commonService("lowcode").call({
|
|
10341
|
-
Action: "DescribeDataSourceBasicPolicy",
|
|
10342
|
-
Param: {
|
|
10343
|
-
EnvId: envId,
|
|
10344
|
-
ResourceType: "table",
|
|
10345
|
-
ResourceId: `${instanceId}#${schema}#${tableName}`,
|
|
10346
|
-
RoleIdentityList: ["allUser"],
|
|
10347
|
-
},
|
|
10348
|
-
});
|
|
10349
|
-
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
10350
|
-
}
|
|
10351
|
-
else {
|
|
10352
|
-
throw new Error(`不支持的资源类型: ${resourceType}`);
|
|
10353
|
-
}
|
|
10354
|
-
return {
|
|
10355
|
-
content: [
|
|
10356
|
-
{
|
|
10357
|
-
type: "text",
|
|
10358
|
-
text: JSON.stringify({
|
|
10359
|
-
success: true,
|
|
10360
|
-
resourceType,
|
|
10361
|
-
resourceId,
|
|
10362
|
-
aclTag: result.AclTag,
|
|
10363
|
-
rule: result.Rule ?? null,
|
|
10364
|
-
raw: result,
|
|
10365
|
-
message: "安全规则读取成功",
|
|
10366
|
-
}, null, 2),
|
|
10367
|
-
},
|
|
10368
|
-
],
|
|
10369
|
-
};
|
|
10370
|
-
});
|
|
10371
|
-
// 写入安全规则 Tool
|
|
10372
|
-
server.registerTool?.(exports.WRITE_SECURITY_RULE, {
|
|
10373
|
-
title: "写入安全规则",
|
|
10374
|
-
description: `设置指定资源(数据库集合、云函数、存储桶)的安全规则。\n\n安全规则文档:\n- 云函数安全规则:https://docs.cloudbase.net/cloud-function/security-rules\n- 存储安全规则:https://docs.cloudbase.net/storage/security-rules\n- 数据库安全规则:https://docs.cloudbase.net/database/security-rules\n\n云函数安全规则仅支持 aclTag="CUSTOM",rule 字段为 JSON 字符串。例如放开所有访问可设置 rule="true"。`,
|
|
10375
|
-
inputSchema: {
|
|
10376
|
-
resourceType: zod_1.z
|
|
10377
|
-
.enum(["sqlDatabase", "noSqlDatabase", "function", "storage"])
|
|
10378
|
-
.describe("资源类型:sqlDatabase=SQL 数据库,noSqlDatabase=noSQL 数据库,function=云函数,storage=存储桶"),
|
|
10379
|
-
resourceId: zod_1.z
|
|
10380
|
-
.string()
|
|
10381
|
-
.describe("资源唯一标识。sqlDatabase=表名,noSqlDatabase=集合名,云函数为函数名,存储为桶名(完整格式如 '6169-xxx-1257473911',可通过 envQuery action=info 获取 EnvInfo.Storages[].Bucket)。"),
|
|
10382
|
-
aclTag: zod_1.z
|
|
10383
|
-
.enum(["READONLY", "PRIVATE", "ADMINWRITE", "ADMINONLY", "CUSTOM"])
|
|
10384
|
-
.describe("权限类别"),
|
|
10385
|
-
rule: zod_1.z
|
|
10386
|
-
.union([zod_1.z.string(), zod_1.z.record(zod_1.z.any())])
|
|
10387
|
-
.optional()
|
|
10388
|
-
.describe(`自定义安全规则内容,仅当 aclTag 为 CUSTOM 时必填。可以直接传 JSON 对象,或者传可解析为 JSON 对象的字符串。函数示例:${FUNCTION_CUSTOM_RULE_EXAMPLE}`),
|
|
10389
|
-
},
|
|
10390
|
-
annotations: {
|
|
10391
|
-
readOnlyHint: false,
|
|
10392
|
-
openWorldHint: true,
|
|
10393
|
-
category: "security-rule",
|
|
10394
|
-
},
|
|
10395
|
-
}, async ({ resourceType, resourceId, aclTag, rule }) => {
|
|
10396
|
-
try {
|
|
10397
|
-
const cloudbase = await getManager();
|
|
10398
|
-
const envId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
10399
|
-
let result;
|
|
10400
|
-
if (resourceType === "noSqlDatabase") {
|
|
10401
|
-
if (aclTag === "CUSTOM") {
|
|
10402
|
-
const normalizedRule = normalizeCustomSecurityRule(resourceType, rule);
|
|
10403
|
-
result = await cloudbase.commonService().call({
|
|
10404
|
-
Action: "ModifySafeRule",
|
|
10405
|
-
Param: {
|
|
10406
|
-
CollectionName: resourceId,
|
|
10407
|
-
EnvId: envId,
|
|
10408
|
-
AclTag: aclTag,
|
|
10409
|
-
Rule: normalizedRule,
|
|
10410
|
-
},
|
|
10411
|
-
});
|
|
10412
|
-
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
10413
|
-
}
|
|
10414
|
-
else {
|
|
10415
|
-
result = await cloudbase.commonService().call({
|
|
10416
|
-
Action: "ModifyDatabaseACL",
|
|
10417
|
-
Param: {
|
|
10418
|
-
CollectionName: resourceId,
|
|
10419
|
-
EnvId: envId,
|
|
10420
|
-
AclTag: aclTag,
|
|
10421
|
-
},
|
|
10422
|
-
});
|
|
10423
|
-
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
10424
|
-
}
|
|
10425
|
-
}
|
|
10426
|
-
else if (resourceType === "function") {
|
|
10427
|
-
if (aclTag !== "CUSTOM")
|
|
10428
|
-
throw new Error("云函数安全规则仅支持 CUSTOM 权限类别");
|
|
10429
|
-
const normalizedRule = normalizeCustomSecurityRule(resourceType, rule);
|
|
10430
|
-
result = await cloudbase.commonService().call({
|
|
10431
|
-
Action: "ModifySecurityRule",
|
|
10432
|
-
Param: {
|
|
10433
|
-
AclTag: aclTag,
|
|
10434
|
-
EnvId: envId,
|
|
10435
|
-
ResourceType: "FUNCTION",
|
|
10436
|
-
Rule: normalizedRule,
|
|
10437
|
-
},
|
|
10438
|
-
});
|
|
10439
|
-
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
10440
|
-
}
|
|
10441
|
-
else if (resourceType === "storage") {
|
|
10442
|
-
if (aclTag === "CUSTOM") {
|
|
10443
|
-
const normalizedRule = normalizeCustomSecurityRule(resourceType, rule);
|
|
10444
|
-
result = await cloudbase.commonService().call({
|
|
10445
|
-
Action: "ModifyStorageSafeRule",
|
|
10446
|
-
Param: {
|
|
10447
|
-
Bucket: resourceId,
|
|
10448
|
-
EnvId: envId,
|
|
10449
|
-
AclTag: aclTag,
|
|
10450
|
-
Rule: normalizedRule,
|
|
10451
|
-
},
|
|
10452
|
-
});
|
|
10453
|
-
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
10454
|
-
}
|
|
10455
|
-
else {
|
|
10456
|
-
result = await cloudbase.commonService().call({
|
|
10457
|
-
Action: "ModifyStorageSafeRule",
|
|
10458
|
-
Param: {
|
|
10459
|
-
Bucket: resourceId,
|
|
10460
|
-
EnvId: envId,
|
|
10461
|
-
AclTag: aclTag,
|
|
10462
|
-
},
|
|
10463
|
-
});
|
|
10464
|
-
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
10465
|
-
}
|
|
10466
|
-
}
|
|
10467
|
-
else if (resourceType === "sqlDatabase") {
|
|
10468
|
-
if (aclTag === "CUSTOM") {
|
|
10469
|
-
throw new Error("SQL 数据库不支持自定义安全规则(CUSTOM)");
|
|
10470
|
-
}
|
|
10471
|
-
const schema = envId;
|
|
10472
|
-
const tableName = resourceId;
|
|
10473
|
-
const instanceId = "default";
|
|
10474
|
-
const resource = `${instanceId}#${schema}#${tableName}`;
|
|
10475
|
-
const resourceType = "table";
|
|
10476
|
-
const effect = "allow";
|
|
10477
|
-
const policyList = [
|
|
10478
|
-
"allUser",
|
|
10479
|
-
"anonymousUser",
|
|
10480
|
-
"externalUser",
|
|
10481
|
-
"internalUser",
|
|
10482
|
-
].map((roleIdentity) => ({
|
|
10483
|
-
RoleIdentity: roleIdentity,
|
|
10484
|
-
ResourceType: resourceType,
|
|
10485
|
-
ResourceId: resource,
|
|
10486
|
-
RowPermission: [],
|
|
10487
|
-
Effect: effect,
|
|
10488
|
-
}));
|
|
10489
|
-
policyList[0].RowPermission = getRowPermission(aclTag);
|
|
10490
|
-
result = await cloudbase.commonService("lowcode").call({
|
|
10491
|
-
Action: "BatchCreateResourcePolicy",
|
|
10492
|
-
Param: {
|
|
10493
|
-
EnvId: envId,
|
|
10494
|
-
PolicyList: policyList,
|
|
10495
|
-
},
|
|
10496
|
-
});
|
|
10497
|
-
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
10498
|
-
function getRowPermission(policy) {
|
|
10499
|
-
return {
|
|
10500
|
-
READONLY: [
|
|
10501
|
-
{ Key: "all", Value: "r" },
|
|
10502
|
-
{ Key: "me", Value: "rw" },
|
|
10503
|
-
],
|
|
10504
|
-
PRIVATE: [{ Key: "me", Value: "rw" }],
|
|
10505
|
-
ADMINWRITE: [{ Key: "all", Value: "r" }],
|
|
10506
|
-
ADMINONLY: [],
|
|
10507
|
-
}[policy];
|
|
10508
|
-
}
|
|
10509
|
-
}
|
|
10510
|
-
else {
|
|
10511
|
-
throw new Error(`不支持的资源类型: ${resourceType}`);
|
|
10512
|
-
}
|
|
10513
|
-
return {
|
|
10514
|
-
content: [
|
|
10515
|
-
{
|
|
10516
|
-
type: "text",
|
|
10517
|
-
text: JSON.stringify({
|
|
10518
|
-
success: true,
|
|
10519
|
-
requestId: result.RequestId,
|
|
10520
|
-
raw: result,
|
|
10521
|
-
message: "安全规则写入成功",
|
|
10522
|
-
}, null, 2),
|
|
10523
|
-
},
|
|
10524
|
-
],
|
|
10525
|
-
};
|
|
10526
|
-
}
|
|
10527
|
-
catch (error) {
|
|
10528
|
-
throw new Error(buildSecurityRuleErrorMessage("writeSecurityRule", resourceType, aclTag, error));
|
|
10529
|
-
}
|
|
10530
|
-
});
|
|
10531
|
-
}
|
|
10532
|
-
|
|
10533
|
-
|
|
10534
11578
|
/***/ }),
|
|
10535
11579
|
|
|
10536
11580
|
/***/ 7932:
|
|
@@ -10967,7 +12011,7 @@ function isPrivateIP(ip) {
|
|
|
10967
12011
|
// 转换 IP 地址为长整数进行范围检查
|
|
10968
12012
|
const ipv4Parts = ip.split('.').map(part => parseInt(part, 10));
|
|
10969
12013
|
if (ipv4Parts.length === 4) {
|
|
10970
|
-
const ipNum = (ipv4Parts[0] << 24) + (ipv4Parts[1] << 16) + (ipv4Parts[2] << 8) + ipv4Parts[3];
|
|
12014
|
+
const ipNum = ((ipv4Parts[0] << 24) >>> 0) + (ipv4Parts[1] << 16) + (ipv4Parts[2] << 8) + ipv4Parts[3];
|
|
10971
12015
|
// 检查私有 IP 范围
|
|
10972
12016
|
// 10.0.0.0 - 10.255.255.255
|
|
10973
12017
|
if (ipNum >= 167772160 && ipNum <= 184549375)
|
|
@@ -11282,6 +12326,191 @@ function registerDownloadTools(server) {
|
|
|
11282
12326
|
|
|
11283
12327
|
module.exports = __WEBPACK_EXTERNAL_MODULE_winston__;
|
|
11284
12328
|
|
|
12329
|
+
/***/ }),
|
|
12330
|
+
|
|
12331
|
+
/***/ 9527:
|
|
12332
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
12333
|
+
|
|
12334
|
+
|
|
12335
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
12336
|
+
exports.registerAgentTools = registerAgentTools;
|
|
12337
|
+
const zod_1 = __webpack_require__(2971);
|
|
12338
|
+
const cloudbase_manager_js_1 = __webpack_require__(3431);
|
|
12339
|
+
const json_content_js_1 = __webpack_require__(4365);
|
|
12340
|
+
const QUERY_AGENT_ACTIONS = ["listAgents", "getAgent", "getAgentLogs"];
|
|
12341
|
+
const MANAGE_AGENT_ACTIONS = ["createAgent", "updateAgent", "deleteAgent"];
|
|
12342
|
+
function buildEnvelope(data, message) {
|
|
12343
|
+
return {
|
|
12344
|
+
success: true,
|
|
12345
|
+
data,
|
|
12346
|
+
message,
|
|
12347
|
+
};
|
|
12348
|
+
}
|
|
12349
|
+
function buildErrorEnvelope(error) {
|
|
12350
|
+
return {
|
|
12351
|
+
success: false,
|
|
12352
|
+
data: {},
|
|
12353
|
+
message: error instanceof Error ? error.message : String(error),
|
|
12354
|
+
};
|
|
12355
|
+
}
|
|
12356
|
+
function normalizeString(value) {
|
|
12357
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
|
|
12358
|
+
}
|
|
12359
|
+
function normalizeNumber(value) {
|
|
12360
|
+
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
12361
|
+
}
|
|
12362
|
+
function normalizeBoolean(value) {
|
|
12363
|
+
return typeof value === "boolean" ? value : undefined;
|
|
12364
|
+
}
|
|
12365
|
+
function normalizeAgentPayload(params) {
|
|
12366
|
+
if (!params) {
|
|
12367
|
+
return {};
|
|
12368
|
+
}
|
|
12369
|
+
const { name, agentId, runtime, timeout, memorySize, installDependency, ...rest } = params;
|
|
12370
|
+
return {
|
|
12371
|
+
...rest,
|
|
12372
|
+
...(normalizeString(name) ? { Name: normalizeString(name) } : {}),
|
|
12373
|
+
...(normalizeString(agentId) ? { AgentId: normalizeString(agentId) } : {}),
|
|
12374
|
+
...(normalizeString(runtime) ? { Runtime: normalizeString(runtime) } : {}),
|
|
12375
|
+
...(normalizeNumber(timeout) !== undefined ? { Timeout: normalizeNumber(timeout) } : {}),
|
|
12376
|
+
...(normalizeNumber(memorySize) !== undefined
|
|
12377
|
+
? { MemorySize: normalizeNumber(memorySize) }
|
|
12378
|
+
: {}),
|
|
12379
|
+
...(normalizeBoolean(installDependency) !== undefined
|
|
12380
|
+
? { InstallDependency: normalizeBoolean(installDependency) }
|
|
12381
|
+
: {}),
|
|
12382
|
+
};
|
|
12383
|
+
}
|
|
12384
|
+
function registerAgentTools(server) {
|
|
12385
|
+
const cloudBaseOptions = server.cloudBaseOptions;
|
|
12386
|
+
const getManager = () => (0, cloudbase_manager_js_1.getCloudBaseManager)({ cloudBaseOptions });
|
|
12387
|
+
server.registerTool?.("queryAgents", {
|
|
12388
|
+
title: "查询 Agent",
|
|
12389
|
+
description: "Agent 域统一只读入口。支持列表、详情与日志查询。",
|
|
12390
|
+
inputSchema: {
|
|
12391
|
+
action: zod_1.z.enum(QUERY_AGENT_ACTIONS),
|
|
12392
|
+
agentId: zod_1.z.string().optional(),
|
|
12393
|
+
pageNumber: zod_1.z.number().optional(),
|
|
12394
|
+
pageSize: zod_1.z.number().optional(),
|
|
12395
|
+
params: zod_1.z.record(zod_1.z.any()).optional(),
|
|
12396
|
+
},
|
|
12397
|
+
annotations: {
|
|
12398
|
+
readOnlyHint: true,
|
|
12399
|
+
openWorldHint: true,
|
|
12400
|
+
category: "agents",
|
|
12401
|
+
},
|
|
12402
|
+
}, async ({ action, agentId, pageNumber, pageSize, params, }) => {
|
|
12403
|
+
try {
|
|
12404
|
+
const cloudbase = await getManager();
|
|
12405
|
+
if (action === "listAgents") {
|
|
12406
|
+
const result = await cloudbase.agent.describeAgentList({
|
|
12407
|
+
PageNumber: pageNumber ?? 1,
|
|
12408
|
+
PageSize: pageSize ?? 20,
|
|
12409
|
+
});
|
|
12410
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
12411
|
+
return (0, json_content_js_1.jsonContent)(buildEnvelope({
|
|
12412
|
+
action,
|
|
12413
|
+
agents: result.AgentList ?? result.Agents ?? [],
|
|
12414
|
+
total: result.Total ?? 0,
|
|
12415
|
+
raw: result,
|
|
12416
|
+
}, "Agent 列表查询成功"));
|
|
12417
|
+
}
|
|
12418
|
+
if (!agentId) {
|
|
12419
|
+
throw new Error(`action=${action} 时必须提供 agentId`);
|
|
12420
|
+
}
|
|
12421
|
+
if (action === "getAgent") {
|
|
12422
|
+
const result = await cloudbase.agent.describeAgent(agentId);
|
|
12423
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
12424
|
+
return (0, json_content_js_1.jsonContent)(buildEnvelope({
|
|
12425
|
+
action,
|
|
12426
|
+
agentId,
|
|
12427
|
+
agent: result.AgentInfo ?? null,
|
|
12428
|
+
readiness: {
|
|
12429
|
+
isReady: result.IsReady,
|
|
12430
|
+
reason: result.NotReadyReason ?? null,
|
|
12431
|
+
},
|
|
12432
|
+
raw: result,
|
|
12433
|
+
}, "Agent 详情查询成功"));
|
|
12434
|
+
}
|
|
12435
|
+
const result = await cloudbase.agent.getAgentLogs({
|
|
12436
|
+
AgentId: agentId,
|
|
12437
|
+
...(params ?? {}),
|
|
12438
|
+
});
|
|
12439
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
12440
|
+
return (0, json_content_js_1.jsonContent)(buildEnvelope({
|
|
12441
|
+
action,
|
|
12442
|
+
agentId,
|
|
12443
|
+
logs: result,
|
|
12444
|
+
}, "Agent 日志查询成功"));
|
|
12445
|
+
}
|
|
12446
|
+
catch (error) {
|
|
12447
|
+
return (0, json_content_js_1.jsonContent)(buildErrorEnvelope(error));
|
|
12448
|
+
}
|
|
12449
|
+
});
|
|
12450
|
+
server.registerTool?.("manageAgents", {
|
|
12451
|
+
title: "管理 Agent",
|
|
12452
|
+
description: "Agent 域统一写入口。支持创建、更新和删除远端 Agent。",
|
|
12453
|
+
inputSchema: {
|
|
12454
|
+
action: zod_1.z.enum(MANAGE_AGENT_ACTIONS),
|
|
12455
|
+
agentId: zod_1.z.string().optional(),
|
|
12456
|
+
params: zod_1.z.record(zod_1.z.any()).optional(),
|
|
12457
|
+
},
|
|
12458
|
+
annotations: {
|
|
12459
|
+
readOnlyHint: false,
|
|
12460
|
+
destructiveHint: true,
|
|
12461
|
+
idempotentHint: false,
|
|
12462
|
+
openWorldHint: true,
|
|
12463
|
+
category: "agents",
|
|
12464
|
+
},
|
|
12465
|
+
}, async ({ action, agentId, params, }) => {
|
|
12466
|
+
try {
|
|
12467
|
+
const cloudbase = await getManager();
|
|
12468
|
+
const payload = normalizeAgentPayload(params);
|
|
12469
|
+
if (action === "createAgent") {
|
|
12470
|
+
const createPayload = {
|
|
12471
|
+
...payload,
|
|
12472
|
+
Name: normalizeString(payload.Name) ?? "",
|
|
12473
|
+
Runtime: normalizeString(payload.Runtime) ?? "Nodejs20.19",
|
|
12474
|
+
};
|
|
12475
|
+
const result = await cloudbase.agent.createAgent(createPayload);
|
|
12476
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
12477
|
+
return (0, json_content_js_1.jsonContent)(buildEnvelope({
|
|
12478
|
+
action,
|
|
12479
|
+
raw: result,
|
|
12480
|
+
}, "Agent 创建成功"));
|
|
12481
|
+
}
|
|
12482
|
+
if (!agentId) {
|
|
12483
|
+
throw new Error(`action=${action} 时必须提供 agentId`);
|
|
12484
|
+
}
|
|
12485
|
+
if (action === "updateAgent") {
|
|
12486
|
+
const result = await cloudbase.agent.updateAgent({
|
|
12487
|
+
AgentId: agentId,
|
|
12488
|
+
...payload,
|
|
12489
|
+
});
|
|
12490
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
12491
|
+
return (0, json_content_js_1.jsonContent)(buildEnvelope({
|
|
12492
|
+
action,
|
|
12493
|
+
agentId,
|
|
12494
|
+
raw: result,
|
|
12495
|
+
}, "Agent 更新成功"));
|
|
12496
|
+
}
|
|
12497
|
+
const result = await cloudbase.agent.deleteAgent({
|
|
12498
|
+
AgentId: agentId,
|
|
12499
|
+
});
|
|
12500
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
12501
|
+
return (0, json_content_js_1.jsonContent)(buildEnvelope({
|
|
12502
|
+
action,
|
|
12503
|
+
agentId,
|
|
12504
|
+
raw: result,
|
|
12505
|
+
}, "Agent 删除成功"));
|
|
12506
|
+
}
|
|
12507
|
+
catch (error) {
|
|
12508
|
+
return (0, json_content_js_1.jsonContent)(buildErrorEnvelope(error));
|
|
12509
|
+
}
|
|
12510
|
+
});
|
|
12511
|
+
}
|
|
12512
|
+
|
|
12513
|
+
|
|
11285
12514
|
/***/ }),
|
|
11286
12515
|
|
|
11287
12516
|
/***/ 9684:
|
|
@@ -11360,8 +12589,6 @@ function shouldRegisterTool(toolName) {
|
|
|
11360
12589
|
// Function tools - local code uploads
|
|
11361
12590
|
'updateFunctionCode',
|
|
11362
12591
|
'createFunction', // also involves local files
|
|
11363
|
-
// Miniprogram tools - local code uploads
|
|
11364
|
-
'uploadMiniprogramCode',
|
|
11365
12592
|
// Download tools - local file downloads
|
|
11366
12593
|
'downloadTemplate',
|
|
11367
12594
|
'downloadRemoteFile',
|
|
@@ -11391,10 +12618,11 @@ exports.registerSQLDatabaseTools = registerSQLDatabaseTools;
|
|
|
11391
12618
|
const zod_1 = __webpack_require__(2971);
|
|
11392
12619
|
const cloudbase_manager_js_1 = __webpack_require__(3431);
|
|
11393
12620
|
const tool_result_js_1 = __webpack_require__(9835);
|
|
11394
|
-
const security_rule_js_1 = __webpack_require__(7862);
|
|
11395
12621
|
const CATEGORY = "SQL database";
|
|
11396
12622
|
const QUERY_SQL_DATABASE = "querySqlDatabase";
|
|
11397
12623
|
const MANAGE_SQL_DATABASE = "manageSqlDatabase";
|
|
12624
|
+
const QUERY_PERMISSIONS = "queryPermissions";
|
|
12625
|
+
const MANAGE_PERMISSIONS = "managePermissions";
|
|
11398
12626
|
const QUERY_ACTIONS = [
|
|
11399
12627
|
"runQuery",
|
|
11400
12628
|
"describeCreateResult",
|
|
@@ -12021,7 +13249,7 @@ async function handleRunStatement(args, context) {
|
|
|
12021
13249
|
statementType,
|
|
12022
13250
|
},
|
|
12023
13251
|
message: statementType === "CREATE"
|
|
12024
|
-
? `SQL statement executed successfully. If you created a table, include the required _openid column and verify its
|
|
13252
|
+
? `SQL statement executed successfully. If you created a table, include the required _openid column and verify its permission configuration with \`${QUERY_PERMISSIONS}(action="getResourcePermission")\` and \`${MANAGE_PERMISSIONS}(action="updateResourcePermission")\`.`
|
|
12025
13253
|
: "SQL statement executed successfully.",
|
|
12026
13254
|
});
|
|
12027
13255
|
}
|
|
@@ -12151,7 +13379,7 @@ async function handleInitializeSchema(args, context) {
|
|
|
12151
13379
|
requestIdList,
|
|
12152
13380
|
},
|
|
12153
13381
|
message: success
|
|
12154
|
-
? `Schema initialization completed successfully. Remember to verify table
|
|
13382
|
+
? `Schema initialization completed successfully. Remember to verify table permissions with \`${QUERY_PERMISSIONS}(action="getResourcePermission")\` and \`${MANAGE_PERMISSIONS}(action="updateResourcePermission")\`, and include the required _openid column in newly created tables.`
|
|
12155
13383
|
: "Schema initialization stopped because one statement failed.",
|
|
12156
13384
|
});
|
|
12157
13385
|
}
|
|
@@ -12207,7 +13435,7 @@ function registerSQLDatabaseTools(server) {
|
|
|
12207
13435
|
});
|
|
12208
13436
|
server.registerTool?.(MANAGE_SQL_DATABASE, {
|
|
12209
13437
|
title: "Manage SQL database lifecycle or execute write SQL",
|
|
12210
|
-
description: "Manage SQL database resources. Supports MySQL provisioning, MySQL destruction, write SQL/DDL execution, and schema initialization
|
|
13438
|
+
description: "Manage SQL database resources. Supports MySQL provisioning, MySQL destruction, write SQL/DDL execution, and schema initialization. IMPORTANT: MySQL must be provisioned first (action=provisionMySQL with confirm=true) before any runStatement or initializeSchema call. If MySQL is not yet provisioned, the tool will return MYSQL_NOT_CREATED with a nextAction to provision first.",
|
|
12211
13439
|
inputSchema: {
|
|
12212
13440
|
action: zod_1.z
|
|
12213
13441
|
.enum(MANAGE_ACTIONS)
|