Skip to main content
Glama
Screen Observer MCP

Screen Observer MCP

by wuhaostudio

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 status

status 输出一份机器可读的 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_state

  • screen_wait_for_change

  • screen_wait_for_title — 阻塞,直到活动窗口的标题包含指定子串,或直到期限用完。适合“等待构建终端显示 构建成功”之类场景。

  • screen_wait_for_idle — 阻塞,直到已发布的修订在 N 毫秒内不再变化,或直到期限用尽。适合“屏幕已停止更新,即任务完成”之类场景。

  • screen_get_ui_tree

  • screen_get_region

  • screen_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_stop

idle_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

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables MCP clients to control macOS via accessibility and screen recording, providing tools to list apps, observe UI, click, type, press keys, and scroll.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    MCP 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
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables 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