Screen Observer MCP
Screen Observer MCP
一个面向 Claude Code 及其他 MCP 客户端的本地、只读 Windows 11 屏幕观察服务。它通过诊断型 CLI 命令和八个 MCP stdio 工具,暴露一个有界、经过隐私过滤、仅驻留内存的帧模型。观察行为由代理显式控制:由客户端自行决定何时开始采集、何时停止采集。
系统要求
Windows 11,用于真实的屏幕捕获和 UI Automation。
Python 3.12。
Related MCP server: blade-computer-use
开发环境搭建
py -3.12 -m venv .venv
.venv\Scripts\python -m pip install -e ".[dev]"安装完成后,生成一份解析后的依赖导出:
.venv\Scripts\python -m pip freeze --local > requirements.lock.txt该导出可能包含一条指向当前检出目录的可编辑(editable)绝对 Windows 路径。若要在另一个检出目录中复现相同的第三方依赖版本,请先过滤掉这一条可编辑行,再单独安装当前检出目录。
CLI
安装后的入口点与模块入口点使用同一个生产级 StateService:
.venv\Scripts\screen-observer --help
.venv\Scripts\python -m screen_observer.main --help
.venv\Scripts\screen-observer statusstatus 输出一份机器可读的 JSON 文档。start 与 stop 只影响在该命令进程内创建的采集器;此版本不含守护进程或跨进程 IPC,因此由模型控制的长时观测要通过下文的 MCP 生命周期工具来完成。读取相关的几个子命令(snapshot、ui-tree、watch)原本与 MCP 工具一一重复,现已移除;需要相同数据时请直接使用 MCP 工具。
MCP stdio 服务器
按以下方式启动 MCP 传输层:
.venv\Scripts\screen-observer mcp它恰好注册十个工具:
screen_observe_start— 开始一次由代理控制的观察会话;同步发布首个脱敏帧,然后启动后台采集。响应携带ready: true信号,以及capabilities和一份精简的firstFrame摘要,代理无需额外一次往返即可呈现就绪状态。screen_observe_stop— 结束本次会话;等待采集流程结束后,清空当前状态、窗口原始上下文,以及内存环形缓冲区中保留的每一帧。响应携带summary块,其中包含用时、实际捕获帧数、活动窗口变化次数和最后一个活动窗口,便于代理在退出前核对本次观察窗口。screen_get_statescreen_wait_for_changescreen_wait_for_title— 阻塞,直到活动窗口的标题包含指定子串,或直到期限用完。适合“等待构建终端显示 构建成功”之类场景。screen_wait_for_idle— 阻塞,直到已发布的修订在 N 毫秒内不再变化,或直到期限用尽。适合“屏幕已停止更新,即任务完成”之类场景。screen_get_ui_treescreen_get_regionscreen_get_frame_history— 从内存环形缓冲区中取出最多 N 个最近的脱敏帧screen_get_frame— 按修订号取出一帧指定的脱敏帧
MCP 服务器绝不会因为初始化就自行启动屏幕采集。代理通过先调用 screen_observe_start 来打开观察窗口,在此窗口内按需(数秒、数分钟,直到任务完成)使用任意读取工具,最后调用 screen_observe_stop 收场。在开始之前以及停止之后,每一个只读工具都会返回结构化的 observer_not_started 错误。停止操作就是内存中的数据边界:它立即清除所有已发布的帧与状态数据,且完全不写入磁盘。
默认只提供 JSON 状态。仅当传入 include_image=true 时,screen_get_state 才会返回图像数据;screen_get_region 则是负责局部区域取图的显式工具。两个 历史类 工具同样支持 include_image=true,也可传入一个有界的可选 region。图像先在源坐标空间中做隐私过滤,随后被编码为内存中的 Base64 PNG,并受二进制图像尺寸和完整响应大小的双重上限限制。帧数据来自一个有界的内存环形缓冲区(不落盘),请见 src/screen_observer/domain/limits.py 中的 RING_DEFAULT_FRAMES、MAX_RING_FRAMES 和 MAX_RING_BYTES。
一个经过验证的 onedir 产物可用的 Claude Code MCP 配置示例:
{
"mcpServers": {
"screen-observer": {
"command": "C:\\project\\screen-observer-mcp\\dist\\screen-observer\\screen-observer.exe",
"args": ["mcp"]
}
}
}若 onedir 目录被复制到别处,务必将其中的绝对命令路径替换为实际位置。onefile 产物尚未构建或验证。
为构建/测试观测提供的 Agent 操作指南
整个生命周期由代理显式驱动。从下面三条工作流中选一条——差别只在于代理如何判断观测目标已结束。这里不需要估计什么“观测时长”:任务开始即开始,满足对应条件即停止。
1. 显式轮询(screen_wait_for_change)
这是最直接的循环。每个步骤由代理自己驱动。
screen_observe_start # response.ready == true, firstRevision, capabilities, firstFrame
…loop:
screen_wait_for_change(since_revision, timeout_ms = 5000)
inspect the result.state to decide whether the task is done
screen_observe_stop # response.summary carries the session counters当代理明确知道该盯住哪个 UI 元素时,这种写法最合适。
2. 等待标题子串(screen_wait_for_title)
让 MCP 服务器阻塞,直到活动窗口的标题匹配:
screen_observe_start
screen_wait_for_title(
title_contains = "Build successful",
since_revision = <firstRevision>,
timeout_ms = 120000)
# response.matched == true => matchedAtRevision, observedTitle
screen_observe_stop如果隐私策略对最新一条窗口标题做了脱敏,这个工具返回 observedRedacted: true 而不是报错,因此嘈杂环境不至于让代理崩溃。
3. 等待屏幕空闲(screen_wait_for_idle)
以“停止变化”判定完成未完成,适合那些没有明显终态提示的任务。
screen_observe_start
screen_wait_for_idle(idle_ms = 3000, since_revision = <firstRevision>, timeout_ms = 120000)
# response.idleReached == true => idleMs, lastObservedRevision
screen_observe_stopidle_ms 最大支持 60 000,但单次调用的超时受公共的 30 000 ms 限制。若需要更长的整体等待窗口,可多次调用并用。
PowerShell 包装脚本
对于人工或一次性脚本使用者,scripts/observe-until.ps1 把两种策略基于封装在单条命令中,并会代替代理主动停止 MCP 服务器:
# Block until a build/test terminal shows "Build successful":
scripts/observe-until.ps1 -WaitForTitle 'Build successful' -TimeoutSec 180
# Block until the screen stops changing for 3 s:
scripts/observe-until.ps1 -WaitForIdleMs 3000 -TimeoutSec 60该脚本会把开始/停止状态的摘要写回管道,期限结束仍未匹配时报错非零退出。
screen_get_state 及两个历史类工具默认返回 JSON;screen_get_region、screen_get_frame,以及任何工具的 include_image=true 路径都返回 Base64 PNG。
JSON 路径包含纯文本客户端所需的一切:修订号、屏幕几何、活动窗口、UI 树和变更摘要。这些 JSON 完全不需要视觉能力即可使用。
PNG 路径则要求 多模态/视觉能力客户端(例如带视觉能力的 Claude)才能解读渲染出的屏幕。没有这一能力,Base64 负载纯属不透明字节。
如果你的客户端仅支持文本,请优先使用 include_image=false(默认值),以 JSON 合同为主要工作依据。
Windows onedir 包
在项目的虚拟环境中生成可复现的 PyInstaller onedir 产物:
powershell -NoProfile -ExecutionPolicy Bypass -File .\scripts\build_windows.ps1预期可执行文件的路径为:
dist\screen-observer\screen-observer.exe构建完成后,运行打包后的 CLI/MCP 冒烟套件:
powershell -NoProfile -ExecutionPolicy Bypass -File .\scripts\smoke_packaged.ps1该冒烟套件会在 pytest 的临时工作目录(由 SCREEN_OBSERVER_PACKAGED_TEST=1 门控)中依次执行 --help、status 和一次 MCP initialize/on再 list/call 的序列。它还会检查上述临时目录中是否出现常见的屏幕图像或视频文件。这用于在当前 Windows 主机上验证 onedir 产物;它不能替代在独立干净的 Windows 机器上做的正式验证。
移动应用时请将整个 dist\screen-observer 目录一并保留,因为可执行文件依赖其中的 _internal 目录。onefile 包尚未被构建或验证。
MCP stdout 仅保留给协议消息。诊断请全部走 stderr;工具处理器应返回结构化的安全错误,而不是直接让 Python 回溯。
隐私与数据生命周期
屏幕状态与最近若干已发布帧,仅通过一个有界的内存环形缓冲区保存在内存中;应用不会有意持久化截图、视频或屏幕数据历史。
图像响应为启用开启,并与 JSON 状态共用同一份发布帧/修订号/隐私上下文。
密码名称与其值在发布前会被剥离。
针对进程、标题和物理像素区域的隐私遮蔽规则会在 resize 与 PNG 编码之前应用。
Base64 图像数据与全量 UI 文本导出不会被写入诊断日志。
本应用无法确保 Windows 永不将进程的内存页面交换到磁盘。
采集后端
生产环境的采集路径使用 DXGI Desktop Duplication(它实现为 dxcam);mss 仍可用于合成测试的性测试。PyInstaller 的 onedir 构建必须执行 collect_all("dxcam"),以便冻结后的可执行文件在 Windows 11 上能解析到预编译进产物中的 DXGI/D3D11 原生库。
验证
.venv\Scripts\python -m pytest -q
.venv\Scripts\python -m ruff check src tests
.venv\Scripts\python -m mypy
.venv\Scripts\python -m pip check相关的 Windows 适配、stdio 协议和打包产物验证分别位于 tests/adapters/test_windows_integration.py、tests/interfaces/test_mcp_server.py 和 tests/integration/test_packaged_smoke.py。运行上述两个 PowerShell 脚本,即可在当前宿主机上重建并验证 onedir 产物。
Related MCP Connectors
Eyes and hands on real Windows PCs — observe, click, type via Glasswarp API.
Securely control computers you explicitly pair through files, terminals, processes, screenshots, desktop UI/input, clipboard, browser automation, diagnostics, and document tools.
Use a person's computer after they approve it there: files, Terminal, browser, local MCP.
Clean PNG/JPEG screenshots via REST or MCP, with goal-driven multi-step navigation.
Related MCP Servers
- AlicenseAqualityCmaintenanceAllows AI clients to see and control Windows 10/11 desktops via MCP, with screenshots, UI Automation, Chrome CDP, keyboard/mouse, and terminal using semantic element targeting.301,635 npmMIT
- AlicenseNot gradedqualityDmaintenanceEnables MCP clients to control macOS via accessibility and screen recording, providing tools to list apps, observe UI, click, type, press keys, and scroll.MIT
- AlicenseNot gradedqualityCmaintenanceMCP server that captures a Windows application's pixels and bounded UI Automation tree with provider-exposed text for Codex inspection. It supports capture, listing, retrieval, and watcher control commands.MIT
- AlicenseNot gradedqualityCmaintenanceEnables MCP clients to control a Linux/X11 desktop like a human: see the screen, move the mouse, click UI elements via the accessibility tree, type text, and manage windows.MIT