@szc-ft/mcp-szcd-client 0.14.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agents/build.js +17 -29
- package/commands/szcd-mcp-api-config.md +1 -1
- package/commands/szcd-mcp-auth.md +39 -0
- package/commands/szcd-mcp-coding-config.md +1 -1
- package/commands/szcd-mcp-url.md +1 -1
- package/package.json +7 -7
- package/qwen-extension/commands/szcd-mcp-api-config.md +1 -1
- package/qwen-extension/commands/szcd-mcp-auth.md +39 -0
- package/qwen-extension/commands/szcd-mcp-coding-config.md +1 -1
- package/qwen-extension/commands/szcd-mcp-url.md +1 -1
- package/qwen-extension/qwen-extension.json +1 -1
- package/qwen-extension/skills/local-api-tool/SKILL.md +233 -0
- package/qwen-extension/skills/szcd-component-helper/SKILL.md +15 -67
- package/scripts/postinstall.js +1 -1
- package/scripts/update-auth.js +198 -0
- package/standard-skill/local-api-tool/SKILL.md +233 -0
- package/standard-skill/szcd-component-helper/SKILL.md +7 -3
package/agents/build.js
CHANGED
|
@@ -252,27 +252,7 @@ function build() {
|
|
|
252
252
|
console.log(` ✓ Written: ${path.relative(AGENTS_DIR, outputPath)}`);
|
|
253
253
|
}
|
|
254
254
|
|
|
255
|
-
// 3.
|
|
256
|
-
const mcpServerAgentsDir = path.join(AGENTS_DIR, "..", "..", "szcd-mcp-server", "agents");
|
|
257
|
-
if (fs.existsSync(path.dirname(mcpServerAgentsDir))) {
|
|
258
|
-
if (!fs.existsSync(mcpServerAgentsDir)) {
|
|
259
|
-
fs.mkdirSync(mcpServerAgentsDir, { recursive: true });
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
const outputFiles = [
|
|
263
|
-
"szcd-component-expert.md",
|
|
264
|
-
"szcd-component-expert.trae.md",
|
|
265
|
-
"szcd-component-expert.qoder.md",
|
|
266
|
-
];
|
|
267
|
-
for (const file of outputFiles) {
|
|
268
|
-
const src = path.join(AGENTS_DIR, file);
|
|
269
|
-
const dest = path.join(mcpServerAgentsDir, file);
|
|
270
|
-
if (fs.existsSync(src)) {
|
|
271
|
-
fs.copyFileSync(src, dest);
|
|
272
|
-
console.log(` ✓ Synced to mcp-server: ${file}`);
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
}
|
|
255
|
+
// 3. 不再同步到 szcd-mcp-server(服务端不消费 agents 目录,由客户端独立维护)
|
|
276
256
|
|
|
277
257
|
// 4. 同步到 qwen-extension/agents/(供 Qwen Code 扩展安装使用)
|
|
278
258
|
const qwenExtDir = path.join(AGENTS_DIR, "..", "qwen-extension");
|
|
@@ -289,15 +269,23 @@ function build() {
|
|
|
289
269
|
// 5. 同步 SKILL.md 和 commands 到 qwen-extension/
|
|
290
270
|
const packageRoot = path.join(AGENTS_DIR, "..");
|
|
291
271
|
|
|
292
|
-
//
|
|
293
|
-
const
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
272
|
+
// 同步所有 skills(从 standard-skill 目录读取)
|
|
273
|
+
const standardSkillDir = path.join(packageRoot, "standard-skill");
|
|
274
|
+
if (fs.existsSync(standardSkillDir)) {
|
|
275
|
+
const skillDirs = fs.readdirSync(standardSkillDir).filter((name) => {
|
|
276
|
+
return fs.statSync(path.join(standardSkillDir, name)).isDirectory();
|
|
277
|
+
});
|
|
278
|
+
for (const skillDir of skillDirs) {
|
|
279
|
+
const srcSkillPath = path.join(standardSkillDir, skillDir, "SKILL.md");
|
|
280
|
+
const destSkillPath = path.join(qwenExtDir, "skills", skillDir, "SKILL.md");
|
|
281
|
+
if (fs.existsSync(srcSkillPath)) {
|
|
282
|
+
if (!fs.existsSync(path.dirname(destSkillPath))) {
|
|
283
|
+
fs.mkdirSync(path.dirname(destSkillPath), { recursive: true });
|
|
284
|
+
}
|
|
285
|
+
fs.copyFileSync(srcSkillPath, destSkillPath);
|
|
286
|
+
console.log(` ✓ Synced skill to qwen-extension/skills/${skillDir}/`);
|
|
287
|
+
}
|
|
298
288
|
}
|
|
299
|
-
fs.copyFileSync(skillSource, skillDest);
|
|
300
|
-
console.log(` ✓ Synced to qwen-extension/skills/`);
|
|
301
289
|
}
|
|
302
290
|
|
|
303
291
|
// 同步 commands
|
|
@@ -32,7 +32,7 @@ argument-hint: <get|set|clear> [--baseUrl=xxx] [--account=yyy] [--password=zzz]
|
|
|
32
32
|
|
|
33
33
|
3. **命令回退**:如果 npx 不可用,依次尝试:
|
|
34
34
|
- `node $(npm root -g)/@szc-ft/mcp-szcd-client/scripts/update-api-config.js <args>`
|
|
35
|
-
- `node /scity/zengzhijie/
|
|
35
|
+
- `node /scity/zengzhijie/mcp/szcd-mcp-client/scripts/update-api-config.js <args>`
|
|
36
36
|
|
|
37
37
|
**配置字段说明**:
|
|
38
38
|
- `YAPI_BASE_URL` - YApi 基础地址
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 管理MCP服务器鉴权密钥(get/set/clear API Key)
|
|
3
|
+
argument-hint: <get|set|clear> [--apiKey=xxx]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
请帮我管理 szcd MCP 的鉴权配置。
|
|
7
|
+
|
|
8
|
+
**交互流程**:
|
|
9
|
+
|
|
10
|
+
1. **向用户询问要执行的操作**,提供以下选项:
|
|
11
|
+
- "查看鉴权配置" -> 执行 get
|
|
12
|
+
- "设置 API Key" -> 执行 set(需进一步追问参数)
|
|
13
|
+
- "清除 API Key" -> 执行 clear
|
|
14
|
+
|
|
15
|
+
2. **根据用户选择执行**:
|
|
16
|
+
|
|
17
|
+
- **查看鉴权配置**:直接执行 `npx szcd-mcp-auth get`
|
|
18
|
+
|
|
19
|
+
- **设置 API Key**:向用户询问 API Key(由 MCP 服务端管理员提供),收集后执行:
|
|
20
|
+
```bash
|
|
21
|
+
npx szcd-mcp-auth set --apiKey="<apiKey>"
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
- **清除 API Key**:确认后执行 `npx szcd-mcp-auth clear`
|
|
25
|
+
|
|
26
|
+
3. **命令回退**:如果 npx 不可用,依次尝试:
|
|
27
|
+
- `node $(npm root -g)/@szc-ft/mcp-szcd-client/scripts/update-auth.js <args>`
|
|
28
|
+
- `node /scity/zengzhijie/mcp/szcd-mcp-client/scripts/update-auth.js <args>`
|
|
29
|
+
|
|
30
|
+
**配置字段说明**:
|
|
31
|
+
- `MCP_API_KEY` — MCP 服务器鉴权密钥(敏感)
|
|
32
|
+
- 设置后,客户端连接时自动通过 `X-API-Key` 请求头传递
|
|
33
|
+
- 服务端需配置相同的 `MCP_API_KEY` 环境变量才会校验
|
|
34
|
+
- 未设置时,若服务端也未开启鉴权,客户端可正常连接
|
|
35
|
+
|
|
36
|
+
配置保存在 `~/.szcd-mcp-config.json` 中,设置后重启 IDE/CLI 生效。
|
|
37
|
+
|
|
38
|
+
当前配置:
|
|
39
|
+
!`cat ~/.szcd-mcp-config.json 2>/dev/null | grep -E "MCP_API_KEY|MCP_SERVER" || echo "配置文件不存在"`
|
|
@@ -29,7 +29,7 @@ argument-hint: <get|set|clear> [--baseUrl=xxx] [--projectId=yyy] [--account=zzz]
|
|
|
29
29
|
|
|
30
30
|
3. **命令回退**:如果 npx 不可用,依次尝试:
|
|
31
31
|
- `node $(npm root -g)/@szc-ft/mcp-szcd-client/scripts/update-coding-config.js <args>`
|
|
32
|
-
- `node /scity/zengzhijie/
|
|
32
|
+
- `node /scity/zengzhijie/mcp/szcd-mcp-client/scripts/update-coding-config.js <args>`
|
|
33
33
|
|
|
34
34
|
**配置字段说明**:
|
|
35
35
|
- `CODING_BASE_URL` — CODING 基础地址
|
package/commands/szcd-mcp-url.md
CHANGED
|
@@ -28,7 +28,7 @@ argument-hint: <new-mcp-server-url>
|
|
|
28
28
|
|
|
29
29
|
3. **命令回退**:如果 npx 不可用,依次尝试:
|
|
30
30
|
- `node $(npm root -g)/@szc-ft/mcp-szcd-client/scripts/update-mcp-url.js "<newUrl>"`
|
|
31
|
-
- `node /scity/zengzhijie/
|
|
31
|
+
- `node /scity/zengzhijie/mcp/szcd-mcp-client/scripts/update-mcp-url.js "<newUrl>"`
|
|
32
32
|
- 手动步骤:编辑 `~/.szcd-mcp-config.json`,再逐个 IDE 同步:
|
|
33
33
|
- trae-cli: `trae-cli mcp remove szcd-component-helper && trae-cli mcp add-json szcd-component-helper '{"type":"http","url":"<URL>/mcp"}'`
|
|
34
34
|
- claude: `claude mcp remove --scope user szcd-component-helper && claude mcp add --transport http --scope user szcd-component-helper <URL>/mcp`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@szc-ft/mcp-szcd-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "MCP client for szcd component library - auto-configures AI coding tools with MCP server, skills, agents and commands",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mcp",
|
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
"szcd-mcp-setup": "scripts/postinstall.js",
|
|
25
25
|
"szcd-mcp-update-url": "scripts/update-mcp-url.js",
|
|
26
26
|
"szcd-mcp-coding-config": "scripts/update-coding-config.js",
|
|
27
|
-
"szcd-mcp-api-config": "scripts/update-api-config.js"
|
|
27
|
+
"szcd-mcp-api-config": "scripts/update-api-config.js",
|
|
28
|
+
"szcd-mcp-auth": "scripts/update-auth.js"
|
|
28
29
|
},
|
|
29
30
|
"files": [
|
|
30
31
|
"mcp-proxy.js",
|
|
@@ -32,9 +33,9 @@
|
|
|
32
33
|
"scripts/update-mcp-url.js",
|
|
33
34
|
"scripts/update-coding-config.js",
|
|
34
35
|
"scripts/update-api-config.js",
|
|
36
|
+
"scripts/update-auth.js",
|
|
35
37
|
"scripts/lib/",
|
|
36
38
|
"standard-skill/",
|
|
37
|
-
"skill/",
|
|
38
39
|
"agents/",
|
|
39
40
|
"commands/",
|
|
40
41
|
"qwen-extension/",
|
|
@@ -56,11 +57,10 @@
|
|
|
56
57
|
},
|
|
57
58
|
"repository": {
|
|
58
59
|
"type": "git",
|
|
59
|
-
"url": "git+https://github.com/szc-ft/szcd.git"
|
|
60
|
-
"directory": "mcp/szcd-mcp-client"
|
|
60
|
+
"url": "git+https://github.com/szc-ft/mcp-szcd.git"
|
|
61
61
|
},
|
|
62
62
|
"bugs": {
|
|
63
|
-
"url": "https://github.com/szc-ft/szcd/issues"
|
|
63
|
+
"url": "https://github.com/szc-ft/mcp-szcd/issues"
|
|
64
64
|
},
|
|
65
|
-
"homepage": "https://github.com/szc-ft/szcd#readme"
|
|
65
|
+
"homepage": "https://github.com/szc-ft/mcp-szcd#readme"
|
|
66
66
|
}
|
|
@@ -32,7 +32,7 @@ argument-hint: <get|set|clear> [--baseUrl=xxx] [--account=yyy] [--password=zzz]
|
|
|
32
32
|
|
|
33
33
|
3. **命令回退**:如果 npx 不可用,依次尝试:
|
|
34
34
|
- `node $(npm root -g)/@szc-ft/mcp-szcd-client/scripts/update-api-config.js <args>`
|
|
35
|
-
- `node /scity/zengzhijie/
|
|
35
|
+
- `node /scity/zengzhijie/mcp/szcd-mcp-client/scripts/update-api-config.js <args>`
|
|
36
36
|
|
|
37
37
|
**配置字段说明**:
|
|
38
38
|
- `YAPI_BASE_URL` - YApi 基础地址
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 管理MCP服务器鉴权密钥(get/set/clear API Key)
|
|
3
|
+
argument-hint: <get|set|clear> [--apiKey=xxx]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
请帮我管理 szcd MCP 的鉴权配置。
|
|
7
|
+
|
|
8
|
+
**交互流程**:
|
|
9
|
+
|
|
10
|
+
1. **向用户询问要执行的操作**,提供以下选项:
|
|
11
|
+
- "查看鉴权配置" -> 执行 get
|
|
12
|
+
- "设置 API Key" -> 执行 set(需进一步追问参数)
|
|
13
|
+
- "清除 API Key" -> 执行 clear
|
|
14
|
+
|
|
15
|
+
2. **根据用户选择执行**:
|
|
16
|
+
|
|
17
|
+
- **查看鉴权配置**:直接执行 `npx szcd-mcp-auth get`
|
|
18
|
+
|
|
19
|
+
- **设置 API Key**:向用户询问 API Key(由 MCP 服务端管理员提供),收集后执行:
|
|
20
|
+
```bash
|
|
21
|
+
npx szcd-mcp-auth set --apiKey="<apiKey>"
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
- **清除 API Key**:确认后执行 `npx szcd-mcp-auth clear`
|
|
25
|
+
|
|
26
|
+
3. **命令回退**:如果 npx 不可用,依次尝试:
|
|
27
|
+
- `node $(npm root -g)/@szc-ft/mcp-szcd-client/scripts/update-auth.js <args>`
|
|
28
|
+
- `node /scity/zengzhijie/mcp/szcd-mcp-client/scripts/update-auth.js <args>`
|
|
29
|
+
|
|
30
|
+
**配置字段说明**:
|
|
31
|
+
- `MCP_API_KEY` — MCP 服务器鉴权密钥(敏感)
|
|
32
|
+
- 设置后,客户端连接时自动通过 `X-API-Key` 请求头传递
|
|
33
|
+
- 服务端需配置相同的 `MCP_API_KEY` 环境变量才会校验
|
|
34
|
+
- 未设置时,若服务端也未开启鉴权,客户端可正常连接
|
|
35
|
+
|
|
36
|
+
配置保存在 `~/.szcd-mcp-config.json` 中,设置后重启 IDE/CLI 生效。
|
|
37
|
+
|
|
38
|
+
当前配置:
|
|
39
|
+
!`cat ~/.szcd-mcp-config.json 2>/dev/null | grep -E "MCP_API_KEY|MCP_SERVER" || echo "配置文件不存在"`
|
|
@@ -29,7 +29,7 @@ argument-hint: <get|set|clear> [--baseUrl=xxx] [--projectId=yyy] [--account=zzz]
|
|
|
29
29
|
|
|
30
30
|
3. **命令回退**:如果 npx 不可用,依次尝试:
|
|
31
31
|
- `node $(npm root -g)/@szc-ft/mcp-szcd-client/scripts/update-coding-config.js <args>`
|
|
32
|
-
- `node /scity/zengzhijie/
|
|
32
|
+
- `node /scity/zengzhijie/mcp/szcd-mcp-client/scripts/update-coding-config.js <args>`
|
|
33
33
|
|
|
34
34
|
**配置字段说明**:
|
|
35
35
|
- `CODING_BASE_URL` — CODING 基础地址
|
|
@@ -28,7 +28,7 @@ argument-hint: <new-mcp-server-url>
|
|
|
28
28
|
|
|
29
29
|
3. **命令回退**:如果 npx 不可用,依次尝试:
|
|
30
30
|
- `node $(npm root -g)/@szc-ft/mcp-szcd-client/scripts/update-mcp-url.js "<newUrl>"`
|
|
31
|
-
- `node /scity/zengzhijie/
|
|
31
|
+
- `node /scity/zengzhijie/mcp/szcd-mcp-client/scripts/update-mcp-url.js "<newUrl>"`
|
|
32
32
|
- 手动步骤:编辑 `~/.szcd-mcp-config.json`,再逐个 IDE 同步:
|
|
33
33
|
- trae-cli: `trae-cli mcp remove szcd-component-helper && trae-cli mcp add-json szcd-component-helper '{"type":"http","url":"<URL>/mcp"}'`
|
|
34
34
|
- claude: `claude mcp remove --scope user szcd-component-helper && claude mcp add --transport http --scope user szcd-component-helper <URL>/mcp`
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: local-api-tool
|
|
3
|
+
description: 本地网络 API 工具,专门处理 10.x.x.x 网段的 Swagger/YApi 文档拉取和联调测试。当服务端 api_tool 因 LOCAL_NETWORK_UNREACHABLE 无法访问时,此技能在用户本地环境执行 curl,再将结果交给服务端解析。适用于内网开发环境、VPN 场景。
|
|
4
|
+
compatibility:
|
|
5
|
+
tools:
|
|
6
|
+
- run_command
|
|
7
|
+
- web_search
|
|
8
|
+
- web_fetch
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# 本地网络 API 工具(local-api-tool)
|
|
12
|
+
|
|
13
|
+
## 概述
|
|
14
|
+
|
|
15
|
+
当 MCP 服务端 `api_tool` 遇到 `10.x.x.x` 网段地址时,因服务器无法直连用户内网,会返回 `reason: "LOCAL_NETWORK_UNREACHABLE"` 及 `action` 字段指引。此技能指导 AI 自动在用户本地终端通过 `run_command` 执行 curl 命令获取数据,再调用服务端的 `parse_swagger_json` 进行解析,全程无需用户手动操作。
|
|
16
|
+
|
|
17
|
+
## 适用场景
|
|
18
|
+
|
|
19
|
+
- Swagger URL 主机为 `10.x.x.x` 网段(如 `http://10.2.7.60:30194/ikmp-knowledge/swagger-ui/index.html`)
|
|
20
|
+
- API 联调测试目标为 `10.x.x.x` 网段
|
|
21
|
+
- 用户在 VPN 或内网开发环境中,本地可访问但远程服务器不可达
|
|
22
|
+
|
|
23
|
+
## 工作流
|
|
24
|
+
|
|
25
|
+
### 流程 A:拉取 Swagger API 文档(fetch)
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
用户请求 fetch Swagger URL (10.x.x.x)
|
|
29
|
+
│
|
|
30
|
+
▼
|
|
31
|
+
调用 api_tool(action="fetch", url=...)
|
|
32
|
+
│
|
|
33
|
+
▼
|
|
34
|
+
服务端返回 { reason: "LOCAL_NETWORK_UNREACHABLE", action: "请使用 local-api-tool ...", swaggerEndpoints: {...} }
|
|
35
|
+
│
|
|
36
|
+
▼
|
|
37
|
+
AI 识别 LOCAL_NETWORK_UNREACHABLE,读取 swaggerEndpoints 和 authInfo
|
|
38
|
+
│
|
|
39
|
+
▼
|
|
40
|
+
AI 通过 run_command 在本地执行 curl:
|
|
41
|
+
步骤1: 鉴权获取 Cookie(如 authInfo.hasPassword 为 true)
|
|
42
|
+
步骤2: 获取完整 API 文档 JSON
|
|
43
|
+
│
|
|
44
|
+
▼
|
|
45
|
+
AI 调用 api_tool(action="parse_swagger_json", swaggerJson=..., swaggerSourceUrl=...)
|
|
46
|
+
│
|
|
47
|
+
▼
|
|
48
|
+
返回解析后的 API 文档给用户
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 流程 B:联调测试(test)
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
用户请求 test API (10.x.x.x)
|
|
55
|
+
│
|
|
56
|
+
▼
|
|
57
|
+
调用 api_tool(action="test", url=..., method=..., data=..., headers=...)
|
|
58
|
+
│
|
|
59
|
+
▼
|
|
60
|
+
服务端返回 { reason: "LOCAL_NETWORK_UNREACHABLE", action: "请使用 local-api-tool ...", method, data, headers }
|
|
61
|
+
│
|
|
62
|
+
▼
|
|
63
|
+
AI 识别 LOCAL_NETWORK_UNREACHABLE,读取 method/data/headers
|
|
64
|
+
│
|
|
65
|
+
▼
|
|
66
|
+
AI 通过 run_command 在本地执行对应 curl 命令
|
|
67
|
+
│
|
|
68
|
+
▼
|
|
69
|
+
将响应结果返回给用户
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## 详细执行步骤
|
|
73
|
+
|
|
74
|
+
### 一、拉取 Swagger 文档(action=fetch)
|
|
75
|
+
|
|
76
|
+
**步骤 1:调用服务端 api_tool**
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
api_tool(action="fetch", url="http://10.2.7.60:30194/ikmp-knowledge/swagger-ui/index.html", username="admin", password="xxx")
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**步骤 2:检测 LOCAL_NETWORK_UNREACHABLE**
|
|
83
|
+
|
|
84
|
+
如果返回结果中包含 `reason: "LOCAL_NETWORK_UNREACHABLE"`,则自动进入本地执行流程。
|
|
85
|
+
|
|
86
|
+
返回结构示例:
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"reason": "LOCAL_NETWORK_UNREACHABLE",
|
|
90
|
+
"hostname": "10.2.7.60",
|
|
91
|
+
"swaggerUrl": "http://10.2.7.60:30194/ikmp-knowledge/swagger-ui/index.html",
|
|
92
|
+
"authInfo": { "username": "admin", "hasPassword": true },
|
|
93
|
+
"swaggerEndpoints": {
|
|
94
|
+
"basePath": "http://10.2.7.60:30194/ikmp-knowledge",
|
|
95
|
+
"apiDocsUrl": "http://10.2.7.60:30194/ikmp-knowledge/v2/api-docs"
|
|
96
|
+
},
|
|
97
|
+
"action": "请使用 local-api-tool 技能处理此请求..."
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**步骤 3:AI 通过 run_command 在本地执行 curl**
|
|
102
|
+
|
|
103
|
+
根据返回数据中的 `authInfo` 和 `swaggerEndpoints`,AI 自行构造 curl 命令并通过 `run_command` 在本地执行:
|
|
104
|
+
|
|
105
|
+
3a. **鉴权(如 authInfo.hasPassword 为 true)**:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
curl -s -D - -X GET 'http://10.2.7.60:30194/ikmp-knowledge/swagger-resources/configuration/ui' \
|
|
109
|
+
-H 'Authorization: Basic <base64(username:password)>' \
|
|
110
|
+
-H 'Accept: application/json'
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
从输出的 `Set-Cookie:` 行提取 Cookie 值(分号前的部分)。
|
|
114
|
+
|
|
115
|
+
3b. **获取 API 文档 JSON**:直接使用 `swaggerEndpoints.apiDocsUrl`:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
curl -s -X GET 'http://10.2.7.60:30194/ikmp-knowledge/v2/api-docs' \
|
|
119
|
+
-H 'Accept: application/json' \
|
|
120
|
+
-H 'Cookie: <步骤3a获取的Cookie>'
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
如果 authInfo.hasPassword 为 false,省略 Cookie 头。
|
|
124
|
+
|
|
125
|
+
**步骤 4:调用服务端解析**
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
api_tool(action="parse_swagger_json", swaggerJson="<步骤3b获取的JSON字符串>", swaggerSourceUrl="http://10.2.7.60:30194/ikmp-knowledge/swagger-ui/index.html")
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**步骤 5:返回解析结果**
|
|
132
|
+
|
|
133
|
+
将 `parse_swagger_json` 返回的解析结果直接返回给用户,格式与正常 fetch 完全一致。
|
|
134
|
+
|
|
135
|
+
### 二、联调测试(action=test)
|
|
136
|
+
|
|
137
|
+
**步骤 1:调用服务端 api_tool**
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
api_tool(action="test", url="http://10.2.7.60:30194/ikmp-knowledge/api/xxx", method="POST", data={...}, headers={...})
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**步骤 2:检测 LOCAL_NETWORK_UNREACHABLE**
|
|
144
|
+
|
|
145
|
+
如果返回结果中包含 `reason: "LOCAL_NETWORK_UNREACHABLE"`,则自动进入本地执行流程。
|
|
146
|
+
|
|
147
|
+
返回结构示例:
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"success": false,
|
|
151
|
+
"reason": "LOCAL_NETWORK_UNREACHABLE",
|
|
152
|
+
"hostname": "10.2.7.60",
|
|
153
|
+
"targetUrl": "http://10.2.7.60:30194/ikmp-knowledge/api/xxx",
|
|
154
|
+
"method": "POST",
|
|
155
|
+
"data": { "key": "value" },
|
|
156
|
+
"headers": {},
|
|
157
|
+
"action": "请使用 local-api-tool 技能处理此请求...",
|
|
158
|
+
"timestamp": "..."
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**步骤 3:AI 通过 run_command 在本地执行 curl**
|
|
163
|
+
|
|
164
|
+
AI 根据返回数据中的 `method`、`data`、`headers`、`targetUrl` 自行构造 curl 命令:
|
|
165
|
+
|
|
166
|
+
GET 请求示例:
|
|
167
|
+
```bash
|
|
168
|
+
curl -s -X GET 'http://10.2.7.60:30194/ikmp-knowledge/api/xxx?key=value' \
|
|
169
|
+
-H 'Accept: application/json'
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
POST 请求示例:
|
|
173
|
+
```bash
|
|
174
|
+
curl -s -X POST 'http://10.2.7.60:30194/ikmp-knowledge/api/xxx' \
|
|
175
|
+
-H 'Accept: application/json' \
|
|
176
|
+
-H 'Content-Type: application/json' \
|
|
177
|
+
-d '{"key":"value"}'
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
如有自定义 headers,添加对应的 `-H` 参数。
|
|
181
|
+
|
|
182
|
+
**步骤 4:返回测试结果**
|
|
183
|
+
|
|
184
|
+
将 curl 的响应内容返回给用户。如果是 JSON 格式,尽量格式化输出。
|
|
185
|
+
|
|
186
|
+
## 快捷方式:AI 直接识别 10 段地址
|
|
187
|
+
|
|
188
|
+
如果 AI 能识别出用户请求的 URL 中包含 `10.x.x.x` 主机地址,可以**直接跳过首次 api_tool 调用**,在本地执行 curl,再调用 `parse_swagger_json`,减少一次无用的服务端请求:
|
|
189
|
+
|
|
190
|
+
1. 从 Swagger URL 推导鉴权地址、文档地址
|
|
191
|
+
2. 通过 `run_command` 在本地依次 curl
|
|
192
|
+
3. 调用 `api_tool(action="parse_swagger_json")` 解析
|
|
193
|
+
|
|
194
|
+
### URL 推导规则
|
|
195
|
+
|
|
196
|
+
对于 Swagger URL 如 `http://10.2.7.60:30194/ikmp-knowledge/swagger-ui/index.html`:
|
|
197
|
+
|
|
198
|
+
| 推导项 | 规则 | 示例 |
|
|
199
|
+
|--------|------|------|
|
|
200
|
+
| basePath | `protocol + host + 第一个路径段` | `http://10.2.7.60:30194/ikmp-knowledge` |
|
|
201
|
+
| authUrl | `basePath + /swagger-resources/configuration/ui` | `http://10.2.7.60:30194/ikmp-knowledge/swagger-resources/configuration/ui` |
|
|
202
|
+
| apiDocsUrl | `basePath + /v2/api-docs` | `http://10.2.7.60:30194/ikmp-knowledge/v2/api-docs` |
|
|
203
|
+
|
|
204
|
+
### curl 执行模板
|
|
205
|
+
|
|
206
|
+
**鉴权(带密码时):**
|
|
207
|
+
```bash
|
|
208
|
+
curl -s -D - -X GET '<authUrl>' \
|
|
209
|
+
-H 'Authorization: Basic <base64(username:password)>' \
|
|
210
|
+
-H 'Accept: application/json'
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**获取文档(带 Cookie 时):**
|
|
214
|
+
```bash
|
|
215
|
+
curl -s -X GET '<apiDocsUrl>' \
|
|
216
|
+
-H 'Accept: application/json' \
|
|
217
|
+
-H 'Cookie: <鉴权获取的Cookie>'
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
**获取文档(无密码时):**
|
|
221
|
+
```bash
|
|
222
|
+
curl -s -X GET '<apiDocsUrl>' \
|
|
223
|
+
-H 'Accept: application/json'
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## 注意事项
|
|
227
|
+
|
|
228
|
+
1. **Cookie 传递**:鉴权步骤获取的 Cookie 需要在后续步骤中通过 `-H 'Cookie: xxx'` 传递
|
|
229
|
+
2. **无密码场景**:如果用户未提供密码,跳过鉴权步骤,直接获取文档
|
|
230
|
+
3. **JSON 格式**:curl 获取的 API 文档必须是有效的 Swagger JSON,否则 `parse_swagger_json` 会报错
|
|
231
|
+
4. **超时处理**:本地 curl 可能因网络原因超时,建议添加 `--connect-timeout 10 --max-time 30` 参数
|
|
232
|
+
5. **错误处理**:如果某步骤 curl 失败,将错误信息返回给用户,不要继续后续步骤
|
|
233
|
+
6. **自动执行**:AI 识别 `reason: "LOCAL_NETWORK_UNREACHABLE"` 后应**自动**通过 `run_command` 执行 curl,无需让用户手动复制粘贴命令
|
|
@@ -19,7 +19,7 @@ compatibility:
|
|
|
19
19
|
|
|
20
20
|
**重要说明**:这是一个客户端 skill,通过 MCP 协议(SSE 或 HTTP)连接到远程 MCP 服务器。服务器由管理员维护,包含源码和数据。
|
|
21
21
|
|
|
22
|
-
**版本**:v0.
|
|
22
|
+
**版本**:v0.17.0 - 新增 10 段网段本地网络兼容:api_tool 新增 parse_swagger_json action,客户端新增 local-api-tool 技能,遇到 10.x.x.x 网段自动在本地 curl 获取 Swagger JSON 再交由服务端解析
|
|
23
23
|
|
|
24
24
|
## 架构说明
|
|
25
25
|
|
|
@@ -58,7 +58,7 @@ compatibility:
|
|
|
58
58
|
|
|
59
59
|
## 推荐工作流(页面生成类任务)
|
|
60
60
|
|
|
61
|
-
AI
|
|
61
|
+
AI 助手在处理页面生成需求时,必须按以下流程使用工具:
|
|
62
62
|
|
|
63
63
|
### 步骤1:架构认知 + 需求理解
|
|
64
64
|
- 调用 `get_architecture_overview(detail="summary")` 获取 7 层架构和模板组合模式
|
|
@@ -178,15 +178,19 @@ AI 助手在处理页面生成需求时,推荐按以下流程使用工具:
|
|
|
178
178
|
### API 工具
|
|
179
179
|
|
|
180
180
|
#### 9. api_tool
|
|
181
|
-
**功能**:统一 API 工具,自动识别 YApi/Swagger 拉取 API
|
|
181
|
+
**功能**:统一 API 工具,自动识别 YApi/Swagger 拉取 API 文档、联调测试、配置管理、解析本地 Swagger JSON。
|
|
182
182
|
**参数**:
|
|
183
|
-
- `action` (enum, required): fetch=拉取API文档, test=联调测试, config
|
|
183
|
+
- `action` (enum, required): fetch=拉取API文档, test=联调测试, config=配置管理, parse_swagger_json=解析本地curl获取的Swagger JSON
|
|
184
184
|
- `url` (string, optional): API文档地址(fetch时)/ 请求地址(test时)
|
|
185
185
|
- `method` (enum, optional, default: "GET"): GET/POST/PUT/DELETE/PATCH(test时)
|
|
186
186
|
- `data` (object, optional, default: {}): 请求参数(test时)
|
|
187
187
|
- `headers` (object, optional, default: {}): 请求头(test时)
|
|
188
188
|
- `username` / `password` / `account` / `cookies` (string, optional): 鉴权信息
|
|
189
189
|
- `yapiBaseUrl` / `yapiAccount` / `yapiPassword` / `yapiCookies` (string, optional): YApi 配置(config set 时生效)
|
|
190
|
+
- `swaggerJson` (string, optional): 客户端本地 curl 获取的 Swagger JSON 字符串(parse_swagger_json 时必填)
|
|
191
|
+
- `swaggerSourceUrl` (string, optional): 原始 Swagger URL(parse_swagger_json 时可选,用于补充元数据)
|
|
192
|
+
|
|
193
|
+
**10段网段本地执行**:当 fetch/test 遇到 `10.x.x.x` 网段地址时,服务端返回 `LOCAL_NETWORK_UNREACHABLE`,此时应使用 `local-api-tool` 技能在用户本地执行 curl,再调用 `parse_swagger_json` 解析。详见 `local-api-tool` 技能。
|
|
190
194
|
|
|
191
195
|
### Repowiki 增强工具(推荐优先使用)
|
|
192
196
|
|
|
@@ -288,8 +292,6 @@ npm install @szc-ft/mcp-szcd-component-helper
|
|
|
288
292
|
|
|
289
293
|
### 步骤2:配置服务器地址
|
|
290
294
|
|
|
291
|
-
#### 方式1:使用配置文件(推荐)
|
|
292
|
-
|
|
293
295
|
编辑配置文件 `~/.szcd-mcp-config.json`:
|
|
294
296
|
|
|
295
297
|
```json
|
|
@@ -300,23 +302,9 @@ npm install @szc-ft/mcp-szcd-component-helper
|
|
|
300
302
|
}
|
|
301
303
|
```
|
|
302
304
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
```bash
|
|
306
|
-
# Linux/macOS
|
|
307
|
-
export MCP_SERVER_URL="http://localhost:3456"
|
|
308
|
-
export MCP_TIMEOUT="30000"
|
|
309
|
-
export MCP_API_KEY="your-api-key"
|
|
310
|
-
|
|
311
|
-
# Windows (PowerShell)
|
|
312
|
-
$env:MCP_SERVER_URL="http://localhost:3456"
|
|
313
|
-
$env:MCP_TIMEOUT="30000"
|
|
314
|
-
$env:MCP_API_KEY="your-api-key"
|
|
315
|
-
```
|
|
305
|
+
### 步骤3:在 IDE 配置中设置
|
|
316
306
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
**方式3a:Trae CLI Streamable HTTP 直连(推荐)**
|
|
307
|
+
**Trae CLI Streamable HTTP 直连(推荐)**
|
|
320
308
|
|
|
321
309
|
在 `~/.trae/trae_cli.yaml` 中配置:
|
|
322
310
|
|
|
@@ -327,7 +315,7 @@ mcp_servers:
|
|
|
327
315
|
type: http
|
|
328
316
|
```
|
|
329
317
|
|
|
330
|
-
|
|
318
|
+
**本地直连 stdio(推荐,无需远程服务器)**
|
|
331
319
|
|
|
332
320
|
```json
|
|
333
321
|
{
|
|
@@ -340,7 +328,7 @@ mcp_servers:
|
|
|
340
328
|
}
|
|
341
329
|
```
|
|
342
330
|
|
|
343
|
-
|
|
331
|
+
**Qwen Code / Qoder CLI Streamable HTTP 直连(推荐)**
|
|
344
332
|
|
|
345
333
|
在 `~/.qwen/settings.json` 中配置:
|
|
346
334
|
|
|
@@ -355,7 +343,7 @@ mcp_servers:
|
|
|
355
343
|
}
|
|
356
344
|
```
|
|
357
345
|
|
|
358
|
-
|
|
346
|
+
**Qwen Code / Qoder CLI 本地直连 stdio(推荐,无需远程服务器)**
|
|
359
347
|
|
|
360
348
|
```json
|
|
361
349
|
{
|
|
@@ -368,7 +356,7 @@ mcp_servers:
|
|
|
368
356
|
}
|
|
369
357
|
```
|
|
370
358
|
|
|
371
|
-
|
|
359
|
+
**Claude Code 配置**
|
|
372
360
|
|
|
373
361
|
```json
|
|
374
362
|
{
|
|
@@ -381,45 +369,13 @@ mcp_servers:
|
|
|
381
369
|
}
|
|
382
370
|
```
|
|
383
371
|
|
|
384
|
-
### 步骤
|
|
385
|
-
|
|
386
|
-
运行以下命令验证配置是否正确:
|
|
372
|
+
### 步骤4:验证配置
|
|
387
373
|
|
|
388
374
|
```bash
|
|
389
|
-
# 测试服务器连接
|
|
390
375
|
curl http://localhost:3456/health
|
|
391
|
-
|
|
392
|
-
# 测试代理脚本
|
|
393
376
|
npx szcd-mcp-proxy --test
|
|
394
377
|
```
|
|
395
378
|
|
|
396
|
-
## 配置优先级
|
|
397
|
-
|
|
398
|
-
地址获取的优先级顺序:
|
|
399
|
-
|
|
400
|
-
1. **环境变量**(最高优先级)
|
|
401
|
-
2. **配置文件** `~/.szcd-mcp-config.json`
|
|
402
|
-
3. **默认值** `http://localhost:3456`
|
|
403
|
-
|
|
404
|
-
## 环境变量说明
|
|
405
|
-
|
|
406
|
-
### MCP 连接配置
|
|
407
|
-
|
|
408
|
-
| 变量 | 说明 | 默认值 | 示例 |
|
|
409
|
-
|------|------|--------|------|
|
|
410
|
-
| `MCP_SERVER_URL` | MCP 服务器地址 | `http://localhost:3456` | `http://192.168.1.100:3456` |
|
|
411
|
-
| `MCP_TIMEOUT` | 请求超时时间(毫秒) | `30000` | `60000` |
|
|
412
|
-
| `MCP_API_KEY` | MCP API 密钥(可选) | `` | `your-secret-key` |
|
|
413
|
-
|
|
414
|
-
### 视觉模型配置(设计稿分析功能必需)
|
|
415
|
-
|
|
416
|
-
| 变量 | 说明 | 默认值 | 示例 |
|
|
417
|
-
|------|------|--------|------|
|
|
418
|
-
| `VISION_API_KEY` | 视觉模型 API 密钥 | 读取 `ANTHROPIC_API_KEY` 或 `OPENAI_API_KEY` | `sk-ant-...` |
|
|
419
|
-
| `VISION_PROVIDER` | 视觉模型提供商 | `anthropic` | `anthropic` / `openai` |
|
|
420
|
-
| `VISION_MODEL` | 视觉模型名称 | `claude-sonnet-4-6` | `gpt-4o` |
|
|
421
|
-
| `DESIGN_ANALYSIS_ORDER` | 分析优先级 | `vision_first` | `vision_first` / `ocr_first` / `vision_only` / `ocr_only` |
|
|
422
|
-
|
|
423
379
|
## 反馈收集(质量闭环)
|
|
424
380
|
|
|
425
381
|
### 触发时机
|
|
@@ -473,8 +429,6 @@ AI 助手应在代码输出后询问:
|
|
|
473
429
|
- `get_component_library_overview`、`list_other_components`、`search_all_components` 等旧工具已移除,请使用 `get_architecture_overview` 和 `search_components_semantic` 替代
|
|
474
430
|
- **需要确保 MCP 服务器正在运行,否则无法查询数据**
|
|
475
431
|
- **设计稿分析功能需要配置视觉模型 API Key**,未配置时 analyze_design_image 工具会返回错误
|
|
476
|
-
- **设计稿分析会调用外部多模态模型 API**,会产生额外费用(单张约 $0.03~0.05)
|
|
477
|
-
- **设计稿分析结果会自动缓存 24 小时**,同一图片重复查询不会重复计费
|
|
478
432
|
- **反馈收集是可选但强烈建议的功能**,有助于持续优化 MCP 工具质量
|
|
479
433
|
|
|
480
434
|
## 故障排除
|
|
@@ -487,9 +441,3 @@ AI 助手应在代码输出后询问:
|
|
|
487
441
|
4. 确认 `MCP_SERVER_URL` 配置正确
|
|
488
442
|
5. 检查环境变量是否正确设置
|
|
489
443
|
6. 检查配置文件 `~/.szcd-mcp-config.json` 是否存在
|
|
490
|
-
|
|
491
|
-
### 配置文件问题
|
|
492
|
-
|
|
493
|
-
1. 检查配置文件路径:`~/.szcd-mcp-config.json`
|
|
494
|
-
2. 检查 JSON 格式是否正确
|
|
495
|
-
3. 检查文件权限
|
package/scripts/postinstall.js
CHANGED
|
@@ -73,7 +73,7 @@ function createConfigTemplate() {
|
|
|
73
73
|
MCP_SERVER_URL: common.getMcpServerUrl(),
|
|
74
74
|
MCP_TIMEOUT: 30000,
|
|
75
75
|
MCP_API_KEY: "",
|
|
76
|
-
_comment: "请修改 MCP_SERVER_URL 为您的 MCP
|
|
76
|
+
_comment: "请修改 MCP_SERVER_URL 为您的 MCP 服务器地址;MCP_API_KEY 为服务端鉴权密钥(npx szcd-mcp-auth set --apiKey=xxx)",
|
|
77
77
|
};
|
|
78
78
|
|
|
79
79
|
common.writeFile(configPath, JSON.stringify(configContent, null, 2));
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* szcd-mcp-auth - 管理 MCP 服务器鉴权密钥
|
|
5
|
+
*
|
|
6
|
+
* 用法:
|
|
7
|
+
* npx szcd-mcp-auth get 查看当前鉴权配置
|
|
8
|
+
* npx szcd-mcp-auth set --apiKey=<key> 设置 API Key
|
|
9
|
+
* npx szcd-mcp-auth clear 清除 API Key(关闭鉴权)
|
|
10
|
+
*
|
|
11
|
+
* 配置保存在 ~/.szcd-mcp-config.json 中,字段名:
|
|
12
|
+
* MCP_API_KEY — MCP 服务器鉴权密钥
|
|
13
|
+
*
|
|
14
|
+
* 客户端连接时通过 X-API-Key / Authorization: Bearer 请求头传递,
|
|
15
|
+
* 服务端校验通过后放行,否则返回 401。
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import fs from "node:fs";
|
|
19
|
+
import path from "node:path";
|
|
20
|
+
import os from "node:os";
|
|
21
|
+
|
|
22
|
+
// ==================== 工具函数 ====================
|
|
23
|
+
|
|
24
|
+
function getHomeDir() {
|
|
25
|
+
if (os.platform() === "win32") {
|
|
26
|
+
return process.env.USERPROFILE || process.env.HOME || os.homedir();
|
|
27
|
+
}
|
|
28
|
+
return process.env.HOME || os.homedir();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function getConfigFilePath() {
|
|
32
|
+
return path.join(getHomeDir(), ".szcd-mcp-config.json");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function loadConfig() {
|
|
36
|
+
const configPath = getConfigFilePath();
|
|
37
|
+
try {
|
|
38
|
+
if (fs.existsSync(configPath)) {
|
|
39
|
+
return JSON.parse(fs.readFileSync(configPath, "utf8"));
|
|
40
|
+
}
|
|
41
|
+
} catch (error) {
|
|
42
|
+
console.error(`Failed to read config: ${error.message}`);
|
|
43
|
+
}
|
|
44
|
+
return {};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function saveConfig(config) {
|
|
48
|
+
const configPath = getConfigFilePath();
|
|
49
|
+
try {
|
|
50
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
51
|
+
return true;
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.error(`Failed to write config: ${error.message}`);
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function maskKey(value) {
|
|
59
|
+
if (!value) return "(未设置)";
|
|
60
|
+
if (value.length <= 8) return "***";
|
|
61
|
+
return value.substring(0, 6) + "***" + value.substring(value.length - 4);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function parseArgs(argv) {
|
|
65
|
+
const args = {
|
|
66
|
+
action: null,
|
|
67
|
+
apiKey: null,
|
|
68
|
+
};
|
|
69
|
+
const positional = [];
|
|
70
|
+
|
|
71
|
+
for (let i = 2; i < argv.length; i++) {
|
|
72
|
+
const arg = argv[i];
|
|
73
|
+
if (arg.startsWith("--")) {
|
|
74
|
+
const eqIdx = arg.indexOf("=");
|
|
75
|
+
if (eqIdx !== -1) {
|
|
76
|
+
const key = arg.slice(2, eqIdx);
|
|
77
|
+
const value = arg.slice(eqIdx + 1);
|
|
78
|
+
if (key === "apiKey" || key === "api-key" || key === "key") args.apiKey = value;
|
|
79
|
+
}
|
|
80
|
+
} else {
|
|
81
|
+
positional.push(arg);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
args.action = positional[0] || "get";
|
|
86
|
+
return args;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ==================== 命令实现 ====================
|
|
90
|
+
|
|
91
|
+
function cmdGet() {
|
|
92
|
+
const config = loadConfig();
|
|
93
|
+
|
|
94
|
+
console.log(`\nMCP 鉴权配置 (${getConfigFilePath()})\n`);
|
|
95
|
+
console.log(` MCP_API_KEY : ${maskKey(config.MCP_API_KEY)}`);
|
|
96
|
+
console.log(` 状态 : ${config.MCP_API_KEY ? "✅ 已开启鉴权" : "⚠️ 未设置(服务端无鉴权时可忽略)"}`);
|
|
97
|
+
console.log(`\n 说明:`);
|
|
98
|
+
console.log(` - 设置后,客户端连接时自动通过 X-API-Key 请求头传递`);
|
|
99
|
+
console.log(` - 服务端需配置相同的 MCP_API_KEY 环境变量才会校验`);
|
|
100
|
+
console.log(` - 用法: npx szcd-mcp-auth set --apiKey=your_api_key\n`);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function cmdSet(apiKey) {
|
|
104
|
+
if (!apiKey) {
|
|
105
|
+
console.error("\n❌ 缺少 --apiKey 参数。用法:");
|
|
106
|
+
console.error(" npx szcd-mcp-auth set --apiKey=your_api_key\n");
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const config = loadConfig();
|
|
111
|
+
const old = maskKey(config.MCP_API_KEY);
|
|
112
|
+
|
|
113
|
+
config.MCP_API_KEY = apiKey;
|
|
114
|
+
|
|
115
|
+
if (saveConfig(config)) {
|
|
116
|
+
console.log(`\n✅ API Key 已保存。`);
|
|
117
|
+
console.log(` MCP_API_KEY : ${old} → ${maskKey(apiKey)}`);
|
|
118
|
+
console.log(` 配置文件 : ${getConfigFilePath()}`);
|
|
119
|
+
console.log(`\n 提示:重启 IDE/CLI 后生效。\n`);
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
console.log("\n❌ 保存配置失败。\n");
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function cmdClear() {
|
|
128
|
+
const config = loadConfig();
|
|
129
|
+
|
|
130
|
+
if (!config.MCP_API_KEY) {
|
|
131
|
+
console.log("\n⚠️ 当前未设置 API Key,无需清除。\n");
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const old = maskKey(config.MCP_API_KEY);
|
|
136
|
+
delete config.MCP_API_KEY;
|
|
137
|
+
|
|
138
|
+
if (saveConfig(config)) {
|
|
139
|
+
console.log(`\n✅ API Key 已清除。`);
|
|
140
|
+
console.log(` MCP_API_KEY : ${old} → (未设置)`);
|
|
141
|
+
console.log(` 配置文件 : ${getConfigFilePath()}`);
|
|
142
|
+
console.log(`\n 提示:服务端若已开启鉴权,清除后客户端将无法连接。\n`);
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
console.log("\n❌ 清除配置失败。\n");
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// ==================== 帮助信息 ====================
|
|
151
|
+
|
|
152
|
+
function printHelp() {
|
|
153
|
+
console.log(`
|
|
154
|
+
Usage: npx szcd-mcp-auth <command> [options]
|
|
155
|
+
|
|
156
|
+
Commands:
|
|
157
|
+
get 查看当前鉴权配置
|
|
158
|
+
set --apiKey=<key> 设置 MCP API Key
|
|
159
|
+
clear 清除 API Key
|
|
160
|
+
|
|
161
|
+
Options for 'set':
|
|
162
|
+
--apiKey=<string> MCP 服务器鉴权密钥(由管理员提供)
|
|
163
|
+
|
|
164
|
+
Examples:
|
|
165
|
+
npx szcd-mcp-auth get
|
|
166
|
+
npx szcd-mcp-auth set --apiKey=3f4ec52f5137dbf2b458d87a28a3948ea88149b1d506e106
|
|
167
|
+
npx szcd-mcp-auth clear
|
|
168
|
+
|
|
169
|
+
Config file: ~/.szcd-mcp-config.json
|
|
170
|
+
`);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// ==================== 主函数 ====================
|
|
174
|
+
|
|
175
|
+
function main() {
|
|
176
|
+
const args = parseArgs(process.argv);
|
|
177
|
+
|
|
178
|
+
if (args.action === "help" || args.action === "-h" || args.action === "--help") {
|
|
179
|
+
printHelp();
|
|
180
|
+
process.exit(0);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (args.action === "get") {
|
|
184
|
+
cmdGet();
|
|
185
|
+
} else if (args.action === "set") {
|
|
186
|
+
const ok = cmdSet(args.apiKey);
|
|
187
|
+
process.exit(ok ? 0 : 1);
|
|
188
|
+
} else if (args.action === "clear") {
|
|
189
|
+
const ok = cmdClear();
|
|
190
|
+
process.exit(ok ? 0 : 1);
|
|
191
|
+
} else {
|
|
192
|
+
console.error(`Unknown command: ${args.action}`);
|
|
193
|
+
printHelp();
|
|
194
|
+
process.exit(1);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
main();
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: local-api-tool
|
|
3
|
+
description: 本地网络 API 工具,专门处理 10.x.x.x 网段的 Swagger/YApi 文档拉取和联调测试。当服务端 api_tool 因 LOCAL_NETWORK_UNREACHABLE 无法访问时,此技能在用户本地环境执行 curl,再将结果交给服务端解析。适用于内网开发环境、VPN 场景。
|
|
4
|
+
compatibility:
|
|
5
|
+
tools:
|
|
6
|
+
- run_command
|
|
7
|
+
- web_search
|
|
8
|
+
- web_fetch
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# 本地网络 API 工具(local-api-tool)
|
|
12
|
+
|
|
13
|
+
## 概述
|
|
14
|
+
|
|
15
|
+
当 MCP 服务端 `api_tool` 遇到 `10.x.x.x` 网段地址时,因服务器无法直连用户内网,会返回 `reason: "LOCAL_NETWORK_UNREACHABLE"` 及 `action` 字段指引。此技能指导 AI 自动在用户本地终端通过 `run_command` 执行 curl 命令获取数据,再调用服务端的 `parse_swagger_json` 进行解析,全程无需用户手动操作。
|
|
16
|
+
|
|
17
|
+
## 适用场景
|
|
18
|
+
|
|
19
|
+
- Swagger URL 主机为 `10.x.x.x` 网段(如 `http://10.2.7.60:30194/ikmp-knowledge/swagger-ui/index.html`)
|
|
20
|
+
- API 联调测试目标为 `10.x.x.x` 网段
|
|
21
|
+
- 用户在 VPN 或内网开发环境中,本地可访问但远程服务器不可达
|
|
22
|
+
|
|
23
|
+
## 工作流
|
|
24
|
+
|
|
25
|
+
### 流程 A:拉取 Swagger API 文档(fetch)
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
用户请求 fetch Swagger URL (10.x.x.x)
|
|
29
|
+
│
|
|
30
|
+
▼
|
|
31
|
+
调用 api_tool(action="fetch", url=...)
|
|
32
|
+
│
|
|
33
|
+
▼
|
|
34
|
+
服务端返回 { reason: "LOCAL_NETWORK_UNREACHABLE", action: "请使用 local-api-tool ...", swaggerEndpoints: {...} }
|
|
35
|
+
│
|
|
36
|
+
▼
|
|
37
|
+
AI 识别 LOCAL_NETWORK_UNREACHABLE,读取 swaggerEndpoints 和 authInfo
|
|
38
|
+
│
|
|
39
|
+
▼
|
|
40
|
+
AI 通过 run_command 在本地执行 curl:
|
|
41
|
+
步骤1: 鉴权获取 Cookie(如 authInfo.hasPassword 为 true)
|
|
42
|
+
步骤2: 获取完整 API 文档 JSON
|
|
43
|
+
│
|
|
44
|
+
▼
|
|
45
|
+
AI 调用 api_tool(action="parse_swagger_json", swaggerJson=..., swaggerSourceUrl=...)
|
|
46
|
+
│
|
|
47
|
+
▼
|
|
48
|
+
返回解析后的 API 文档给用户
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 流程 B:联调测试(test)
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
用户请求 test API (10.x.x.x)
|
|
55
|
+
│
|
|
56
|
+
▼
|
|
57
|
+
调用 api_tool(action="test", url=..., method=..., data=..., headers=...)
|
|
58
|
+
│
|
|
59
|
+
▼
|
|
60
|
+
服务端返回 { reason: "LOCAL_NETWORK_UNREACHABLE", action: "请使用 local-api-tool ...", method, data, headers }
|
|
61
|
+
│
|
|
62
|
+
▼
|
|
63
|
+
AI 识别 LOCAL_NETWORK_UNREACHABLE,读取 method/data/headers
|
|
64
|
+
│
|
|
65
|
+
▼
|
|
66
|
+
AI 通过 run_command 在本地执行对应 curl 命令
|
|
67
|
+
│
|
|
68
|
+
▼
|
|
69
|
+
将响应结果返回给用户
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## 详细执行步骤
|
|
73
|
+
|
|
74
|
+
### 一、拉取 Swagger 文档(action=fetch)
|
|
75
|
+
|
|
76
|
+
**步骤 1:调用服务端 api_tool**
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
api_tool(action="fetch", url="http://10.2.7.60:30194/ikmp-knowledge/swagger-ui/index.html", username="admin", password="xxx")
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**步骤 2:检测 LOCAL_NETWORK_UNREACHABLE**
|
|
83
|
+
|
|
84
|
+
如果返回结果中包含 `reason: "LOCAL_NETWORK_UNREACHABLE"`,则自动进入本地执行流程。
|
|
85
|
+
|
|
86
|
+
返回结构示例:
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"reason": "LOCAL_NETWORK_UNREACHABLE",
|
|
90
|
+
"hostname": "10.2.7.60",
|
|
91
|
+
"swaggerUrl": "http://10.2.7.60:30194/ikmp-knowledge/swagger-ui/index.html",
|
|
92
|
+
"authInfo": { "username": "admin", "hasPassword": true },
|
|
93
|
+
"swaggerEndpoints": {
|
|
94
|
+
"basePath": "http://10.2.7.60:30194/ikmp-knowledge",
|
|
95
|
+
"apiDocsUrl": "http://10.2.7.60:30194/ikmp-knowledge/v2/api-docs"
|
|
96
|
+
},
|
|
97
|
+
"action": "请使用 local-api-tool 技能处理此请求..."
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**步骤 3:AI 通过 run_command 在本地执行 curl**
|
|
102
|
+
|
|
103
|
+
根据返回数据中的 `authInfo` 和 `swaggerEndpoints`,AI 自行构造 curl 命令并通过 `run_command` 在本地执行:
|
|
104
|
+
|
|
105
|
+
3a. **鉴权(如 authInfo.hasPassword 为 true)**:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
curl -s -D - -X GET 'http://10.2.7.60:30194/ikmp-knowledge/swagger-resources/configuration/ui' \
|
|
109
|
+
-H 'Authorization: Basic <base64(username:password)>' \
|
|
110
|
+
-H 'Accept: application/json'
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
从输出的 `Set-Cookie:` 行提取 Cookie 值(分号前的部分)。
|
|
114
|
+
|
|
115
|
+
3b. **获取 API 文档 JSON**:直接使用 `swaggerEndpoints.apiDocsUrl`:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
curl -s -X GET 'http://10.2.7.60:30194/ikmp-knowledge/v2/api-docs' \
|
|
119
|
+
-H 'Accept: application/json' \
|
|
120
|
+
-H 'Cookie: <步骤3a获取的Cookie>'
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
如果 authInfo.hasPassword 为 false,省略 Cookie 头。
|
|
124
|
+
|
|
125
|
+
**步骤 4:调用服务端解析**
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
api_tool(action="parse_swagger_json", swaggerJson="<步骤3b获取的JSON字符串>", swaggerSourceUrl="http://10.2.7.60:30194/ikmp-knowledge/swagger-ui/index.html")
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**步骤 5:返回解析结果**
|
|
132
|
+
|
|
133
|
+
将 `parse_swagger_json` 返回的解析结果直接返回给用户,格式与正常 fetch 完全一致。
|
|
134
|
+
|
|
135
|
+
### 二、联调测试(action=test)
|
|
136
|
+
|
|
137
|
+
**步骤 1:调用服务端 api_tool**
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
api_tool(action="test", url="http://10.2.7.60:30194/ikmp-knowledge/api/xxx", method="POST", data={...}, headers={...})
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**步骤 2:检测 LOCAL_NETWORK_UNREACHABLE**
|
|
144
|
+
|
|
145
|
+
如果返回结果中包含 `reason: "LOCAL_NETWORK_UNREACHABLE"`,则自动进入本地执行流程。
|
|
146
|
+
|
|
147
|
+
返回结构示例:
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"success": false,
|
|
151
|
+
"reason": "LOCAL_NETWORK_UNREACHABLE",
|
|
152
|
+
"hostname": "10.2.7.60",
|
|
153
|
+
"targetUrl": "http://10.2.7.60:30194/ikmp-knowledge/api/xxx",
|
|
154
|
+
"method": "POST",
|
|
155
|
+
"data": { "key": "value" },
|
|
156
|
+
"headers": {},
|
|
157
|
+
"action": "请使用 local-api-tool 技能处理此请求...",
|
|
158
|
+
"timestamp": "..."
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**步骤 3:AI 通过 run_command 在本地执行 curl**
|
|
163
|
+
|
|
164
|
+
AI 根据返回数据中的 `method`、`data`、`headers`、`targetUrl` 自行构造 curl 命令:
|
|
165
|
+
|
|
166
|
+
GET 请求示例:
|
|
167
|
+
```bash
|
|
168
|
+
curl -s -X GET 'http://10.2.7.60:30194/ikmp-knowledge/api/xxx?key=value' \
|
|
169
|
+
-H 'Accept: application/json'
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
POST 请求示例:
|
|
173
|
+
```bash
|
|
174
|
+
curl -s -X POST 'http://10.2.7.60:30194/ikmp-knowledge/api/xxx' \
|
|
175
|
+
-H 'Accept: application/json' \
|
|
176
|
+
-H 'Content-Type: application/json' \
|
|
177
|
+
-d '{"key":"value"}'
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
如有自定义 headers,添加对应的 `-H` 参数。
|
|
181
|
+
|
|
182
|
+
**步骤 4:返回测试结果**
|
|
183
|
+
|
|
184
|
+
将 curl 的响应内容返回给用户。如果是 JSON 格式,尽量格式化输出。
|
|
185
|
+
|
|
186
|
+
## 快捷方式:AI 直接识别 10 段地址
|
|
187
|
+
|
|
188
|
+
如果 AI 能识别出用户请求的 URL 中包含 `10.x.x.x` 主机地址,可以**直接跳过首次 api_tool 调用**,在本地执行 curl,再调用 `parse_swagger_json`,减少一次无用的服务端请求:
|
|
189
|
+
|
|
190
|
+
1. 从 Swagger URL 推导鉴权地址、文档地址
|
|
191
|
+
2. 通过 `run_command` 在本地依次 curl
|
|
192
|
+
3. 调用 `api_tool(action="parse_swagger_json")` 解析
|
|
193
|
+
|
|
194
|
+
### URL 推导规则
|
|
195
|
+
|
|
196
|
+
对于 Swagger URL 如 `http://10.2.7.60:30194/ikmp-knowledge/swagger-ui/index.html`:
|
|
197
|
+
|
|
198
|
+
| 推导项 | 规则 | 示例 |
|
|
199
|
+
|--------|------|------|
|
|
200
|
+
| basePath | `protocol + host + 第一个路径段` | `http://10.2.7.60:30194/ikmp-knowledge` |
|
|
201
|
+
| authUrl | `basePath + /swagger-resources/configuration/ui` | `http://10.2.7.60:30194/ikmp-knowledge/swagger-resources/configuration/ui` |
|
|
202
|
+
| apiDocsUrl | `basePath + /v2/api-docs` | `http://10.2.7.60:30194/ikmp-knowledge/v2/api-docs` |
|
|
203
|
+
|
|
204
|
+
### curl 执行模板
|
|
205
|
+
|
|
206
|
+
**鉴权(带密码时):**
|
|
207
|
+
```bash
|
|
208
|
+
curl -s -D - -X GET '<authUrl>' \
|
|
209
|
+
-H 'Authorization: Basic <base64(username:password)>' \
|
|
210
|
+
-H 'Accept: application/json'
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**获取文档(带 Cookie 时):**
|
|
214
|
+
```bash
|
|
215
|
+
curl -s -X GET '<apiDocsUrl>' \
|
|
216
|
+
-H 'Accept: application/json' \
|
|
217
|
+
-H 'Cookie: <鉴权获取的Cookie>'
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
**获取文档(无密码时):**
|
|
221
|
+
```bash
|
|
222
|
+
curl -s -X GET '<apiDocsUrl>' \
|
|
223
|
+
-H 'Accept: application/json'
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## 注意事项
|
|
227
|
+
|
|
228
|
+
1. **Cookie 传递**:鉴权步骤获取的 Cookie 需要在后续步骤中通过 `-H 'Cookie: xxx'` 传递
|
|
229
|
+
2. **无密码场景**:如果用户未提供密码,跳过鉴权步骤,直接获取文档
|
|
230
|
+
3. **JSON 格式**:curl 获取的 API 文档必须是有效的 Swagger JSON,否则 `parse_swagger_json` 会报错
|
|
231
|
+
4. **超时处理**:本地 curl 可能因网络原因超时,建议添加 `--connect-timeout 10 --max-time 30` 参数
|
|
232
|
+
5. **错误处理**:如果某步骤 curl 失败,将错误信息返回给用户,不要继续后续步骤
|
|
233
|
+
6. **自动执行**:AI 识别 `reason: "LOCAL_NETWORK_UNREACHABLE"` 后应**自动**通过 `run_command` 执行 curl,无需让用户手动复制粘贴命令
|
|
@@ -19,7 +19,7 @@ compatibility:
|
|
|
19
19
|
|
|
20
20
|
**重要说明**:这是一个客户端 skill,通过 MCP 协议(SSE 或 HTTP)连接到远程 MCP 服务器。服务器由管理员维护,包含源码和数据。
|
|
21
21
|
|
|
22
|
-
**版本**:v0.
|
|
22
|
+
**版本**:v0.17.0 - 新增 10 段网段本地网络兼容:api_tool 新增 parse_swagger_json action,客户端新增 local-api-tool 技能,遇到 10.x.x.x 网段自动在本地 curl 获取 Swagger JSON 再交由服务端解析
|
|
23
23
|
|
|
24
24
|
## 架构说明
|
|
25
25
|
|
|
@@ -178,15 +178,19 @@ AI 助手在处理页面生成需求时,必须按以下流程使用工具:
|
|
|
178
178
|
### API 工具
|
|
179
179
|
|
|
180
180
|
#### 9. api_tool
|
|
181
|
-
**功能**:统一 API 工具,自动识别 YApi/Swagger 拉取 API
|
|
181
|
+
**功能**:统一 API 工具,自动识别 YApi/Swagger 拉取 API 文档、联调测试、配置管理、解析本地 Swagger JSON。
|
|
182
182
|
**参数**:
|
|
183
|
-
- `action` (enum, required): fetch=拉取API文档, test=联调测试, config
|
|
183
|
+
- `action` (enum, required): fetch=拉取API文档, test=联调测试, config=配置管理, parse_swagger_json=解析本地curl获取的Swagger JSON
|
|
184
184
|
- `url` (string, optional): API文档地址(fetch时)/ 请求地址(test时)
|
|
185
185
|
- `method` (enum, optional, default: "GET"): GET/POST/PUT/DELETE/PATCH(test时)
|
|
186
186
|
- `data` (object, optional, default: {}): 请求参数(test时)
|
|
187
187
|
- `headers` (object, optional, default: {}): 请求头(test时)
|
|
188
188
|
- `username` / `password` / `account` / `cookies` (string, optional): 鉴权信息
|
|
189
189
|
- `yapiBaseUrl` / `yapiAccount` / `yapiPassword` / `yapiCookies` (string, optional): YApi 配置(config set 时生效)
|
|
190
|
+
- `swaggerJson` (string, optional): 客户端本地 curl 获取的 Swagger JSON 字符串(parse_swagger_json 时必填)
|
|
191
|
+
- `swaggerSourceUrl` (string, optional): 原始 Swagger URL(parse_swagger_json 时可选,用于补充元数据)
|
|
192
|
+
|
|
193
|
+
**10段网段本地执行**:当 fetch/test 遇到 `10.x.x.x` 网段地址时,服务端返回 `LOCAL_NETWORK_UNREACHABLE`,此时应使用 `local-api-tool` 技能在用户本地执行 curl,再调用 `parse_swagger_json` 解析。详见 `local-api-tool` 技能。
|
|
190
194
|
|
|
191
195
|
### Repowiki 增强工具(推荐优先使用)
|
|
192
196
|
|