WinApp MCP
](#changelog)
MCP(模型上下文协议)服务器,为AI编码代理提供Windows桌面应用程序上的“眼睛”和“手” FlaUI 以及Windows用户界面自动化(UIA3)。
适用于任何公开标准UI自动化树的Windows应用程序,包括 WPF, 桌面应用程序, WinUI 3,以及 .NET MAUI 应用程序。
先决条件
- Windows 10/11
- .NET 10 SDK — 下载
- 支持MCP的AI客户端(Claude Desktop、VS Code Copilot、Cursor等)
构建与运行
cd WinApp-MCP
dotnet build
dotnet run服务器通过以下方式进行通信 标准 (stdin/stdout)使用MCP协议。
客户端配置
克劳德桌面/VS代码副本/光标
添加到MCP配置中:
{
"mcpServers": {
"winapp-mcp": {
"command": "dotnet",
"args": ["run", "--project", "C:\\path\\to\\WinApp-MCP\\WinApp-MCP.csproj"]
}
}
}或者直接运行编译后的二进制文件:
{
"mcpServers": {
"winapp-mcp": {
"command": "C:\\path\\to\\WinApp-MCP\\bin\\Debug\\net10.0-windows\\win-x64\\WinApp-MCP.exe"
}
}
}工具参考
发现
| 工具 | 说明 |
|---|---|
list_windows | 列出所有顶级窗口(可选 processName 过滤器) |
attach_application | 通过以下方式连接到正在运行的应用程序 processName 或 processId |
list_attached | 显示当前附加的窗口 |
检查
| 工具 | 说明 |
|---|---|
get_window_tree | 获取精简文本格式的UI元素树。支持 maxDepth, rootAutomationId,以及 propertyProfile (minimal, standard, diagnostic) |
find_elements | 按以下方式查找元素 automationId, name, controlType,或 xpath.支持 visibleOnly, enabledOnly 过滤器和 rootAutomationId 用于子树范围的搜索 |
get_element_properties | 获取元素的详细属性和支持的UIA模式 |
get_selectable_items | 枚举组合框/列表框中的项目,包括可见的文本摘要、CLR类型名称检测、原始提供程序文本和可选的行级操作发现(includeActions) |
get_child_controls | 发现复合父级中的子控件,按交互类型分类(edit, button, toggle, picker, expander, label, other) |
文本
| 工具 | 说明 |
|---|---|
get_visible_text | 按阅读顺序从窗口或子树中读取所有可见文本 |
get_element_text | 使用多策略回退链从特定元素读取文本/值。支持 rootAutomationId |
set_text | 通过ValuePattern(键盘回退选择加入)在支持文本的控件中设置文本。支持 rootAutomationId |
交互
| 工具 | 说明 |
|---|---|
click_element | 单击元素(左/右/双)。支持 rootAutomationId.当多个元素匹配时报告歧义 |
invoke_element | 通过UIA-InvokePattern调用(无鼠标,按钮首选)。支持 rootAutomationId.报告含糊不清 |
type_text | 在输入框中键入文本(可选先清除)。支持 rootAutomationId |
toggle_element | 切换复选框/切换按钮。支持 rootAutomationId |
select_item | 按值或索引选择组合框/列表框中的项目。使用多策略回退。支持 rootAutomationId |
file_dialog_select | 通过输入路径并单击接受按钮,完成标准的Windows打开/保存文件对话框。自动处理模糊的“打开”按钮 |
send_keys | 发送键盘快捷键(例如。, Ctrl+A, Enter, Alt+F4) |
focus_element | 聚焦一个元素/将窗口置于前台。支持 rootAutomationId |
捕获并等待
| 工具 | 说明 |
|---|---|
screenshot | 将窗口或元素捕获为base64 PNG(最大1280px宽)。支持 rootAutomationId |
wait_for_element | 等待元素出现(可配置超时)。支持 rootAutomationId |
代理工作流示例
1. list_windows(processName: "MyMauiApp")
→ PID: 12345, Handle: "1A2B3C", Title: "My App"
2. attach_application(processName: "MyMauiApp")
→ Handle: "1A2B3C"
3. get_window_tree(windowHandle: "1A2B3C", maxDepth: 3)
→ [Window] "My App" id="" class="WinUIDesktopWin32WindowClass"
[Text] "Welcome" id="lblWelcome"
[Edit] "" id="txtUsername" class="TextBox"
[Edit] "" id="txtPassword" class="PasswordBox"
[Button] "Sign In" id="btnSignIn"
4. type_text(windowHandle: "1A2B3C", automationId: "txtUsername", text: "admin")
→ Typed text via ValuePattern
5. type_text(windowHandle: "1A2B3C", automationId: "txtPassword", text: "pass123")
→ Typed text via ValuePattern
6. invoke_element(windowHandle: "1A2B3C", automationId: "btnSignIn")
→ Invoked: [Button] "Sign In" id="btnSignIn"
7. wait_for_element(windowHandle: "1A2B3C", name: "Dashboard", timeoutMs: 5000)
→ Element found
8. get_visible_text(windowHandle: "1A2B3C")
→ Found 3 text element(s):
[Name] Welcome back, admin
[Name] Dashboard
[ValuePattern] Last login: 2026-03-08
9. screenshot(windowHandle: "1A2B3C")
→ [Screenshot captured: 1280x720px]元素识别
元素可以通过以下方式找到(按优先级顺序):
automationId--最可靠。由开发人员设置,在窗口内独一无二。xpath--结构路径类似//Button[@Name='OK']当Automation Id缺失时,该功能正常。name+controlType--显示文本+类型组合。可用于标记控件。当多个元素匹配时,排名分辨率使用结构上下文(深度、对话角色、父类型)选择最佳候选者。
分级解决方案和模糊性
当名称+控制类型搜索匹配多个元素时(例如,在一个标准文件对话框中,有几个按钮被命名为“打开”),解析器会对每个候选项进行评分:
- 浅层元素 (更靠近窗口根)是首选。
- 对话框操作按钮 (automationId
"1"/"2")获得丰厚奖金。 - 下拉按钮 (automationId
"DropDown")以及 组合框儿童 受到惩罚。 - 已启用,可见 元素得分更高。
最佳评分元素会自动使用。当存在歧义时,工具如 click_element 和 invoke_element 附加一个诊断警告,列出所有候选人的分数和家长背景。
子树范围搜索
大多数工具支持 rootAutomationId --一个可选参数,将元素搜索范围限定到子树而不是整个窗口。这对于定位已知容器内的元素非常有用(例如,在指定的组合框中单击下拉按钮)。
文件对话框处理
标准的Windows打开/保存对话框公开了多个名为“打开”的控件——主接受按钮,以及“文件名:”和“文件类型:”组合框内的下拉按钮。WinApp MCP处理此问题:
file_dialog_select--推荐的方法。在一次操作中输入文件路径并单击对话框接受按钮。同时适用于“打开”和“保存”对话框。- 排名决议 --如果你使用
click_element或invoke_element随着name="Open",主对话框按钮(automationId"1")自动优先于下拉按钮。 - 子树范围 --要明确指向特定组合框中的下拉按钮,请使用
rootAutomationId以确定搜索范围。
供应商容忍度
WinApp MCP旨在与可能暴露不完整或非标准属性的真实UI自动化提供程序配合使用:
- 不支持的属性 按元素捕获并报告为 `` 而不是使操作失败。
- 树木检查 继续经过发生故障的节点,发出
[]不可检查儿童的占位符。 - 项目选择 使用多策略回退链(名称→ 价值模式→ Legacy可访问→ 文本后代),当提供程序元数据不完整时。
- 模板化列表行 返回CLR类型名称(例如。
Namespace.Model.ClassName)而不是用户可见的文本被自动解析为可见的后代摘要。 - 复合控制 对于弱父元数据,可以通过以下方式进行探索
get_child_controls,根据互动类型对儿童进行分类。 - 瞬时COM故障 (例如。
E_UNEXPECTED)使用元素重新解析重试。 - 错误分类 区分
ElementNotFound,PropertyNotSupported,TransientProviderFailure,以及OperationNotSupported因此,代理人可以做出明智的决定。
故障排除
| 问题 | 解决方案 |
|---|---|
| 未找到窗口 | 确保目标应用正在运行。某些应用程序需要以管理员权限启动。 |
| 空UI树 | 该应用程序可能使用不公开UIA的自定义绘制控件。尝试 screenshot 相反。 |
| 未找到元素 | 使用 get_window_tree 更高 maxDepth 探索。检查树输出中的Automation Id。 |
| 单击不起作用 | 试试看 invoke_element 相反(使用UIA模式,没有鼠标)。一些应用程序阻止程序化鼠标输入。 |
| 不支持属性 | 使用 get_window_tree 随着 propertyProfile: "minimal" 为了获得最大的可靠性,或 "diagnostic" 了解全部细节。 |
| 组合框选择失败 | 使用 get_selectable_items 以诊断哪些项目对UIA可见以及哪些文本源可用。 |
| 列表显示CLR类型名称 | 模板行会自动解析为可见文本。检查 rawProviderText 和 summaryParts 在 get_selectable_items 输出。 |
| 复合控制难以交互 | 使用 get_child_controls 发现按互动类型分类的可操作儿童。 |
| 无法读取验证文本 | 使用 get_visible_text 从窗口或子树中读取所有可见文本。 |
| 截图失败 | 确保窗口未最小化。服务器需要一个桌面会话(不是无头会话)。 |
| DPI/协调问题 | 确保该过程是DPI感知的。BoundingRectangle值以物理像素为单位。 |
| 登录到stdout会中断MCP | 默认情况下,所有日志记录路由都指向stderr。不添加 Console.WriteLine 电话。 |
| 文件对话框点击了错误的“打开”按钮 | 使用 file_dialog_select 用于标准文件对话框,或使用 invoke_element 随着 automationId="1" 直接针对接受按钮。分级分辨率现在自动首选主对话框按钮。 |
建筑
WinApp-MCP/
├── Program.cs # Host builder, DI, MCP server setup
├── Services/
│ ├── FlaUIService.cs # Singleton: UIA3Automation, window cache, tree serialization
│ ├── ElementResolver.cs # Element lookup with ranked resolution and transient failure recovery
│ └── SafeUIA.cs # Safe UIA property access and multi-strategy text extraction
├── Models/
│ ├── ElementInfo.cs # Compact DTO for element properties
│ ├── ErrorCategory.cs # Error classification enum
│ ├── ResolveResult.cs # Ranked resolution result with ambiguity diagnostics
│ ├── RowAction.cs # Row-level action metadata for list items
│ └── ToolResult.cs # Structured tool result with error categorization
└── Tools/
├── WindowTools.cs # list_windows, attach_application, list_attached
├── InspectionTools.cs # get_window_tree, find_elements, get_element_properties, get_selectable_items, get_child_controls
├── InteractionTools.cs # click, invoke, type_text, toggle, select, file_dialog_select, send_keys, focus
├── TextTools.cs # get_visible_text, get_element_text, set_text
├── CaptureTools.cs # screenshot
└── WaitTools.cs # wait_for_element更新日志
看 更改日志.md 发布历史。
许可证
麻省理工学院
