@tencentcloud/tccc-mcp-server 0.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Tencent Cloud
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,163 @@
1
+ # @tencentcloud/tccc-mcp-server
2
+
3
+ **English** | [简体中文](./README_zh.md)
4
+
5
+ tccc-mcp-server enables AI assistants to quickly integrate with Tencent Cloud Contact Center (TCCC) via MCP (Model Context Protocol).
6
+
7
+ ## Quick start
8
+
9
+ ### 1. Get credentials
10
+
11
+ | Variable | Required | Description | Where to get it |
12
+ |---|---|---|---|
13
+ | `TENCENTCLOUD_SECRET_ID` | ✅ | Tencent Cloud SecretId (starts with `AKID`) | [CAM - API Key Management](https://console.tencentcloud.com/cam/capi) |
14
+ | `TENCENTCLOUD_SECRET_KEY` | ✅ | Tencent Cloud SecretKey (32-char random string) | Same as above |
15
+ | `TCCC_SDK_APP_ID` | Recommended | Default SdkAppId so you don't pass it on every call | [CCC Console](https://console.tencentcloud.com/ccc) |
16
+ | `TCCC_REGION` | Optional | Explicit region override. If unset, the region is **auto-derived from the SdkAppId of each call**: app IDs in `[20000000, 30000000)` or `[1720000000, 1730000000)` are Singapore-site → `ap-singapore`; all others → `ap-guangzhou` | — |
17
+
18
+ > ⚠️ **Don't swap the key pair**: `SecretId` starts with `AKID`; `SecretKey` is a 32-character random string. If reversed you'll get `The SecretId is not found`.
19
+
20
+ ### 2. Add to your MCP client
21
+
22
+ #### WorkBuddy / Cursor / Claude Desktop / Cline (universal format)
23
+
24
+ ```json
25
+ {
26
+ "mcpServers": {
27
+ "tccc": {
28
+ "type": "stdio",
29
+ "command": "npx",
30
+ "args": ["-y", "@tencentcloud/tccc-mcp-server"],
31
+ "env": {
32
+ "TENCENTCLOUD_SECRET_ID": "AKIDxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
33
+ "TENCENTCLOUD_SECRET_KEY": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
34
+ "TCCC_SDK_APP_ID": "1400000000"
35
+ },
36
+ "timeout": 60000
37
+ }
38
+ }
39
+ }
40
+ ```
41
+
42
+ Config file locations:
43
+
44
+ | Client | Location |
45
+ |---|---|
46
+ | WorkBuddy | `~/.workbuddy/mcp.json` |
47
+ | Cursor | project `.cursor/mcp.json` or global `~/.cursor/mcp.json` |
48
+ | Claude Desktop | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) |
49
+ | Cline | MCP panel in VS Code settings |
50
+
51
+ **Restart your client** after editing — MCP processes are spawned at client startup. The first `npx` run downloads the package (a few seconds); keep `timeout` at 60 s or higher.
52
+
53
+ #### Offline / air-gapped environments
54
+
55
+ ```bash
56
+ npm install -g @tencentcloud/tccc-mcp-server
57
+ which tccc-mcp-server # get the absolute path
58
+ ```
59
+
60
+ ```json
61
+ {
62
+ "mcpServers": {
63
+ "tccc": {
64
+ "type": "stdio",
65
+ "command": "/usr/local/bin/tccc-mcp-server",
66
+ "env": { "...": "..." }
67
+ }
68
+ }
69
+ }
70
+ ```
71
+
72
+ ### 3. Verify
73
+
74
+ ```bash
75
+ npx -y @tencentcloud/tccc-mcp-server --help
76
+ npx -y @tencentcloud/tccc-mcp-server --version
77
+ ```
78
+
79
+ Then just ask your AI assistant in natural language:
80
+
81
+ > Which TCCC applications do I have?
82
+ > List the agents under SdkAppId 1400000000
83
+ > Pull the call records from the last 24 hours
84
+ > How many voice AI agents are there in this application?
85
+
86
+ ## Capability overview (84 APIs)
87
+
88
+ | Category | Count | Representative tools |
89
+ |---|---|---|
90
+ | Voice AI agents | 13 | `DescribeAIAgentInfoList` `DescribeAIAgentCallList` `DescribeAICallExtractResult` |
91
+ | Agent (staff) management | 11 | `DescribeStaffInfoList` `CreateStaff` `ModifyStaff` `DeleteStaff` `CreateSDKLoginToken` |
92
+ | Number management | 10 | `DescribeNumbers` `CreateOwnNumberApply` `BindNumberCallOutSkillGroup` |
93
+ | Predictive dialing | 10 | `CreatePredictiveDialingCampaign` `DescribePredictiveDialingSessions` |
94
+ | Others | 10 | `DescribeExtension` `DescribeChatMessages` etc. |
95
+ | Call records | 7 | `DescribeTelCdr` `DescribeTelRecordAsr` `DescribeProtectedTelCdr` |
96
+ | Skill groups | 6 | `DescribeSkillGroupInfoList` `BindStaffSkillGroupList` `CreateCCCSkillGroup` |
97
+ | SIP extensions | 6 | `CreateExtension` `ModifyExtension` `DeleteExtension` |
98
+ | Instant-message records | 3 | `DescribeIMCdrList` `DescribeChatMessages` |
99
+ | Auto callout | 3 | `CreateAutoCalloutTask` `DescribeAutoCalloutTasks` |
100
+ | Carrier qualification | 3 | `CreateCompanyApply` `DescribeCarrierPrivilegeNumberApplicants` |
101
+ | AI double-call | 1 | `CreateAICall` |
102
+ | Purchase info | 1 | `DescribeCCCBuyInfoList` |
103
+
104
+ Tool names are the snake_case form of the API action, e.g. `DescribeStaffInfoList` → `describe_staff_info_list`.
105
+
106
+ ## ⚠️ Destructive operations
107
+
108
+ 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
+
110
+ `DeleteStaff` · `DeleteExtension` · `DeleteCCCSkillGroup` · `DeletePredictiveDialingCampaign` · `AbortPredictiveDialingCampaign` · `HangUpCall` · `StopAutoCalloutTask` · `ForceMemberOffline` · `ResetExtensionPassword` · `UnbindNumberCallOutSkillGroup` … 16 in total.
111
+
112
+ Special notes:
113
+
114
+ - **`DeleteStaff` has no recycle bin.** Deleted agents can only be recreated; the original staff number is not restored.
115
+ - Bulk-modify APIs usually **overwrite the full configuration** — read the current state first and keep a backup before modifying.
116
+
117
+ ## Security recommendations
118
+
119
+ 1. **Use a CAM sub-account key** restricted to `QcloudCCCReadOnlyAccess` or a minimal custom policy. Never use your root account key.
120
+ 2. Keep keys only in your local `env` config; never commit them to version control.
121
+ 3. Enable CloudAudit for production operations.
122
+
123
+ ## Troubleshooting
124
+
125
+ **Q: Tools load fine, but calls fail with `InvalidParameterValue | SdkAppId invalid`**
126
+
127
+ Run the list tool to see which application IDs actually exist under your key:
128
+
129
+ ```
130
+ describe_cccbuy_info_list
131
+ ```
132
+
133
+ If the target ID is not in the list, your **key belongs to a different Tencent Cloud account** (TCCC apps are not visible across accounts) — switch keys; it's not a typo in the ID.
134
+
135
+ **Q: `UnknownParameter: SdkAppId not recognized`**
136
+
137
+ 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
+
139
+ **Q: A query returns empty**
140
+
141
+ 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`).
142
+
143
+ ## Known limitations
144
+
145
+ - Rate limits: most APIs allow 20 requests/second; `UploadIvrAudio` and `CreateCompanyApply` only 1/second. Throttle bulk operations yourself.
146
+ - File-related APIs like `UploadIvrAudio` take a COS URL, not a file stream — upload the file first.
147
+ - Covers only the `ccc` service of API 3.0 (OpenAPI). TCCC WebSocket / client-SDK signaling is out of scope.
148
+
149
+ ## Development
150
+
151
+ ```bash
152
+ npm install
153
+ npm run generate # re-parse SDK type definitions into src/tools.json
154
+ npm start # run locally (stdio)
155
+ ```
156
+
157
+ Tool definitions are generated from `ccc_models.d.ts` (251 structs) and `ccc_client.d.ts` (84 methods) under `node_modules/tencentcloud-sdk-nodejs-ccc/tencentcloud/services/ccc/v20200210/`. Field descriptions come straight from the official JSDoc. After an SDK upgrade, run `npm run generate` to sync.
158
+
159
+ `prepublishOnly` re-runs `generate` automatically before each publish, so the shipped schema always matches the SDK version.
160
+
161
+ ## License
162
+
163
+ [MIT](./LICENSE)
package/README_zh.md ADDED
@@ -0,0 +1,163 @@
1
+ # @tencentcloud/tccc-mcp-server
2
+
3
+ [English](./README.md) | **简体中文**
4
+
5
+ tccc-mcp-server 通过 MCP(Model Context Protocol)向 AI 助手提供 Tencent Cloud Contact Center (TCCC) 快速集成能力。
6
+
7
+ ## 快速开始
8
+
9
+ ### 1. 准备凭据
10
+
11
+ | 变量 | 必填 | 说明 | 获取地址 |
12
+ |---|---|---|---|
13
+ | `TENCENTCLOUD_SECRET_ID` | ✅ | 腾讯云 SecretId,`AKID` 开头 | [CAM 密钥管理](https://console.cloud.tencent.com/cam/capi) |
14
+ | `TENCENTCLOUD_SECRET_KEY` | ✅ | 腾讯云 SecretKey,32 位随机串 | 同上 |
15
+ | `TCCC_SDK_APP_ID` | 推荐 | 应用 ID,配了之后调用时不用每次传 | [TCCC 控制台](https://console.cloud.tencent.com/ccc) |
16
+ | `TCCC_REGION` | 可选 | 显式指定地域(优先级最高)。不配时**按每次调用的 SdkAppId 号段自动推导**:`[20000000, 30000000)` 与 `[1720000000, 1730000000)` 号段为新加坡站 → `ap-singapore`,其余号段为中国站 → `ap-guangzhou` | — |
17
+
18
+ > ⚠️ **SecretId / SecretKey 不要填反**:`SecretId` 以 `AKID` 开头,`SecretKey` 是 32 位随机串。填反会报 `The SecretId is not found`。
19
+
20
+ ### 2. 配置到 MCP 客户端
21
+
22
+ #### WorkBuddy / Cursor / Claude Desktop / Cline(通用格式)
23
+
24
+ ```json
25
+ {
26
+ "mcpServers": {
27
+ "tccc": {
28
+ "type": "stdio",
29
+ "command": "npx",
30
+ "args": ["-y", "@tencentcloud/tccc-mcp-server"],
31
+ "env": {
32
+ "TENCENTCLOUD_SECRET_ID": "AKIDxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
33
+ "TENCENTCLOUD_SECRET_KEY": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
34
+ "TCCC_SDK_APP_ID": "1400000000"
35
+ },
36
+ "timeout": 60000
37
+ }
38
+ }
39
+ }
40
+ ```
41
+
42
+ 配置文件位置:
43
+
44
+ | 客户端 | 位置 |
45
+ |---|---|
46
+ | WorkBuddy | `~/.workbuddy/mcp.json` |
47
+ | Cursor | 项目 `.cursor/mcp.json` 或全局 `~/.cursor/mcp.json` |
48
+ | Claude Desktop | `~/Library/Application Support/Claude/claude_desktop_config.json`(macOS) |
49
+ | Cline | VS Code 设置里的 MCP 面板 |
50
+
51
+ 改完**重启客户端**,MCP 进程是客户端启动时拉起的。首次启动 `npx` 会下载包(几秒),`timeout` 建议不低于 60 秒。
52
+
53
+ #### 离线 / 内网环境
54
+
55
+ ```bash
56
+ npm install -g @tencentcloud/tccc-mcp-server
57
+ which tccc-mcp-server # 拿到绝对路径
58
+ ```
59
+
60
+ ```json
61
+ {
62
+ "mcpServers": {
63
+ "tccc": {
64
+ "type": "stdio",
65
+ "command": "/usr/local/bin/tccc-mcp-server",
66
+ "env": { "...": "..." }
67
+ }
68
+ }
69
+ }
70
+ ```
71
+
72
+ ### 3. 验证
73
+
74
+ ```bash
75
+ npx -y @tencentcloud/tccc-mcp-server --help
76
+ npx -y @tencentcloud/tccc-mcp-server --version
77
+ ```
78
+
79
+ 配好凭据后直接问你的 AI:
80
+
81
+ > 我有哪些 TCCC 应用?
82
+ > 查一下 1400000000 下面的座席
83
+ > 最近 24 小时的通话记录拉出来
84
+ > 这个应用下有多少个 AI 智能体?
85
+
86
+ ## 能力概览(84 个接口)
87
+
88
+ | 分类 | 数量 | 代表接口 |
89
+ |---|---|---|
90
+ | 语音智能体 | 13 | `DescribeAIAgentInfoList` `DescribeAIAgentCallList` `DescribeAICallExtractResult` |
91
+ | 座席管理 | 11 | `DescribeStaffInfoList` `CreateStaff` `ModifyStaff` `DeleteStaff` `CreateSDKLoginToken` |
92
+ | 号码管理 | 10 | `DescribeNumbers` `CreateOwnNumberApply` `BindNumberCallOutSkillGroup` |
93
+ | 预测式外呼 | 10 | `CreatePredictiveDialingCampaign` `DescribePredictiveDialingSessions` |
94
+ | 其他 | 10 | `DescribeExtension` `DescribeChatMessages` 等 |
95
+ | 电话记录 | 7 | `DescribeTelCdr` `DescribeTelRecordAsr` `DescribeProtectedTelCdr` |
96
+ | 技能组 | 6 | `DescribeSkillGroupInfoList` `BindStaffSkillGroupList` `CreateCCCSkillGroup` |
97
+ | 话机(SIP) | 6 | `CreateExtension` `ModifyExtension` `DeleteExtension` |
98
+ | 在线记录 | 3 | `DescribeIMCdrList` `DescribeChatMessages` |
99
+ | 外呼 | 3 | `CreateAutoCalloutTask` `DescribeAutoCalloutTasks` |
100
+ | 号码资质 | 3 | `CreateCompanyApply` `DescribeCarrierPrivilegeNumberApplicants` |
101
+ | 双呼 | 1 | `CreateAICall` |
102
+ | 购买 | 1 | `DescribeCCCBuyInfoList` |
103
+
104
+ 工具名是接口名的 snake_case,例如 `DescribeStaffInfoList` → `describe_staff_info_list`。
105
+
106
+ ## ⚠️ 危险操作
107
+
108
+ 以下操作有实际业务影响,AI 调用前应当二次确认(工具描述里已自动打上 ⚠️ 标记):
109
+
110
+ `DeleteStaff` · `DeleteExtension` · `DeleteCCCSkillGroup` · `DeletePredictiveDialingCampaign` · `AbortPredictiveDialingCampaign` · `HangUpCall` · `StopAutoCalloutTask` · `ForceMemberOffline` · `ResetExtensionPassword` · `UnbindNumberCallOutSkillGroup` …… 共 16 个。
111
+
112
+ 特别注意:
113
+
114
+ - **`DeleteStaff` 没有回收站**,删除后只能重建,原工号不会自动恢复。
115
+ - 批量修改类接口通常是**全量覆盖**,改之前先查一遍现有配置做备份。
116
+
117
+ ## 安全建议
118
+
119
+ 1. **用 CAM 子账号密钥**,只授予 `QcloudCCCReadOnlyAccess` 或按需的最小策略,不要使用主账号密钥。
120
+ 2. 密钥只放在本地 `env` 里,不要提交到版本库。
121
+ 3. 生产环境建议开启操作审计(CloudAudit)。
122
+
123
+ ## 常见问题
124
+
125
+ **Q:工具都加载了,但调用报 `InvalidParameterValue | SdkAppId invalid`**
126
+
127
+ 先跑列表接口确认这对密钥下真实存在的应用 ID:
128
+
129
+ ```
130
+ describe_cccbuy_info_list
131
+ ```
132
+
133
+ 如果目标 ID 不在返回列表里,说明**密钥属于另一个腾讯云账号**(TCCC 应用不跨账号可见)—— 换密钥即可,不是 ID 写错。
134
+
135
+ **Q:报 `UnknownParameter: SdkAppId not recognized`**
136
+
137
+ 部分接口(如 `DescribeCCCBuyInfoList`)不需要 `SdkAppId`。server 会自动判断,不会给没有该字段的接口注入;如果仍出现请提 issue。
138
+
139
+ **Q:查询返回空**
140
+
141
+ 先怀疑标识符拼写。座席邮箱、域名这类手工输入的值常有 typo(例如 `gmai.com` 少了 `l`)。
142
+
143
+ ## 已知限制
144
+
145
+ - 频率限制:多数接口 20 次/秒,`UploadIvrAudio`、`CreateCompanyApply` 为 1 次/秒,批量操作需自行节流。
146
+ - `UploadIvrAudio` 等涉及文件的接口,参数里是 COS 链接而非文件流,需先自行上传。
147
+ - 仅覆盖 API 3.0 的 `ccc` 服务,不含 TCCC 的 WebSocket / SDK 侧信令。
148
+
149
+ ## 开发
150
+
151
+ ```bash
152
+ npm install
153
+ npm run generate # 重新解析 SDK 类型定义,生成 src/tools.json
154
+ npm start # 本地启动(stdio)
155
+ ```
156
+
157
+ 工具定义来自 `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` 即可同步。
158
+
159
+ 发布前 `prepublishOnly` 会自动重跑 `generate`,保证产物与 SDK 版本一致。
160
+
161
+ ## License
162
+
163
+ [MIT](./LICENSE)
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@tencentcloud/tccc-mcp-server",
3
+ "version": "0.0.1",
4
+ "description": "MCP server for Tencent Cloud Contact Center (TCCC)",
5
+ "type": "module",
6
+ "bin": {
7
+ "tccc-mcp-server": "./src/index.mjs"
8
+ },
9
+ "files": [
10
+ "src",
11
+ "README.md",
12
+ "README_zh.md",
13
+ "LICENSE"
14
+ ],
15
+ "scripts": {
16
+ "generate": "node src/generate.mjs",
17
+ "start": "node src/index.mjs",
18
+ "prepublishOnly": "npm run generate"
19
+ },
20
+ "dependencies": {
21
+ "@modelcontextprotocol/sdk": "^1.30.0",
22
+ "tencentcloud-sdk-nodejs-ccc": "^4.1.310"
23
+ },
24
+ "engines": {
25
+ "node": ">=18"
26
+ },
27
+ "publishConfig": {
28
+ "access": "public"
29
+ },
30
+ "keywords": [
31
+ "mcp",
32
+ "mcp-server",
33
+ "modelcontextprotocol",
34
+ "tccc",
35
+ "tencentcloud",
36
+ "tencent",
37
+ "call-center",
38
+ "contact-center",
39
+ "voice-agent",
40
+ "llm",
41
+ "ai",
42
+ "agent",
43
+ "腾讯云",
44
+ "云联络中心",
45
+ "呼叫中心"
46
+ ],
47
+ "author": "qiaoyang",
48
+ "license": "MIT",
49
+ "homepage": "https://github.com/tencentcloud/tccc-mcp-server#readme",
50
+ "repository": {
51
+ "type": "git",
52
+ "url": "git+https://github.com/tencentcloud/tccc-mcp-server.git"
53
+ },
54
+ "bugs": {
55
+ "url": "https://github.com/tencentcloud/tccc-mcp-server/issues"
56
+ }
57
+ }
@@ -0,0 +1,130 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * 从腾讯云官方 SDK 的 TypeScript 类型定义自动生成 MCP 工具定义。
4
+ *
5
+ * 数据源:node_modules/tencentcloud-sdk-nodejs-ccc/tencentcloud/services/ccc/v20200210/
6
+ * - ccc_models.d.ts :251 个结构体,每个字段带 JSDoc 中文说明 + 是否可选
7
+ * - ccc_client.d.ts :84 个接口方法,带 JSDoc 中文说明
8
+ *
9
+ * 输出:src/tools.json(MCP tools/list 用的定义清单)
10
+ */
11
+ import fs from 'node:fs';
12
+ import path from 'node:path';
13
+ import { fileURLToPath } from 'node:url';
14
+
15
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
16
+
17
+ const SDK_DIR = path.resolve(
18
+ __dirname,
19
+ '../node_modules/tencentcloud-sdk-nodejs-ccc/tencentcloud/services/ccc/v20200210'
20
+ );
21
+ const OUT = path.join(__dirname, 'tools.json');
22
+
23
+ if (!fs.existsSync(SDK_DIR)) {
24
+ console.error('找不到 CCC SDK 类型定义,请先执行 npm install:', SDK_DIR);
25
+ process.exit(1);
26
+ }
27
+
28
+ const modelsSrc = fs.readFileSync(path.join(SDK_DIR, 'ccc_models.d.ts'), 'utf8');
29
+ const clientSrc = fs.readFileSync(path.join(SDK_DIR, 'ccc_client.d.ts'), 'utf8');
30
+
31
+ /** 把 JSDoc 里的 HTML 与星号清理成一行纯文本描述 */
32
+ function cleanDoc(raw) {
33
+ return raw
34
+ .replace(/^\s*\*\s?/gm, '')
35
+ .replace(/<br\s*\/?>/gi, ' ')
36
+ .replace(/<[^>]+>/g, '')
37
+ .replace(/&nbsp;/g, ' ')
38
+ .replace(/&lt;/g, '<')
39
+ .replace(/&gt;/g, '>')
40
+ .replace(/&amp;/g, '&')
41
+ .replace(/\s+/g, ' ')
42
+ .trim();
43
+ }
44
+
45
+ // ---------- 1. 解析所有 interface ----------
46
+ const models = new Map();
47
+ const ifaceRe = /export interface (\w+) \{([\n\r][\s\S]*?)\n\}/g;
48
+ let m;
49
+ while ((m = ifaceRe.exec(modelsSrc))) {
50
+ const fields = [];
51
+ const fieldRe = /\/\*\*([\s\S]*?)\*\/\s*\n\s*(\w+)(\??):\s*([^;]+);/g;
52
+ let f;
53
+ while ((f = fieldRe.exec(m[2]))) {
54
+ fields.push({ name: f[2], optional: f[3] === '?', tsType: f[4].trim(), doc: cleanDoc(f[1]) });
55
+ }
56
+ models.set(m[1], fields);
57
+ }
58
+
59
+ // ---------- 2. TS 类型 -> JSON Schema(递归展开嵌套结构体) ----------
60
+ function tsToSchema(tsType, depth = 0, seen = new Set()) {
61
+ const t = tsType.trim();
62
+ const arr = /^Array<(.*)>$/.exec(t);
63
+ if (arr) return { type: 'array', items: tsToSchema(arr[1], depth, seen) };
64
+ // 联合类型:腾讯云 SDK 里常见 `number | bigint`(int64 字段)。
65
+ // 逐个分支解析,取第一个能识别的具体类型;全都不认识才退化成 object。
66
+ if (t.includes('|')) {
67
+ for (const branch of t.split('|').map((s) => s.trim())) {
68
+ if (!branch) continue;
69
+ const s = tsToSchema(branch, depth, seen);
70
+ if (s.type !== 'object' || s.properties) return s;
71
+ }
72
+ return { type: 'object', additionalProperties: true };
73
+ }
74
+ if (t === 'string') return { type: 'string' };
75
+ if (t === 'number') return { type: 'number' };
76
+ if (t === 'boolean') return { type: 'boolean' };
77
+ if (models.has(t) && depth < 6 && !seen.has(t)) {
78
+ return structToSchema(models.get(t), depth + 1, new Set([...seen, t]));
79
+ }
80
+ return { type: 'object', additionalProperties: true }; // 兜底,避免丢字段
81
+ }
82
+
83
+ function structToSchema(fields, depth = 0, seen = new Set()) {
84
+ const schema = { type: 'object', properties: {}, required: [], additionalProperties: false };
85
+ for (const f of fields) {
86
+ const s = tsToSchema(f.tsType, depth, seen);
87
+ if (f.doc) s.description = f.doc;
88
+ schema.properties[f.name] = s;
89
+ if (!f.optional) schema.required.push(f.name);
90
+ }
91
+ if (!schema.required.length) delete schema.required;
92
+ return schema;
93
+ }
94
+
95
+ // ---------- 3. 解析 client 方法 ----------
96
+ /** 具有副作用/破坏性的接口,执行前必须向用户二次确认 */
97
+ const DESTRUCTIVE = /^(Delete|Abort|Stop|HangUp|Reset|Disable|Force|Unbind|TransferToManual|PlaySoundCall|ControlAIConversation)/;
98
+
99
+ const tools = [];
100
+ const methodRe =
101
+ /\/\*\*([\s\S]*?)\*\/\s*\n\s*(\w+)\(req: (\w+Request), cb\?: \(error: string, rep: (\w+Response)\) => void\): Promise<\w+Response>;/g;
102
+
103
+ while ((m = methodRe.exec(clientSrc))) {
104
+ const [, docRaw, action, reqName] = m;
105
+ const fields = models.get(reqName);
106
+ if (!fields) {
107
+ console.warn(` ! 跳过 ${action}:找不到 ${reqName}`);
108
+ continue;
109
+ }
110
+ const inputSchema = structToSchema(fields);
111
+ const desc = cleanDoc(docRaw) || action;
112
+ const dangerous = DESTRUCTIVE.test(action);
113
+
114
+ tools.push({
115
+ // MCP 工具名用 snake_case,便于模型调用
116
+ name: action.replace(/([a-z0-9])([A-Z])/g, '$1_$2').toLowerCase(),
117
+ action,
118
+ destructive: dangerous,
119
+ description: (dangerous ? '⚠️ 危险/有副作用操作,执行前必须先向用户确认。' : '') + desc.slice(0, 400),
120
+ inputSchema,
121
+ });
122
+ }
123
+
124
+ tools.sort((a, b) => a.name.localeCompare(b.name));
125
+ fs.writeFileSync(OUT, JSON.stringify(tools, null, 2));
126
+
127
+ const totalFields = tools.reduce((a, t) => a + Object.keys(t.inputSchema.properties || {}).length, 0);
128
+ console.log(`✓ 已生成 ${tools.length} 个 MCP 工具 -> ${OUT}`);
129
+ console.log(` 结构体 ${models.size} 个,参数字段 ${totalFields} 个,平均 ${(totalFields / tools.length).toFixed(1)} 个/接口`);
130
+ console.log(` 危险操作标记:${tools.filter((t) => t.destructive).length} 个`);