Skip to main content
Glama
Winter-And-You-Gone

ScreenShotTool MCP

ScreenShotTool MCP

⚠️ 截图很慢!每次 capture_window / capture_screen_region 需要 1-5 秒,且可能阻塞目标应用的渲染线程(PrintWindow 发 WM_PRINT 消息,目标必须同步响应)。 优先用其他工具替代截图: list_windows / get_window_state / click_window + 再次 list_windows 验证状态变化、从目标应用日志/文件读数据。只在真正需要视觉内容时才截图。

Windows 本地截图与窗口操控 MCP Server,供 Codex、Claude Code 等 MCP 客户端通过 stdio 调用。支持启动应用、发现窗口、截取窗口或屏幕区域、模拟鼠标/键盘操作、点击原生菜单。多数窗口操作支持 best-effort 后台模式:尽量不抢焦点、不移动鼠标、不改变用户当前前台窗口。

功能

  • launch_app — 启动指定 .exe,可等待第一个可见窗口。noActivate:true 会在发现新窗口后恢复原前台窗口,并把目标窗口压到 z-order 底部;startMinimized:true 会在发现窗口后请求后台/最小化呈现。少数程序启动时仍可能短暂置顶或自行抢焦点。

  • list_windows — 按 pid、进程名、标题关键字列出可见窗口。

  • capture_window — ⚠️ 截图很慢(1-5s),尽量用其他工具替代。截取窗口。默认使用 captureMethod:"print"(PrintWindow API),可截取被遮挡或最小化的窗口。仅当 print 模式抓不到的场景(如需要捕获 Qt ToolTip、Electron 子窗口等独立顶层弹窗)才改为 captureMethod:"screen"noActivate:true 自动使用 PrintWindow,不操作 z-order,不闪烁。

  • capture_screen_region — ⚠️ 截图很慢(1-5s),尽量避免使用。按屏幕绝对坐标截取矩形。

  • click_window — 按窗口相对坐标投递鼠标点击消息,不移动主机物理鼠标。

  • move_mouse_window — 按窗口相对坐标投递鼠标移动消息,不移动主机物理鼠标。

  • click_menu_item — 按原生菜单路径触发菜单命令,支持中文菜单名,不移动主机物理鼠标。

  • close_app — 用 taskkill /T /F 终止指定 pid 及其子进程树。

  • type_text — 输入文本。noActivate:truePostMessage(WM_CHAR) 直接投递到目标窗口的编辑控件,窗口无需焦点、无需前台。注意:对标准 Edit/RichEdit 控件可能走 EM_REPLACESEL,会替换当前选区而不是在光标处插入;若需要纯插入,先发一个取消选区的按键即可。

  • send_key — 发送按键。noActivate:truePostMessage(WM_KEYDOWN/WM_KEYUP),窗口无需焦点。

  • read_clipboard — 读取 Windows 剪贴板文本。无文本时返回 available:false

  • write_clipboard — 写文本到剪贴板(支持 Unicode、CJK、换行;传空串清空)。上限 1,000,000 字符。配合 send_key 的 Ctrl+V 比逐字符 type_text 快很多。

  • get_window_state — 查询单个窗口的详细状态(minimized/maximized/foreground/topmost/layered/cloaked/style 等),比 list_windows 信息更全。

  • wait_for_window — 阻塞等待匹配窗口出现 (mode:"appear") 或消失 (mode:"disappear")。超时返回 found:false 而不是抛错,比客户端轮询高效。

截图默认保存到:

X:\MCP\ScreenShotTool\outputs\YYYYMMDD-HHMMSS-xxxxxx.png

工具返回 JSON 文本,包含:

{
  "path": "X:\\MCP\\ScreenShotTool\\outputs\\20260524-120000-abc123.png",
  "width": 800,
  "height": 600,
  "target": "window:123456",
  "rect": { "x": 0, "y": 0, "width": 800, "height": 600 },
  "timestamp": "2026-05-24T04:00:00.0000000Z"
}

Related MCP server: Windows MCP Server

后台模式

后台操作推荐显式传入 noActivate:true,截图时再配合 captureMethod:"print"focus:false。这是一组 Win32 best-effort 策略,不是操作系统级沙箱:如果目标程序启动时主动调用 SetForegroundWindow、忽略窗口消息、或安全策略禁止后台输入,工具只能尽量恢复原前台窗口并把目标窗口压到底层。

工具

noActivate 行为

launch_app

新窗口出现后立即推到 HWND_BOTTOM,并恢复用户原来的前台窗口。发现窗口后会继续持续监控至少 8 秒,且不短于本次 timeoutMs:压制多窗口 app 的后续窗口、捕获 app 自激活恢复、以及覆盖较慢启动的窗口。使用 Alt 键技巧绕过 SetForegroundWindow 限制。当 app 启动超慢、Wait-And-Suppress 没能先发现窗口时,还有一个 fallback 阶段会对已找到的窗口补做持续压制。

capture_window

自动切换到 PrintWindow 模式,从窗口绘制表面直接捕获,无需操作 z-order,不会导致窗口闪现。

type_text

通过 GetGUIThreadInfo 定位焦点子控件(如 Scintilla、Edit),再用 PostMessage(WM_CHAR) 投递字符;窗口在后台时用 EnumChildWindows 按类名查找编辑控件。

send_key

PostMessage(WM_KEYDOWN/WM_KEYUP) 代替 keybd_event,无需前台焦点。

完整示例——后台启动记事本、输入文字、截图、关闭:

// 1. 启动(best-effort 不抢焦点,并压到底层)
{ "exePath": "C:\\Windows\\System32\\notepad.exe", "waitForWindow": true, "noActivate": true, "startMinimized": true }

// 2. 输入文字(noActivate,PostMessage WM_CHAR 直达编辑控件)
{ "hwnd": "123456", "text": "Hello from background!", "noActivate": true }

// 3. 截图(默认 PrintWindow,不把窗口拉到前台)
{ "hwnd": "123456", "focus": false, "noActivate": true }

// 4. 关闭
{ "pid": 7890 }

VaporView 这类 Qt 程序建议使用同一套参数:

// launch_app
{
  "exePath": "X:\\Project\\GPS\\VaporView\\build\\Release\\VaporView.exe",
  "waitForWindow": true,
  "timeoutMs": 10000,
  "noActivate": true,
  "startMinimized": true
}

// click_window: 本身使用窗口消息,不移动物理鼠标
{ "hwnd": "123456", "x": 535, "y": 50, "delayMs": 300 }

// capture_window(默认 PrintWindow)
{ "hwnd": "123456", "focus": false, "noActivate": true }

安装与构建

npm install
npm run build

开发时直接运行:

npm run dev

构建后运行:

npm start

热重载

npm start 启动的 MCP server 默认启用工具层热重载:每次 tools/list 或工具调用前会检查 dist/schemas.jsdist/windows.jsscripts/win-capture.ps1 的修改时间;如果发生变化,会重新加载工具模块,并重启长驻 PowerShell helper。这样修改截图/点击/窗口操作逻辑后,通常不用重启 Codex 或 Inspector。

TypeScript 源码改动仍然需要先编译到 dist/。开发时可以另开一个终端运行:

npm run build:watch

然后保持 MCP 客户端继续使用:

npm start

热重载边界:

  • scripts/win-capture.ps1 改动:下一次工具调用直接生效。

  • src/windows.ts / src/schemas.ts 改动:npm run buildnpm run build:watch 编译后,下一次工具调用生效。

  • src/index.ts、依赖、启动参数、MCP transport 层改动:仍需重启 MCP server。

  • 如需关闭热重载,可设置环境变量 SCREENSHOTTOOL_HOT_RELOAD=0 后再启动 server。


🤖 给 AI Agent 的安装指引

这一节专门写给 Codex / Claude Code 等 AI Agent 阅读,按顺序执行即可完成安装和接入。

前置条件检查

# 1. 必须是 Windows 桌面会话
[System.Environment]::OSVersion.Platform   # 期望: Win32NT

# 2. Node 版本必须 >= 20
node --version

# 3. 必须能调用 PowerShell(pwsh.exe 优先,否则 powershell.exe)
where.exe pwsh.exe
where.exe powershell.exe

如果 Node 缺失或版本过低,先告知用户并停止。不要自动安装 Node。

克隆 + 构建

# 选一个目录(示例用 X:\MCP,你可以换成任意绝对路径)
cd X:\MCP
git clone git@github.com:Winter-And-You-Gone/ScreenShotTool-MCP.git
cd ScreenShotTool-MCP
npm install
npm run build

构建产物在 dist/index.js这就是 MCP 客户端要调用的入口

配置 MCP 客户端

把以下条目写入客户端的 mcpServers 配置(绝对路径必须用双反斜杠转义):

{
  "mcpServers": {
    "screenshottool": {
      "command": "node",
      "args": ["X:\\MCP\\ScreenShotTool\\dist\\index.js"],
      "cwd": "X:\\MCP\\ScreenShotTool"
    }
  }
}

开发期也可以用 tsx 直接运行 TypeScript 源码(无需每次构建):

{
  "mcpServers": {
    "screenshottool": {
      "command": "npx",
      "args": ["tsx", "X:\\MCP\\ScreenShotTool\\src\\index.ts"],
      "cwd": "X:\\MCP\\ScreenShotTool"
    }
  }
}

不同客户端的配置文件位置:

  • Claude Code: %APPDATA%\Claude\claude_desktop_config.json~/.claude.json

  • Codex CLI: ~/.codex/config.toml(TOML 格式,需要换种写法)

  • MCP Inspector: npm run inspect

自检(不依赖客户端)

# 单元测试
npm test                    # 期望全部通过

# 启动 + 关闭 Notepad 的端到端测试
npm run smoke:notepad

# 验证 noActivate 不抢焦点
npm run smoke:no-activate

如果 smoke:no-activate 失败,通常是因为:

  1. 当前没有桌面会话(远程会话/服务模式跑不动)

  2. UAC 阻止了 keybd_event(用普通用户权限运行即可,不要用管理员权限)

接入后的第一次调用

确认接入成功的最小调用:

// 1. 列出当前可见窗口(不会改变任何状态)
{ "tool": "list_windows", "arguments": {} }

// 2. noActivate 启动记事本(不抢焦点)
{ "tool": "launch_app", "arguments": {
    "exePath": "C:\\Windows\\System32\\notepad.exe",
    "waitForWindow": true,
    "noActivate": true
} }

返回的 window.hwnd 就是后续 type_textcapture_windowclick_window 的目标。

常见错误

现象

原因

修复

exePath must be an absolute path

路径不是绝对路径

C:\\Windows\\System32\\notepad.exe 这类完整路径

outputPath must end with .png

输出路径后缀不对

省略 outputPath 让工具自动生成,或确保以 .png 结尾

PowerShell helper exited unexpectedly

helper 进程崩溃(一般是首次启动慢)

重试一次;持续失败查看 outputs/ 同级是否有报错日志

noActivate 模式下窗口仍然闪一下

极少数程序自身会调用 SetForegroundWindow

这是程序行为,工具层面已尽力抑制

中文菜单匹配失败

旧版本 (< 73a9fa6) 的 ANSI 编码问题

拉取最新 main 重新构建

不要做的事

  • ❌ 不要自动 git pull 升级——可能引入 break change

  • ❌ 不要修改 outputs/dist/.claude/ 目录——都被 gitignore

  • ❌ 不要给 type_text 传超长字符串(单次最多 1000 字符,且会按 delayMs + pressMs 拒绝预计过慢的请求),分段发送更可靠

  • ❌ 不要在 click_window 之后立刻 capture_window——加 delayMs: 200 给 UI 重绘时间

示例调用

启动 Notepad:

{
  "exePath": "C:\\Windows\\System32\\notepad.exe",
  "waitForWindow": true,
  "timeoutMs": 10000
}

截取窗口:

{
  "hwnd": "123456",
  "focus": true
}

截图时保留已打开的菜单或浮层:

{
  "hwnd": "123456",
  "focus": false
}

截取被遮挡/最小化的窗口(PrintWindow):

{
  "hwnd": "123456",
  "captureMethod": "print"
}

截取窗口内左上角区域:

{
  "hwnd": "123456",
  "region": { "x": 0, "y": 0, "width": 300, "height": 200 }
}

截取屏幕区域:

{
  "region": { "x": 0, "y": 0, "width": 800, "height": 600 }
}

点击窗口内按钮:

{
  "titleContains": "VaporView",
  "x": 115,
  "y": 50,
  "button": "left",
  "delayMs": 300
}

x / y 是目标窗口左上角起算的物理像素坐标。click_window 会根据命中区域投递客户区或非客户区鼠标消息,不移动主机物理鼠标。常见流程是先 capture_window 看图,再估算要点击的窗口内坐标,调用 click_window,最后再次 capture_window

点击原生菜单项(支持中文):

{
  "titleContains": "Notepad3",
  "path": ["帮助(&H)", "关于(&A)..."]
}

path 匹配会忽略 & 助记符、大小写和菜单文本中的快捷键后缀,例如 帮助(&H) 可以用 帮助 匹配。

悬停窗口内菜单项:

{
  "titleContains": "VaporView",
  "x": 150,
  "y": 260,
  "delayMs": 300
}

测试

npm test

Windows 桌面 smoke test 会打开并关闭 Notepad:

npm run smoke:notepad

验证 noActivate 模式不抢焦点:

npm run smoke:no-activate

验证无光标点击不会移动主机物理鼠标:

npm run smoke:no-cursor-click

用 MCP Inspector 手动验收:

npm run build
npm run inspect

限制

  • ⚠️ 不要尝试用 MCP 实现鼠标拖拽、拖动滑块、缩放、手势操作——click_window 只发送按下+抬起消息,不支持连续移动。如果需要拖拽或任意复杂的鼠标操作,直接请求人类用户手动完成,你的描述清晰告诉用户需要做什么就好。

  • ⚠️ 不要依赖 move_mouse_window 触发 tooltip、hover 效果、右键菜单等 UI 状态变化——它只投递一个假的消息,不移动真实光标。Qt/Electron 等现代框架读取系统鼠标位置,不会响应假消息。需要此类交互时,直接请求人类用户操作

  • ⚠️ 截图很慢(1-5s),能不用就不用——优先用 list_windows / get_window_state 或读应用日志替代。

  • 只支持 Windows 桌面会话;需要 Node 20+。

  • 不做 OCR、图像比对。

  • type_textnoActivate 模式通过 PostMessage(WM_CHAR) 投递,少数自绘编辑控件可能不响应 WM_CHAR

  • exePath 要求绝对 .exe 路径。

  • args 必须是字符串数组,不接受拼接后的命令行。

  • 截图使用物理像素坐标;helper 会尝试启用 DPI aware,减少高 DPI 缩放偏差。

  • 服务器进程持有一个长驻 PowerShell helper 进程,命中第一次启动后,后续每次工具调用约几十毫秒;helper 异常退出时会按需重启。

  • 请求模型:长驻 worker 是串行的——list_windows、点击、输入、剪贴板、窗口状态查询、launch_app 内部的 wait-and-suppress 等共享一个 stdin,worker 处理完前一个请求才会响应下一个。capture_windowcapture_screen_regionwait_for_window 走独立 PS 进程,不阻塞其他工具。长时间操作(如超长 type_text,或 launch_app noActivate 的持续压制阶段)仍会占用共享 worker;相关 schema 和超时保护会限制单次请求的边界。

  • 后台模式的极限noActivate 发现窗口后会持续压制至少 8 秒,且不短于本次 timeoutMs(默认约 10 秒)。如果目标应用在这段时间后才主动调用 SetForegroundWindow(极少见,多见于延迟加载插件或开机自启注册),窗口仍可能抢到前台。这是应用行为,工具侧已做到了合理覆盖。

截图模式与遮挡 / tooltip 的关键限制(Qt、Electron 类应用特别注意)

下面几条是 Win32 API 层面的硬限制,反复换参数也不会改变结果。遇到这些场景时,应该在程序里换验证方式,而不是反复截图。

  • capture_windowscreen 模式按屏幕可见像素拷贝(Graphics.CopyFromScreen:它根本不看 hwnd,只看那块屏幕矩形当时显示了什么。如果目标窗口被遮挡、不在前台、或多显示器坐标偏移,就会抓到遮挡物。这是物理限制,工具层无法绕过。

  • capture_windowprint 模式(PrintWindow)只绘制目标 hwnd 及其子窗口的客户区:抓不到独立顶层窗口——典型例子是 Qt 的 Qt::ToolTipQt::Popup 弹窗、Electron 的子窗口、独立的下拉菜单。这些是带 WS_EX_TOOLWINDOW 的独立 hwnd,不在主窗口的子窗口树里,EnumChildWindows 也找不到。

  • move_mouse_windowPostMessage(WM_MOUSEMOVE) 投递窗口消息,但 Qt/Electron 的 tooltip 由 QCursor::pos() + hover 定时器驱动:窗口消息不更新系统鼠标位置,所以 Qt 看到鼠标"还在别处",不会启动 hover 计时器,不会出现 tooltip。这个工具对 Qt/Electron 的 hover 触发基本无效

  • capture_screen_regionscreen 模式:按屏幕可见像素截取,受多显示器坐标、DPI、前台遮挡影响。如果目标区域被别的窗口盖住,截到的就是遮挡物。

结论:本工具适合抓稳定的窗口内容。对于「hover 触发 + 独立顶层 tooltip + 多显示器/遮挡」这类组合场景(典型如 Qt 应用),更可靠的验证方式是:

  1. 在目标程序里临时加测试入口,强制显示 tooltip/弹窗后再截图;

  2. 用真实鼠标 + 可交互录屏;

  3. 让目标程序把要验证的 UI 状态写到日志/文件,工具读文件而非看图。

Install Server
F
license - not found
A
quality
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Winter-And-You-Gone/ScreenShotTool-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server