desktop-automation-mcp
by loser1727
README.md
# 🖱️ desktop-automation-mcp
**Windows 桌面自动化 MCP 服务:截图 → 视觉定位 → 精确点击 一步闭环**
让任何 MCP 客户端(Pi / Claude / Cursor...)通过 4 个工具控制 Windows 桌面:
精确点击任何坐标、全屏截图、**视觉定位 UI 元素(三阶段校准,±1~5px)**、定位+点击一步完成。
> 零依赖(仅 Node 18+ 内置 API + 可选 sharp),原生解决"注入点击被应用过滤、视觉模型定位不准"两大痛点。
> 视觉模型通过 **config.json / 环境变量** 配置,代码内**不含任何密钥**,可放心上传 GitHub。
---
## ✨ 4 个工具
| 工具 | 功能 |
|---|---|
| `desktop_click(x, y, hold_ms?, times?)` | 鼠标单击指定物理像素坐标(高完整性 + 真人式按压) |
| `desktop_screenshot(path?)` | 全屏截图,返回 PNG 路径 |
| `desktop_locate(target, image_path?, refine?)` | 视觉定位目标元素,返回物理坐标(三阶段校准) |
| `desktop_click_target(target, image_path?)` | **定位 + 点击 一步完成** |
## 🚀 安装
### 1. 克隆
```bash
git clone https://github.com/loser1727/desktop-automation-mcp
cd desktop-automation-mcp
```
### 2. 编译点击工具(可选,仓库已带编译好的 exe)
```bash
cd tools
# Windows 自带 .NET Framework csc(或任意 C# 编译器)
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /nologo /target:exe ^
/out:CursorClick.exe /win32manifest:CursorClick.manifest CursorClick.cs
```
> `CursorClick.exe` 是**自提权**程序(manifest `requireAdministrator`)——点击时自动 UAC 提升
> (需系统 `ConsentPromptBehaviorAdmin=0` 自动批准,或无干扰时手动点"是")。
### 3. 确保 `sharp` 可用(定位裁剪/放大需要)
sharp 一般已随 Pi/其他依赖就绪;若缺,在 server.js 所在目录执行:
```bash
npm install sharp
```
### 4. 配置视觉模型(关键,见下节)
```bash
cp config.example.json config.json # 然后编辑填入你的 baseUrl / apiKey / model
```
### 5. 注册到 MCP(Pi 的 `~/.pi/agent/mcp.json`)
```jsonc
{
"mcpServers": {
"desktop-automation": {
"command": "node",
"args": ["C:\\path\\to\\desktop-automation-mcp\\server.js"]
}
}
}
```
其他 MCP 客户端(Claude Desktop 等)同理放入其 mcp 配置。**重启 Pi/客户端生效。**
---
## ⚙️ 视觉模型配置(换模型超简单)
配置优先级:**环境变量 > `config.json` > 内置默认值**。`config.json` 位于 server.js 同目录,已被 `.gitignore` 忽略(不会泄露密钥)。
### 方式一:config.json(推荐)—— 支持多模型阶梯式自动切换
```json
{
"models": [
{
"name": "智谱 GLM-4V-Flash (免费, 优先)",
"baseUrl": "https://open.bigmodel.cn/api/paas/v4",
"apiKey": "你的智谱密钥",
"model": "glm-4v-flash",
"disableThinking": false
},
{
"name": "火山方舟 Doubao (备用)",
"baseUrl": "https://ark.cn-beijing.volces.com/api/v3",
"apiKey": "ark-你的密钥",
"model": "doubao-seed-2-1-turbo-260628",
"disableThinking": true
}
],
"maxWidth": 1024,
"timeoutMs": 90000,
"retries": 2,
"maxTokens": 500,
"disableThinking": true,
"extraBody": {},
"fineCropWidth": 320,
"fineCropHeight": 240,
"fineZoom": 3,
"ultraCropWidth": 150,
"ultraCropHeight": 110,
"ultraZoom": 6,
"clickExe": ""
}
```
**阶梯式自动切换**:`models` 数组按顺序尝试——第一个失败(网络/HTTP 错误/超时/空响应)自动切第二个,以此类推;全部失败才报错。启动日志会打印当前阶梯:`视觉模型阶梯: A → B → C`。
> 💡 建议把**免费模型放最前面**(如智谱 GLM-4V-Flash),付费/更强模型作后备——零成本优先,挂了再自动升级。
| 字段 | 说明 |
|---|---|
| `models` | 视觉模型阶梯数组(按顺序尝试)。每项可覆盖全局设置:`name`/`baseUrl`/`apiKey`/`model`/`disableThinking`/`timeoutMs`/`retries`/`maxWidth`/`extraBody` |
| `baseUrl` | 任意 **OpenAI 兼容** `/chat/completions` 端点(豆包 Ark、智谱 GLM、Gemini、MiniMax、OpenAI…) |
| `apiKey` | 你的密钥(**只放这里,绝不进代码**) |
| `model` | 视觉模型 ID —— **换模型只改这一行** |
| `maxWidth` | 粗定位输入图最大宽度(默认 1024;越小越快,精度略降) |
| `disableThinking` | `true` 时发送 `{"thinking":{"type":"disabled"}}`(豆包等带思考的模型默认思考极慢,必须关;GLM-4V-Flash 等无此参数会忽略) |
| `extraBody` | 附加请求参数,`Object.assign` 进请求体 —— 适配任何 API 的特殊参数(如 `{"enable_thinking": false}`) |
| `fineCropWidth/Height/zoom`、`ultraCropWidth/Height/zoom` | 细/超细定位的裁剪尺寸与放大倍数 |
| `timeoutMs` / `retries` / `maxTokens` | 单次视觉请求超时、重试次数、最大输出 token |
| `clickExe` | 自定义点击工具路径(默认 `<repo>/tools/CursorClick.exe`) |
> 兼容:不写 `models` 数组时,使用传统单模型字段 `baseUrl/apiKey/model`(等价于一个元素的阶梯)。
### 方式二:环境变量
| 变量 | 说明 |
|---|---|
| `VISION_BASE_URL` | 视觉 API 网关地址(兼容别名 `LITTLEAPI_BASE` / `ARK_BASE`) |
| `VISION_API_KEY` | API 密钥(兼容别名 `LITTLEAPI_KEY` / `ARK_API_KEY`) |
| `VISION_MODEL` | 模型 ID(兼容别名 `LITTLEAPI_VISION_MODEL` / `ARK_VISION_MODEL`) |
| `VISION_MAX_WIDTH` / `VISION_QUALITY` / `VISION_TIMEOUT_MS` / `VISION_RETRIES` / `VISION_MAX_TOKENS` / `VISION_DISABLE_THINKING` | 对应 config 字段 |
| `CLICK_EXE` | 点击工具路径 |
> 兼容性说明:旧的 `LITTLEAPI_*` / `ARK_*` 环境变量继续有效,升级无缝。
---
## 💡 使用示例
### A. 定位一个按钮
```
desktop_locate(target="下载按钮")
→ {"x":1180,"y":341,"method":"ultra(粗→细→超细 6x)"}
```
### B. 定位并点击(一步)
```
desktop_click_target(target="开始游戏")
→ {"located":{"x":700,"y":400,"method":"ultra..."},"click":{"ok":true}}
```
### C. 先截图再人工检查
```
desktop_screenshot() → 返回路径 → 任何工具打开查看
```
## 🔬 工作原理
### 定位:三阶段渐进放大 + 十字校准
视觉模型报"绝对像素坐标"不可靠(后端把图缩放进内部网格,无尺子,误差 100px+),但在**局部放大图**上定位非常准。所以:
```
① 粗定位:全图 → maxWidth(1024)px → 四角红十字校准 → 仿射变换 → ±50px
② 细定位:320×240 裁剪 3× 放大 → 局部十字校准 → ±10px
③ 超细定位:150×110 裁剪 6× 放大 → ±1~5px ✅
```
实测误差(合成 UI):**Cancel (341,306) vs (340,305) / Settings (661,181) vs (660,180) = 1px**
### 点击:高完整性真人式点击
```
CursorClick.exe(自提权 manifest)
→ per-monitor DPI aware(物理像素坐标系,适配 125%/150% 缩放)
→ SetCursorPos 精确定位
→ SendInput DOWN → 保持 120ms(真实按压时长,防止极短按压被 UI 忽略)→ UP
```
解决了两类常见问题:
- **UIPI 权限**:普通权限注入点击被管理员级应用(如 Steam)静默丢弃 → 自提权运行
- **注入过滤**:Steam 等应用会检测 `LLMHF_INJECTED` 过滤合成输入 → 保持时长/多阶段重试提高命中
## 📁 文件结构
```
desktop-automation-mcp/
├── server.js ← MCP 服务本体(零依赖)
├── config.example.json ← 配置模板(含多模型阶梯示例,复制为 config.json 后填写)
├── .gitignore ← 忽略 config.json / 日志(防密钥泄露)
├── tools/
│ ├── CursorClick.cs ← 点击工具源码(C#,可编译)
│ ├── CursorClick.manifest ← 自提权清单(requireAdministrator)
│ └── CursorClick.exe ← 编译好的可执行文件
└── README.md
```
## ⚠️ 注意事项
- 坐标 = **物理像素**:截图尺寸与点击坐标同源,天然一致;DPI 缩放系统下也可直接使用
- 点击前确保目标窗口在前台(SendInput 投递到前台窗口)
- `desktop_click_target` 依赖视觉 API 可用;网络不佳时自动重试(可配置)
- 未配置 API Key 时服务仍可启动(截图/点击可用),但定位会报错——请按上文配置
## 与 pi-vision-locate 扩展的配合
- **pi-vision-locate**(Pi 扩展):聊天内直接识图/定位
- **本项目**(MCP):程序化截图/定位/点击闭环
两者可独立使用,也可组合(扩展定位 → MCP 点击)。
## 📄 License
MIT
TDQS
A3.8/5.0
Scored across 4 tools
Disambiguation5/5
每个工具都有明确且独立的用途:点击坐标、截图、定位元素、组合定位并点击。即使click和click_target有相似性,但一个是精确点击给定坐标,另一个自动定位后点击,描述清晰,不存在混淆。
Naming Consistency5/5
所有工具统一使用desktop_前缀,后接明确的动词(click, screenshot, locate)或动词组合(click_target),命名模式完全一致,易于预测和记忆。
Tool Count5/5
仅有4个工具,但每个工具都覆盖了桌面自动化核心操作:截图、定位、点击、点击目标,没有冗余或遗漏,规模小而精悍,符合最小可用原则。
Completeness2/5
工具集缺少键盘输入、双击、右键、拖动等常见桌面自动化操作,仅覆盖了基本的鼠标左键单击和截图定位,对于完整桌面自动化场景存在明显功能缺口。
Maintenance
ActivitySlowing
ResponsivenessNo issues