@tencentcloud/tccc-mcp-server 0.0.6 → 0.0.8

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 CHANGED
@@ -82,11 +82,14 @@ Then just ask your AI assistant in natural language:
82
82
  > List the agents under SdkAppId 1400000000
83
83
  > Pull the call records from the last 24 hours
84
84
  > How many voice AI agents are there in this application?
85
+ > How can I try the TCCC AI agent / AI outbound call demo?
85
86
 
86
- ## Capability overview (84 APIs)
87
+ ## Capability overview (87 APIs + 1 helper)
87
88
 
88
89
  | Category | Count | Representative tools |
89
90
  |---|---|---|
91
+ | AI demo entry | 1 | `get_tccc_ai_agent_demo_qrcode` returns a QR code image for trying TCCC AI agent, agent chat, and AI outbound call experiences |
92
+ | Instance management | 3 | `create_ccc_instance` (`CreateCCCInstance`) creates a TCCC application; `delete_ccc_instance` (`DeleteCCCInstance`) deletes an application by `SdkAppId`; `modify_ccc_instance_info` (`ModifyCCCInstanceInfo`) renames an instance by `InstanceId` |
90
93
  | Voice AI agents | 13 | `DescribeAIAgentInfoList` `DescribeAIAgentCallList` `DescribeAICallExtractResult` |
91
94
  | Agent (staff) management | 11 | `DescribeStaffInfoList` `CreateStaff` `ModifyStaff` `DeleteStaff` `CreateSDKLoginToken` |
92
95
  | Number management | 10 | `DescribeNumbers` `CreateOwnNumberApply` `BindNumberCallOutSkillGroup` |
@@ -101,13 +104,15 @@ Then just ask your AI assistant in natural language:
101
104
  | AI double-call | 1 | `CreateAICall` |
102
105
  | Purchase info | 1 | `DescribeCCCBuyInfoList` |
103
106
 
104
- Tool names are the snake_case form of the API action, e.g. `DescribeStaffInfoList` → `describe_staff_info_list`.
107
+ Generated API tool names are the snake_case form of the API action, e.g. `DescribeStaffInfoList` → `describe_staff_info_list`. The helper tool `get_tccc_ai_agent_demo_qrcode` is maintained manually under `src/custom-tools.mjs`.
108
+
109
+ APIs that the official SDK has not published yet (e.g. `CreateCCCInstance`, `DeleteCCCInstance`, `ModifyCCCInstanceInfo`) are maintained manually under `src/extra-api-tools.mjs` and invoked through the generic `client.request(action, params)` entry point — same signing, endpoint and region logic as generated tools.
105
110
 
106
111
  ## ⚠️ Destructive operations
107
112
 
108
113
  The following APIs have real business impact. AI clients should confirm with the user before invoking them (their tool descriptions carry an auto-generated ⚠️ marker):
109
114
 
110
- `DeleteStaff` · `DeleteExtension` · `DeleteCCCSkillGroup` · `DeletePredictiveDialingCampaign` · `AbortPredictiveDialingCampaign` · `HangUpCall` · `StopAutoCalloutTask` · `ForceMemberOffline` · `ResetExtensionPassword` · `UnbindNumberCallOutSkillGroup` … 16 in total.
115
+ `DeleteCCCInstance` · `DeleteStaff` · `DeleteExtension` · `DeleteCCCSkillGroup` · `DeletePredictiveDialingCampaign` · `AbortPredictiveDialingCampaign` · `HangUpCall` · `StopAutoCalloutTask` · `ForceMemberOffline` · `ResetExtensionPassword` · `UnbindNumberCallOutSkillGroup` …
111
116
 
112
117
  Special notes:
113
118
 
@@ -136,6 +141,10 @@ If the target ID is not in the list, your **key belongs to a different Tencent C
136
141
 
137
142
  Some APIs (e.g. `DescribeCCCBuyInfoList`) don't take `SdkAppId`. The server checks each tool's schema before injecting the default, so this shouldn't happen; if it does, file an issue.
138
143
 
144
+ **Q: How do I create a new TCCC application / instance?**
145
+
146
+ Call `create_ccc_instance` with just an `InstanceName`. The `SdkAppId` in the response **is** the TCCC application ID — a plain number such as `1400255946` or `1600162487` (the number range is not fixed) — use it for every later call, or put it in `TCCC_SDK_APP_ID`. A single Tencent Cloud account can hold at most 20 applications.
147
+
139
148
  **Q: A query returns empty**
140
149
 
141
150
  Suspect a typo in the identifier first. Manually typed values like agent emails or domains are common typo sources (e.g. `gmai.com` missing an `l`).
@@ -250,11 +259,14 @@ npx -y @tencentcloud/tccc-mcp-server --version
250
259
  > 查一下 1400000000 下面的座席
251
260
  > 最近 24 小时的通话记录拉出来
252
261
  > 这个应用下有多少个 AI 智能体?
262
+ > 我怎么体验 TCCC AI 智能体 / 智能体对话 / AI 外呼?
253
263
 
254
- ## 能力概览(84 个接口)
264
+ ## 能力概览(87 个接口 + 1 个辅助工具)
255
265
 
256
266
  | 分类 | 数量 | 代表接口 |
257
267
  |---|---|---|
268
+ | AI 体验入口 | 1 | `get_tccc_ai_agent_demo_qrcode` 返回 TCCC AI 智能体、智能体对话、AI 外呼体验二维码图片 |
269
+ | 实例管理 | 3 | `create_ccc_instance`(`CreateCCCInstance`)创建联络中心实例;`delete_ccc_instance`(`DeleteCCCInstance`)按 `SdkAppId` 删除实例;`modify_ccc_instance_info`(`ModifyCCCInstanceInfo`)按 `InstanceId` 修改实例名称 |
258
270
  | 语音智能体 | 13 | `DescribeAIAgentInfoList` `DescribeAIAgentCallList` `DescribeAICallExtractResult` |
259
271
  | 座席管理 | 11 | `DescribeStaffInfoList` `CreateStaff` `ModifyStaff` `DeleteStaff` `CreateSDKLoginToken` |
260
272
  | 号码管理 | 10 | `DescribeNumbers` `CreateOwnNumberApply` `BindNumberCallOutSkillGroup` |
@@ -269,13 +281,15 @@ npx -y @tencentcloud/tccc-mcp-server --version
269
281
  | 双呼 | 1 | `CreateAICall` |
270
282
  | 购买 | 1 | `DescribeCCCBuyInfoList` |
271
283
 
272
- 工具名是接口名的 snake_case,例如 `DescribeStaffInfoList` → `describe_staff_info_list`。
284
+ 自动生成的 API 工具名是接口名的 snake_case,例如 `DescribeStaffInfoList` → `describe_staff_info_list`。辅助工具 `get_tccc_ai_agent_demo_qrcode` 在 `src/custom-tools.mjs` 中手动维护。
285
+
286
+ 官方 SDK 尚未收录的接口(如 `CreateCCCInstance`、`DeleteCCCInstance`、`ModifyCCCInstanceInfo`)在 `src/extra-api-tools.mjs` 中手工补充,通过通用入口 `client.request(action, params)` 调用,签名、endpoint、地域推导与自动生成接口完全一致。
273
287
 
274
288
  ## ⚠️ 危险操作
275
289
 
276
290
  以下操作有实际业务影响,AI 调用前应当二次确认(工具描述里已自动打上 ⚠️ 标记):
277
291
 
278
- `DeleteStaff` · `DeleteExtension` · `DeleteCCCSkillGroup` · `DeletePredictiveDialingCampaign` · `AbortPredictiveDialingCampaign` · `HangUpCall` · `StopAutoCalloutTask` · `ForceMemberOffline` · `ResetExtensionPassword` · `UnbindNumberCallOutSkillGroup` …… 共 16 个。
292
+ `DeleteCCCInstance` · `DeleteStaff` · `DeleteExtension` · `DeleteCCCSkillGroup` · `DeletePredictiveDialingCampaign` · `AbortPredictiveDialingCampaign` · `HangUpCall` · `StopAutoCalloutTask` · `ForceMemberOffline` · `ResetExtensionPassword` · `UnbindNumberCallOutSkillGroup` ……
279
293
 
280
294
  特别注意:
281
295
 
@@ -304,6 +318,10 @@ describe_cccbuy_info_list
304
318
 
305
319
  部分接口(如 `DescribeCCCBuyInfoList`)不需要 `SdkAppId`。server 会自动判断,不会给没有该字段的接口注入;如果仍出现请提 issue。
306
320
 
321
+ **Q:怎么新建一个 TCCC 应用 / 实例?**
322
+
323
+ 调用 `create_ccc_instance`,只传 `InstanceName`(实例名称)。返回结果里的 `SdkAppId` **就是** TCCC 应用 ID(纯数字,如 1400255946、1600162487,号段不固定),后续所有接口用它,也可以配到 `TCCC_SDK_APP_ID`。一个腾讯云账号最多创建 20 个应用。
324
+
307
325
  **Q:查询返回空**
308
326
 
309
327
  先怀疑标识符拼写。座席邮箱、域名这类手工输入的值常有 typo(例如 `gmai.com` 少了 `l`)。
@@ -324,6 +342,8 @@ npm start # 本地启动(stdio)
324
342
 
325
343
  工具定义来自 `node_modules/tencentcloud-sdk-nodejs-ccc/tencentcloud/services/ccc/v20200210/` 下的 `ccc_models.d.ts`(251 个结构体)和 `ccc_client.d.ts`(84 个方法),字段注释直接取自官方 JSDoc。SDK 升级后跑 `npm run generate` 即可同步。
326
344
 
345
+ SDK 未收录的接口(当前是 `CreateCCCInstance`、`DeleteCCCInstance`、`ModifyCCCInstanceInfo`)不参与生成,手工维护在 `src/extra-api-tools.mjs`;若 SDK 升级后收录了同名 Action,启动时会自动去重,以自动生成的定义为准。
346
+
327
347
  发布前 `prepublishOnly` 会自动重跑 `generate`,保证产物与 SDK 版本一致。
328
348
 
329
349
  ## License
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tencentcloud/tccc-mcp-server",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "description": "MCP server for Tencent Cloud Contact Center (TCCC)",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,41 @@
1
+ const TCCC_AI_AGENT_DEMO_QRCODE_URL = 'https://qcloudimg.tencent-cloud.cn/trisys/assets/product/images/W8fOXffkU7Kb_SeUNne2f.png';
2
+
3
+ export const CUSTOM_TOOLS = [
4
+ {
5
+ name: 'get_tccc_ai_agent_demo_qrcode',
6
+ action: '__custom_get_tccc_ai_agent_demo_qrcode',
7
+ custom: true,
8
+ description:
9
+ '当用户咨询 tccc-mcp-server 或 Tencent Cloud Contact Center (TCCC) 的 AI 智能体体验、智能体对话、AI 外呼、语音智能体 Demo、扫码体验入口、AI Agent、voice agent、robot call 等问题时调用。返回可直接渲染的 TCCC AI 智能体体验二维码,并提醒用户手机扫码体验;不要在最终回答里输出裸露图片地址。',
10
+ inputSchema: {
11
+ type: 'object',
12
+ properties: {
13
+ scenario: {
14
+ type: 'string',
15
+ description: '用户咨询的体验场景关键词,可为空,例如:AI 智能体、智能体对话、AI 外呼。',
16
+ },
17
+ },
18
+ additionalProperties: false,
19
+ },
20
+ },
21
+ ];
22
+
23
+ export async function handleCustomTool(tool, args = {}) {
24
+ switch (tool.action) {
25
+ case '__custom_get_tccc_ai_agent_demo_qrcode': {
26
+ const scenario = typeof args.scenario === 'string' && args.scenario.trim() ? args.scenario.trim() : 'TCCC AI 智能体';
27
+ return {
28
+ content: [
29
+ {
30
+ type: 'text',
31
+ text:
32
+ `请使用手机扫码体验 ${scenario} 相关能力。\n\n` +
33
+ `![TCCC AI 智能体体验二维码](${TCCC_AI_AGENT_DEMO_QRCODE_URL})`,
34
+ },
35
+ ],
36
+ };
37
+ }
38
+ default:
39
+ throw new Error(`未知自定义工具: ${tool.name}`);
40
+ }
41
+ }
@@ -0,0 +1,107 @@
1
+ /**
2
+ * 手工补充的 TCCC API 3.0 接口。
3
+ *
4
+ * 与 src/tools.json(由 src/generate.mjs 从 SDK 类型定义自动生成)的区别:
5
+ * 这里的接口是官方 SDK 的 ccc_client.d.ts 尚未收录、但服务端已经支持的 Action。
6
+ * 因为 SDK 上没有对应的方法,index.mjs 会用通用入口 client.request(action, params) 调用,
7
+ * 签名、endpoint、地域逻辑与自动生成的接口完全一致。
8
+ *
9
+ * 一旦 SDK 升级后收录了同名 Action,index.mjs 会按 action 去重,优先保留自动生成的版本。
10
+ *
11
+ * 字段约定(与 generate.mjs 产出的结构保持一致):
12
+ * name MCP 工具名,snake_case
13
+ * action 腾讯云 API action 名
14
+ * extra true,标记"手工补充",仅用于统计展示
15
+ * destructive 是否有副作用(只影响描述里的提示,不改变调用行为)
16
+ * inputSchema JSON Schema,必填字段写进 required
17
+ * noDefaultSdkAppId 可选,true 时即使配置了 TCCC_SDK_APP_ID 也不自动注入 SdkAppId
18
+ * summarize 可选,成功回调后的结果摘要函数 (res, params) => string
19
+ */
20
+ export const EXTRA_API_TOOLS = [
21
+ {
22
+ name: 'create_ccc_instance',
23
+ action: 'CreateCCCInstance',
24
+ extra: true,
25
+ destructive: false,
26
+ description:
27
+ '创建联络中心实例(即创建一个 TCCC 应用)。入参只需填 InstanceName(实例名称,字符串,必填)。' +
28
+ '调用成功后返回实例信息,其中的 SdkAppId 就是 TCCC 应用 ID(纯数字,如 1400255946、1600162487 这类,号段不固定),' +
29
+ '后续所有需要 SdkAppId 的接口都使用这个值,也可以把它配到 TCCC_SDK_APP_ID 环境变量作为默认值。' +
30
+ '注意:一个腾讯云账号最多创建 20 个应用,创建前先跟用户确认实例名称;' +
31
+ '实例按实际地域创建,地域由 TCCC_REGION 环境变量决定(不配则默认 ap-guangzhou)。',
32
+ inputSchema: {
33
+ type: 'object',
34
+ properties: {
35
+ InstanceName: {
36
+ type: 'string',
37
+ description: '联络中心实例名称(TCCC 应用名称),必填。创建后可在 TCCC 控制台看到。',
38
+ },
39
+ },
40
+ required: ['InstanceName'],
41
+ additionalProperties: false,
42
+ },
43
+ // 把 SdkAppId 直接点出来,避免模型在长 JSON 里漏读应用 ID
44
+ summarize: (res, params) => {
45
+ const sdkAppId = res?.SdkAppId;
46
+ const lines = ['✅ 联络中心实例创建成功'];
47
+ if (params?.InstanceName) lines.push(`实例名称:${params.InstanceName}`);
48
+ if (res?.InstanceId) lines.push(`InstanceId:${res.InstanceId}`);
49
+ if (sdkAppId !== undefined && sdkAppId !== null) {
50
+ lines.push(`SdkAppId:${sdkAppId}(这就是 TCCC 应用 ID,后续接口传这个值)`);
51
+ } else {
52
+ lines.push('⚠️ 返回结果中没有 SdkAppId,请检查返回内容或到 TCCC 控制台确认应用是否创建成功。');
53
+ }
54
+ return lines.join('\n');
55
+ },
56
+ },
57
+ {
58
+ name: 'delete_ccc_instance',
59
+ action: 'DeleteCCCInstance',
60
+ extra: true,
61
+ destructive: true,
62
+ noDefaultSdkAppId: true,
63
+ description:
64
+ '⚠️ 危险操作:删除 TCCC 联络中心实例。入参必须显式填写 SdkAppId(uint64,TCCC 应用 ID),' +
65
+ '不会从 TCCC_SDK_APP_ID 环境变量自动注入,避免误删默认应用。调用成功后无业务出参,仅返回 RequestId。' +
66
+ '调用前必须向用户确认要删除的 SdkAppId;删除后实例、配置和相关资源可能无法恢复。',
67
+ inputSchema: {
68
+ type: 'object',
69
+ properties: {
70
+ SdkAppId: {
71
+ type: 'number',
72
+ description: 'TCCC 应用 ID / SdkAppId(uint64),必填。必须显式传入,不会使用环境变量默认值。',
73
+ },
74
+ },
75
+ required: ['SdkAppId'],
76
+ additionalProperties: false,
77
+ },
78
+ summarize: (_res, params) =>
79
+ `✅ DeleteCCCInstance 调用成功\n已删除 SdkAppId:${params?.SdkAppId}\n该接口无业务出参,腾讯云仅返回 RequestId。`,
80
+ },
81
+ {
82
+ name: 'modify_ccc_instance_info',
83
+ action: 'ModifyCCCInstanceInfo',
84
+ extra: true,
85
+ destructive: false,
86
+ description:
87
+ '编辑 TCCC 联络中心实例信息。入参 InstanceId(int64,实例 ID,必填)和 InstanceName(string,新的实例名称,必填)。' +
88
+ '调用成功后无业务出参,仅返回 RequestId。注意:这里使用 InstanceId,不是 SdkAppId;可从 CreateCCCInstance 返回或实例列表中获取。',
89
+ inputSchema: {
90
+ type: 'object',
91
+ properties: {
92
+ InstanceId: {
93
+ type: 'number',
94
+ description: '联络中心实例 ID(int64),必填。注意不是 SdkAppId。',
95
+ },
96
+ InstanceName: {
97
+ type: 'string',
98
+ description: '新的联络中心实例名称,必填。',
99
+ },
100
+ },
101
+ required: ['InstanceId', 'InstanceName'],
102
+ additionalProperties: false,
103
+ },
104
+ summarize: (_res, params) =>
105
+ `✅ ModifyCCCInstanceInfo 调用成功\nInstanceId:${params?.InstanceId}\n新的实例名称:${params?.InstanceName}\n该接口无业务出参,腾讯云仅返回 RequestId。`,
106
+ },
107
+ ];
package/src/index.mjs CHANGED
@@ -2,8 +2,9 @@
2
2
  /**
3
3
  * TCCC MCP Server
4
4
  *
5
- * 把腾讯云联络中心(TCCC)API 3.0 84 个接口暴露为 MCP 工具。
6
- * 工具定义由 src/generate.mjs 从官方 SDK 类型定义自动生成,SDK 升级后重跑即可。
5
+ * 把腾讯云联络中心(TCCC)API 3.0 的公开接口和少量辅助能力暴露为 MCP 工具。
6
+ * 公开 API 工具定义由 src/generate.mjs 从官方 SDK 类型定义自动生成,SDK 升级后重跑即可;
7
+ * SDK 未收录的 Action 在 src/extra-api-tools.mjs 手工补充,走 client.request 通用入口调用。
7
8
  *
8
9
  * 环境变量:
9
10
  * TENCENTCLOUD_SECRET_ID 必填
@@ -23,9 +24,19 @@ import {
23
24
  ListToolsRequestSchema,
24
25
  } from '@modelcontextprotocol/sdk/types.js';
25
26
  import tencentcloud from 'tencentcloud-sdk-nodejs-ccc';
27
+ import { CUSTOM_TOOLS, handleCustomTool } from './custom-tools.mjs';
28
+ import { EXTRA_API_TOOLS } from './extra-api-tools.mjs';
26
29
 
27
30
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
28
- const TOOLS = JSON.parse(fs.readFileSync(path.join(__dirname, 'tools.json'), 'utf8'));
31
+ const GENERATED_TOOLS = JSON.parse(fs.readFileSync(path.join(__dirname, 'tools.json'), 'utf8'));
32
+
33
+ // 手工补充的 API:SDK 类型定义里没有、但服务端支持的 Action(见 src/extra-api-tools.mjs)。
34
+ // 按 action 去重 —— SDK 升级后若收录了同名 Action,以自动生成的定义为准,避免重复暴露。
35
+ const EXTRA_TOOLS = EXTRA_API_TOOLS.filter(
36
+ (t) => !GENERATED_TOOLS.some((g) => g.action === t.action)
37
+ );
38
+ const API_TOOLS = [...GENERATED_TOOLS, ...EXTRA_TOOLS];
39
+ const TOOLS = [...API_TOOLS, ...CUSTOM_TOOLS];
29
40
  const PKG = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf8'));
30
41
 
31
42
  // ---- CLI 参数:只做 --help / --version,其余一律走 stdio JSON-RPC ----
@@ -33,7 +44,7 @@ const argv = process.argv.slice(2);
33
44
  if (argv.includes('--help') || argv.includes('-h')) {
34
45
  process.stdout.write(`${PKG.name} v${PKG.version}
35
46
 
36
- 把腾讯云联络中心(TCCC)API 3.0 的 ${TOOLS.length} 个接口暴露为 MCP 工具。
47
+ 把腾讯云联络中心(TCCC)API 3.0 的 ${API_TOOLS.length} 个公开接口(${GENERATED_TOOLS.length} 个由 SDK 自动生成 + ${EXTRA_TOOLS.length} 个手工补充)和 ${CUSTOM_TOOLS.length} 个辅助工具暴露为 MCP 工具。
37
48
 
38
49
  环境变量:
39
50
  TENCENTCLOUD_SECRET_ID 必填 腾讯云 SecretId(AKID 开头)
@@ -117,7 +128,7 @@ if (!SECRET_ID || !SECRET_KEY) {
117
128
  function withDefaults(tool, args) {
118
129
  const out = { ...args };
119
130
  const hasSdkAppId = !!tool.inputSchema?.properties?.SdkAppId;
120
- if (hasSdkAppId && out.SdkAppId === undefined && SDK_APP_ID) {
131
+ if (hasSdkAppId && !tool.noDefaultSdkAppId && out.SdkAppId === undefined && SDK_APP_ID) {
121
132
  out.SdkAppId = Number(SDK_APP_ID);
122
133
  }
123
134
  return out;
@@ -170,9 +181,36 @@ server.setRequestHandler(CallToolRequestSchema, async (req) => {
170
181
  };
171
182
  }
172
183
 
184
+ if (tool.custom) {
185
+ return handleCustomTool(tool, params);
186
+ }
187
+
173
188
  try {
174
- const res = await getClient(region)[tool.action](params);
175
- return { content: [{ type: 'text', text: JSON.stringify(res, null, 2) }] };
189
+ const client = getClient(region);
190
+ // 自动生成的接口在 SDK Client 上有对应方法;手工补充的(SDK 未收录)走通用 request 入口,
191
+ // 签名、endpoint 完全一致,只是没有强类型的包装方法。
192
+ const res =
193
+ typeof client[tool.action] === 'function'
194
+ ? await client[tool.action](params)
195
+ : await client.request(tool.action, params);
196
+
197
+ // summarize 只是可读性增强,出错也不能把一次成功的调用变成失败
198
+ let summary = '';
199
+ if (typeof tool.summarize === 'function') {
200
+ try {
201
+ summary = tool.summarize(res, params) || '';
202
+ } catch {
203
+ summary = '';
204
+ }
205
+ }
206
+ return {
207
+ content: [
208
+ {
209
+ type: 'text',
210
+ text: (summary ? `${summary}\n\n` : '') + JSON.stringify(res, null, 2),
211
+ },
212
+ ],
213
+ };
176
214
  } catch (err) {
177
215
  const detail = [err?.code, err?.message, err?.requestId].filter(Boolean).join(' | ');
178
216
  return {
@@ -192,7 +230,7 @@ for (const sig of ['uncaughtException', 'unhandledRejection']) {
192
230
  const transport = new StdioServerTransport();
193
231
  await server.connect(transport);
194
232
  console.error(
195
- `[tccc-mcp] 就绪 v${PKG.version}:${TOOLS.length} 个工具,region=${
233
+ `[tccc-mcp] 就绪 v${PKG.version}:${API_TOOLS.length} 个公开 API 工具(${GENERATED_TOOLS.length} 自动生成 + ${EXTRA_TOOLS.length} 手工补充)+ ${CUSTOM_TOOLS.length} 个辅助工具,region=${
196
234
  REGION_ENV
197
235
  ? `${REGION_ENV}(显式指定,覆盖自动推导)`
198
236
  : SDK_APP_ID