# 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 与 C# helper 的分工:Go 负责 MCP 服务层,C# helper 负责 Windows 桌面/UIA 执行层。真实联系人、群组、消息、文件能力进入 `docs/mcp-core-tools-contract.md` 的核心工具路线。 ## 3. 分工原则 ### 3.1 Go MCP Server Go 是对外服务层,负责: - MCP 工具注册。 - 参数校验。 - 调用 C# helper。 - 控制超时。 - 解析 helper JSON 输出。 - 工具执行策略。 - 执行审计记录。 - 把 helper 结果整理成 MCP 返回值。 Go 通过 helper 获取窗口结构和执行结果,iSphere 控件细节由 C# helper 封装。 ### 3.2 C# Windows Helper C# 是 Windows 执行层,负责: - 枚举桌面窗口。 - 找疑似 iSphere / IMPlatformClient 窗口。 - 读取指定窗口的 UI Automation 控件树。 - 后续在 selector 稳定后执行少量受控窗口动作。 C# 保持 Windows helper 定位,只返回 Go 请求的 helper 结果。 ## 4. 进程模型 第一阶段采用一次性 CLI 模型: ```text Go 启动 C# helper Go 通过 stdin 写入一个 JSON 请求 C# 执行一个 op C# 通过 stdout 返回一个 JSON 响应 C# 退出 ``` 原因: - 简单。 - 易测试。 - 默认一次一进程,便于调试和替换。 - 联系人、消息、文件路径通过 stdin JSON 传入,命令行参数保持简单。 - 后续需要提速时,再评估长连接。 标准约束: - 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 WRITE_NOT_READY VERIFY_FAILED ``` ## 6. 当前只读 helper op 当前 helper 只支持只读探测类 op。`version`、`self_check`、`scan_windows`、`dump_uia` 是第一阶段窗口/UIA 基线;`probe_client_runtime` 是 C30 为 B 路线发送连接器新增的只读运行时探测;`probe_send_entrypoints` 和 `probe_send_uia_controls` 是 R6a/C31 为发送连接器新增的只读预检。 ### 6.1 `version` 用途:确认 helper 可运行,返回协议版本、程序版本、运行时信息。 请求: ```json { "protocol": "isphere.helper.v1", "request_id": "...", "op": "version", "args": {} } ``` 响应 data 示例: ```json { "helper_name": "ISphereWinHelper", "helper_version": "0.4.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` 参数控制。 ### 6.5 `probe_client_runtime` 用途:为 B 路线发送连接器做只读运行时探测,确认本机是否存在已运行的 `IMPlatformClient.exe` / iSphere 相关进程,以及进程位数、安装路径、关键模块是否加载。 这个 op 只做进程和模块枚举: - 不发送消息; - 不上传文件; - 不点击、不输入; - 不注入、不 hook; - 不读取聊天内容。 请求示例: ```json { "protocol": "isphere.helper.v1", "request_id": "...", "op": "probe_client_runtime", "timeout_ms": 5000, "args": { "process_names": ["IMPlatformClient", "IMPP.ISphere", "iSphere", "importal"], "include_modules": true, "max_modules": 120 } } ``` 响应 data 示例: ```json { "probe_mode": "read_only_process_module_inventory", "host": { "is_64_bit_os": true, "is_64_bit_process": true }, "target_count": 1, "targets": [ { "pid": 1234, "process_name": "IMPlatformClient", "main_window_title": "iSphere", "executable_path": "C:\\...\\IMPlatformClient.exe", "bitness": "x86", "assembly_presence": { "IMPlatformClient.exe": true, "smack.dll": true, "IMPP.Interface.dll": true, "IMPP.ServiceBase.dll": true, "IMPP.Service.dll": true }, "module_probe_ok": true } ] } ``` 该 op 是 C30 的 B 路线入口检查。它暂不等于发送能力,只用于判断后续是否值得做 sidecar / in-process 调用验证。 ### 6.6 `probe_send_entrypoints` 用途:对复制或安装目录里的 iSphere / IMPlatformClient 二进制做只读元数据检查,确认 B 路线是否存在文本发送和文件发送候选入口。 这个 op 只做文件存在、版本、SHA256、.NET 反射/字符串元数据检查: - 不发送消息; - 不上传文件; - 不点击、不输入; - 不注入、不 hook; - 不抓包; - 不读取聊天内容。 请求示例: ```json { "protocol": "isphere.helper.v1", "request_id": "...", "op": "probe_send_entrypoints", "timeout_ms": 15000, "args": { "install_dir": "C:\\Program Files (x86)\\Impp" } } ``` 响应 data 示例: ```json { "probe_mode": "read_only_send_entrypoint_metadata", "summary": { "entrypoint_count": 7, "available_count": 7, "required_count": 5, "required_available_count": 5, "all_required_available": true, "b_route_entrypoint_preflight": "pass" }, "entrypoints": [ { "id": "text_high_level_by_jid", "assembly": "IMPlatformClient.exe", "type_name": "IMPP.Client.Core.Plugins.Manager.AppContextManager", "method_name": "SendTxtMessageByJid", "available": true } ], "safety": { "sent_message": false, "sent_file": false, "uploaded_file": false, "clicked_ui": false, "typed_text": false, "captured_network": false, "attached_hook": false, "modified_client_data": false } } ``` 该 op 是 R6a/C31 的 B 路线入口可达性预检。它证明“值得继续做 preview/dry-run”,但不等于生产发送能力。 ### 6.7 `probe_send_uia_controls` 用途:对指定窗口做只读 UIA 分类,判断 A 路线 fallback 所需的搜索框、接收区、发送编辑区、发送按钮、发送文件菜单和离线发送阻断状态是否可识别。 请求示例: ```json { "protocol": "isphere.helper.v1", "request_id": "...", "op": "probe_send_uia_controls", "timeout_ms": 5000, "args": { "hwnd": "0x001A0B2C", "max_depth": 8, "max_children": 200 } } ``` 响应 data 示例: ```json { "probe_mode": "read_only_uia_send_control_classifier", "flags": { "has_search_edit": true, "has_receive_document": true, "has_send_editor": true, "has_send_button": true, "has_file_menu": true, "offline_blocker_visible": true, "send_button_enabled": false, "route_hint": "A_ROUTE_OFFLINE_BLOCKED" }, "safety": { "sent_message": false, "sent_file": false, "uploaded_file": false, "clicked_ui": false, "typed_text": false, "captured_network": false, "attached_hook": false, "modified_client_data": false } } ``` 该 op 不返回聊天内容。控件名只返回固定 safe label 或是否存在,用于判断后续是否能进入 A 路线 draft-only 预检。 ## 7. 后续 op 扩展顺序 必须等真实登录窗口的 UIA dump 被确认后,再扩展真实动作。 建议顺序: ```text search_contacts open_conversation read_latest_messages write_draft send_message send_file receive_file ``` 其中: - `search_contacts`、`open_conversation`、`read_latest_messages` 是后续核心工具候选 op。 - `write_draft` 用于构造待发送内容。 - `send_message`、`send_file`、`receive_file` 归入核心 MCP 工具路线。 ## 8. 写入与审计接口 Go 负责把业务工具请求转换成 helper op,并记录目标、内容摘要、文件摘要、时间、连接器和执行结果。C# helper 只执行 Go 发来的单次 op,并返回可核验结果。 ## 9. 部署形态 helper 保持普通企业辅助工具形态:普通命令行程序、普通安装路径、固定名称、可构建、可签名、可替换。正式部署关注安装路径、版本、日志和运维可见性。 ## 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 execution/ execution.go ``` C# 侧第一阶段结构: ```text native/ ISphereWinHelper/ Program.cs HelperProtocol.cs WindowScanner.cs UiaDumper.cs ``` 第一阶段目录保持最小。 ## 11. 验收标准 当前只读 helper 基线验收: 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. `probe_client_runtime` 在无目标客户端运行时也能返回合法空结果。 9. 用户手动登录 iSphere 后,`probe_client_runtime` 能返回目标进程、位数、路径和关键模块探测结果。 10. 当前验收仍聚焦只读探测;发送、文件上传、点击、输入都不在本节验收范围内。 ## 12. 下一步 当前下一步是 C30 B 路线运行时探测: ```text version self_check scan_windows dump_uia probe_client_runtime ``` Go MCP 代码已经具备基础 helper 调用能力;`probe_client_runtime` 暂不暴露为 MCP 业务工具。待真实登录客户端上的 B1/B2 探测通过后,再决定是否新增 sidecar 调用层和受控发送工具。