Files
isphere-ai-bridge/docs/go-csharp-helper-boundary.md
2026-07-05 12:33:19 +08:00

8.3 KiB
Raw Permalink Blame History

Go MCP 与 C# Windows Helper 边界设计

1. 目标

最终程序分成两层:

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 模型:

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

协议名固定为:

isphere.helper.v1

5.1 请求格式

{
  "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 成功响应

{
  "protocol": "isphere.helper.v1",
  "request_id": "uuid-string",
  "op": "scan_windows",
  "ok": true,
  "data": {},
  "error": null,
  "warnings": []
}

5.3 失败响应

{
  "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": []
}

第一版错误码只保留:

INVALID_REQUEST
UNSUPPORTED_OP
HELPER_FAILED
TIMEOUT
WINDOW_NOT_FOUND
AMBIGUOUS_WINDOW
UIA_DUMP_FAILED

后续真实动作阶段再增加:

SELECTOR_NOT_FOUND
APP_NOT_LOGGED_IN
APP_BUSY
APPROVAL_REQUIRED
VERIFY_FAILED

6. 第一阶段 op

第一阶段只支持四个 op。

6.1 version

用途:确认 helper 可运行,返回协议版本、程序版本、运行时信息。

请求:

{
  "protocol": "isphere.helper.v1",
  "request_id": "...",
  "op": "version",
  "args": {}
}

响应 data 示例:

{
  "helper_name": "ISphereWinHelper",
  "helper_version": "0.1.0",
  "protocol": "isphere.helper.v1",
  "runtime": ".NET Framework"
}

6.2 self_check

用途:检查 helper 是否能访问当前桌面、UI Automation 是否可用。

响应 data 示例:

{
  "desktop_access": true,
  "uia_available": true
}

6.3 scan_windows

用途:枚举当前桌面窗口,返回疑似 iSphere / IMPlatformClient 候选。

args 示例:

{
  "include_all_visible": false
}

响应 data 示例:

{
  "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 示例:

{
  "hwnd": "0x001A0B2C",
  "max_depth": 8,
  "include_text": true
}

响应 data 示例:

{
  "hwnd": "0x001A0B2C",
  "root": {
    "name": "iSphere",
    "control_type": "Window",
    "automation_id": "",
    "class_name": "WindowsForms10.Window.8.app.0.xxxxx",
    "children": []
  }
}

第一阶段 Go 可以把该响应保存到:

runs/real-loggedin-lab/uia-dumps/

C# helper 默认不主动写文件,除非未来明确加入 out_path 参数。

7. 后续 op 扩展顺序

必须等真实登录窗口的 UIA dump 被确认后,再扩展真实动作。

建议顺序:

search_contacts
open_conversation
read_latest_messages
write_draft
send_after_approval
send_file_after_approval
receive_file_after_approval

其中:

  • search_contactsopen_conversationread_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 侧未来结构:

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# 侧第一阶段结构:

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 第一阶段:

version
self_check
scan_windows
dump_uia

Go MCP 代码暂不写。等 C# helper 能稳定拿到真实 iSphere 窗口结构后,再实现 Go 的 helperclient 和 MCP tools。