mcpField
S
Screen Control

Screen Control

本地服务
github.comAI 与智能体62 天前更新

关于 Screen Control

Screen Control 是面向 AI Agent 的本地电脑控制服务,提供屏幕读取以及鼠标、键盘和窗口操作。它结合 OCR 与图像查看,并在服务端执行安全检查,所有操作均在本机运行。

主要功能

  1. 01通过 OCR 和图像帧读取屏幕
  2. 02实时传输屏幕画面
  3. 03控制鼠标和键盘
  4. 04管理窗口与虚拟桌面
  5. 05执行令牌认证和安全防护
  6. 06通过 HTTP 或 MCP 操作

适用场景

  1. 01让 Agent 查看并操作桌面应用
  2. 02自动执行需要鼠标或键盘输入的任务
  3. 03为支持图像或仅支持文本的模型读取屏幕内容
  4. 04使用本地控制服务,避免数据发送到云端

MCP 相关

Screen Control 除 HTTP API 外,还通过 MCP 接口提供电脑感知与控制能力。它支持 Claude Desktop、Cursor 和 VS Code 等 MCP 客户端。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

暂未收录安装方式

我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。

代码仓库

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

🖥️ 让所有 Agent 都能操作电脑

屏幕控制标志

许可证:MIT 平台 Python CI:安全测试 MCP 已在 mcpservers.org 上架 Glama 质量评分 Agensi 技能市场

面向 AI Agent 的本地远程控制系统:实时查看电脑屏幕,并向电脑发送鼠标/键盘命令。所有操作都在你自己的设备上运行——数据绝不会离开设备,也不经过云端中间服务。

AI Agent 通过屏幕控制 API 在记事本中输入内容

此 GIF 中的每次按键和每张屏幕截图都通过 API 完成——Agent 从未触碰实体键盘。


致 AI Agent

请先阅读 AGENT_GUIDE.md——此文档专为你编写,包含端点、安全防护和实用操作示例。本 README 是面向人类用户的参考文档。

首先询问服务端的信息——GET /api/capabilities → platform。 Windows: 按照指南全文操作。Linux: 检查 echo $XDG_SESSION_TYPE——支持 X11(参阅指南 → Linux(X11)使用说明);不支持 Wayland:服务端会拒绝启动,并返回 HTTP 501 UNSUPPORTED_DISPLAY_SERVER(请切换到 X11 会话)。完整的环境路由说明见 AGENT_GUIDE.md → 先确认你的环境。


为什么选择屏幕控制?

如今的 AI Agent 可以编写代码、调用 API,却无法 看到 或 操作 你的桌面。屏幕控制通过简洁且具备安全防护的 HTTP/MCP 接口,让任何 Agent 都能通用地操作电脑:

  • 感知——通过 OCR 识别文本;获取单帧画面或实时 MJPEG 流,供具备视觉能力的模型使用;还可通过纯文本差异端点,为完全无法处理图像的模型提供信息。
  • 操作——支持绝对和相对鼠标操作、Unicode 安全键盘输入、窗口管理、后台(无需聚焦)控制和虚拟桌面。
  • 保障安全——服务端始终强制执行令牌身份验证、危险快捷键屏蔽、焦点保护、输入卡死监控和紧急故障保护,无论 Agent 多么混乱都不例外。

只需一个进程,无需配置,任何支持 HTTP 的语言均可使用;也可通过 MCP 原生接入 Claude Desktop、Cursor、VS Code 和云端 Agent。

性能受限于 Agent

Screen Control 是感知与执行层——也就是眼睛和双手。 使用它的任何 Agent 的实际速度和能力,都受该 Agent 本身及其运行环境的限制:

  • 思考速度 — 每个 Agent“回合”执行一个动作:感知 → 规划 → 执行 → 验证的循环由 Agent 完成,因此模型推理延迟和推理深度会直接决定节奏。API 本身每次调用只增加几毫秒延迟。
  • 上下文容量 — 屏幕读取内容(OCR 文本、帧、差异)会占用 Agent 的上下文窗口;窗口越大,在验证效果下降前就能掌握更多情境。
  • 运行环境 — 网络延迟、MCP/HTTP 往返开销、工具调用限制和托管约束都会叠加到循环中。

实际情况是:同一个 repo,能让推理速度快的模型表现得又快又强,也会让慢模型表现得很慢——工具链并非瓶颈。 实时或操作密集型任务需要推理速度快、工具循环延迟低的 Agent;速度较慢的 Agent 则应优先处理需要深思熟虑、频繁验证的任务。


目录


功能

功能描述
🖼️ 实时屏幕画面浏览器中持续刷新的屏幕截图
🖱️ 鼠标控制通过实时屏幕截图执行单击、右键单击、双击、滚动、拖放
⌨️ 键盘控制输入文本(支持 Unicode/Turkish,不受键盘布局影响)、按键和快捷键(Ctrl+C、Alt+Tab…)
👁️ OCR将屏幕上的文本转换为机器可读格式
📷 视觉访问面向具备图像处理能力的模型的原始像素路径:单帧、MJPEG 流、基于文本的动作检测
🪟 窗口管理列出、聚焦、安全关闭(WM_CLOSE)、强制结束(类似任务管理器)
🖥️ 免焦点控制通过 PostMessage 读取/写入后台窗口,且不会抢占焦点
🎮 游戏模式通过相对鼠标移动控制视角,按住按键持续移动
🔐 令牌身份验证每个请求都需要 X-Auth-Token(CSRF 防护)
🦺 输入卡住监视器闲置 30 s 后自动释放按住的按键
🛟 故障保护将光标移至左上角即可中止所有命令(游戏模式下禁用)

架构

┌─────────────────────────────────────────────────────────┐
│                    Browser (Web UI)                      │
│  ┌──────────┐  ┌──────────┐  ┌────────────────────────┐ │
│  │  Live     │  │  Control  │  │  Windows / Game Mode   │ │
│  │  View     │  │  Panel    │  │  Panel                 │ │
│  └────┬─────┘  └────┬─────┘  └───────────┬────────────┘ │
│       │              │                     │              │
└───────┼──────────────┼─────────────────────┼──────────────┘
        │              │                     │
        ▼              ▼                     ▼
┌─────────────────────────────────────────────────────────┐
│                  HTTP API (Flask)                        │
│                  127.0.0.1:8745                           │
│                                                         │
│  /api/screenshot    /api/mouse     /api/key              │
│  /api/vision/*      /api/ocr       /api/window           │
│  /api/game          /api/held      /api/release_all      │
│  /api/windows       /api/desktops  /api/desktop          │
│                                                         │
│  ┌─────────────┐  ┌──────────────┐  ┌──────────────┐   │
│  │ Auth Layer  │  │  Watchdog    │  │  OCR Engine  │   │
│  │ (token)     │  │  (30s auto)  │  │  (RapidOCR)  │   │
│  └─────────────┘  └──────────────┘  └──────────────┘   │
└─────────────────────────────────────────────────────────┘
        │              │                     │
        ▼              ▼                     ▼
┌─────────────────────────────────────────────────────────┐
│                  control.py (Core)                        │
│                                                         │
│  Screen:  mss (fast capture), PIL (processing)          │
│  Mouse:   pyautogui (absolute), SendInput (relative)    │
│  Keyboard: pyautogui + SendInput+KEYEVENTF_UNICODE      │
│  Windows: Win32 API (EnumWindows, SetForegroundWindow)   │
│  Background: PrintWindow (capture), PostMessage (input)  │
│  Virtual Desktops: pyvda                                 │
│  Game Mode: ClipCursor + MOUSE_MOVE_RELATIVE             │
└─────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────┐
│              backends/ (pluggable)           │
│  WindowsBackend  │ LinuxBackend │ MacOSBackend│
│      (full)      │    (X11)     │   (stub)   │
└──────────────────────────────────────────────┘
坐标与并发

逐显示器 DPI 感知。 control.py 在导入时调用 SetProcessDpiAwarenessContext(PER_MONITOR_AWARE_V2) —— 早于导入 pyautogui,因为 pyautogui 在导入期间会访问坐标 API, 否则会将进程锁定为解释器清单的默认设置(系统感知)。启用 PMv2 后,系统中的每个坐标 从头到尾都是物理像素:mss 截屏、OCR 边界框、 pyautogui/SendInput 点击、ClipCursor。在高 DPI 显示器(125%/150% 缩放)上,OCR 报告的位置与鼠标点击的位置之间不会出现偏移。

锁架构。 服务使用两个独立的锁,而非一个 全局锁:

锁保护对象端点
_input_lock鼠标、键盘、游戏模式、窗口操作/api/mouse、/api/key、/api/game、/api/window/post、...
_read_lock截屏、OCR、视觉、枚举/api/screenshot、/api/ocr、/api/vision/*、/api/windows、...

缓慢的 OCR(繁忙屏幕上需要 3–5 s)不再会阻塞并发的截屏或 视觉读取 —— 读取排在读取之后,输入排在输入之后。

实时循环工作原理

本系统专为实时感知-行动循环设计,而非预先编写的 命令链:

  1. 读取 — 每次操作前后都通过 OCR 或视觉读取屏幕
  2. 单次操作 — 每轮只发送一条命令
  3. 验证 — 验收标准是“内容出现在屏幕上”,而不是“我已发送命令”
  4. 调整 — 如果验证失败,下一步会根据实际看到的内容进行调整

这一机制由 expect_hwnd 守卫强制执行:如果前台窗口与目标不匹配, 则会拒绝输入(409)。


安装

根据 Agent 的工作方式选择合适的版本:

你是……版本安装
AI Agent 用户(Claude Code、Cursor、支持技能的 Agent)SkillSkill 版本 — 将 skills/computer-use/ 复制到 Agent 的技能文件夹中
支持 MCP 的应用(Claude Desktop、VS Code、云端 Agent)MCPMCP 支持 — 通过 stdio 或 streamable-HTTP 运行 mcp_server.py
开发者 / API 客户端REST本页面 — pip install -r requirements.txt + python server.py
Skill 版本

可移植的 Agent 技能位于 skills/computer-use/ (SKILL.md 加完整的 API 参考)。它会教会任何支持技能的 Agent 感知-行动-验证循环、安全规则和端点目录 — 然后由 Agent 驱动正在运行的服务。

# Claude Code — user-level (available in every project)
cp -r skills/computer-use ~/.claude/skills/

# Claude Code — this project only
mkdir -p .claude/skills && cp -r skills/computer-use .claude/skills/

对于其他支持技能的 Agent,请将该文件夹复制到该 Agent 自己的技能 目录中。无论采用哪种方式,服务都必须正在运行(python server.py)— 技能提供的是操作说明,而非后端。

REST 服务
cd screen-control
pip install -r requirements.txt
要求
软件包用途是否必需?
mss快速截屏✅ 是
pyautogui鼠标/键盘控制✅ 是
pyvda虚拟桌面管理✅ 是
flaskHTTP 服务✅ 是
Pillow图像处理✅ 是
rapidocr-onnxruntimeOCR(屏幕文字读取)⚠️ 可选

注意: OCR 软件包体积较大,安装可能需要一些时间。如果安装 失败,其他功能仍可正常使用 — 只有 OCR 功能不可用。

系统要求
  • 操作系统: Windows 10/11(x64),或 Linux(Ubuntu/Mint 系列,X11 会话 — 参见 Linux(X11))
  • Python: 3.10+
  • 显示器: 任意分辨率;系统会自动适配

Linux(X11)

Linux 支持但有限制(路线图第 5 阶段)— 已在 X11 会话下的 Linux Mint Cinnamon 桌面环境中测试;预计其他 X11 桌面环境也能正常工作。Windows 仍是参考后端。

系统要求
  • 操作系统: Ubuntu / Linux Mint 系列(基于 apt)
  • 会话: X11——先检查:
echo $XDG_SESSION_TYPE    # must print: x11
  • Wayland? 不支持——服务会快速失败,而不是半工作状态 (请参见已知限制)。
  • 系统软件包(由下方的安装脚本安装):
sudo apt install -y xdotool wmctrl imagemagick python3-venv python3-tk python3-dev

xdotool 用于驱动输入和窗口焦点,wmctrl 用于窗口管理,ImageMagick 的 import 用于捕获窗口像素(可选——也提供 mss 区域回退方案), python3-venv 用于创建虚拟环境,python3-dev 允许 evdev (游戏模式)从源代码编译。

一条命令完成设置
cd screen-control
./install-linux.sh

该脚本可重复运行,并按顺序检查:Wayland(清晰提示后退出)、DISPLAY、apt 软件包、.venv 虚拟环境、pip install -r requirements.txt,最后报告游戏模式是否可用。

uinput 权限(游戏模式)

游戏模式会写入 /dev/uinput。使用以下命令验证访问权限:

[ -w /dev/uinput ] && echo "game mode: OK" || echo "game mode: unavailable"

如果无法访问,可采用以下任一修复方式(规范 §5.4):

sudo usermod -aG input $USER        # then log out and back in
# — or a udev rule:
echo 'KERNEL=="uinput", MODE="0660", GROUP="input"' | sudo tee /etc/udev/rules.d/99-uinput.rules
sudo udevadm control --reload && sudo udevadm trigger

除游戏模式外,其他功能均不需要此访问权限。

运行
./start-server.sh
# → same API as Windows: http://127.0.0.1:8745 (X-Auth-Token from .token)
已知限制(Linux X11)
限制详情
仅支持 X11在 Wayland 下,后端会快速失败:ApiError("UNSUPPORTED_DISPLAY_SERVER")(HTTP 501),并且 server.py 会打印该消息并退出,而不会启动服务。修复方法:注销 → 在登录屏幕选择会话 → 选择“Cinnamon on Xorg”。Wayland 支持属于 ROADMAP Phase 6。
后台输入 = 先获取焦点每个 /api/window/post 操作都会先聚焦目标窗口,然后全局发送输入(X11 没有可靠的已投递消息路径)——也就是说会抢占焦点。capabilities.background_input 为 false。
游戏模式下不限制光标X11 无法限制光标;游戏必须自行捕获指针。紧急停止方式:按实体键盘上的 Esc/Alt+Tab,或调用 POST /api/release_all。
不支持虚拟桌面capabilities.virtual_desktops 为 false;GET /api/desktops 和 POST /api/desktop 返回 503。
尚未测试小数缩放验证显示器的缩放比例为 1.0;小数缩放下的坐标尚未验证。
capture_window(窗口捕获)对 client=0 和 client=1 均仅捕获客户区——不会捕获装饰(在 Windows 上,client=0 会包含边框)。安装了 ImageMagick 时使用 import(即使窗口被遮挡,通常也能获取窗口自身的像素);否则回退到使用 mss 截取窗口矩形区域,因此被遮挡的窗口会显示上层窗口的内容。失败时返回 HTTP 409。
窗口几何信息来源rect 来自 xwininfo -root -tree 的绝对边界——即外框/窗口边界(与 Windows GetWindowRect 一致);client_to_screen 使用 xwininfo 的“Absolute upper-left”。
window_hotkey 响应返回 {"ok","vk","vks"};对于热键操作,vk(X11 keysym)仅在 Linux 上存在(Windows 返回 {"ok","vks"})——跨平台代码必须读取 vks。

Agent 提示: OCR 是最慢的读取方式(全屏测得约 5–6 s)。 重复读取时优先使用 /api/vision/frame 或 /api/stream,使用区域 OCR,并在操作之间批量读取——请参见 AGENT_GUIDE.md → Linux (X11) Usage。


快速入门

# 1. Start the server
cd screen-control
python server.py

# 2. Open in browser
#    http://127.0.0.1:8745

# 3. Or control via API
TOKEN=$(cat .token)
curl -H "X-Auth-Token: $TOKEN" http://127.0.0.1:8745/api/screenshot -o screen.jpg

API 参考

功能特性

返回当前后端名称及其支持的功能。Agent 应先调用此接口(多平台计划请参见 ROADMAP.md)。

GET /api/capabilities
→ {"ok": true, "backend": "windows",
   "capabilities": {"screen_capture": true, "game_mode": true, ...}}

功能值:true(支持)、false(不支持)、null(未知——存根后端)、"optional"(取决于可选依赖)。

平台支持矩阵
能力WindowsLinux X11Linux Wayland†macOS
屏幕捕获完整完整取决于 Portal需要权限
OCR完整/可选完整/可选完整/可选完整/可选
鼠标控制完整完整受限需要辅助功能权限
键盘控制完整完整受限需要辅助功能权限
窗口枚举完整取决于 WM有限取决于辅助功能/API
后台输入强优先聚焦(会抢占焦点)通常不可用有限
虚拟桌面支持不支持(503)取决于 DE/WM特定于 Spaces
游戏模式支持实验性有限实验性

Linux X11 已实现并受支持,但存在限制——设置、要求和完整的限制列表见 Linux (X11)。Wayland 会快速失败并返回 UNSUPPORTED_DISPLAY_SERVER(501),而 macOS 仍是默认拒绝的存根:在 ROADMAP 第 7 阶段之前,每项操作都会返回 BACKEND_UNAVAILABLE(501)。Windows 是参考后端。

† Wayland 列仅用于假设性的能力规划——服务不会在 Wayland 上启动(参见上面的说明),因此目前无法使用任何 Wayland 单元格。

身份验证

每个请求都必须包含 X-Auth-Token 标头。令牌会在每次服务启动时生成,并写入 .token。

TOKEN=$(cat .token)
代码含义
401缺少令牌或令牌无效
415POST 请求缺少 Content-Type: application/json

令牌引导(用于捆绑的 Web UI):

GET /token
→ {"ok": true, "token": "abc123..."}

/token 端点是安全的:同源策略会阻止外部页面读取它。


屏幕捕获
GET /api/screenshot

返回 JPEG 屏幕截图。

参数类型默认值描述
monitorint1显示器索引
regionstring—x,y,w,h 子区域
curl -H "X-Auth-Token: $TOKEN" -o screen.jpg http://127.0.0.1:8745/api/screenshot
curl -H "X-Auth-Token: $TOKEN" "http://127.0.0.1:8745/api/screenshot?region=0,0,800,600"
GET /api/info

返回屏幕尺寸和系统状态。

{"ok": true, "width": 1920, "height": 1080, "ocr_available": true,
 "failsafe": true, "game_mode": false}

鼠标控制
POST /api/mouse
action必需参数可选参数描述
movex、yduration(默认值为 0.15)将光标移动到绝对位置
clickx、ybutton(left/right)、clicks(默认值为 1)单击指定位置
scrollclicksx、y滚动滚轮(正数=向上)
dragx1、y1、x、yduration、button在两点之间拖动
downbutton(默认值为 "left")—按住鼠标按钮
upbutton(默认值为 "left")—松开鼠标按钮
# Click at center of screen
curl -X POST http://127.0.0.1:8745/api/mouse -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"action":"click","x":960,"y":540,"button":"left"}'

# Right-click
curl -X POST http://127.0.0.1:8745/api/mouse -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"action":"click","button":"right","x":960,"y":540}'

# Scroll down
curl -X POST http://127.0.0.1:8745/api/mouse -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"action":"scroll","clicks":-3}'

键盘控制
POST /api/key
action必需参数描述
presskey按下并释放按键
downkey按住按键(由看门狗跟踪)
upkey释放按住的按键
hotkeykeys(数组)按键组合(例如 ["ctrl","c"])
typetext输入文本(Unicode,与键盘布局无关)
可选参数默认值描述
expect_hwnd—用于验证焦点的窗口句柄(不匹配时返回 409)
interval0.03type 输入字符之间的延迟
# Press Enter
curl -X POST http://127.0.0.1:8745/api/key -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" -d '{"action":"press","key":"enter"}'

# Ctrl+C
curl -X POST http://127.0.0.1:8745/api/key -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" -d '{"action":"hotkey","keys":["ctrl","c"]}'

# Type text (Turkish characters supported)
curl -X POST http://127.0.0.1:8745/api/key -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" -d '{"action":"type","text":"Merhaba dünya"}'

# Hold W key down (for walking in games)
curl -X POST http://127.0.0.1:8745/api/key -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" -d '{"action":"down","key":"w"}'

OCR(屏幕读取)
POST /api/ocr

将屏幕上的文本转换为机器可读格式。

参数类型默认值描述
regionarray—[x, y, w, h] 子区域(速度更快)
{
  "ok": true,
  "text": "Hello World\nFile Edit View",
  "lines": ["Hello World", "File Edit View"],
  "items": [
    {"text": "Hello World", "x": 960, "y": 40},
    {"text": "File Edit View", "x": 100, "y": 15}
  ]
}
# Full screen OCR
curl -X POST http://127.0.0.1:8745/api/ocr -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" -d '{}'

# Region-only (faster, ~10x for small regions)
curl -X POST http://127.0.0.1:8745/api/ocr -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" -d '{"region":[0,0,800,100]}'

视觉访问(图像模型)

为能够处理图像的模型提供三个端点:

端点描述
GET /api/vision/frame单帧 JPEG(原始格式或 base64)
GET /api/streamMJPEG 实时流
POST /api/vision/diff基于文本的运动检测(无需视觉处理)
GET /api/vision/frame
参数默认值描述
scale1.0缩小比例(0.5 = 一半大小)
gray0设为 1 时转为灰度图
quality80JPEG 质量(20-95)
format—返回 JSON 时设为 base64
region—x,y,w,h 子区域
# Half-size greyscale frame as base64 (for text-only models)
curl "http://127.0.0.1:8745/api/vision/frame?scale=0.5&gray=1&format=base64" \
  -H "X-Auth-Token: $TOKEN"
GET /api/stream

MJPEG 实时流。可放入 <img src>,也可逐帧读取。

参数默认值描述
fps10每秒帧数(1-30)
quality70JPEG 质量
scale1.0缩小比例
region—x,y,w,h 子区域
POST /api/vision/diff

基于文本的运动检测——无需视觉模型。

请求体描述
{}与上次存储的帧进行比较
{"grab":"gray"}存储当前帧以供下次比较
{"b64_prev":"..."}与提供的上一帧进行比较
{
  "ok": true,
  "changed": true,
  "changed_pct": 12.5,
  "bbox": [100, 200, 400, 350],
  "tiles": [
    {"row": 2, "col": 4, "pct": 35.2, "center": [1000, 390]}
  ]
}

窗口管理
GET /api/windows

列出所有可见窗口。

{
  "ok": true,
  "windows": [
    {
      "hwnd": 123456,
      "title": "My Application",
      "process": "app.exe",
      "pid": 7890,
      "focused": true,
      "rect": [0, 0, 1920, 1080],
      "desktop": 1
    }
  ]
}
POST /api/window
操作必填可选描述
focushwnd—将窗口置于前台
closehwndexpect_title、expect_process通过 WM_CLOSE 安全关闭
killhwnd、pid—强制终止(类似任务管理器)
topmosthwnd—设为始终置顶
untopmosthwnd—取消始终置顶
maximizehwnd—最大化窗口
# Focus a window
curl -X POST http://127.0.0.1:8745/api/window -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" -d '{"hwnd":12345,"action":"focus"}'

# Safe close (with title verification)
curl -X POST http://127.0.0.1:8745/api/window -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"action":"close","hwnd":12345,"expect_title":"Notepad"}'

# Kill process
curl -X POST http://127.0.0.1:8745/api/window -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" -d '{"action":"kill","hwnd":12345,"pid":7890}'
POST /api/launch

启动应用、打开 URL 或打开本地文件。app、url、file 三者必须且只能指定一个。绝不会通过 shell 运行:app 是在 PATH 上解析的普通命令名称([A-Za-z0-9._+-]+),url/file 则通过 xdg-open 打开。

字段类型描述
appstring命令名称;必须存在于 PATH 中(否则返回 400)
urlstringscheme://...(例如 https://、steam://)
filestring现有文件的绝对路径
argslist仅用于 app 的参数
expect_titlestring同时等待标题包含此内容的窗口
timeoutnumber等待 expect_title:默认 10,最长 30 秒
{"ok": true, "pid": 4321, "window": {"hwnd": ..., "title": "..."}}

设置 expect_title 后,window 为匹配到的窗口或 null(启动成功,但窗口尚未出现)——无论哪种情况,HTTP 状态码均为 200。

curl -X POST http://127.0.0.1:8745/api/launch -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"app":"firefox","expect_title":"Mozilla Firefox","timeout":15}'
GET /api/window/wait

阻塞等待标题包含 title(不区分大小写的子字符串)的窗口出现,然后返回该窗口。timeout 默认 10 秒,最长 30 秒;找到窗口时返回 200,超时则返回 408 OPERATION_TIMEOUT。

curl -H "X-Auth-Token: $TOKEN" \
  "http://127.0.0.1:8745/api/window/wait?title=Notepad&timeout=10"

无需切换焦点(后台)控制

无需窃取焦点即可读取和控制窗口——用户可以继续在主桌面上工作。

Linux(X11)说明:后台控制采用先切换焦点的方式——先聚焦目标窗口,再向全局发送输入(会窃取焦点)。 只有后台捕获真正无需切换焦点。请参阅 已知限制。

GET /api/window/capture

通过 PrintWindow 捕获窗口(即使窗口位于其他虚拟桌面也有效)。

参数描述
hwnd(必填)窗口句柄
client1 = 仅捕获客户区
ocr1 = 返回 OCR 文本而非图像
# Capture window as PNG
curl "http://127.0.0.1:8745/api/window/capture?hwnd=12345" \
  -H "X-Auth-Token: $TOKEN" -o window.png

# Capture + OCR in one call
curl "http://127.0.0.1:8745/api/window/capture?hwnd=12345&ocr=1" \
  -H "X-Auth-Token: $TOKEN"
POST /api/window/post

向窗口发送输入,并自动选择传递路径。

actionDescription
type输入文本(支持 Unicode)
key发送按键
hotkey发送组合键
click在客户端坐标处单击
scroll滚动窗口
drag在窗口内拖动

可选的 mode 参数控制路由:

modeBehavior
auto(默认)由输入模式探测决定(见下文)
background强制使用 PostMessage 路径(窗口保持焦点和 Z 序)
focused强制使用聚焦 + SendInput 路径
# Type into a background Notepad
curl -X POST http://127.0.0.1:8745/api/window/post -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"hwnd":12345,"action":"type","text":"Hello from background!"}'

路由规则(mode=auto):

  • postmessage — 传统 Win32 应用:在后台使用 PostMessage,不改变焦点。
  • uia — WinUI/UWP/XAML 界面(单个 DirectX 画布,没有 Win32 子控件):投递的消息会被静默丢弃,因此窗口会获得焦点,并通过 SendInput 重放操作(将客户端坐标转换为屏幕坐标)。这是现代应用中有文档说明的回退方式。
  • focused — 窗口已处于前台:使用聚焦的 SendInput 路径。
  • invalid — HTTP 409;不是可访问的顶层窗口。
GET /api/window/input-mode

在向窗口发送输入前,判断窗口接收输入的方式。返回以下值之一: focused | postmessage | uia | invalid。

curl "http://127.0.0.1:8745/api/window/input-mode?hwnd=12345" \
  -H "X-Auth-Token: $TOKEN"

**WinUI 说明:**新版记事本(以及其他由 XAML 承载的应用)没有可供发送消息的传统子级 Edit 控件——整个 UI 是一个 DirectX 界面。 对于这些应用,input-mode 会返回 uia;随后 /api/window/post 会自动使用聚焦的 SendInput 路径。对于具有真实子控件的传统应用,/api/window/children 仍然很有用。

GET /api/window/children

列出窗口的子控件(类名 + 标题 + hwnd)。

curl "http://127.0.0.1:8745/api/window/children?hwnd=12345" -H "X-Auth-Token: $TOKEN"

虚拟桌面
GET /api/desktops

列出所有虚拟桌面。

POST /api/desktop
actionParamsDescription
switchnumber切换到桌面 N
create—创建新的桌面
curl http://127.0.0.1:8745/api/desktops -H "X-Auth-Token: $TOKEN"

curl -X POST http://127.0.0.1:8745/api/desktop -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" -d '{"action":"switch","number":2}'

游戏模式
actionParamsDescription
startsensitivity(默认 12)将光标锁定在中心,启用游戏输入
movedx、dy、sensitivity旋转摄像机(相对鼠标)
stop—释放光标 + 所有按住的输入
heartbeat—长时间按住时保持连接
# Start game mode
curl -X POST http://127.0.0.1:8745/api/game -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" -d '{"action":"start","sensitivity":12}'

# Look right
curl -X POST http://127.0.0.1:8745/api/game -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" -d '{"action":"move","dx":50,"dy":0}'

# Hold W to walk forward
curl -X POST http://127.0.0.1:8745/api/key -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" -d '{"action":"down","key":"w"}'

# ... later ...
curl -X POST http://127.0.0.1:8745/api/key -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" -d '{"action":"up","key":"w"}'

# Stop game mode
curl -X POST http://127.0.0.1:8745/api/game -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" -d '{"action":"stop"}'

安全端点
GET /api/held

返回当前按住的按键/按钮以及看门狗状态。

{
  "ok": true,
  "keys": ["w", "shift"],
  "buttons": ["left"],
  "game_mode": true,
  "idle_seconds": 5.2,
  "watchdog_count": 0,
  "last_watchdog": null
}
POST /api/release_all

紧急操作:释放所有内容(按住的按键、鼠标按钮、游戏模式光标锁定)。

curl -X POST http://127.0.0.1:8745/api/release_all -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" -d '{}'


🤖 面向 AI Agent

为 AI Agent(大模型、视觉模型、自动化框架)提供的专用综合指南见 AGENT_GUIDE.md。

更愿意将其作为技能加载,而不是浏览文档?请安装技能版本。

内容包括:

  • 环境路由——先识别 Windows 还是 Linux(X11/Wayland)
  • 感知-行动循环(读取 → 规划 → 执行 → 验证)
  • 焦点保护(expect_hwnd),防止误操作错误窗口
  • 应用自动化和游戏控制工作流
  • Linux(X11)用法:慢速 OCR 批处理、捕获语义、游戏模式注意事项
  • 面向支持图像的模型提供视觉访问
  • 基于文本的运动检测
  • 带宽优化
  • 完整的 curl 示例

MCP 支持(一键式云端 Agent)

Model Context Protocol(MCP) 将此项目变为即插即用的工具箱,适用于任何支持 MCP 的 Agent:Claude Desktop、Claude Code、Cursor、VS Code Copilot Agent 模式、自定义云端 Agent——无需自定义粘合代码,也无需 curl 脚本。Agent 可原生发现并调用这些工具。

工作原理
MCP agent (cloud or desktop)
        │  MCP protocol (stdio or streamable-HTTP)
        ▼
  mcp_server.py   ← thin wrapper: tools → HTTP calls, token auto-read
        │  REST + X-Auth-Token (localhost only)
        ▼
  server.py       ← the single source of truth:
                    auth, locks, watchdog, focus guard, all safety rules

mcp_server.py 不会增加任何新功能——所有安全机制(身份验证令牌、输入/读取锁、看门狗、Alt+F4 拦截、焦点保护、故障保护)仍由 server.py 强制执行。

设置
pip install mcp            # optional dependency (see requirements.txt)
python server.py           # start the REST server first (it writes .token)

MCP 服务会自动从 .token(或 SCREEN_CONTROL_TOKEN 环境变量)读取令牌——无需任何配置。

桌面 Agent(stdio 传输)

Claude Desktop — claude_desktop_config.json:

{
  "mcpServers": {
    "screen-control": {
      "command": "python",
      "args": ["C:/path/to/screen-control/mcp_server.py"]
    }
  }
}

Claude Code:claude mcp add screen-control -- python C:/path/to/screen-control/mcp_server.py

Cursor / VS Code:将相同条目添加到其 MCP 配置文件中。

远程 / 云端 Agent(streamable-HTTP 传输)
python mcp_server.py --http --port 8751
# MCP endpoint: http://127.0.0.1:8751/mcp

HTTP 传输受令牌保护:每个请求都必须携带 X-Auth-Token 请求头(与 REST 服务使用相同的令牌)。查询字符串令牌 (?token=...)会被有意拒绝——URL 会泄露到代理 / 隧道 日志、浏览器历史记录和共享链接中,而且此令牌授予完整的桌面控制权限。 无法发送自定义请求头的客户端应改为运行本地 stdio mcp_server.py。只有 GET /health 是开放的,用于存活探测。 此传输有意禁用了 DNS 重绑定防护——隧道请求会携带外部的 Host 请求头, 而令牌防护已足以应对重绑定威胁。

对于云端 Agent,可通过隧道公开服务:

cloudflared tunnel --url http://127.0.0.1:8751
# → prints a https://<random>.trycloudflare.com URL

然后,将 Agent 的 MCP 连接配置为 <tunnel-url>/mcp,并将 .token 中的令牌作为请求头(X-Auth-Token)传入。

无请求头的连接器(受限密钥)

对于无法发送自定义请求头的客户端(例如只能填写端点 URL 的 Web 连接器),请创建一个受限 API 密钥——一种持久且可设置时限的凭据——并将其嵌入 URL 路径中:

# Create a 24-hour scoped key (requires the server to be running)
curl -X POST http://127.0.0.1:8745/api/keys -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"action":"create","name":"spark","expires_in_hours":24}'

# Connector endpoint becomes:
#   https://<tunnel-url>/mcp/<scoped-key>

设计保证(SC-06):

  • 主会话令牌不得用于 URL(403)——只有受限密钥 可以放在 URL 中
  • 受限密钥会自动过期;过期的密钥无法通过任何身份验证
  • 可随时通过 POST /api/keys ({"action":"revoke","name":"spark"}) 按名称撤销受限密钥——撤销会 立即在所有端点生效
  • .apikeys 文件只存储 SHA-256 哈希,绝不存储原始密钥

⚠️ 隧道会将 PC 控制权限暴露给互联网。请妥善保管令牌, 对于无请求头的连接器,优先使用短时隧道和受限密钥, 并在不使用时停止服务。

一键启动(启动器 + 自动隧道)

start-server.bat 会自动完成整个云端配置,并打印云端 Agent 所需的所有内容,可直接复制粘贴:

  1. 如果缺少 cloudflared.exe,则下载该文件(便携版,无需管理员权限)
  2. 停止上次运行遗留的实例
  3. 启动 REST 服务(端口 8745)和 MCP HTTP 服务(端口 8751)
  4. 等待两个服务均健康运行(探测 /token 和 /health)
  5. 启动 cloudflared 快速隧道,从 tunnel.log 中提取其公共 URL,并打印摘要:
 ============================================================
  ALL SYSTEMS RUNNING
 ============================================================
  Local REST API  : http://127.0.0.1:8745
  Local MCP       : http://127.0.0.1:8751/mcp
  Public MCP URL  : https://<random>.trycloudflare.com/mcp

  ------------------------------------------------------------
  PASTE INTO YOUR CLOUD AGENT  (MCP connector settings)
  ------------------------------------------------------------
  Endpoint : https://<random>.trycloudflare.com/mcp
  Header   : X-Auth-Token: <token>
  URL form : https://<random>.trycloudflare.com/mcp?token=<token>
             (only if the connector cannot send headers)
  ------------------------------------------------------------

stop-server.bat 会一次性停止所有三个服务(REST、MCP、隧道)。

可用工具(16 个)
类别工具
感知get_info、ocr_screen、screenshot(为视觉模型提供真实图像块)、motion_diff
鼠标 / 键盘mouse、keyboard(带 expect_hwnd)、get_held、release_all
Windowslist_windows、focus_window、window_children、window_input_mode、window_post、window_capture_ocr、close_window
游戏模式game(启动 / 移动 / 停止 / 心跳)
适用传输方式
使用方传输方式命令
Claude Desktop / Cursor / VS Code(本地)stdiopython mcp_server.py
Claude Codestdioclaude mcp add ...(如上)
云端 / 远程 Agentstreamable-HTTPstart-server.bat(推荐),或 python mcp_server.py --http --port 8751 + cloudflared tunnel --url http://127.0.0.1:8751

注意: 此项目面向 MCP Python SDK 2.x(MCPServer API)。 使用 SDK 1.x 时,将导入语句替换为 from mcp.server.fastmcp import FastMCP, Image, 并将 MCPServer 替换为 FastMCP。


安全模型

威胁:恶意网页(CSRF)

即使绑定到 127.0.0.1,浏览器中的恶意页面仍可向本地主机发送无需预检的请求(text/plain fetch、HTML 表单 POST)。 浏览器会阻止响应,但不会阻止请求——服务器仍会执行命令。

**缓解措施:**每个请求都必须包含 X-Auth-Token。外部网页无法读取此令牌(同源策略),因此无法通过身份验证。

其他防护层:

  • POST 请求必须使用 Content-Type: application/json(否则返回 415)
  • 即使令牌泄露,也能阻止表单编码和 text/plain POST 请求
  • **Host 标头信任(DNS 重绑定):**绑定到环回地址时,会拒绝带有非环回 Host 标头的请求,并返回 421——将域名解析到 127.0.0.1 的重绑定网页无法读取 /token 或调用 API
  • /token 和 / 的响应带有 Cache-Control: no-store,因此浏览器或代理不会持久保存凭据
威胁:按键卡住/游戏模式锁定

在游戏模式下,ClipCursor 会将光标固定在 2×2 的区域内——经典的 pyautogui 故障保护(将光标移到左上角)不起作用。

缓解措施:

  1. 实体 Esc/Alt+Tab——真实硬件输入;此 API 无法阻止,且始终有效
  2. POST /api/release_all——立即释放所有输入
  3. 看门狗(自动)——服务器端检测到输入按住期间 30 s 无活动时,会触发自动释放
威胁:在错误窗口中输入

缓解措施:

  • /api/key 上的 expect_hwnd 防护——如果前台窗口不匹配,则拒绝输入并返回 409
  • /api/window/post 的聚焦路径会在切换焦点之后、发送任何模拟输入之前验证焦点(不匹配时返回 409)——绝不会将输入重放到恰好处于前台的窗口
  • focus_window() 失败时会引发错误,而不是静默返回
威胁:危险按键组合

缓解措施:在 API 层通过所有输入路径进行拦截(403)——直接的 /api/key 路由、后台 /api/window/post 路由(PostMessage)以及聚焦回退路径共用同一套安全策略(control._assert_allowed):

  • Alt+F4——唯一禁止的 Alt 组合(Alt+Tab、Alt+菜单键均为合法操作)
  • Win 键——防止打开“开始”菜单和切换任务
  • Ctrl+Alt+Del——系统安全屏幕
  • 类似 Shift+Delete 的组合——防止永久删除
威胁:终止系统进程

缓解措施:

  • 直接根据 PID 确定进程名称(Win32 toolhelp 快照),而不是从可见窗口列表中查找——无窗口/后台系统进程也能获得与可见进程同等的保护
  • 将关键系统进程列入黑名单(对未知 PID 默认拒绝):winlogon.exe、csrss.exe、smss.exe、services.exe、lsass.exe、svchost.exe、system、registry、dwm.exe
  • 可选的 expect_process 确认:不匹配时会中止终止操作并返回 409——防止误杀刚被重新分配的 PID
威胁:资源耗尽(恶意 Agent/DoS)

持有令牌但行为异常的客户端不应能够耗尽内存或占用输入锁。

缓解措施:

  • MAX_CONTENT_LENGTH = 1 MB——拒绝过大的请求正文(413)
  • 限制 region 的宽度、高度和面积以及 scale(否则返回 400)
  • 每次输入调用的 text 载荷上限为 10,000 个字符
  • MJPEG 流最多允许 10 个并发客户端(超过时返回 429)
  • 为客户端提供的图像设置 Pillow 解压缩炸弹限制
网络访问

服务器默认绑定到 127.0.0.1。要将其开放到网络:

python server.py --host 0.0.0.0  # ⚠️ anyone on the network can control this machine

游戏模式指南

设置
# 1. Focus the game window
curl -X POST http://127.0.0.1:8745/api/window -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" -d '{"hwnd":GAME_HWND,"action":"focus"}'

# 2. Start game mode
curl -X POST http://127.0.0.1:8745/api/game -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" -d '{"action":"start","sensitivity":12}'
摄像机视角
# Look right
curl -X POST http://127.0.0.1:8745/api/game -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" -d '{"action":"move","dx":50,"dy":0}'

# Look down
curl -X POST http://127.0.0.1:8745/api/game -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" -d '{"action":"move","dx":0,"dy":30}'
移动
# Walk forward (hold W)
curl -X POST http://127.0.0.1:8745/api/key -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" -d '{"action":"down","key":"w"}'

# ... walk for a while ...

# Release W
curl -X POST http://127.0.0.1:8745/api/key -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" -d '{"action":"up","key":"w"}'
Minecraft 专用
# Place block (right-click)
curl -X POST http://127.0.0.1:8745/api/mouse -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"action":"click","button":"right","x":960,"y":540}'

# Break block (hold left-click)
curl -X POST http://127.0.0.1:8745/api/mouse -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" -d '{"action":"down","button":"left"}'

# ... after breaking ...

curl -X POST http://127.0.0.1:8745/api/mouse -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" -d '{"action":"up","button":"left"}'

# Select hotbar slot
curl -X POST http://127.0.0.1:8745/api/key -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" -d '{"action":"press","key":"1"}'

# Open inventory
curl -X POST http://127.0.0.1:8745/api/key -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" -d '{"action":"press","key":"e"}'
适用性
游戏类型适用?备注
Minecraft(建造)✅ 是放置方块、行走、挖掘
Minecraft(PvP)❌ 否对快速战斗来说太慢
回合制游戏✅ 是有充足时间进行读取→行动→验证
RPG / 冒险游戏✅ 是物品栏、对话、探索
快节奏 FPS❌ 否反应速度不足
解谜游戏✅ 是基于点击,阅读内容较多

视觉访问指南

适用于支持图像的模型

如果使用的模型可以处理图像,请直接使用视觉端点:

GET /api/vision/frame?scale=0.5&gray=1&quality=70

此端点会返回单张 JPEG,供模型分析以下内容:

  • 游戏 HUD 元素(生命值、法力值、物品栏)
  • 屏幕上的文字(菜单、聊天、工具提示)
  • 视觉场景理解(方块、实体、地形)
适用于纯文本模型

使用差异端点进行动作检测,无需视觉能力:

POST /api/vision/diff {"grab":"gray"}   → first call: stores frame
POST /api/vision/diff                    → subsequent calls: returns diff

响应会告知你哪些位置发生了变化(图块坐标)以及变化了多少(百分比),足以用于:

  • 检测某项操作是否产生了效果
  • 定位屏幕上移动的元素
  • 跟踪动画状态变化
带宽优化
方式负载使用场景
scale=1.0, gray=0~500 KB完整细节
scale=0.5, gray=1~50 KB适用于大多数视觉模型
scale=0.25, gray=1~10 KB最大程度压缩
diff(文本)~1 KB纯文本 Agent
region=...不定聚焦特定区域

故障排查

“未安装 OCR 引擎”
pip install rapidocr-onnxruntime
服务无法启动(端口已被占用)
# Find the process using port 8745
netstat -ano | findstr ":8745"

# Kill it
taskkill /PID <pid> /F
输入时出现“焦点不匹配”(409)

在调用焦点接口和输入接口之间,前台窗口发生了变化。 解决方法:始终传入 expect_hwnd,并在输入前验证焦点。

未找到窗口

窗口可能已关闭,也可能是 EnumWindows 不会公开的系统窗口。尝试:

curl http://127.0.0.1:8745/api/windows -H "X-Auth-Token: $TOKEN"
游戏模式下光标卡住

使用 POST /api/release_all,或在实体键盘上按 Esc / Alt+Tab。

OCR 延迟过高

对完整的 1920×1080 屏幕进行 OCR 可能需要几秒到约 30 秒,具体取决于 CPU 和屏幕内容的复杂程度。请使用区域截图——小范围裁剪通常快 10 倍:

{"region": [0, 0, 800, 100]}
土耳其语字符未显示

系统使用 SendInput + KEYEVENTF_UNICODE,与键盘布局无关。 如果字符仍未显示,目标应用可能不支持 Unicode 输入——请改用 POST /api/window/post,并将 action: "type" 作为操作。

Linux:服务立即退出,并提示“检测到 Wayland 显示服务器”

在 Wayland 会话中这是预期行为——后端会快速失败并返回 UNSUPPORTED_DISPLAY_SERVER(501),而不是进入半可用状态。请注销,在登录屏幕选择 X11 会话(“Cinnamon on Xorg”),然后重新启动服务。参见 Linux(X11)。

Linux:“未安装 xdotool 或其不在 PATH 中”(501)

缺少 X11 辅助工具。请安装这些工具(或重新运行安装程序):

sudo apt install xdotool wmctrl

项目结构

screen-control/
├── server.py            # Flask HTTP server + all API endpoints
├── core/                # PlatformBackend interface + standardized errors
│   ├── backends.py      # Abstract backend + lazy discovery
│   └── errors.py        # ApiError envelope + error codes
├── backends/            # OS implementations behind PlatformBackend
│   ├── windows.py       # Reference backend (moved from control.py)
│   ├── linux.py         # X11 backend: xdotool/wmctrl + mss + uinput (Phase 5)
│   ├── imageops.py      # Shared PIL helpers (frame diff, JPEG, scaling)
│   ├── uinput.py        # Virtual input device for Linux game mode
│   ├── macos.py         # Fail-closed stub (ROADMAP Phase 7)
│   ├── fake.py          # In-memory backend for tests
│   └── forbidden.py     # Shared blocked-key policy
├── control.py           # Compatibility shim re-exporting backends.windows
├── tests/unit/          # Offline unit + integration tests (no real input)
├── mcp_server.py        # MCP server (stdio + streamable-HTTP) — thin wrapper over the API
├── sdk/
│   └── screen_control.py  # Python SDK client (pip-installable style)
├── index.html           # Bundled web UI (live view + control panels)
├── docs/images/         # README assets (demo GIF captured by the API itself)
├── requirements.txt     # Python dependencies
├── start-server.bat     # One command: REST + MCP + cloud tunnel (Windows)
├── stop-server.bat      # Stop all three processes
├── install-linux.sh     # One-command Linux setup (apt, venv, uinput check)
├── start-server.sh      # Linux launcher (.venv/bin/python server.py)
├── test-security.py     # Security + game-mode test suite (34 checks)
├── test-linux.py        # Live Linux X11 acceptance suite (7 items)
├── test-game.py         # Live game-mechanics test (app launch → draw → safe close)
├── test-endtoend.py     # End-to-end test: open Notepad → type → save → verify
├── .github/workflows/   # CI: runs the security suite on every push
├── AGENT_GUIDE.md       # AI agent integration guide (separate from this file)
├── README.md            # This file
└── .token               # Auto-generated auth token (gitignored)

测试

前置条件

服务必须处于运行状态:

cd screen-control
python server.py
安全测试套件

测试身份验证、被阻止的按键组合、窗口管理、安全关闭、关键进程保护和游戏模式;所有测试均不会造成破坏。

cd screen-control
python test-security.py

预期输出:

== Token Authentication ==
✓ Missing token -> 401
✓ Wrong token -> 401
✓ Correct token -> 200
✓ Non-JSON POST -> 415

== Blocked Key Combos ==
✓ Alt+F4 blocked (403)
✓ Win key blocked (403)
✓ Win+D blocked (403)
✓ Delete blocked (403)

== Window List ==
✓ Windows list requires GET
✓ Window list is non-empty  — 8 windows
✓ Exactly one focused window

== Safe Close Verification ==
✓ Wrong title aborts close

== Critical Process Protection ==
✓ System process (pid 4) rejected (403)
✓ pid 0 rejected (403)

== Game Mode ==
✓ Game mode started
✓ Relative camera look
✓ Game mode stopped

== Watchdog (dry run) ==
✓ Held state returns ok
✓ Watchdog count reported

========================================
RESULT: 19 passed, 0 failed
实时游戏机制测试

启动一个真实应用(mspaint 或 notepad),执行按住绘制的游戏机制,通过像素分析进行验证,然后安全关闭应用,并处理“不要保存”对话框。

cd screen-control
python test-game.py

**注意:**此测试会启动一个真实应用。它会自动清理(发送 WM_CLOSE,并在出现对话框时点击“不要保存”)。

Linux 实时验收测试(仅限 Linux X11)

对 Linux 后端进行七项实时检查:鼠标移动/点击、输入文字 + 热键、屏幕截图、OCR、窗口列表/焦点、游戏模式(uinput),以及原生游戏项目(显示为 SKIP——未安装 Linux 游戏)。需要正在运行的服务和真实的 X11 会话;每个辅助窗口都有唯一的 pid,且只会聚焦或点击这些窗口。

cd screen-control
./start-server.sh &              # server must be running
.venv/bin/python test-linux.py   # → "RESULT: 6 passed, 0 failed"; item 7 prints SKIP

贡献

  1. Fork 此仓库
  2. 创建功能分支
  3. 进行更改
  4. 在 Windows 机器上测试
  5. 提交拉取请求
代码风格
  • Python: 遵循 PEP 8,使用类型提示,为所有公共函数编写文档字符串
  • 文档字符串: 使用英文,遵循 Google 风格
  • 错误消息: 使用英文,描述清晰
  • 注释: 使用英文,解释为什么,而不是是什么

许可证

MIT 许可证。详情请参阅 LICENSE。


为本地自动化和 AI Agent 研究倾心打造。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。