9.3 KiB
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。version、self_check、scan_windows、dump_uia 是第一阶段窗口/UIA 基线;probe_client_runtime 是 C30 为 B 路线发送连接器新增的只读运行时探测。
6.1 version
用途:确认 helper 可运行,返回协议版本、程序版本、运行时信息。
请求:
{
"protocol": "isphere.helper.v1",
"request_id": "...",
"op": "version",
"args": {}
}
响应 data 示例:
{
"helper_name": "ISphereWinHelper",
"helper_version": "0.3.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 调用验证。
7. 后续 op 扩展顺序
必须等真实登录窗口的 UIA dump 被确认后,再扩展真实动作。
建议顺序:
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 侧未来结构:
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 基线验收:
- C# helper 能编译。
version返回合法 JSON。self_check返回 UIA 可用状态。scan_windows能列出当前可见窗口。- 打开记事本后,
dump_uia能导出记事本控件树。 - 用户手动登录 iSphere 后,
scan_windows能找到候选窗口。 - 对 iSphere 候选窗口执行
dump_uia能返回控件树。 probe_client_runtime在无目标客户端运行时也能返回合法空结果。- 用户手动登录 iSphere 后,
probe_client_runtime能返回目标进程、位数、路径和关键模块探测结果。 - 当前验收仍聚焦只读探测;发送、文件上传、点击、输入都不在本节验收范围内。
12. 下一步
当前下一步是 C30 B 路线运行时探测:
version
self_check
scan_windows
dump_uia
probe_client_runtime
Go MCP 代码已经具备基础 helper 调用能力;probe_client_runtime 暂不暴露为 MCP 业务工具。待真实登录客户端上的 B1/B2 探测通过后,再决定是否新增 sidecar 调用层和受控发送工具。