420 lines
8.3 KiB
Markdown
420 lines
8.3 KiB
Markdown
# Go MCP 与 C# Windows Helper 边界设计
|
||
|
||
## 1. 目标
|
||
|
||
最终程序分成两层:
|
||
|
||
```text
|
||
MCP Client
|
||
-> Go MCP Server
|
||
-> C# Windows Helper
|
||
-> 已登录的 iSphere / IMPlatformClient 窗口
|
||
```
|
||
|
||
当前阶段只提前固定 Go 与 C# 之间的边界,不实现 Go MCP 主程序,也不实现真实搜索、发送、文件操作。
|
||
|
||
第一阶段的实际目标是:用 C# helper 只读探测已登录客户端窗口,并把窗口和 UI Automation 控件树以稳定 JSON 返回给未来 Go MCP 服务。
|
||
|
||
## 2. 不做什么
|
||
|
||
当前阶段不做以下内容:
|
||
|
||
- 不写 Go MCP 实现代码。
|
||
- 不做 C# 常驻后台进程。
|
||
- 不做 Windows Service。
|
||
- 不做 named pipe、gRPC、HTTP 本地服务。
|
||
- 不做插件框架。
|
||
- 不做 selector 自动学习系统。
|
||
- 不执行搜索联系人、发消息、发文件、收文件。
|
||
- 不自动登录。
|
||
- 不读取密码、token、cookie、私钥。
|
||
- 不注入进程、不 hook、不读目标进程内存、不提权。
|
||
- 不加壳、不混淆、不伪装系统进程。
|
||
|
||
## 3. 分工原则
|
||
|
||
### 3.1 Go MCP Server
|
||
|
||
Go 是对外服务层,负责:
|
||
|
||
- MCP 工具注册。
|
||
- 参数校验。
|
||
- 调用 C# helper。
|
||
- 控制超时。
|
||
- 解析 helper JSON 输出。
|
||
- 审批校验。
|
||
- 审计记录。
|
||
- 把 helper 结果整理成 MCP 返回值。
|
||
|
||
Go 不直接操作窗口,不直接使用 UIA,不点击按钮,不保存 iSphere 控件细节。
|
||
|
||
### 3.2 C# Windows Helper
|
||
|
||
C# 是 Windows 执行层,负责:
|
||
|
||
- 枚举桌面窗口。
|
||
- 找疑似 iSphere / IMPlatformClient 窗口。
|
||
- 读取指定窗口的 UI Automation 控件树。
|
||
- 后续在 selector 稳定后执行少量受控窗口动作。
|
||
|
||
C# 不做 MCP,不做审批策略中心,不做业务状态中心,不联网,不常驻。
|
||
|
||
## 4. 进程模型
|
||
|
||
第一阶段采用一次性 CLI 模型:
|
||
|
||
```text
|
||
Go 启动 C# helper
|
||
Go 通过 stdin 写入一个 JSON 请求
|
||
C# 执行一个 op
|
||
C# 通过 stdout 返回一个 JSON 响应
|
||
C# 退出
|
||
```
|
||
|
||
原因:
|
||
|
||
- 简单。
|
||
- 易测试。
|
||
- 不常驻后台,减少安防误报和运维复杂度。
|
||
- 不把联系人、消息、文件路径暴露在命令行参数里。
|
||
- 后续如果确实需要提速,再评估长连接,不提前设计。
|
||
|
||
标准约束:
|
||
|
||
- stdout 只能输出 JSON 响应。
|
||
- stderr 可输出诊断信息。
|
||
- exit code 非 0 表示 helper 进程级失败。
|
||
- 业务失败用 JSON 中的 `ok:false` 表达。
|
||
|
||
## 5. Helper JSON Contract v1
|
||
|
||
协议名固定为:
|
||
|
||
```text
|
||
isphere.helper.v1
|
||
```
|
||
|
||
### 5.1 请求格式
|
||
|
||
```json
|
||
{
|
||
"protocol": "isphere.helper.v1",
|
||
"request_id": "uuid-string",
|
||
"op": "scan_windows",
|
||
"timeout_ms": 5000,
|
||
"args": {}
|
||
}
|
||
```
|
||
|
||
字段说明:
|
||
|
||
| 字段 | 必填 | 说明 |
|
||
| --- | --- | --- |
|
||
| `protocol` | 是 | 固定 `isphere.helper.v1` |
|
||
| `request_id` | 是 | Go 生成,用于关联请求和响应 |
|
||
| `op` | 是 | 操作名 |
|
||
| `timeout_ms` | 否 | Go 和 C# 都应尊重的超时 |
|
||
| `args` | 是 | op 参数 |
|
||
|
||
### 5.2 成功响应
|
||
|
||
```json
|
||
{
|
||
"protocol": "isphere.helper.v1",
|
||
"request_id": "uuid-string",
|
||
"op": "scan_windows",
|
||
"ok": true,
|
||
"data": {},
|
||
"error": null,
|
||
"warnings": []
|
||
}
|
||
```
|
||
|
||
### 5.3 失败响应
|
||
|
||
```json
|
||
{
|
||
"protocol": "isphere.helper.v1",
|
||
"request_id": "uuid-string",
|
||
"op": "scan_windows",
|
||
"ok": false,
|
||
"data": null,
|
||
"error": {
|
||
"code": "WINDOW_NOT_FOUND",
|
||
"message": "no matching iSphere window found"
|
||
},
|
||
"warnings": []
|
||
}
|
||
```
|
||
|
||
第一版错误码只保留:
|
||
|
||
```text
|
||
INVALID_REQUEST
|
||
UNSUPPORTED_OP
|
||
HELPER_FAILED
|
||
TIMEOUT
|
||
WINDOW_NOT_FOUND
|
||
AMBIGUOUS_WINDOW
|
||
UIA_DUMP_FAILED
|
||
```
|
||
|
||
后续真实动作阶段再增加:
|
||
|
||
```text
|
||
SELECTOR_NOT_FOUND
|
||
APP_NOT_LOGGED_IN
|
||
APP_BUSY
|
||
APPROVAL_REQUIRED
|
||
VERIFY_FAILED
|
||
```
|
||
|
||
## 6. 第一阶段 op
|
||
|
||
第一阶段只支持四个 op。
|
||
|
||
### 6.1 `version`
|
||
|
||
用途:确认 helper 可运行,返回协议版本、程序版本、运行时信息。
|
||
|
||
请求:
|
||
|
||
```json
|
||
{
|
||
"protocol": "isphere.helper.v1",
|
||
"request_id": "...",
|
||
"op": "version",
|
||
"args": {}
|
||
}
|
||
```
|
||
|
||
响应 data 示例:
|
||
|
||
```json
|
||
{
|
||
"helper_name": "ISphereWinHelper",
|
||
"helper_version": "0.1.0",
|
||
"protocol": "isphere.helper.v1",
|
||
"runtime": ".NET Framework"
|
||
}
|
||
```
|
||
|
||
### 6.2 `self_check`
|
||
|
||
用途:检查 helper 是否能访问当前桌面、UI Automation 是否可用。
|
||
|
||
响应 data 示例:
|
||
|
||
```json
|
||
{
|
||
"desktop_access": true,
|
||
"uia_available": true
|
||
}
|
||
```
|
||
|
||
### 6.3 `scan_windows`
|
||
|
||
用途:枚举当前桌面窗口,返回疑似 iSphere / IMPlatformClient 候选。
|
||
|
||
args 示例:
|
||
|
||
```json
|
||
{
|
||
"include_all_visible": false
|
||
}
|
||
```
|
||
|
||
响应 data 示例:
|
||
|
||
```json
|
||
{
|
||
"windows": [
|
||
{
|
||
"hwnd": "0x001A0B2C",
|
||
"pid": 1234,
|
||
"process_name": "IMPlatformClient",
|
||
"title": "iSphere",
|
||
"class_name": "WindowsForms10.Window.8.app.0.xxxxx",
|
||
"visible": true,
|
||
"bounds": {
|
||
"x": 100,
|
||
"y": 80,
|
||
"width": 1200,
|
||
"height": 800
|
||
},
|
||
"score": 90
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
### 6.4 `dump_uia`
|
||
|
||
用途:对指定窗口导出 UI Automation 控件树。
|
||
|
||
args 示例:
|
||
|
||
```json
|
||
{
|
||
"hwnd": "0x001A0B2C",
|
||
"max_depth": 8,
|
||
"include_text": true
|
||
}
|
||
```
|
||
|
||
响应 data 示例:
|
||
|
||
```json
|
||
{
|
||
"hwnd": "0x001A0B2C",
|
||
"root": {
|
||
"name": "iSphere",
|
||
"control_type": "Window",
|
||
"automation_id": "",
|
||
"class_name": "WindowsForms10.Window.8.app.0.xxxxx",
|
||
"children": []
|
||
}
|
||
}
|
||
```
|
||
|
||
第一阶段 Go 可以把该响应保存到:
|
||
|
||
```text
|
||
runs/real-loggedin-lab/uia-dumps/
|
||
```
|
||
|
||
C# helper 默认不主动写文件,除非未来明确加入 `out_path` 参数。
|
||
|
||
## 7. 后续 op 扩展顺序
|
||
|
||
必须等真实登录窗口的 UIA dump 被确认后,再扩展真实动作。
|
||
|
||
建议顺序:
|
||
|
||
```text
|
||
search_contacts
|
||
open_conversation
|
||
read_latest_messages
|
||
write_draft
|
||
send_after_approval
|
||
send_file_after_approval
|
||
receive_file_after_approval
|
||
```
|
||
|
||
其中:
|
||
|
||
- `search_contacts`、`open_conversation`、`read_latest_messages` 可先做只读或低风险动作。
|
||
- `write_draft` 只能写入草稿,不点击发送。
|
||
- `send_after_approval` 必须带 `approval_id`。
|
||
- 文件发送、文件接收也必须带 `approval_id`。
|
||
|
||
## 8. 审批和审计边界
|
||
|
||
审批主逻辑放在 Go。
|
||
|
||
Go 负责:
|
||
|
||
- 生成审批记录。
|
||
- 校验 `approval_id`。
|
||
- 记录操作者、目标联系人、消息摘要、文件路径摘要、时间、结果。
|
||
|
||
C# 负责二次保护:
|
||
|
||
- 对真实发送和文件类 op,如果没有 `approval_id`,直接返回 `APPROVAL_REQUIRED`。
|
||
- 执行前确认当前窗口和目标会话仍然匹配。
|
||
- 执行后返回可核验结果。
|
||
|
||
第一阶段没有真实发送类 op,因此不实现审批逻辑,只在协议里预留字段。
|
||
|
||
## 9. 安防低误报约束
|
||
|
||
helper 必须保持普通企业辅助工具形态:
|
||
|
||
- 普通命令行程序。
|
||
- 不需要管理员权限。
|
||
- 不注入目标进程。
|
||
- 不 hook 全局键盘鼠标。
|
||
- 不读目标进程内存。
|
||
- 不修改目标程序文件。
|
||
- 不自启动。
|
||
- 不隐藏进程。
|
||
- 不联网。
|
||
- 不加壳、不混淆。
|
||
- 不伪装系统进程名。
|
||
- 默认不写日志文件。
|
||
- 只在 Go 指定输出路径时保存证据文件。
|
||
|
||
正式部署时依靠:
|
||
|
||
- 明确程序名。
|
||
- 固定安装路径。
|
||
- 代码签名。
|
||
- 企业白名单。
|
||
- 可审计日志。
|
||
|
||
不依靠规避、隐藏或绕过安防。
|
||
|
||
## 10. 建议目录结构
|
||
|
||
当前只需要规划,不需要一次性全部创建。
|
||
|
||
Go 侧未来结构:
|
||
|
||
```text
|
||
go/
|
||
cmd/
|
||
isphere-mcp/
|
||
main.go
|
||
internal/
|
||
mcpserver/
|
||
server.go
|
||
tools/
|
||
real_lab.go
|
||
helperclient/
|
||
client.go
|
||
contract.go
|
||
audit/
|
||
audit.go
|
||
approval/
|
||
approval.go
|
||
```
|
||
|
||
C# 侧第一阶段结构:
|
||
|
||
```text
|
||
native/
|
||
ISphereWinHelper/
|
||
Program.cs
|
||
HelperProtocol.cs
|
||
WindowScanner.cs
|
||
UiaDumper.cs
|
||
```
|
||
|
||
第一阶段不要再拆更多目录。
|
||
|
||
## 11. 验收标准
|
||
|
||
第一阶段完成后,只验收:
|
||
|
||
1. C# helper 能编译。
|
||
2. `version` 返回合法 JSON。
|
||
3. `self_check` 返回 UIA 可用状态。
|
||
4. `scan_windows` 能列出当前可见窗口。
|
||
5. 打开记事本后,`dump_uia` 能导出记事本控件树。
|
||
6. 用户手动登录 iSphere 后,`scan_windows` 能找到候选窗口。
|
||
7. 对 iSphere 候选窗口执行 `dump_uia` 能返回控件树。
|
||
8. 全流程不点击、不输入、不发送、不修改目标客户端。
|
||
|
||
## 12. 下一步
|
||
|
||
建议下一步只做 C# helper 第一阶段:
|
||
|
||
```text
|
||
version
|
||
self_check
|
||
scan_windows
|
||
dump_uia
|
||
```
|
||
|
||
Go MCP 代码暂不写。等 C# helper 能稳定拿到真实 iSphere 窗口结构后,再实现 Go 的 `helperclient` 和 MCP tools。
|