内容
<p align="center">
<img src="assets/banner.svg" alt="屏幕控制" width="680">
</p>
<h3 align="center">截图是为人类眼睛准备的图片。<br>这将屏幕作为数据交给AI。</h3>
<p align="center"><sub>适用于Windows的MCP服务器 · 一键安装适用于Claude Desktop · 适用于任何MCP客户端</sub></p>
<p align="center">
<a href="../../releases/latest"><img alt="下载" src="https://img.shields.io/badge/⬇%20Download%20for%20Windows-22d3ee?style=for-the-badge&labelColor=0f172a"></a>
<a href="docs/GUIDE.md"><img alt="指南" src="https://img.shields.io/badge/📖%205--minute%20guide-0f172a?style=for-the-badge"></a>
</p>
<p align="center">
<img alt="MIT" src="https://img.shields.io/badge/license-MIT-0f172a?style=flat-square">
<img alt="Windows" src="https://img.shields.io/badge/platform-Windows-0f172a?style=flat-square">
<img alt="Python 3.9+" src="https://img.shields.io/badge/python-3.9%2B-0f172a?style=flat-square">
<img alt="35 tools" src="https://img.shields.io/badge/tools-35-22d3ee?style=flat-square">
<a href="../../actions/workflows/ci.yml"><img alt="CI" src="../../actions/workflows/ci.yml/badge.svg"></a>
</p>
---
## 安装
这是一个普通的MCP服务器,所以**任何MCP客户端都可以使用它** — Claude Desktop,
Claude Code,Cline,Continue,Zed,或您自己编写的客户端。下面的一键式`.mcpb`文件是Claude Desktop的捆绑包格式;对于其他所有文件,本页面底部有四行配置。
需要Windows和[Python 3.9+](https://www.python.org/downloads/) — 在安装过程中勾选**"Add python.exe to PATH"**。
**1.** 下载 **[`pc-screen-control.mcpb`](../../releases/latest)**
**2.** 在Claude中:`Settings → Extensions → Advanced → Install extension…` 并选择文件
> **请勿双击文件。** Windows没有`.mcpb`的处理程序,Windows会询问您要使用哪个程序打开它。没有正确的答案。
**3.** 完全关闭Claude — 包括系统托盘图标 — 然后重新启动
没有第四步,也无需打开任何开关。要检查,请让Claude运行`describe_screen`;您应该会得到一个打开的窗口列表。
<sub>**[完整指南 →](docs/GUIDE.md)** · 从源代码开始:下载此存储库为ZIP并运行`scripts\INSTALL.bat` · 删除:*设置 → 扩展*,或`scripts\UNINSTALL.bat`</sub>
---
## 为什么它比截图更好
让AI点击某物时,它通常会截取屏幕截图,观察截图,然后猜测坐标 — 但无法确定点击是否准确。
Windows已经将屏幕上的内容以结构化数据发布:每个按钮、字段和列表都有其名称和状态。这就是屏幕阅读器的工作原理。该服务器向Claude提供相同的内容。
```
使用截图: "点击 847, 312" 猜测,且无法检查
使用此方法: 调用(“保存”的引用) 按名称,且有验证
```
| | |
|---|---|
| **它会点击正确的内容** | 控件按名称查找,而不是按像素。窗口移动或分辨率更改时不会漂移。 |
| **它知道是否成功** | 每个操作都会返回元素变更前后的状态。成功被显示,而不是被假设。 |
| **您的鼠标仍然属于您** | 大部分操作通过可访问性接口进行,而不是指针,因此您可以继续工作。 |
---
## 成本阶梯
从顶部开始,停在第一个有效的阶梯。
| | | 对您的影响 |
|---|---|---|
| **1** | `read_ui_tree` `find_elements` `read_text` `read_table` | 无需成本 |
| **2** | `invoke` `set_text` `set_value` `toggle` `select` `window` | **您的光标从未被触碰** |
| **3** | `capture` | 无需成本,但信息较少 |
| **4** | `click` `drag` `send_keys` | **占用您的鼠标或键盘** |
阶梯1-3涵盖了几乎所有情况。截图循环别无选择,只能停在阶梯4,每次都这样。
**对于一个应用程序中的长时间作业,它可以完全不干扰您。**
`claim_window` 将该窗口移动到每个监视器的边缘之外。它继续运行,并通过名称保持完全可操作 — 但您无法看到它,也无法点击它,因为Windows不允许鼠标指针离开监视器。在双显示器桌面上测量:监视器在x = 4920处结束,窗口停在x = 5120处,`SetCursorPos(5170)`落在4919处。`release_window`将其移回像素处,退出处理程序也是如此 — 包括崩溃后,因为在窗口移动之前,位置已写入磁盘。您无法触及的窗口不是任何人应该能够搁置的窗口。
**它不会在您移动到的窗口或字段中输入。** 无目标发送的按键会在键盘焦点所在的位置生效,这在调用之间是好的,直到您在一次调用之间点击某个地方 — 然后用于表单的Enter键会落在您的聊天中。服务器在每次调用后都会记录**前景窗口**和**焦点控件**;如果在下一次盲键入或坐标点击之前它们已更改,则该更改来自外部,工具会拒绝并说明更改了什么。控件与窗口一样重要:点击窗口中已经在前面的不同字段不会更改任何内容,焦点所在的位置也不会更改。
**顺序是:冻结,然后查看,然后操作。** 首先检查并锁定后会留有空隙,点击可能会在毫秒级发生 — 只有有时有效的检查比没有检查更糟糕。因此,输入被冻结,首先屏幕在最后一次按键后给予40毫秒,然后再验证目标。如果目标已更改,则锁定被释放,什么也不输入。`force:true`会覆盖整个过程。
**工具从不悄悄降级。** 在发布者未提供任何按下方式的控件上调用`invoke`不会回退到实际点击 — 它会拒绝,说明元素提供了什么,并为您提供确切的`click(x,y)`调用(如果您决定指针值得一试)。如果在工具内部存在更便宜的路由,则会首先采用:`close_window`要求窗口自行关闭,只有在它不关闭时才查找Alt + F4;`menu`尝试展开模式,然后是上下文菜单键,最后是右键。无论何时其中之一执行,它都会说明其执行方式 — `"how"`命名路由,`"took_input"`为`true`。这样,是否花费鼠标的决定始终在上一个层面上进行,并且永远不会在工具内部进行。
**阶梯4是例外,而不是习惯。** 只有在应用程序绘制自己的界面且根本不发布任何控件时才会达到此级别 — 编辑画布,视频时间线,游戏。
**当您使用计算机时,它会收到警告。** 屏幕边缘缓慢向内呼吸 — 您有时间完成您正在输入的内容 — 然后像释放的橡皮筋一样弹回,而这次弹回正是您的输入被冻结,而Claude正在工作。您的按键被暂停;Claude的按键通过。Escape在任何时候都可以中止。之后,您的窗口,焦点和文本光标会准确恢复到原来的位置。如果您正在玩游戏或执行必须不被中断的操作,则`set_guard priority:"me"`会让Claude在获得您的批准后再继续。
<p align="center">
<img src="docs/img/edge-glow.png" alt="输入被占用时的屏幕边缘" width="560">
</p>
在具有十个打开的窗口的实时桌面上测量:`describe_screen` 3.4s,其他操作在0.07s至0.86s之间,连续60次调用为0.09s。`tests/stress.py`在您的机器上重现这些结果。
---
## 实际会话的样子
来自真实桌面的未经编辑的输出。
```jsonc
describe_screen()
// 7个窗口,没有一个是截图:
// Claude 219个节点 可读 "woken": true
// 工具 – 文件资源管理器 207个节点 可读
// Edge,17个标签页 182个节点 可读
// 任务栏 53个节点 可读
```
`"woken": true`是Chromium修复程序正在运行 — 该窗口在第一次浅显的查看时测量为13个节点,而在正确询问后为219个节点。
```jsonc
read_table({ window_handle: 2100558 })
// { "headers": ["名称", "修改日期", "类型", "大小"],
// "rows": [["audit", "21.07.2026 09:42", "Python 文件", "7 KB"],
// ["build", "21.07.2026 09:42", "批处理文件", "2 KB"],
// ["build_log", "21.07.2026 09:51", "文本文件","1 KB"]] }
```
```jsonc
find_elements({ window_handle: 2100558, query: "更新" })
// { "ref": "2100558:2.0.1.3", "role": "ButtonControl",
// "name": "\"工具\" 更新(F5)",
// "automation_id": "refreshButton", "matched_on": "name",
// "note": "匹配显示名称,该名称依赖于语言。
// 如果显示自动化ID,则优先使用它。" }
```
这是Windows的德语版本。`refreshButton`在地球上的每台机器上都是相同的;
`"tools" 更新(F5)`不是 — 而工具说明了这一点,而不是让您编写可能会在国外损坏的内容。
---
## 35种工具
| | |
|---|---|
| **`describe_screen`** | 每个窗口,分类为`可读` / `浅` / `仅画布`。从这里开始。 |
| `list_windows` `read_ui_tree` `find_elements` | 控件树,可搜索,每个节点都有一个`ref` |
| `element_from_point` `get_focus` `get_text` `read_text` | 什么在哪里,焦点是什么,它说什么 |
| **`read_table`** | 网格或详细列表为行,列和标题 |
| **`capture`** | 屏幕,窗口或**单个元素**的图像 |
| `invoke` `toggle` `expand` `select` `set_text` | 操作控件 — 所有操作都会返回变更前后的状态 |
| **`set_value`** | 滑块,旋转器或滚动位置到确切的数字 |
| **`window`** | 移动,调整大小,最小化,最大化 — 无需鼠标 |
| **`clipboard`** | 读取或写入它。一个调用代替数百次按键 |
| **`menu`** | 打开上下文菜单并读取它 — 菜单在打开之前不存在 |
| `click` `drag` `scroll` | 坐标输入,最后的手段用于自绘制曲面 |
| `send_keys` `hold_key` | 键盘,用于快捷键 |
| **`wait_for`** `wait` | 等待条件,而不是时钟 |
| **`batch`** | 一个调用中的多个验证步骤 |
| `launch_app` `close_window` `focus_window` | 进程和窗口 |
| **`self_test`** | 检查所有内容并用普通语言说明有什么问题以及该怎么做 |
| **`claim_window`** `release_window` | 将窗口停在鼠标无法触及的地方,然后将其移回像素处 |
| **`set_guard`** | 谁在Claude使用鼠标时具有优先级 — `claude`或`me` |
| **`check_for_update`** | 唯一一个联网的工具,按需 |
---
## 它能和不能到达哪里
使用`tests/measure_desktop.py`测量,该文件随此存储库提供,因此您可以在自己的机器上驳斥这些数字。
| | 可操作节点 | |
|---|---:|---|
| 文件资源管理器 | 220 | 完全控制,文件列表为真实表格 |
| Chrome / Electron | 207–398 | 完整页面内容,唤醒后 |
| DaVinci Resolve(项目管理器) | 53 | 按名称的按钮和复选框 |
**Chromium需要修复,而不是借口。** 浏览器和Electron应用程序仅在有人询问时构建其可访问性树。第一次浅显的查看报告了Claude窗口的13个节点;唤醒后,207个节点。这涵盖了VS Code,Slack,Discord,Teams,Notion和每个Web应用程序。
**自行绘制的曲面成本更高,它们不是禁区。** 编辑画布,时间线和游戏不公开控件 — 没有什么可以读取,如果没有发布的内容。`capture`显示它们,`click` / `drag`在同一个服务器上操作它们。您会失去精度和证明,而不是访问权限。
---
## 在依赖它之前
- **仅限Windows。** `docs/PORTING.md`将此处使用的每个模式映射到macOS可访问性API。该映射不是实现。
- **控件名称跟随窗口的语言。** 在德语Windows上,保存按钮为*Speichern*。大约一半的元素还带有`automation_id`,它不会翻译;`find_elements`搜索两者并说明匹配了哪个。
- **您的防病毒软件可能会反对。** 编写其他应用程序并移动鼠标的结构化程序与间谍软件无法区分。没有签名也没有公司 — 但整个服务器是一个可读的Python文件,比签名更有信任基础。
- **管理员进程不可见。** Windows按设计阻止跨完整性级别的输入。
- **没有自己的撤销。** `send_keys {Ctrl}z`到达应用程序的撤销。关闭窗口或发送消息不是任何工具都会撤销的操作。
---
## 设计笔记
**操作证明自己。** `ok:true`仅表示调用未抛出异常。每个操作都会重新读取元素并报告更改了什么 — 或清楚地说明根本没有更改。
**工具拒绝昂贵的路径。** `drag`在滑块上指向`set_value`;`send_keys`在文本字段上指向`set_text`。两者都接受`force:true`。
**等待状态,而不是时钟。** 固定的睡眠是屏幕自动化容易出错的主要原因。
---
## 存储库布局
```
src/ 服务器 — 一个可读的Python文件,加上屏幕边缘叠加层
tests/ 自己运行这些:设置逻辑,桌面测量,压力测试
docs/ 安装指南和映射到macOS端口的指南
scripts/ 从源代码安装,无需扩展
```
<details>
<summary>其他MCP客户端 — Claude Code, Cline, Continue, Zed, 您自己的</summary>
```json
{
"mcpServers": {
"pc-screen-control": {
"command": "C:/Path/To/python.exe",
"args": ["C:/Users/you/AppData/Local/pc-screen-control/server.py"]
}
}
}
```
需要`uiautomation`;`pillow`仅用于`capture`。服务器在第一次运行安装两者。`python src\server.py --install`在不使用批处理包装器的情况下执行设置。
</details>
---
## 免责声明
**此软件控制您的计算机。** 它可以按按钮,输入,关闭窗口并拖动内容,包括在保存了未保存的工作的应用程序中。
按原样提供,不提供保修 — 请参见`LICENSE`。您负责使用它自动化哪些内容;请在您可以承受损失的内容上进行测试。它收集的数据不发送。恰好有一个工具,`check_for_update`,联网,仅当调用时;其他34个工具不建立任何输出连接。自动化第三方软件可能与该软件的使用条款冲突。 [SECURITY.md](.github/SECURITY.md)有威胁模型。
早期软件,由一个人利用空闲时间编写。没有支持义务,没有服务级别,没有维护保证。
MIT — 请参见 [LICENSE](LICENSE)。 © 2026 NATHAN Development.