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

ScreenShotTool MCP

ScreenShotTool MCP

截图与结构化状态工具的选择

当任务需要查看视觉内容、检查布局、验证渲染效果、生成图像结果, 或用户明确要求截图时,直接使用 capture_windowcapture_screen_region

当任务需要读取控件值、判断选中状态、定位语义控件或验证业务 后置条件时,使用 resolve_semantic_controlui_getui_query 或 profile action。

两类工具互补,不设固定的全局优先级。可以先用结构化状态验证 操作结果,再用截图提供视觉证据。当用户明确要求截图、图像或视觉 验证时,执行截图而不是用状态查询代替。

一个通用的 Windows UI Automation MCP Server,供 Codex、Claude Code 等 MCP 客户端通过 stdio 调用。核心能力:

  • 启动应用、发现窗口、截取窗口或屏幕区域、投递鼠标/键盘消息(不移动物理鼠标)。

  • 结构化 UI Automation(UIA)能力:读取控件结构、状态、值和业务后置条件;按 selector 查询控件、通过 UIA Pattern 操作控件、等待状态变化。

  • App Pack 声明式适配:任何桌面软件都可以通过一个 JSON 目录(App Pack)接入,无需修改 MCP 源码。

  • 管道引擎run_steps / profile_run_steps / run_workflow 服务端串联多步操作,支持命名步骤、exports、后置条件(expect)、重试、finally 清理、状态恢复与失败续接(continue_run)。

  • 机器可读工具契约tools/list 直接返回每个工具的 inputSchemaoutputSchema 与标准 annotations(readOnlyHint/destructiveHint/idempotentHint/openWorldHint),pipeSafeFields 通过 _meta 携带;另有 tool_contract_list / tool_contract_describe 高层发现接口。所有工具调用(普通调用与管道步骤)都经过统一执行器做 input + output Schema 运行时校验。

目录

  1. 快速开始

  2. App Pack 是什么

  3. 创建自己的 App Pack

  4. App Pack 文件格式

  5. 加载本地私有 Pack

  6. 验证 Pack

  7. 生成 Pack 草稿

  8. 使用 Workflow

  9. profile_run_steps

  10. 交互模式(interactionMode)

  11. 命名步骤与 exports

  12. expect / retry / finally

  13. 续接失败的 run

  14. 输出 Schema 与 structuredContent

  15. 安全限制

  16. 私有 Pack 与公共仓库

  17. 测试

Related MCP server: mcp-test-utils

快速开始

前置条件:Windows 桌面会话、Node.js >= 20、可调用 PowerShell(pwsh.exe 优先)。

git clone https://github.com/Winter-And-You-Gone/ScreenShotTool-MCP.git
cd ScreenShotTool-MCP
npm install
npm run build
npm test

在 MCP 客户端配置(stdio):

{
  "mcpServers": {
    "screenshottool": {
      "command": "node",
      "args": ["X:\\MCP\\ScreenShotTool\\dist\\index.js"],
      "env": { "MY_APP_EXE": "X:\\path\\to\\your-app.exe" }
    }
  }
}

首次接入推荐顺序(模型第一次使用时):

已加载 App Pack:  app_pack_list → app_pack_describe → workflow_catalog → run_workflow
                  或 app_pack_describe → profile_run_steps
未知应用:         launch_app → ui_catalog → app_pack_probe → 创建 App Pack
                  → app_pack_validate → 加载 Pack
底层高级用户:     validate_steps → run_steps → continue_run

模型推荐调用路径

工具选择由契约(tools/list 的 description / inputSchema / outputSchema)与 app_pack_describe 返回的 usageGuidance 引导。通用推荐顺序:

已知 App Pack 时

app_pack_describe → profile_launch → 使用 targetRef 的 profile_action
                  → 业务后置条件验证(ui_wait / expect)
                  → 按任务需要 capture_window(视觉证据/布局检查/用户要求截图时)

用户已明确指定 Profile 时可直接 profile_launch → profile_action,不强制先调用 app_pack_list用户已经明确提供目标 EXE 绝对路径时,首次 profile_launch 应直接 传 exePath;不要先依赖 executableEnv 或自动解析再失败重试。 profile_launch 返回的 targetRef 是后续动作的首选目标绑定: 窗口重建后它会自动重新绑定到新窗口,无需手工换 HWND。targetRef 是 session 身份: 只要拿到 targetRef,后续目标窗口工具(profile_action / ui_query / capture_window / click_window / get_window_state / type_text / send_key 等)一律复用 targetRef,而不是 把返回的 hwnd 跨调用携带——hwnd 是诊断性/临时性的,可能变化。

自然语言复合目标(推荐主路径)

用户用自然语言描述目标(例如 "RD105 通道1 传感器配置")时:

profile_launch → resolve_semantic_control("RD105 通道1 传感器配置")
              → 按 suggestedPath 依次 profile_action(selection group 控件用 ensureSelected)
              → 业务后置条件验证
              → 按任务需要 capture_window(视觉证据/布局检查/用户要求截图时)

resolve_semantic_control 是纯解析(不执行动作):它把自然语言映射到逻辑控件路径 (suggestedPath)和推荐动作(selection-group 控件自动推荐 ensureSelected——幂等且 验证 before/after 状态,而不是 raw invoke)。不要为自然语言目标猜控件 ID 直接调用 profile_action;用户已明确给出控件 ID 时才可直接 profile_action。

查找未知控件

profile controls(profile_resolve / profile_action)→ scoped ui_query
(rootSelector / ancestorSelector / nameContains / fields / maxResults)
→ ui_catalog → scoped ui_inspect_tree

ui_catalogui_inspect_tree 是诊断 fallback:不要为了定位一个已知语义控件 枚举整棵应用树。ui_query 支持 depthStrategy=auto 自动从浅到深扩展搜索深度。 ui_query 要求至少一个查询范围(selector / rootSelector / ancestorSelector 三选一;nameContains 只是过滤条件,不能单独作为 selector root)——公开 JSON Schema 与运行时一致,非法调用在 tools/list 阶段即被拒绝。

禁止的反模式

  • 有 Profile/App Pack 仍先用 launch_app(launch_app 是低层 fallback)。

  • 每次动作都重新抓整棵树(用 profile controls 或 scoped ui_query)。

  • 把旧 hwnd 永久复用(窗口重建后用 targetRef,绑定会自动刷新)。

  • 手工换算 screen/client 坐标(boundingRect 标注 coordinateSpace:"screen", 点击工具只接受 client-area 坐标并标注 coordinateSpace)。

  • 把窗口消息点击描述成真实鼠标点击(结果明确 physicalCursorMoved:false)。

  • 看到没有窗口就断言应用崩溃(区分 processAlive / windowAlive / profileWindowMatchedWINDOW_NOT_FOUND_FOR_PROCESS 不代表进程退出)。

  • 为自然语言目标猜控件 ID(先 resolve_semantic_control 并跟随 suggestedPath)。

  • 对 selection-group 控件用 raw invoke 而不使用推荐的 ensureSelected

  • 给 capture_window 编造输出路径(用户没指定时省略 outputPath,服务器写入默认 outputs/ 目录并返回路径;不要猜磁盘根目录如 X:\...)。

错误输出契约

所有工具的业务错误都以统一结构返回,且满足该工具公开的 outputSchema (不会再出现 -32602 output schema mismatch 掩盖真实错误码):

{
  "success": false,
  "error": {
    "code": "ELEMENT_NOT_FOUND",
    "message": "No element matched selector: ...",
    "suggestion": "Use scoped ui_query within the nearest known profile control...",
    "retryable": false
  }
}

常见错误码都带 suggestion(TARGET_REQUIRED / WINDOW_NOT_FOUND / WINDOW_NOT_FOUND_FOR_PROCESS / STALE_WINDOW_HANDLE / ELEMENT_NOT_FOUND / ELEMENT_AMBIGUOUS / FOREGROUND_REQUIRED / MAX_DEPTH_EXCEEDED / ACTION_STATE_INCONSISTENT / BACKGROUND_CAPTURE_UNAVAILABLE / TREE_OUTPUT_TOO_LARGE)。

控件解析失败(profile_action 的 ELEMENT_NOT_FOUND)会升级为 PROFILE_CONTROL_UNRESOLVED,携带语义诊断上下文: page / component / parent / group / candidatesTried / diagnosticScope(机器可用的 scoped ui_query 建议:{rootControl, maxResults}), 让模型在最近的已知语义范围内诊断,而不是枚举整棵树。

目标进程退出(targetRef 解析失败)返回 TARGET_PROCESS_EXITED,携带结构化证据: processAlive / windowAlive / startedByMcp / exitCode(尽力而为)/ exitObservedAt / lastOperation(工具名 + 时间戳)/ causality: "unknown"lastOperation 是时间相关性诊断上下文,不代表工具导致退出——措辞规则: 只有真实观测到正常退出才能写 "Observed normal process exit.";有异常 exit code 时写 "Observed abnormal process termination shortly after . The temporal association is recorded, but causality is not proven.";证据不足时写 "Target disappeared; root cause remains unknown."。禁止写 "MCP crashed the app" / "UIA caused the crash"。

profile_launch 可选返回 packCompatibility(App Pack ↔ EXE 兼容性): verified(sha256 等强身份匹配)/ compatible-unverified(有版本信息但无法完全证明 binary 身份)/ mismatch(Pack 声明的已验证 binary 与当前 binary 不一致,警告, 不阻止启动)/ not-declared(Pack 未声明 testedAgainst)。mismatch 时控件解析失败 应优先怀疑 App Pack selector 漂移,而不是 UIA 核心故障。

App Pack 是什么

App Pack 是一个声明式 JSON 目录,把"某个软件的启动方式、窗口识别、逻辑控件名、UIA selector、动作契约、默认后置条件、可复用工作流"全部描述为数据。任何用户都可以为自己的 Windows 软件创建一个 App Pack,不需要修改 MCP 源码

核心不包含任何具体软件的硬编码(启动、窗口、菜单、控件、工作流全部来自 Pack)。公共仓库只附带两个通用示例 Pack

  • app-packs/examples/notepad/ — 记事本/编辑器(演示 launch、窗口识别、多候选 selector、剪贴板验证的输入工作流)。

  • app-packs/examples/generic-qt/ — 通用 Qt 应用(演示菜单路由 hints、模态对话框、ComboBox 契约)。

创建自己的 App Pack

  1. 启动目标应用。

  2. app_pack_probe { "pid": <pid> } 生成草稿(候选主窗口规则 + 控件清单 + controls.json 草稿)。

  3. 复制 app-packs/templates/ 到你的包目录,按草稿填写。

  4. app_pack_validate { "packPath": "你的包目录" } 本地校验(不安装)。

  5. 通过 SCREENSHOT_MCP_APP_PACK_DIRS 或本地目录加载,用 run_workflow / profile_run_steps 验证。

$env:SCREENSHOT_MCP_APP_PACK_DIRS = "X:\Private\AppPacks;D:\Team\AppPacks"

App Pack 文件格式

每个 App Pack 是一个目录,其中 manifest.jsonprofile.json 必须存在,其余文件可选:

<pack-directory>/
├─ manifest.json    必选:id、版本、可见性、文件引用
├─ profile.json     必选:可执行文件、主窗口规则、启动与安全参数
├─ controls.json    逻辑控件名 → UIA selector 候选(含语义元数据、搜索作用域、滚动关系、业务后置条件)
├─ actions.json     控件+动作契约(幂等、可重试、defaultExpect)
├─ workflows.json   可复用命名工作流
├─ pages.json       可选:页面语义地图(页面、导航入口、就绪标志、选择组)
├─ components.json  可选:卡片/区域语义地图(组件、子控件、映射状态)
└─ README.md        说明

完整 JSON Schema 见 app-packs/schemas/manifest.schema.jsonprofile.schema.jsoncontrols.schema.jsonactions.schema.jsonworkflows.schema.json),模板见 app-packs/templates/

// manifest.json
{ "schemaVersion": 1, "id": "example-app", "displayName": "Example App",
  "version": "1.0.0", "catalogVisibility": "session", "enabled": true }

// profile.json —— 禁止保存绝对路径、PID、HWND、坐标、凭据
{ "id": "example-app", "executableNames": ["Example.exe"],
  "executableEnv": "EXAMPLE_APP_EXE",
  "mainWindow": { "title": "^Example App$", "titleMatch": "regex", "frameworkId": "Qt" },
  "security": { "requiresAsInvoker": false } }

// controls.json
{ "controls": {
    "mainWindow": { "selectors": [{ "controlType": "Window", "name": "^Example App$", "match": "regex" }],
                    "confidence": "runtime-verified" },
    "confirmButton": { "selectors": [{ "automationId": "confirmButton$", "match": "regex", "controlType": "Button" }],
                       "confidence": "runtime-verified" } } }

// actions.json —— 幂等/可重试/默认后置条件
{ "contracts": [ { "control": "confirmButton", "action": "invoke",
                   "idempotent": false, "retrySafe": false,
                   "defaultExpect": { "profileControl": "resultPanel", "condition": "exists",
                                      "timeoutMs": 5000 } } ] }

// workflows.json —— ${pack.id} 由服务端注入
{ "workflows": [ { "id": "open_settings", "safe": true, "tested": true,
                   "steps": [
                     { "id": "launch", "tool": "profile_launch", "args": { "profile": "${pack.id}" },
                       "exports": { "pid": "pid" } },
                     { "id": "openSettings", "tool": "profile_action",
                       "args": { "profile": "${pack.id}", "pid": "${launch.pid}",
                                 "control": "settingsButton", "action": "invoke" } } ] } ] }

要点:

  • id 必须匹配 ^[a-z][a-z0-9._-]{0,63}$,与 profile.json 一致。

  • catalogVisibilitysession(对客户端可见)/ hidden(知道 id 可调用,不列出)。internal 已移除(无组合引擎,internal 不可达)。

  • selector 支持 automationId / name / controlType / className / frameworkId + match(exact/contains/regex)+ ancestor / path / index

语义地图(pages.json / components.json)

声明了 pages.json / components.json 的 Pack 会获得语义发现能力:模型先取紧凑地图,再通过通用工具组合动作,而不是为每个任务写 Workflow。

  • 页面:导航入口(navigationControl)、页面根(rootControl)、内容级就绪标志readyMarkers,验证页面内容可见而非仅按钮选中态)、滚动容器。

  • 选择组:互斥的通道/标签/模式(selectionGroups,成员引用控件 id)。

  • 组件/卡片:真实 UI 结构(components),带根控件、子控件和映射状态(mappingStatus: "partial" + reason)。

  • 控件语义元数据(controls.json 条目):aliases(自然语言别名)、page / parent / grouprolesearch局部搜索作用域与深度,绝不全局提升)、visibility(所属滚动容器与滚动策略,供通用 ensureVisible)、controlState(控件自身状态)、postconditions业务后置条件:引用内容标志控件,ensureSelected 必须同时满足控件状态与业务状态——UIA toggleState 单独不能证明内容已切换)、supportedActionsfallbackPolicy(禁止物理鼠标/全局键盘)。

发现工具:app_pack_describeinclude/page/compact 参数返回语义地图)、resolve_semantic_control(自然语言 → 逻辑控件路径,纯解析不执行动作)。

  • confidence 支持 stable / conditionally-stable / fragile / source-derived / runtime-verified / unsupported / action-limited

  • 菜单类控件用 menu hints 声明:opensSubmenu(键盘 Right 打开子菜单)、invokeMode:"keyboard-enter"(模态对话框命令的非阻塞触发)、panelControl(接收键盘事件的菜单面板窗口)、sectionControl(openMenu 枚举 section 的 selector)。

加载本地私有 Pack

加载来源优先级从高到低:

1. 命令行 --app-pack-dir <dir>
2. 环境变量 SCREENSHOT_MCP_APP_PACK_DIRS(平台路径分隔符分号/冒号分隔多目录)
3. %APPDATA%\ScreenShotTool-MCP\app-packs
4. <项目>/local-app-packs/           (私有 Pack,gitignored)
5. <项目>/app-packs/examples/        (公共示例)

规则:

  • 只扫描每个来源的直接子目录,每个子目录必须含 manifest.json

  • 同名 Pack 报 PACK_ID_CONFLICT,不静默覆盖。

  • 引用文件必须位于 Pack 根目录内;../ 与符号链接逃逸被拒绝(PATH_ESCAPE)。

  • Pack 只包含 JSON,不执行任何代码

  • app_pack_reload 原子重载:新配置校验失败时保留旧配置;正在运行的管道继续使用启动时快照。语义校验也是原子的:候选 Pack 存在任何 error(未知工具/不存在的 control/未知动作/错误 workflow 引用/无效输出路径/不安全 retry/重复 ID/目录逃逸/Schema 错误)时整体 reloaded=false,旧 Registry 与旧 validation cache 原样保留——app_pack_list / app_pack_describe / app_pack_validate / workflow_catalog / run_workflow / profile_launch / profile_action 始终看到同一活动版本;warning 允许加载。

验证 Pack

// 校验已加载的 Pack
{ "pack": "example-app" }
// 本地校验一个目录(不安装)
{ "packPath": "X:\\Private\\AppPacks\\example-app" }

检查项:manifest/profile/controls/actions/workflows 的 Schema、control 引用、workflow 工具名、参数 Schema、输出引用路径、循环/前向引用、敏感字段、目录逃逸、绝对路径、重复 ID、未知动作、不安全重试(非幂等 + retrySafe)。返回 { valid, errors[], warnings[], checked[] }

App Pack validator 会对可执行参数位置中疑似硬编码的凭据值发出 SENSITIVE_VALUE 警告(profile、workflow steps/finally/captureBefore 参数、嵌套 inputSchema 的 default/example/examples/const/enum、action 字面量参数),并精确标注来源文件(profile.json / workflows.json / actions.json)。控件标识符、selector、显示名称、描述与明确的环境变量名称字段(如 executableEnv)不会被当作凭据;全大写文本也不会自动视为环境变量引用。只有 App Pack 正式支持的 ${...} 引用语法(如 ${env.APP_PASSWORD})被视为非字面量引用。请使用输入或环境变量引用代替字面量秘密。

生成 Pack 草稿

{ "pid": 12345, "includeProcessPopups": true }

app_pack_probe 返回:候选主窗口规则、可操作控件(稳定 automationId、推荐 selector、Patterns)、可能的菜单层级、输入控件、Dialog、无法访问控件,以及 controls.json / profile.json 草稿(可写入临时目录)。草稿不会自动安装

使用 Workflow

{ "pack": "example-app", "workflow": "open_settings", "inputs": {} }
  • 输入按 workflow 的 inputSchema 完整校验(type / required / enum / minimum / maximum / minLength / maxLength / pattern / 嵌套对象 / 数组 items / additionalProperties),错误返回 WORKFLOW_INPUT_INVALID + validationErrors:[{path,message}];校验使用与工具 outputSchema 相同的统一 Schema 校验器,不存在第二套手写 workflow 校验器。

  • ${pack.id} 服务端注入;${inputs.x} 引用工作流输入。

  • Pack 的 defaultExpect 自动生效;步骤可引用前序步骤:${launch.pid}

  • 返回 runId、命名步骤结果、exportsfinallyResults

  • internal 可见性已移除(没有组合引擎时 internal 工作流不可达):visibility 只接受 session / hidden;声明 internal 的 Pack 在加载时被拒绝。

  • Workflow visibility 语义:session(默认)出现在 workflow_catalog 且可直接调用;hidden 不出现在 workflow_catalog,但知道准确 Pack ID + Workflow ID 时仍可通过 run_workflow 调用。

profile_run_steps

模型不需要重复传 profile / pid / includeProcessPopups

{ "profile": "example-app", "launch": { "reuseIfRunning": true },
  "steps": [
    { "id": "openMenu", "control": "mainMenuButton", "action": "openMenu" },
    { "id": "openSettings", "control": "settingsButton", "action": "invoke" } ] }

服务端自动:profile_launch(可复用运行中实例)→ 注入 profile/pid/hwnd → 按 Pack selector 解析控件 → 复合动作(selectByName / selectByIndex / openMenu / openSubmenu / ensureSelected)处理同 PID popup 并验证前后状态 → 应用 defaultExpect → finally 清理。永不移动物理鼠标。

交互模式(interactionMode)

统一交互模式控制"是否允许把目标应用带到前台"。核心保持通用:未配置的软件 保持 auto(旧行为不变);只有 App Pack 声明默认值或调用方显式传入时才改变行为。

三个模式:

  • auto(默认)——旧行为,不做任何强制、不做任何承诺。

  • background——严格后台:不抢占前台、不置顶、不移动物理鼠标、不用全局键盘输入; 截图不要求目标窗口位于屏幕顶层;后台方法失败时绝不静默升级为前台

  • foregroundDemo——仅调用方显式指定时生效:允许恢复/激活/置顶目标窗口,允许菜单、 弹窗在顶层出现;演示结束时默认恢复用户原来的前台窗口restorePreviousForeground 默认 true)。

优先级

调用方显式 interactionMode → workflow 配置(workflows.json interactionMode)
→ App Pack profile 默认值(profile.json interaction.defaultMode)→ auto

支持的参数

以下高层工具支持可选参数(显式 interactionMode 优先级高于旧的 noActivate / focus 参数,两者统一换算为 interaction policy):

{ "interactionMode": "background" }
{ "interactionMode": "foregroundDemo",
  "foregroundDemo": { "restorePreviousForeground": true, "stepDelayMs": 200 } }
  • profile_launch / profile_action / capture_window / run_steps / profile_run_steps / run_workflow

Pack 声明:profile.json

{ "interaction": {
    "defaultMode": "background",
    "allowForegroundFallback": false,   // 必须保持 false:核心从不静默升级前台
    "backgroundPresentation": "behind", // 后台显示在用户当前前台窗口之后(默认)
    "restorePreviousForeground": true } }

Pack 声明:actions.json backgroundPolicy

每个动作契约可声明后台能力:

{ "control": "sampleButton", "action": "invoke", "backgroundPolicy": "safe" }
  • safe——已确认不需要激活窗口或全局输入。

  • bestEffort——通常能后台完成,但应用或 UIA Provider 可能拒绝;失败返回明确错误, 不自动升级前台。

  • foregroundRequired——background 模式下执行前直接拒绝(FOREGROUND_REQUIRED)。

错误与管道预检

  • background 无可用后台方法 → FOREGROUND_REQUIRED (details:requestedMode/effectiveMode/foregroundChanged/reason/suggestedMode:"foregroundDemo")。

  • 管道(run_steps / profile_run_steps / run_workflow)在 background 模式下包含 foregroundRequired 步骤 → 执行任何步骤之前返回 PIPELINE_NOT_BACKGROUND_SAFE, details 列出 unsafeSteps: [{stepId, section, backgroundPolicy, suggestedMode}]预检同时覆盖主流程 steps 与 finally:即使 finally 含强制前台步骤,整条管道也会在 启动应用/执行第一步之前被拒绝。continue_run 续跑前对剩余主步骤和 finally 使用同一套预检。 bestEffort 步骤允许执行,运行时失败再返回明确错误。禁止执行到中途突然抢前台。

  • 集中后台策略表:通用工具的 backgroundPolicy 由单一策略表定义(只读 UIA 查询 = safe; UIA Pattern 操作 / PrintWindow 截图 / 定向 PostMessage / 剪贴板 / 启动 = bestEffort; 屏幕区域截图与全局键盘输入 = foregroundRequired)。步骤显式 noActivate:truesend_key / type_text 从 foregroundRequired 降为 bestEffort(允许后台执行),但绝不 把全局输入错误标成 safe。workflow_catalog 的后台能力与运行时使用同一套计算 (backgroundUnsafePipelineSteps,同时检查 steps 与 finally),目录与预检永远不会不一致。

  • 后台截图空白帧 → BACKGROUND_CAPTURE_UNAVAILABLE(不自动置顶重试)。

  • 后台启动时若应用自身抢前台,核心尝试恢复原前台窗口并如实报告 foregroundChanged:true / foregroundRestored:true;无法恢复时返回 warning,绝不谎报。

统一结果元数据 interaction

高层工具与管道结果新增 interaction 报告:

{ "interaction": { "requestedMode": "background", "effectiveMode": "background",
    "backgroundPolicy": "safe", "method": "InvokePattern",
    "foregroundBefore": "0x1A2B3C", "foregroundAfter": "0x1A2B3C",
    "foregroundChanged": false, "foregroundChangedDuringRun": true,
    "foregroundRestored": true,
    "targetActivated": false, "physicalCursorMoved": false } }

管道顶层报告在开始时与全部步骤/restore/finally 结束后真实读取前台 HWND,并汇总所有 步骤、finally 与恢复动作的 interaction:

  • foregroundChanged = 结束时前台与开始时不同(最终差异)。

  • foregroundChangedDuringRun = 过程中任何时刻发生过前台变化——即使最终已恢复也如实 保留(不得因恢复成功而隐藏过程变化)。

  • foregroundRestored = 最终前台读回与开始时相同(以最终读取为准,不只相信子步骤布尔值)。

  • targetActivated / physicalCursorMoved = 汇总真实步骤结果。

  • background 管道结束时前台未恢复 → foregroundChanged:true / foregroundRestored:false + warning BACKGROUND_FOREGROUND_NOT_RESTORED(不影响已完成业务步骤的成功语义)。

continue_run 继承原运行已解析的交互上下文(interactionMode / foregroundDemo 选项 restorePreviousForeground / stepDelayMs / allowForegroundFallback),不根据当前 Pack 默认值 重新推导;旧格式快照回退为 Pack 默认并返回 RUN_INTERACTION_CONTEXT_MISSING warning。

覆盖 profile_launch / profile_action / profile_run_steps / run_workflow / continue_run / capture_window(截图还报告真实 captureMethod)。workflow_catalogapp_pack_describe 公开 defaultInteractionMode / backgroundPolicy / foregroundRequiredSteps,模型第一次使用时即可判断哪些 Workflow 可完全后台运行。

命名步骤与 exports

{ "steps": [
    { "id": "app", "tool": "profile_launch", "args": { "profile": "example-app" },
      "exports": { "pid": "pid", "hwnd": "hwnd" } },
    { "id": "check", "tool": "ui_wait",
      "args": { "pid": "${app.pid}", "selector": { "controlType": "Window" }, "condition": "exists" } } ] }
  • 引用:${app.pid}(命名)、${0.pid}(旧数字引用,保持兼容)、${pack.id}${inputs.x}

  • Step id 规则 ^[A-Za-z][A-Za-z0-9_-]{0,63}$,必须唯一;保留名 vars/env/steps/results/run/pack/inputs

  • exports 在步骤完成后立即校验:路径存在、中间节点非 null、类型正确、敏感字段名禁止(password/token/credential/secret/authorization/cookie)。错误码 EXPORT_PATH_NOT_FOUND / EXPORT_VALUE_NULL / EXPORT_SENSITIVE_VALUE_BLOCKED 等。

  • 限制:每步最多 32 个 exports、路径 ≤256 字符、嵌套深度 ≤16、单字符串 ≤64 KiB。

expect / retry / finally

步骤成功 = 工具执行成功 AND 后置条件匹配。 仅 InvokePattern 未报错不算完成。

{ "id": "openDialog", "tool": "profile_action",
  "args": { "profile": "example-app", "pid": "${app.pid}", "control": "settingsButton", "action": "invoke" },
  "expect": { "profileControl": "settingsDialog", "condition": "exists", "timeoutMs": 5000 },
  "retry": { "maxAttempts": 3, "delayMs": 200, "onlyCodes": ["ELEMENT_NOT_AVAILABLE", "POPUP_NOT_READY"] } }
  • 条件:exists/notExists/visible/hidden/enabled/disabled/valueEquals/valueContains/toggleStateEquals/selected/notSelected/expanded/collapsed/countEquals

  • 超时错误:STEP_POSTCONDITION_TIMEOUT

  • actions.jsondefaultExpect 在调用方未提供 expect 时自动生效;显式 expect 优先;expect:false 关闭(返回 warning)。

  • 默认可重试:ELEMENT_NOT_AVAILABLE / UIA_ROOT_UNAVAILABLE / TARGET_WINDOW_NOT_READY / POPUP_NOT_READY / PROVIDER_BUSY不可重试(除非 onlyCodes 显式列出):ELEMENT_AMBIGUOUS / WINDOW_AMBIGUOUS / INVALID_SELECTOR / INVALID_PARAMS / PATTERN_NOT_SUPPORTED / PASSWORD_VALUE_PROTECTED / TOOL_OUTPUT_SCHEMA_MISMATCH。非幂等动作不自动重试;validate_steps 对非幂等 + retry 报 UNSAFE_RETRY

  • finally:主流程成功或失败都执行;失败单独记录、不覆盖主错误;ignoreCodes 容忍指定错误码。

  • 状态恢复:captureBefore 在操作前读取控件的类型化状态(value / toggle / selection / range / expanded / visibility / page),restore: "always" | "never" | "onFailure" 在 finally 用匹配的反向动作恢复(setValue / setChecked / selectByName / setRangeValue / expand|collapse / ensureSelected),恢复后重新查询 UI 验证(真实重读,绝不用保存值自证)。密码控件禁止捕获/恢复/导出(RESTORE_SENSITIVE_STATE_BLOCKED);无法可靠读取的状态不执行猜测式恢复(RESTORE_STATE_UNAVAILABLE)。旧格式 {saveAs, read} 自动映射为 value 类型;{saveAs, state:"auto"} 按控件状态自动检测。

  • selection 恢复:捕获的是操作前真实选中项element.value/selectedName + provider 暴露的 selectedIndex,必要时通过列表项扫描读取),绝不使用步骤的目标 value/index 参数。恢复顺序:有可靠 name → selectByName 并验证;name 失败且有原始 index → selectByIndex(originalIndex) 并验证;两者皆不可得 → RESTORE_STATE_UNAVAILABLE(不猜测)。

  • page 恢复:页面组由控件/动作契约的可选 selectionGroup 声明(同组控件互斥)。捕获在动作前逐个查询同组控件,找到唯一选中(toggleState On / selected true)的作为原页面——绝不把动作目标当原页面;0 个或多个选中 → RESTORE_STATE_UNAVAILABLE。恢复对原页面 ensureSelected,验证时重查原页面 selected 且目标页面不再 selected。

  • restore 结果包含 {kind, attempted, success, verified, code, message};错误码:RESTORE_STATE_UNAVAILABLE(原状态不可读,不执行恢复)/ RESTORE_VERIFICATION_FAILED(已恢复但状态不匹配)/ RESTORE_SENSITIVE_STATE_BLOCKED(密码/敏感状态禁止捕获)。

续接失败的 run

run_steps / profile_run_steps / run_workflow 都返回 runId。失败后:

{ "runId": "run_abc123", "continueFrom": "openSettings" }

续接前检查:run 未过期(内存保留 10 分钟,最多 20 个)→ Pack 版本未变(RUN_PACK_VERSION_CHANGED)→ 进程仍存在且窗口仍有效RUN_PROCESS_EXITED / RUN_WINDOW_RECREATED / RUN_WINDOW_UNAVAILABLE——进程存活用 OpenProcess/GetExitCodeProcess 真实查询,绝不用"是否还有顶层窗口"代表进程存活)→ 快照可续接(RUN_NOT_CONTINUABLE)。续接从失败步骤重放,已完成步骤的最小投影(后续步骤引用的字段 + pipe-safe 字段 + exports)复用,不重复执行、不保存完整原始结果。超大的快照(含被引用的巨型字段)如实标记 continuable:false + continuationReason:"RUN_SNAPSHOT_TRUNCATED",绝不伪装成可恢复。

续跑的统一生命周期

续跑是一条单一 run:开始计算一次总截止时间(沿用原 maxTotalMs),剩余主步骤、expect、retry、restore、finally 与 foregroundDemo 的 stepDelayMs 全部共享该 deadline——不允许每个步骤重新获得完整预算。续跑结束时:

  • restore:用 RunSnapshot 中保存的原运行捕获状态重放恢复动作并重新验证 UI;快照没有可用状态时如实返回 RESTORE_STATE_UNAVAILABLE,绝不静默跳过并谎报 cleanup 成功。已由原运行执行的 finally/restore 不会重复执行:RunSnapshot 记录 finallyRan(finally 步骤 key)与 capturedState(原捕获值),续跑只执行原运行未到达的 finally 步骤、只重放并验证 restore。

  • finally:续跑成功失败都执行一次;原失败运行在进入 finally 前停止时,由续跑执行;原运行已执行完成的 finally 步骤报告为 alreadyRan,不重复执行。

  • 续跑段 exports 按全局步骤索引记录(不是从 0 开始的段内索引),多次续接不会错位。

输出 Schema 与 structuredContent

每个工具在 src/contracts.ts 有统一 ToolContractdescriptioninputSchemaoutputSchemapipeSafeFieldsannotations(readOnly / destructive / idempotent / retrySafe / needsExpect)。Schema 校验是结构性子集(type / required / properties / items / enum / anyOf / additionalProperties / minimum / maximum / minLength / maxLength / pattern),并非完整 JSON Schema 实现;未声明的关键字被忽略,额外字段默认允许。

稳定公共输出字段:schemaVersion / success / pid / hwnd / title / found / count / element / elements / value / matched / timedOut / code / message / details

  • 工具成功结果同时返回 content(JSON 文本,保持兼容)与 structuredContent(机器可读对象)。业务错误同样结构化:isError:true + text 内容(旧客户端兼容)+ structuredContent:{ success:false, error:{ code, message, details } }

  • 管道中每个步骤的结果都会用该工具的 outputSchema 做运行时校验,不符合返回 TOOL_OUTPUT_SCHEMA_MISMATCH无效结果不会流入后续步骤

  • 数组工具的 canonical 输出list_windows / profile_list / app_pack_list / workflow_catalog / tool_contract_list 等数组型工具在普通调用、structuredContent、管道步骤结果、exports 与 run snapshot 中统一返回 { items: [...] },与 tools/list 的 outputSchema 完全一致:${step.items.0.hwnd} 可静态验证并运行。旧的 ${0.0.hwnd} 裸数组引用保持兼容(引用解析器自动把顶层数字段映射到 items.N)。

安全限制

  • 每条管道 ≤50 步、finally ≤20 步、每步 ≤32 exports、引用深度 ≤16、单步结果 ≤1 MiB、整条结果 ≤5 MiB、默认总超时 120s、最大重试 5 次、最多 20 个 run、TTL 10 分钟。

  • 最多加载 64 个 Pack;每个 Pack ≤1000 controls、≤200 workflows。

  • 禁止:eval / Function 构造器 / 任意脚本 / 任意 PowerShell / JSONPath 脚本表达式 / 从 Pack 读取环境变量值 / 访问 Pack 外文件 / 从 Pack 发起网络请求 / 跨 run 未授权引用 / 密码写入日志。

  • 禁止:SetCursorPos、真实鼠标 SendInput、固定坐标点击、OCR 坐标点击、图像模板点击。降级链全部使用窗口消息或键盘输入,physicalCursorMoved 恒为 false。

私有 Pack 与公共仓库

  • local-app-packs/private-app-packs/runtime-app-pack-cache/outputs/ 已被 .gitignore 忽略。

  • 私有 Pack 不得提交到公共仓库:本机绝对路径、控件清单、工作流细节属于私有时,不要放入公共 README 或测试。

  • 本仓库的实机验证使用本地 Qt 应用 App Pack(通过环境变量提供可执行文件路径),其配置不包含在公共仓库中。公共测试脚本只读取 SCREENSHOT_MCP_TEST_PACK / SCREENSHOT_MCP_TEST_EXE / SCREENSHOT_MCP_APP_PACK_DIRS 环境变量,不写死任何私有应用名。

测试

npm test                          # 单元测试(App Pack / pipeline / executor / contracts / workflows / runs / piping / schemas / UIA)
npm run smoke:app-pack            # App Pack + 管道 e2e(公共示例 Pack;含 reload 坏配置 → reloaded:false)
npm run smoke:run-steps           # run_steps 顺序/管道/停链语义
npm run smoke:continue-run        # runId / continue_run e2e
npm run smoke:workflow            # workflow_catalog / run_workflow e2e
npm run smoke:first-use-pipeline  # fresh-process 稳定性基准(默认 20 次迭代)
npm run smoke:public-contract-pipeline  # 公开契约驱动管道测试(不读取源码)
npm run smoke:page-fixture          # 页面恢复实机 fixture(临时 WPF 应用,3 页互斥导航)
npm run smoke:uia-notepad         # 通用 UIA smoke(系统编辑器)
npm run smoke:private-app-pack    # 私有 Pack 驱动(读 SCREENSHOT_MCP_TEST_PACK 等环境变量)
# 以及既有 smoke:notepad / type-text / menu-click / no-cursor-click / print-capture /
# p1-fixes / perf / no-activate / clipboard / window-state / wait-for-window

关于 benchmark 的准确表述

  • smoke:first-use-pipelinefresh-process pipeline stability benchmark(固定工作流的进程级稳定性)与 contract-driven first-use simulation(公开契约驱动的首次使用模拟):每次迭代启动全新服务器进程,仅通过 tools/listapp_pack_describeworkflow_catalog 等公开能力驱动固定工作流。它不是真实大模型自主生成管道的测试。

  • 统计严格区分:workflowFirstAttemptSuccessRate / pipelineFirstAttemptSuccessRate(首次尝试,不含 continue 恢复)、*EventuallySuccessRate(最终成功,允许一次 continue_run 恢复)、continueRecoverySuccessRatecleanupSuccessRate(finally 独立)、infrastructureFailureCount(服务器/传输失败,不计为工作流失败)。

  • continueRecoverySuccessRate 的分母是 continueAttempts(实际 continue_run 调用次数),不是迭代次数;continueRecoverySuccessCount 表示成功的 continue_run 调用次数(同一 iteration 内多次 continue 各自独立计数),而非发生过恢复成功的 iteration 数量;0 次尝试时返回 null(绝不用 0 伪装成"恢复全部失败")。continue 成功从不改变 firstAttempt 统计。

  • 环境前提:键盘类步骤(type_text / send_key)依赖前台焦点。残留的编辑器实例(多个同进程名窗口)或前台全屏程序会抢占焦点并拉低 first-attempt 成功率(实测:清理残留实例后 20/20)。

  • 真实不同模型的自主生成成功率需要单独评测:仅凭公开工具契约构造合法管道由 smoke:public-contract-pipeline 证明——该测试不导入任何 src/ 实现,只通过 MCP 客户端读取契约并构造、校验、执行管道。

热重载边界:默认启用(SCREENSHOTTOOL_HOT_RELOAD=0 关闭),但只对实际动态加载的模块生效src/schemas.tssrc/windows.tssrc/profiles/registry.tsscripts/win-capture.ps1。 修改其他核心源码(pipeline / contracts / executor / app-packs / interaction 等)后建议重启 MCP 服务器——这些模块是静态导入的,运行中不承诺热重载,混合新旧模块状态不受支持。 App Pack JSON 通过 app_pack_reload 独立热重载。

限制(真实,已实机确认)

  • click_window / move_mouse_window 只投递窗口消息:不支持拖拽、手势、真实 hover。Qt/Electron 应用读取系统光标位置,假消息不会触发 tooltip/右键菜单——需要时请请求人类操作。

  • PrintWindow 无法捕获独立顶层弹窗(Qt ToolTip、菜单面板、Electron 子窗口);captureMethod:"screen" 捕获的是屏幕可见内容,可能被遮挡。

  • 严格 background 模式使用非激活的 PrintWindow。如果 PrintWindow 返回 blank frame 或明显异常的窗口几何,而用户确实需要可见屏幕截图,可针对同一 targetRef 显式重试:captureMethod="screen" + interactionMode="foregroundDemo"不要只修改 captureMethod,因为 background 模式会继续强制使用 PrintWindow。

  • UIA 依赖目标应用的无障碍实现:无 ValuePattern 的编辑控件不能 setValue;自定义绘制的菜单/ComboBox 只能走声明在 Pack 中的降级路径;某些控件如实标记 unsupported(如 popup 内未暴露的 QLineEdit)。

  • 前台被游戏/全屏程序占用时,光标与焦点相关断言可能假失败。

Available Tools

10 tools
capture_screen_regionB

Capture a screen-space rectangle in physical pixels.

ParametersJSON Schema
NameRequiredDescriptionDefault
regionYesScreen-space rectangle in physical pixels.
outputPathNoOptional absolute PNG output path.

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations exist, so the description must disclose behavioral traits. It only states the basic functionality and fails to mention error handling (e.g., invalid region), output format, or any side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single clear sentence with no wasted words. It could be slightly expanded for context, but it remains concise and front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (2 parameters, nested object) and no output schema, the description lacks completeness. It omits details on output path behavior, coordinate system, and potential errors, making it insufficient for an agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with descriptions for each parameter. The description adds no extra meaning beyond the schema, so a baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('capture') and the resource ('a screen-space rectangle'), and the sibling tool 'capture_window' implies a distinct purpose, so it effectively distinguishes from alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus siblings like 'capture_window'. The description provides no context on appropriate scenarios or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

capture_windowA

Capture a window by hwnd, pid, process name, or title substring. captureMethod 'print' works on occluded/minimized windows. noActivate avoids stealing focus.

ParametersJSON Schema
NameRequiredDescriptionDefault
hwndNoWindow handle from list_windows or launch_app. Numbers are accepted at runtime, but strings are safest for Codex.
pidNo
processNameNo
titleContainsNo
regionNoOptional rectangle relative to the target window top-left corner.
focusNoBring the window to the foreground before capturing. Set false to preserve open menus, popups, or transient UI.
captureMethodNoCapture method: 'screen' uses CopyFromScreen (needs visible area), 'print' uses PrintWindow API (captures window content even behind other windows).screen
noActivateNoWhen true with captureMethod 'screen', the window is raised above overlapping windows without stealing keyboard focus, then restored after capture.
outputPathNoOptional absolute PNG output path.

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must fully disclose behavioral traits. It mentions special behaviors for print method and noActivate, but lacks details on permission requirements, error handling (e.g., if no window matches), or side effects (e.g., window state changes). The description is adequate but not comprehensive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise: two sentences that front-load the core purpose and highlight two key options. Every sentence adds value, with no wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 9 parameters (complex) and no output schema, the description could be more complete. It doesn't mention the output format (presumably an image file) or error conditions. However, the high schema coverage and concise core description make it minimally viable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 67% (high), so the schema already documents many parameters. The description adds context for captureMethod ('captures window content even behind other windows') and noActivate ('avoids stealing focus'), but these are partially redundant with schema descriptions. The added value is modest, warranting a baseline of 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Capture' and resource 'a window', and lists specific identification methods (hwnd, pid, process name, title substring). This distinguishes it from siblings like capture_screen_region (which captures a region, not a window) and list_windows (which lists windows without capturing).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides guidance on when to use 'print' capture method (for occluded/minimized windows) and noActivate (to avoid stealing focus). However, it does not explicitly state when not to use the tool or suggest alternatives beyond implicit differentiation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

click_menu_itemA

Invoke a native Windows menu item by menu path without moving the physical cursor or using keyboard shortcuts.

ParametersJSON Schema
NameRequiredDescriptionDefault
hwndNoWindow handle from list_windows or launch_app. Numbers are accepted at runtime, but strings are safest for Codex.
pidNo
processNameNo
titleContainsNo
pathYesNative menu path, for example ["帮助", "关于"]. Matching ignores accelerator markers and is case-insensitive.
delayMsNoDelay after invoking the menu command.

TDQS

A3.6/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the burden. It only states the basic action and does not disclose error behavior, prerequisites (e.g., window focus), or what happens if the menu path is invalid.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single sentence that is front-loaded with the main action and key distinguishing feature. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 6 parameters and no output schema, the description is too sparse. It lacks guidance on window identification (hwnd vs pid vs processName vs titleContains), error handling, and return behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 50% (3 of 6 params described). The description adds meaningful context for 'path' by specifying matching behavior (ignore accelerators, case-insensitive), which aids correct invocation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool invokes a native Windows menu item by menu path, and distinguishes from moving cursor or using keyboard shortcuts, which differentiates it from sibling tools like click_window and send_key.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies use for menu navigation without cursor or keyboard, but does not explicitly state when to use this tool versus alternatives like click_window, send_key, or type_text for menu access.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

click_windowA

Post mouse click messages to a window-relative coordinate without moving the physical cursor.

ParametersJSON Schema
NameRequiredDescriptionDefault
hwndNoWindow handle from list_windows or launch_app. Numbers are accepted at runtime, but strings are safest for Codex.
pidNo
processNameNo
titleContainsNo
xYesX coordinate relative to the target window top-left corner.
yYesY coordinate relative to the target window top-left corner.
buttonNoMouse button: left, right, or middle.left
doubleClickNo
delayMsNoDelay after posting mouse messages, useful before taking the next screenshot.

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden. It discloses the key behavior (no cursor movement) but omits other behavioral traits like permissions, side effects, trigger behavior, or error handling. It is moderately transparent but incomplete.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence that conveys the core purpose and distinguishing feature efficiently. Every word earns its place with no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 9 parameters, no output schema, and no annotations, the description is incomplete. It fails to explain how to identify the target window using hwnd/pid/processName/titleContains, which is crucial for correct usage. The description only covers the click mechanism, leaving significant context gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 56%, above 50% baseline. The description adds no further parameter details beyond the schema. With moderate schema coverage, a score of 3 is appropriate as the description does not enhance parameter understanding.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool posts mouse click messages to window-relative coordinates without moving the physical cursor. It uses a specific verb ('Post') and resource ('mouse click messages'), and distinguishes itself from sibling tools like move_mouse_window and click_menu_item.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage when a click without cursor movement is needed, but does not explicitly state when to use this tool over alternatives. It lacks explicit 'use this when' or 'instead of' guidance, making it adequate but not strong.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

close_appA

Terminate a process and its descendants via taskkill /T /F.

ParametersJSON Schema
NameRequiredDescriptionDefault
pidYesProcess ID. taskkill /T /F is used, which terminates the entire process tree (the target plus any child processes it spawned).

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Without annotations, the description reveals that the tool is destructive (terminates process tree) and uses forced termination (/F). However, it does not discuss side effects, permissions required, or data loss risks, leaving gaps in transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, efficient sentence that conveys the core action and method without any superfluous content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple tool with one parameter and no output schema, the description fully captures the essential behavior and constraints, leaving no critical gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already covers the pid parameter with a detailed description that matches the tool's description. Since schema coverage is 100%, the baseline is 3, and the description adds no additional semantic value beyond reiteration.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly specifies the action ('terminate'), the resource ('process and its descendants'), and distinguishes from siblings like launch_app or capture by focusing on process termination via taskkill with /T /F flags.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool vs. alternatives (e.g., close_window or other termination methods), nor any warnings about prerequisites or contexts to avoid.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

launch_appA

Launch a Windows .exe and optionally wait for its first visible window. Use noActivate to prevent the window from stealing focus.

ParametersJSON Schema
NameRequiredDescriptionDefault
exePathYesAbsolute path to the .exe to launch.
argsNoProcess arguments as an array.
cwdNoOptional working directory for the process.
waitForWindowNoWait for the first visible window for the process.
timeoutMsNo
startMinimizedNoStart the process minimized. The window will not appear on top.
noActivateNoWhen true, the window is placed at the bottom of the z-order without receiving focus. Combines well with startMinimized for fully non-intrusive launches.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and adequately discloses key behaviors: optional waiting, noActivate prevents focus stealing, and startMinimized for non-intrusive launches. However, it does not mention errors, permissions, or return behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no wasted words. Each sentence provides essential information: what the tool does and a key parameter hint.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema, the description does not explain return values or whether the tool is synchronous. It covers the main purpose and two key parameters but lacks explicit mention of required fields (exePath) and process behavior after launch.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is high (86%), so baseline is 3. The description adds value beyond schema by explaining noActivate's effect and suggesting combination with startMinimized for non-intrusive launches, providing usage context not in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action 'Launch a Windows .exe' and key optional behaviors like waiting for the first visible window and preventing focus stealing with noActivate. This distinguishes it from sibling tools like close_app or list_windows.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for launching executables and controlling focus, but does not explicitly state when to use this tool versus alternatives (e.g., close_app). No exclusions or when-not-to-use guidance provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_windowsA

List visible top-level Windows desktop windows, optionally filtered by pid, process name, or title substring.

ParametersJSON Schema
NameRequiredDescriptionDefault
pidNo
processNameNoProcess name with or without .exe.
titleContainsNoCase-insensitive title substring.

TDQS

A3.5/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description bears full burden for behavioral disclosure. It mentions 'visible top-level' and optional filters but does not explain side effects, performance, error cases, or read-only nature. The description is too vague.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence of 16 words, front-loaded with the main action. Every word earns its place; no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Adequate but missing return format details (e.g., what data is returned for each window). With no output schema, the description should explain the output. Also no mention of behavior with no filters (lists all windows).

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description adds meaning by stating filters are optional and what they filter by. While the schema covers 67% of parameters with descriptions, the tool description confirms the filtering pattern and adds context for pid which lacks schema description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists visible top-level Windows desktop windows with optional filters, using a specific verb and resource. It distinguishes from siblings like capture_window and click_window which perform different actions on windows.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit guidance on when to use this tool versus alternatives. The description lacks context about prerequisites or when not to use it, which is needed given the many sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

move_mouse_windowA

Post a WM_MOUSEMOVE message to a window-relative coordinate without moving the physical cursor, useful for hover states before taking a screenshot.

ParametersJSON Schema
NameRequiredDescriptionDefault
hwndNoWindow handle from list_windows or launch_app. Numbers are accepted at runtime, but strings are safest for Codex.
pidNo
processNameNo
titleContainsNo
xYesX coordinate relative to the target window top-left corner.
yYesY coordinate relative to the target window top-left corner.
delayMsNoDelay after posting WM_MOUSEMOVE, useful before taking the next screenshot.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full behavioral burden. It discloses the key behavioral trait: the tool does not move the physical cursor (only posts a message). It also indicates the intended effect (hover states). However, it omits potential side effects, blocking behavior, or error handling.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, concise sentence that front-loads the action and key details, with no unnecessary words or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 7 parameters and no output schema, the description is brief and covers the primary purpose and use case. It does not explain how to target the window (via hwnd, pid, etc.) or discuss return values or error conditions. The sibling tools context helps, but the description could be more complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 57% (4 of 7 parameters have descriptions). The tool description adds no new parameter information beyond what is in the schema; it only mentions 'window-relative coordinate' which is already described for x and y. The undocumented parameters (pid, processName, titleContains) are not explained.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action: posting a WM_MOUSEMOVE message to a window-relative coordinate without moving the physical cursor. It specifies the use case (hover states before screenshot) and distinguishes from sibling tools (no other tool moves the mouse without clicking).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a clear use case ('useful for hover states before taking a screenshot'), which guides when to use it. It does not explicitly state when not to use or list alternatives, but the sibling tools imply that this is for simulated hover without cursor movement.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

send_keyB

Send a keystroke with optional modifiers. noActivate uses PostMessage WM_KEYDOWN/WM_KEYUP so the target window doesn't need focus.

ParametersJSON Schema
NameRequiredDescriptionDefault
hwndNoWindow handle from list_windows or launch_app.
pidNo
processNameNo
titleContainsNo
keyYesKey name to send. Supports single printable ASCII characters and named keys: esc, tab, enter, space, arrows, f1-f12, backspace, delete, home, end, pageup, pagedown.
modifiersNoModifier keys to hold during the keypress.
delayMsNo
pressMsNo
noActivateNoWhen true, sends WM_KEYDOWN/WM_KEYUP via PostMessage instead of keybd_event, so the target window never needs focus. Some applications may not respond to posted messages.

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It explains the noActivate behavior but does not disclose other behavioral traits such as whether it simulates actual keystrokes, how modifiers combine, or any side effects like focus changes. Minimal disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences are concise and front-loaded. The first sentence states the core function, and the second explains a key parameter. However, it lacks detail on other parameters.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 9 parameters and no output schema or annotations, the description is incomplete. It does not explain how to target a window using hwnd, pid, processName, or titleContains, nor does it clarify delayMs and pressMs behavior. Lacks sufficient context for a complex tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 44%, so the description adds no extra parameter meaning beyond the schema's descriptions. The schema already describes hwnd, key, modifiers, and noActivate adequately. The tool description only repeats noActivate behavior.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool sends a keystroke with optional modifiers and distinguishes itself from siblings like type_text by mentioning the noActivate behavior. It uses a specific verb and resource.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus alternatives like type_text or click_window. The description does not mention prerequisites, contexts, or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

type_textA

Type text into a window via SendInput Unicode. noActivate uses PostMessage WM_CHAR so the target window doesn't need focus.

ParametersJSON Schema
NameRequiredDescriptionDefault
hwndNoWindow handle from list_windows or launch_app.
pidNo
processNameNo
titleContainsNo
textYesText to type into the target window. Sent via SendInput Unicode, so any Unicode character including CJK is supported.
delayMsNoDelay between keystrokes in milliseconds.
pressMsNoDuration of each key press in milliseconds.
noActivateNoWhen true, sends WM_CHAR messages via PostMessage instead of SendInput, so the target window never needs focus. Some applications may not respond to posted messages.

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Despite no annotations, the description discloses the underlying mechanism (SendInput vs PostMessage WM_CHAR), notes that some applications may not respond to posted messages, and explains the noActivate behavior. However, it lacks details on safety, visibility requirements, or interruption behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence that front-loads the core action. Every part contributes meaning, with no wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (8 parameters, no output schema), the description covers the targeting method and a behavioral variant but omits return values, error handling, and safety considerations. Adequate but not fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description adds value beyond the schema by explaining that hwnd comes from list_windows or launch_app and that text supports any Unicode characters. With 63% schema coverage, these additions are helpful, though not exhaustive.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action (type text), the method (SendInput Unicode), and the resource (window). It also distinguishes the noActivate alternative, providing a specific verb and resource.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not provide guidance on when to use type_text versus sibling tools like send_key, click_window, or launch_app. No explicit when-to-use or when-not-to-use information is given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 10 tool updatesv0.1.0
    • First observedcapture_screen_region
    • First observedcapture_window
    • First observedclick_menu_item
    • First observedclick_window
    • First observedclose_app
    • First observedlaunch_app
    • First observedlist_windows
    • First observedmove_mouse_window
    • First observedsend_key
    • First observedtype_text

TDQS

A3.9/5.0
Disambiguation5/5

All tools have clearly distinct purposes: capturing, listing, launching/closing apps, and various input actions (click, menu click, move mouse, send key, type text). Even the two input tools (send_key vs type_text) are differentiated by keystrokes vs text input.

Naming Consistency5/5

All tools follow a consistent verb_noun pattern with lowercase and underscores (e.g., capture_screen_region, click_window, send_key). No mixing of camelCase or other conventions.

Tool Count5/5

10 tools cover the main actions for screen capture and window interaction (capture, list, launch, close, click, menu click, keyboard input, mouse move). Not too few or too many for the scope.

Completeness4/5

Covers core capture and interaction needs, but lacks explicit full-screen capture, monitor enumeration, mouse scrolling, or window sizing. These are minor omissions for a screenshot-focused toolset.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

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

Related MCP Connectors

Related MCP Servers

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