# 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。