
Screen Control
io.github.Xeakaes由 GitHub 账号 Xeakaes 发布v1.0.0更新于 Oct 26, 2026
Safety-gated computer use for AI agents: screen OCR and vision, mouse, keyboard, window control.
概览
本地 MCP 服务器,让助手全面操控桌面:截图、OCR、鼠标、键盘、窗口与应用控制,并带安全限制。
- 可以做什么
- 截取整屏或单个窗口,输出图片、MJPEG 流或 base64 帧,并检测帧间画面变化
- 用 OCR 读取屏幕文字,可整屏或指定区域
- 移动、点击、滚动、拖拽鼠标,输入文字或发送按键与快捷键
- 列出、聚焦、关闭、强制结束、最大化和截取窗口,并启动应用、网址或本地文件
- 向后台窗口发送输入、管理虚拟桌面,以及使用相对鼠标的游戏模式
- 紧急释放所有按住的按键和鼠标按钮,配有看门狗与角落失效保护
- 适用场景
- 当助手需要直接操作 Windows 或 Linux X11 桌面时使用:例如填写没有 API 的图形界面程序、读取屏幕上的文字,或用鼠标键盘驱动浏览器和游戏。不适合无头服务器或 macOS,后者只是返回失败的空壳后端。
- 运行要求
- 作为本地进程运行。需先启动 REST 后端(Python 3.10+,pip 包 mss、pyautogui、pyvda、flask、Pillow;OCR 可选 rapidocr-onnxruntime)。系统需 Windows 10/11,或使用 X11 会话的 Linux(不支持 Wayland);macOS 为占位实现。Linux 还需 xdotool、wmctrl、ImageMagick,游戏模式需 /dev/uinput 权限。请求必须带 X-Auth-Token 头,令牌从 .token 文件或 SCREEN_CONTROL_TOKEN 环境变量读取。
安装
在 SourceWeft 中
- 打开 控制台中的 Screen Control,将其添加到工作区。
- 为需要使用其工具的对话启用该服务。
Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。
其他 MCP 客户端
参照 仓库 中的启动说明。
README
🖥️ Computer use for all agents
[License: MIT] [Platform] [Python] [CI: security tests] [MCP] [Listed on mcpservers.org] [Glama quality score] [Agensi skill marketplace]
A local remote-control system for AI agents: watch your computer's screen live and send mouse/keyboard commands to it. Everything runs on your own machine — no data ever leaves it, no cloud middleman.
[An AI agent typing into Notepad through the screen-control API]
Every keystroke and every screenshot in this GIF went through the API — the agent never touched a physical keyboard.
If You Are an AI Agent
Read AGENT_GUIDE.md first — it is written for you: endpoints, safety gates and working recipes. This README is the human-facing reference.
First ask the server what it is — GET /api/capabilities → platform.
Windows: follow the whole guide as written. Linux: check
echo $XDG_SESSION_TYPE — X11 is supported (guide →
Linux (X11) Usage); Wayland is
unsupported: the server refuses to start, HTTP 501
UNSUPPORTED_DISPLAY_SERVER (switch to an X11 session). Full routing lives
in AGENT_GUIDE.md → Find Your Environment First.
Why Screen Control?
AI agents today can write code and call APIs — but they can't see or touch your desktop. Screen Control gives any agent general-purpose computer use over a clean, safety-gated HTTP/MCP interface:
- Perceive — OCR for text, single frames or a live MJPEG stream for vision-capable models, and a text-only diff endpoint for models that can't consume images at all.
- Act — absolute and relative mouse, Unicode-safe keyboard, window management, background (focus-free) control, virtual desktops.
- Stay safe — token auth, blocked deadly shortcuts, focus guard, a stuck-input watchdog and an emergency failsafe are all enforced server-side, no matter how confused the agent gets.
One process, zero configuration, works with any language that can speak HTTP — or natively through MCP in Claude Desktop, Cursor, VS Code and cloud agents.
Performance Is Agent-Bound
Screen Control is the perception and actuation layer — the eyes and hands. The effective speed and capability of any agent using it are bounded by that agent itself and by the environment it runs in:
- Thinking speed — one action per agent "turn": the perceive → plan → act → verify loop lives in the agent, so model inference latency and reasoning depth directly set the pace. The API itself adds only milliseconds per call.
- Context capacity — screen readings (OCR text, frames, diffs) consume the agent's context window; a larger window means more situational awareness before verification degrades.
- Runtime environment — network latency, MCP/HTTP round-trip overhead, tool-call limits and hosting constraints all stack on top of the loop.
In practice this means: the same repo makes a fast reasoning model fast and capable, and makes a slow model slow — the toolchain is not the bottleneck. Real-time or action-heavy tasks need an agent with fast inference and tight tool-loop latency; slower agents should prefer deliberate, verification-heavy tasks.
Table of Contents
- If You Are an AI Agent
- Why Screen Control?
- Features
- Architecture
- Installation
- Linux (X11)
- Quick Start
- API Reference
- 🤖 For AI Agents
- MCP Support (One-Click Cloud Agents)
- Security Model
- Game Mode Guide
- Vision Access Guide
- Troubleshooting
- Testing
- Contributing
- License
Features
Architecture
Coordinates & Concurrency
Per-Monitor DPI awareness. control.py calls
SetProcessDpiAwarenessContext(PER_MONITOR_AWARE_V2) at import time —
before the pyautogui import, because pyautogui touches coordinate APIs
during import and would otherwise lock the process to the interpreter
manifest's default (system-aware). With PMv2 active, every coordinate in the
system is a physical pixel end to end: mss capture, OCR bounding boxes,
pyautogui/SendInput clicks, ClipCursor. On High-DPI displays (125%/150%
scaling) nothing drifts between what OCR reports and where the mouse clicks.
Lock architecture. The server uses two independent locks instead of one global lock:
A slow OCR (3–5 s on a busy screen) no longer freezes concurrent screenshot or vision reads — reads queue behind reads, inputs behind inputs.
Live-Loop Working Principle
This system is designed for a live perceive-act loop, not pre-written command chains:
- READ — OCR or vision reads the screen before and after every action
- ONE ACTION — each round sends a single command
- VERIFY — acceptance is "it appeared on screen", not "I sent it"
- ADAPT — if verification fails, the next step changes based on what is actually seen
This is enforced by the expect_hwnd guard: typing is refused (409) if
the foreground window doesn't match the target.
Installation
Pick the version that fits how your agent works:
Skill version
The portable agent skill lives in skills/computer-use/
(SKILL.md plus a full API reference). It teaches any skills-capable agent
the perceive-act-verify loop, the safety rules and the endpoint catalogue —
the agent then drives a running server.
For other skill-capable agents, copy the folder into that agent's own skills
directory. Either way the server must be running (python server.py) —
the skill provides instructions, not a backend.
REST server
Requirements
Note: The OCR package is large and may take a while to install. If it fails, everything else still works — only the OCR feature is unavailable.
System Requirements
- OS: Windows 10/11 (x64), or Linux (Ubuntu/Mint family, X11 session — see Linux (X11))
- Python: 3.10+
- Display: Any resolution; the system adapts automatically
Linux (X11)
Linux is supported with limits (ROADMAP Phase 5) — tested on Linux Mint with Cinnamon in an X11 session; other X11 desktop environments are expected to work. Windows remains the reference backend.
Requirements
- OS: Ubuntu / Linux Mint family (apt-based)
- Session: X11 — check this first:
- Wayland? Not supported — the server fails fast instead of half-working (see Known limitations).
- System packages (installed by the setup script below):
xdotool drives input/focus, wmctrl window management, ImageMagick's
import captures window pixels (optional — an mss region fallback exists),
python3-venv creates the virtualenv and python3-dev lets evdev
(game mode) compile from source.
One-command setup
The script is idempotent and checks, in order: Wayland (exits with a clear
message), DISPLAY, the apt packages, the .venv virtualenv,
pip install -r requirements.txt, and finally reports whether game mode can
work.
uinput permissions (game mode)
Game mode writes to /dev/uinput. Verify access with:
If it is unavailable, either remediation works (spec §5.4):
Everything except game mode works without this access.
Run
Known limitations (Linux X11)
Agent note: OCR is the slowest read (≈5–6 s full-screen measured). Prefer
/api/vision/frameor/api/streamfor repeated reads, use region OCR, and batch reads between actions — see AGENT_GUIDE.md → Linux (X11) Usage.
Quick Start
API Reference
Capabilities
Returns the active backend name and what it can do. Agents should call this first (see ROADMAP.md for the multi-platform plan).
Feature values: true (supported), false (absent), null (unknown —
stub backend), "optional" (depends on an optional dependency).
Platform Support Matrix
Linux X11 is implemented and supported with limits — setup, requirements and the full limitations list are in Linux (X11). Wayland fails fast with
UNSUPPORTED_DISPLAY_SERVER(501), and macOS remains a fail-closed stub: every operation returnsBACKEND_UNAVAILABLE(501) until ROADMAP Phase 7. Windows is the reference backend.† Wayland column is hypothetical capability planning only — the server never starts on Wayland (see the note above), so no Wayland cell is currently reachable.
Authentication
Every request must include the X-Auth-Token header. The token is
generated on each server start and written to .token.
Token bootstrap (for the bundled web UI):
The
/tokenendpoint answers only loopback callers on a loopback bind: the check uses the accepted socket's peer address (a LAN client cannot spoof it), theHostheader guards against DNS rebinding, and the response is never cached. When the server is bound to0.0.0.0or is reached from a non-loopback peer,/tokenreturns 403.
Screen Capture
GET /api/screenshot
Returns a JPEG screenshot.
GET /api/info
Returns screen dimensions and system state.
Mouse Control
POST /api/mouse
Keyboard Control
POST /api/key
OCR (Screen Reading)
POST /api/ocr
Converts on-screen text to machine-readable format.
Vision Access (Image Models)
Three endpoints for models that can consume images:
GET /api/vision/frame
GET /api/stream
MJPEG live stream. Drop into <img src> or consume frame-by-frame.
POST /api/vision/diff
Text-based motion detection — no vision model required.
Window Management
GET /api/windows
List all visible windows.
POST /api/window
POST /api/launch
Spawn an application, open a URL, or open a local file. Exactly one of
app | url | file. Never runs through a shell: app is a plain command
name resolved on PATH ([A-Za-z0-9._+-]+), url/file go through
xdg-open.
Launch policy: interpreter and executor names (
python*,node,sh/bash/cmd/powershell,env,xargs,sudo,curl, …) are refused with 400 —/api/launchis for GUI applications, not a remote code-execution endpoint.
With expect_title, window is the match or null (spawn succeeded, no
window yet) — the HTTP status stays 200 either way.
GET /api/window/wait
Block until a window whose title contains title (case-insensitive
substring) appears, then return it. timeout default 10 s, max 30 s;
200 with the window, or 408 OPERATION_TIMEOUT.
Focus-Free (Background) Control
Read and control windows without stealing focus — the user keeps working on their main desktop.
Linux (X11) note: background control there is focus-first — the target window is focused, then input is sent globally (focus stealing). Only background capture is truly focus-free. See Known limitations.
GET /api/window/capture
Capture a window via PrintWindow (works even on another virtual desktop).
POST /api/window/post
Send input to a window, choosing the delivery path automatically.
Optional mode parameter controls routing:
Routing rules (mode=auto):
postmessage— classic Win32 app: background PostMessage, no focus change.uia— WinUI/UWP/XAML surface (single DirectX canvas, no Win32 child controls): posted messages are silently swallowed, so the window is focused and the action is replayed through SendInput (client coords converted to screen). This is the documented fallback for modern apps.focused— window is already foreground: focused SendInput path.invalid— HTTP 409; not a reachable top-level window.
GET /api/window/input-mode
Classify how a window receives input before posting to it. Returns one of
focused | postmessage | uia | invalid.
WinUI note: New Notepad (and other XAML-hosted apps) has no classic child Edit control to post to — the whole UI is one DirectX surface.
input-modereportsuiafor these;/api/window/postthen automatically uses the focused SendInput path./api/window/childrenremains useful for classic apps with real child controls.
GET /api/window/children
List child controls of a window (class name + title + hwnd).
Virtual Desktops
GET /api/desktops
List all virtual desktops.
POST /api/desktop
Game Mode
Safety Endpoints
GET /api/held
Returns currently held keys/buttons and watchdog status.
POST /api/release_all
Emergency: release everything (held keys, mouse buttons, game-mode cursor lock).
🤖 For AI Agents
A dedicated, comprehensive guide for AI agents (LLMs, vision models, automation frameworks) is available in AGENT_GUIDE.md.
Prefer loading this as a skill instead of browsing docs? Install the Skill version.
It covers:
- Environment routing — find Windows vs Linux (X11/Wayland) first
- Perceive-act loop (read → plan → act → verify)
- Focus guard (
expect_hwnd) to prevent wrong-window accidents - App automation and game control workflows
- Linux (X11) usage: slow-OCR batching, capture semantics, game-mode caveats
- Vision access for image-capable models
- Text-based motion detection
- Bandwidth optimization
- Complete curl examples
MCP Support (One-Click Cloud Agents)
Model Context Protocol (MCP) turns this project into a plug-and-play toolbox for any MCP-capable agent: Claude Desktop, Claude Code, Cursor, VS Code Copilot Agent mode, custom cloud agents — no custom glue code, no curl scripts. The agent discovers and calls the tools natively.
How it works
mcp_server.py adds no new powers — every safety mechanism
(auth token, input/read locks, watchdog, Alt+F4 block, focus guard,
failsafe) stays enforced by server.py.
Setup
The MCP server auto-reads the token from .token (or the
SCREEN_CONTROL_TOKEN env var) — zero configuration.
Desktop agents (stdio transport)
Claude Desktop — claude_desktop_config.json:
Claude Code: claude mcp add screen-control -- python C:/path/to/screen-control/mcp_server.py
Cursor / VS Code: add the same entry to their MCP config files.
Remote / cloud agents (streamable-HTTP transport)
The HTTP transport is token-protected: every request must carry the
X-Auth-Token header (same token as the REST server). Query-string tokens
(?token=...) are rejected by design — URLs leak into proxy/tunnel
logs, browser history and shared links, and this token grants full desktop
control. Clients that cannot send custom headers should run a local stdio
mcp_server.py instead. Only GET /health is open, for liveness probes.
DNS-rebinding protection is disabled on this transport deliberately —
tunneled requests arrive with a foreign Host header, and the rebinding
threat is already covered by the token guard.
For a cloud agent, expose it through a tunnel:
Then configure the agent's MCP connection with <tunnel-url>/mcp plus the
token from .token as a header (X-Auth-Token).
Headerless connectors (scoped keys)
For clients that cannot send custom headers (e.g. web connectors that only take an endpoint URL), create a scoped API key — a persistent, optionally time-limited credential — and embed it in the URL path:
Design guarantees (SC-06):
- The master session token is refused in URLs (403) — only scoped keys may travel there
- Keys carry scopes (
rest,mcp): a key minted with{"scopes":["mcp"]}cannot call the REST API at all, and any scoped key is refused on admin endpoints (/api/keys,/api/session*) — those accept the master token only - Scoped keys expire automatically; expired keys authenticate nothing
- Scoped keys are revocable by name at any moment via
POST /api/keys({"action":"revoke","name":"spark"}) — revocation takes effect immediately on every endpoint - The
.apikeysfile stores only SHA-256 hashes, never raw keys, and is written with0600permissions
⚠️ A tunnel exposes PC control to the internet. Keep the token secret, prefer short-lived tunnels and scoped keys for headerless connectors, and stop the server when not in use.
One-Command Startup (launcher, tunnel opt-in)
start-server.bat automates the whole setup and prints a paste-ready
scoped key for your cloud agent:
- Downloads
cloudflared.exefrom a pinned release and verifies its SHA-256 against Cloudflare's published checksum (no mutablelatestURL, no unverified binary) - Stops leftover instances from a previous run
- Starts the REST server (port 8745) and the MCP HTTP server (port 8751)
- Waits until both are healthy (
/tokenand/healthprobes) - Starts the quick tunnel only when you opt in with
start-server.bat --tunnel, extracts its public URL fromtunnel.log, and prints the summary:
Without --tunnel nothing is exposed to the internet — the launcher is a
local-only startup. The pasted credential is a 24-hour mcp-scoped key
(minted locally, revocable via POST /api/keys {"action":"revoke",...}).
stop-server.bat stops all three (REST, MCP, tunnel) in one go.
Available tools (16)
Which transport for whom
Note: This project targets MCP Python SDK 2.x (
MCPServerAPI). With SDK 1.x, replace the import withfrom mcp.server.fastmcp import FastMCP, ImageandMCPServerwithFastMCP.
Security Model
Threat: Malicious Web Pages (CSRF)
Even bound to 127.0.0.1, a malicious page in the browser can trigger
non-preflighted requests (text/plain fetch, HTML form POST) to localhost.
The browser blocks the response but not the request — the server
would still execute the command.
Mitigation: Every request requires X-Auth-Token. A foreign page
cannot read this token (Same-Origin Policy), so it cannot authenticate.
Additional layers:
- POST requests must use
Content-Type: application/json(415 otherwise) - This blocks form-encoded and text-plain POSTs even if the token leaked
- Host header trust (DNS rebinding): when bound to loopback, requests
carrying a non-loopback
Hostheader are refused with421— a rebinding page that resolves its domain to127.0.0.1cannot read/tokenor call the API /tokenand/responses carryCache-Control: no-storeso the credential is never persisted by browsers or proxies
Threat: Stuck Keys / Game Mode Lock
In game mode, ClipCursor pins the cursor to a 2×2 box — the classic
pyautogui failsafe (cursor to top-left) does not work.
Mitigations:
- Physical
Esc/Alt+Tab— real hardware input; this API cannot block it, and it always works POST /api/release_all— instant release of everything- Watchdog (automatic) — 30 s of server-side inactivity with held input triggers automatic release
Threat: Wrong Window Typing
Mitigations:
expect_hwndguard on/api/key— if the foreground window doesn't match, typing is refused with 409- The focused path of
/api/window/postverifies the focus after the focus switch and before any synthetic input (409 on mismatch) — input is never replayed into whatever window happens to be foreground focus_window()raises on failure instead of silently returning
Threat: Dangerous Key Combos
Mitigation: Blocked at the API level (403) on every delivery path —
the direct /api/key route, the background /api/window/post route
(PostMessage), and the focused fallback route share one safety policy
(control._assert_allowed):
Alt+F4— the only banned Alt combo (Alt+Tab, Alt+menu are legitimate)- Win key — prevents Start menu, task switching
Ctrl+Alt+Del— system security screenShift+Deletestyle — prevents permanent deletion
Threat: Killing System Processes
Mitigations:
- The process name is resolved from the PID directly (Win32 toolhelp snapshot), not from the visible-window inventory — windowless/background system processes get the same protection as visible ones
- Critical system processes are blacklisted (default-deny for unknown PIDs):
winlogon.exe,csrss.exe,smss.exe,services.exe,lsass.exe,svchost.exe,system,registry,dwm.exe - Optional
expect_processconfirmation: a mismatch aborts the kill with409— protects against killing a newly-reused PID
Threat: Resource Exhaustion (rogue agent / DoS)
A token-holding but misbehaving client should not be able to exhaust memory or starve the input lock.
Mitigations:
MAX_CONTENT_LENGTH= 1 MB — oversized request bodies are rejected (413)regionwidth/height/area andscaleare bounded (400 otherwise)textpayloads are capped at 10,000 characters per input call- MJPEG streams are capped at 10 concurrent clients (429 beyond that)
- Pillow decompression-bomb limit is set for client-supplied images
Network Access
The server binds to 127.0.0.1 by default. To expose it to the network:
Game Mode Guide
Setup
Camera Look
Movement
Minecraft-Specific
Suitability
Vision Access Guide
For Image-Capable Models
If the consuming model can process images, use the vision endpoints directly:
This returns a single JPEG that the model can analyze for:
- Game HUD elements (health, mana, inventory)
- On-screen text (menus, chat, tooltips)
- Visual scene understanding (blocks, entities, terrain)
For Text-Only Models
Use the diff endpoint for motion detection without vision:
The response tells you where things changed (tile coordinates) and how much (percentage), which is sufficient for:
- Detecting that an action had an effect
- Locating moving elements on screen
- Tracking animation state changes
Bandwidth Optimization
Troubleshooting
"OCR engine not installed"
Server won't start (port in use)
"Focus mismatch" (409) when typing
The foreground window changed between the focus call and the type call.
Solution: always pass expect_hwnd and verify focus before typing.
Window not found
The window may have been closed or may be a system window that
EnumWindows doesn't expose. Try:
Game mode cursor stuck
Use POST /api/release_all or press Esc / Alt+Tab physically.
High OCR latency
OCR on a full 1920×1080 screen can take from a few seconds up to ~30 s depending on your CPU and on-screen complexity. Use a region — small crops are typically 10× faster:
Turkish characters not appearing
The system uses SendInput + KEYEVENTF_UNICODE which is layout-independent.
If characters still don't appear, the target app may not support Unicode
input — try POST /api/window/post with action: "type" instead.
Linux: server exits immediately with "Wayland display server detected"
Expected on a Wayland session — the backend fails fast with
UNSUPPORTED_DISPLAY_SERVER (501) instead of half-working. Log out, choose
the X11 session ("Cinnamon on Xorg") at the login screen, then start the
server again. See Linux (X11).
Linux: "xdotool is not installed or not on PATH" (501)
The X11 helper tools are missing. Install them (or re-run the installer):
Project Structure
Testing
Prerequisites
The server must be running:
Security test suite
Tests authentication, blocked key combos, window management, safe close, critical process protection, and game mode — all non-destructive.
Expected output:
Live game-mechanics test
Launches a real application (mspaint or notepad), performs hold-to-draw game mechanics, verifies via pixel analysis, then safely closes with "Don't Save" dialog handling.
Note: This test launches a real application. It handles cleanup automatically (sends WM_CLOSE and clicks "Don't Save" if a dialog appears).
Live Linux acceptance test (Linux X11 only)
Seven-item live check of the Linux backend: mouse move/click, typing +
hotkey, screenshot, OCR, window list/focus, game mode (uinput) and the
native-game item (printed as SKIP — no Linux game is installed). Needs a
running server and a real X11 session; every helper window is pid-unique and
only those are ever focused or clicked.
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Test on a Windows machine
- Submit a pull request
Code Style
- Python: PEP 8, type hints, docstrings on all public functions
- Docstrings: English, Google style
- Error messages: English, descriptive
- Comments: English, explain why not what
License
MIT License. See LICENSE for details.
Built with ❤️ for local automation and AI agent research.
来源:README.md,提交 9806d44
工具
0版本历史
1- v1.0.0最新Sep 18, 2026
评分
已满足适用检查项的 50%
该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。
- 近 30 天内可连通25 分
请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。
- 已声明认证方式10 分
请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。
- 已列出工具15 分
请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。
- 描述必需15 分
- 图标10 分
- 文档15 分
- 许可证10 分