Files
isphere-ai-bridge/docs/go-csharp-helper-boundary.md
2026-07-10 13:37:08 +08:00

12 KiB
Raw 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 与 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 模型:

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

协议名固定为:

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
WRITE_NOT_READY
VERIFY_FAILED

6. 当前只读 helper op

当前 helper 只支持只读探测类 op。versionself_checkscan_windowsdump_uia 是第一阶段窗口/UIA 基线;probe_client_runtime 是 C30 为 B 路线发送连接器新增的只读运行时探测;probe_send_entrypointsprobe_send_uia_controls 是 R6a/C31 为发送连接器新增的只读预检。

6.1 version

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

请求:

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

响应 data 示例:

{
  "helper_name": "ISphereWinHelper",
  "helper_version": "0.4.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 参数控制。

6.5 probe_client_runtime

用途:为 B 路线发送连接器做只读运行时探测,确认本机是否存在已运行的 IMPlatformClient.exe / iSphere 相关进程,以及进程位数、安装路径、关键模块是否加载。

这个 op 只做进程和模块枚举:

  • 不发送消息;
  • 不上传文件;
  • 不点击、不输入;
  • 不注入、不 hook
  • 不读取聊天内容。

请求示例:

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

{
  "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
  • 不抓包;
  • 不读取聊天内容。

请求示例:

{
  "protocol": "isphere.helper.v1",
  "request_id": "...",
  "op": "probe_send_entrypoints",
  "timeout_ms": 15000,
  "args": {
    "install_dir": "C:\\Program Files (x86)\\Impp"
  }
}

响应 data 示例:

{
  "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 所需的搜索框、接收区、发送编辑区、发送按钮、发送文件菜单和离线发送阻断状态是否可识别。

请求示例:

{
  "protocol": "isphere.helper.v1",
  "request_id": "...",
  "op": "probe_send_uia_controls",
  "timeout_ms": 5000,
  "args": {
    "hwnd": "0x001A0B2C",
    "max_depth": 8,
    "max_children": 200
  }
}

响应 data 示例:

{
  "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 被确认后,再扩展真实动作。

建议顺序:

search_contacts
open_conversation
read_latest_messages
write_draft
send_message
send_file
receive_file

其中:

  • search_contactsopen_conversationread_latest_messages 是后续核心工具候选 op。
  • write_draft 用于构造待发送内容。
  • send_messagesend_filereceive_file 归入核心 MCP 工具路线。

8. 写入与审计接口

Go 负责把业务工具请求转换成 helper op并记录目标、内容摘要、文件摘要、时间、连接器和执行结果。C# helper 只执行 Go 发来的单次 op并返回可核验结果。

9. 部署形态

helper 保持普通企业辅助工具形态:普通命令行程序、普通安装路径、固定名称、可构建、可签名、可替换。正式部署关注安装路径、版本、日志和运维可见性。

10. 建议目录结构

当前以规划为主,目录按节点逐步创建。

Go 侧未来结构:

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

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 路线运行时探测:

version
self_check
scan_windows
dump_uia
probe_client_runtime

Go MCP 代码已经具备基础 helper 调用能力;probe_client_runtime 暂不暴露为 MCP 业务工具。待真实登录客户端上的 B1/B2 探测通过后,再决定是否新增 sidecar 调用层和受控发送工具。