huawang-api-mcp
v0.8.1
Published
MCP server for HET API Management Platform - 通过 AI 自动同步代码变更到接口文档
Maintainers
Readme
huawang-het-api-mcp
MCP 服务器,对接内部 HET API 管理平台(http://10.6.16.99/hetapi),让 AI 能:
- 按 URL+method 一步定位接口(
het_find_api) - 浏览项目树、模块树、接口详情
- 更新接口文档、新建接口 / 分组
- 从 Swagger/OpenAPI 批量同步 BFF 接口到 HET(含 dry-run / smart merge / annotations)
核心机制:签名是怎么破解的?
HET 平台每个请求都要 3 个动态 header:CLife-Timestamp、CLife-Nonce、CLife-Signature。通过反向工程 app.*.js 的 axios 拦截器得出:
signature = HMAC_SHA256(timestamp + nonce, "CLifeTesterMagic").hex().toLowerCase()- 算法:HMAC-SHA256
- Secret:
CLifeTesterMagic(硬编码在前端 JS 里) - payload:
timestamp + nonce拼接(不含 body、path、method) - 编码:小写 hex 64 位
完整算法实现见 src/signer.ts。
安装
cd d:\project\main\MCP\het-api-mcp
npm install
npm run build配置(环境变量)
| 变量 | 默认 | 说明 |
|---|---|---|
| HET_BASE_URL | http://10.6.16.99/hetapi | 平台地址 |
| HET_SECRET | CLifeTesterMagic | 签名密钥(反向工程得到) |
| HET_USERNAME | - | 可选:启动时自动登录用 |
| HET_PASSWORD | - | 可选:启动时自动登录用 |
| HET_SESSION_FILE | <tmpdir>/het-api-mcp-session.json | JWT 本地缓存 |
| HET_REQUEST_TIMEOUT_MS | 15000 | HTTP 超时 |
| HET_ENABLE_MUTATION | 0 | 设 1 开启写入工具 |
| MCP_LOG_FILE | <tmpdir>/het-api-mcp.log | MCP 日志文件 |
| MCP_LOG_DISABLE | 0 | 设 1 禁用日志 |
| MCP_LOG_STDERR | 0 | 设 1 同时写 stderr(仅独立调试,MCP 子进程下禁用) |
工具清单(4 只读 + 5 写入 = 9 个,写入需开关)
登录由
HET_USERNAME/HET_PASSWORD环境变量 + autoLogin 自动完成,无需手动调用。
查接口(4 个)
het_find_api(url, method?, project_id?, match_mode?)— 🚀 主推:给 URL(可选 method)一步定位api_id,跳过多步漏斗。默认match_mode=endsWith,代码里只写后端相对路径也能匹配上 HET 上的 BFF 全路径。het_list_projects(keyword?)— 按名字搜项目(浏览用)。het_get_project_tree(project_id)— 拿项目完整模块树(浏览用,节点 level=2 是接口且带 url 字段)。het_get_api(api_id)— 拿接口完整 FieldSpec 树(改接口前必调,PATCH 会整体覆盖)。
写入类(5 个,需 HET_ENABLE_MUTATION=1)
het_update_api(api_id, patch)— 改接口。一步完成。必先het_get_api拿完整结构再改 patch。het_create_api(spec)— 新建接口,自动做同名/同 URL 冲突检测(仅报告,不阻止)。het_create_module(parent_id, name)— 建分组(模块)。het_resolve_module_by_branch(project_id)— 工作流入口:根据 git 分支自动找/建版本分组,返回module_id。het_sync_from_openapi({openapi, project_id, module_id, ...})— 批量同步:从 Swagger/OpenAPI 把整个 BFF 模块同步到 HET。自动 schema 转换 + 跟 HET 现有接口 URL 匹配 + diff + smart merge。默认 dry-run。
🧠 AI 工作流指南
🚀 改接口(已知 method+URL,不知道接口名)— 首选:
find_api(url="/app/location/nearbyStations", method="POST")→ 一步拿{api_id, project_id, module_id, name, url}get_api(api_id)拿完整结构(PATCH 整体覆盖前提)update_api(api_id, patch)→ 直接写入,返回changed_fields
改单个接口(已知 api_id):
get_api(api_id)拿完整结构- 基于它构造
patch update_api(api_id, patch)
批量同步整个 BFF 模块:
resolve_module_by_branch(project_id)→ 拿module_idsync_from_openapi({openapi, project_id, module_id, url_prefix, path_filter, mode:'dry-run'})→ 看计划- AI 读 Java 源码生成
annotations字典(补业务描述) sync_from_openapi({..., annotations, mode:'upsert'})→ 实际写入
⚠️ AI 必知规则
- PATCH 会整体覆盖:
update_api的 patch 中request_body / response / url_config等结构字段是整体覆盖。一定要先get_api拿完整结构再改。 - sync_from_openapi 自动 smart merge:annotations 里没写的字段会保留 HET 现有值,不覆盖人工填过的 remark/initial_value。
- FieldSpec 递归结构:每个字段
{name, remark, data_type, necessary, initial_value, rule, show, disable, child[]}。Array 元素用特殊的items子节点包裹:{ name:'stations', data_type:'Array', child:[ { name:'items', data_type:'Object', disable:true, child:[真正的字段] } ]} - GET 接口用
request_query,POST 用request_body。GET 接口的request_body留空{kind:"json",data:[],raw:""}。 - annotations 字段路径规则(用于
sync_from_openapi):- body 顶层:
"longitude" - body 嵌套 object:
"address.city" - body 嵌套 array:
"tags[].name" - response 业务字段:
"data.total"(自动包裹了{code,msg,data}外壳) - response 嵌套 array:
"data.stations[].stationId"
- body 顶层:
在 Windsurf / Cursor 中配置
在 MCP 配置文件里加(假设已 npm run build):
{
"mcpServers": {
"het-api": {
"command": "node",
"args": ["d:\\project\\main\\MCP\\het-api-mcp\\build\\index.js"],
"env": {
"HET_USERNAME": "[email protected]",
"HET_PASSWORD": "your_password",
"HET_ENABLE_MUTATION": "1"
}
}
}
}典型使用
一句话改单个接口
头儿:"LocationService.nearbyStations 接口改了,同步到 HET"
AI 内部流程(v0.8.0):
1. het_find_api(url="/app/location/nearbyStations", method="POST")
→ [{ api_id: 63425, name: "获取附近站点列表", project_id: 294, module_id: 5692 }]
2. het_get_api(63425) → 当前完整结构
3. [AI 基于代码构造 patch]
4. het_update_api(63425, patch) → 直接写入,返回 changed_fields批量同步整个 BFF 模块
头儿:"把 clife-senior-station-assistant-bff 的 /app/location/** 都同步到 HET"
AI 内部流程:
1. het_resolve_module_by_branch(project_id=294) → module_id=5692
2. het_sync_from_openapi({ ← 第一波 dry-run
openapi: "http://localhost:185/v3/api-docs",
project_id: 294,
module_id: 5692,
url_prefix: "/v1/saas/senior/station-assistant",
path_filter: "/app/location/**",
mode: "dry-run"
})
→ plan: [{ action: "update", api_id: 63425, struct_diff: +0/-0 =25, meta_diff: ... }, ...]
3. [AI 读 LocationController.java + 各 DTO 的 JavaDoc 注释生成 annotations 字典]
4. het_sync_from_openapi({..., annotations, mode: "upsert"}) ← 实际写入
→ executed: { update: 2, create: 0, failed: 0 }annotations 示例(参考 test/annotations-location.json):
{
"POST /app/location/nearbyStations": {
"name": "获取附近站点列表",
"remark": "长者端站点定位 v2.0:...",
"request_body": {
"longitude": { "remark": "用户当前经度", "initial_value": "113.949" }
},
"response": {
"data.total": { "remark": "站点总数", "necessary": true },
"data.stations[].stationId": { "remark": "站点 ID", "necessary": true }
}
}
}反向工程过程
见 ../het-api-platform.md 和 ../het-reverse/verify-signature.js。
核心代码位置:../het-reverse/app.0febcf26b8183595aa2f.js 的第 1525617 字节附近。
架构原则(三防)
沿用 mysql-mcp-server 和 mcp-log-query 的三防原则:
- 日志文件不走 stderr — 避免 MCP host 不读 stderr 时 pipe buffer 满阻塞 event loop
- Handler 接 cancel signal — AI 取消请求时立即返回,不拖死进程
- 超时强制终止 — HTTP 请求 15s + 工具调用 45s + 看门狗 90s
