关于 core
Electron Stagewright 是面向真实 Electron 应用的 MCP 服务,供 Agent 驱动 UX 测试。它支持启动或连接应用、检查可访问性界面状态、执行交互并验证行为,同时提供有界证据和诊断信息。
主要功能
- 01启动、连接或注入 Electron 应用
- 02检查可访问性快照和状态
- 03通过稳定元素引用进行交互
- 04重试式断言与组合条件等待
- 05采集截图、控制台和会话跟踪
- 06验证已打包并签名的应用
适用场景
- 01在开发期间测试 Electron 应用界面流程
- 02连接正在运行的应用而不重启
- 03使用重试式预期验证行为
- 04通过跟踪和诊断信息排查故障
MCP 相关
向兼容 MCP 的 Agent 提供 Electron 应用自动化和验证工具。客户端可启动或连接应用、检查并操作界面、断言状态及收集诊断信息。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
55收录的工具列表 · 更新于 4 天前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| ref | integer | 否 | 来自快照的元素 ref(解析为 [data-sw-ref="N"])。请提供 ref 或 selector。 |
| flags | string | 否 | 应用于正则表达式谓词的可选正则标志(i、m、s、u 中的任意项);由于 g 和 y 具有状态性,因此不接受。仅当使用正则表达式谓词时有效。 |
| equals | string | 否 | 该值必须与此值完全相等。 |
| contains | string | 否 | 该值必须包含此子字符串。 |
| selector | string | 否 | CSS 选择器。请提供 ref 或 selector,不能同时提供两者。 |
| attribute | string | 否 | 要读取的属性名称(例如 "value"、"aria-label")。省略则读取文本。 |
| sessionId | string | 否 | 目标会话 ID。仅在有多个会话运行时省略。 |
| matches_regex | string | 否 | 该值必须匹配此 JavaScript 正则表达式。 |
详细介绍
Electron Stagewright
面向 Agent 的真实 Electron 应用 UX 测试。为应用发出指令、验证体验,并通过 MCP 返回有界证据。
Electron Stagewright 是一个模型上下文协议(MCP)服务,可让 Claude Code、Codex、Cursor、Cline、Aider 以及任何兼容 MCP 的 Agent 操作真实的 Electron 应用。启动或连接应用,检查无障碍树,通过稳定的 ref 进行交互,使用可重试的断言验证行为,并捕获诊断信息,避免每次检查都要额外往返一次 Agent。
为什么要开发它
浏览器自动化已经拥有成熟的 Agent 工具。Electron 则增加了不同的边界:主进程、渲染器界面、原生菜单和对话框、多个窗口、打包后的运行时,以及经过签名的发布构件。通过 MCP 暴露的浏览器 API 并不能覆盖整个产品。
Electron Stagewright 从底层原语开始,专为 Agent 优先而设计:
- 错误会提供提示、建议的后续操作和相似 ref 的替代项 — Agent 无需额外往返询问上下文即可恢复。
- 每个响应都会报告自身的 token 开销 — Agent 可以实时进行预算规划,而不是事后估算。
get_state一次调用即可返回完整状态封装 — 可见、启用、选中、聚焦、禁用、aria-expanded、aria-busy、aria-invalid。无需连续调用 4 次,才能判断按钮是否可点击。wait_for_state接受复合谓词 —{ visible: true, enabled: true, focused: false }由服务原子性地评估。一次调用即可替代三次。- 快照会标记
recently_changed元素 — Agent 可专注推理与上次视图相比发生变化的内容,而不必重新处理整棵树。 - 快照差异是一个参数,而非单独的工具 —
electron_snapshot({ since: 'last' })只返回差异。需要记住的 API 更少。 - 按需紧凑文本编码 —
electron_snapshot({ format: 'text' })会为每个元素渲染一行([3] textbox "Email" value="" focused),仅包含非默认状态;当 Agent 只需查看界面时,与 JSON 格式相比,快照 token 数可减少 5 到 10 倍。 expect_*原语取代读取、比较、重试链 —electron_expect_text({ ref, equals: 'Welcome', timeoutMs: 5000 })一次调用即可完成,而不是五次。electron_find可通过语义查询无障碍树 —{ role: 'button', name_contains: 'Submit', visible: true }— 无需 CSS 选择器、XPath 或猜测。- 感知热重载 — 快照和查找响应会报告渲染器是否在上次基线之后重新加载,让 Agent 知道 ref 可能需要刷新。
- 与框架无关的快照 — 基于无障碍角色和 ARIA,而非框架内部属性。当前测试样例涵盖 vanilla、React、Vue 和 Angular;更广泛的渲染器支持矩阵仍在扩展中。
Electron 工作流深度集成
该服务将三种 Electron 专属工作流视为一等功能:
- 连接到正在运行的开发服务,无需重启。
electron_attach可连接到提供环回 CDP 端点的应用;如果事先未配置调试标志,electron_inject可通过 Node Inspector 握手连接到正在运行的主进程。 - 支持确定性重放和按工具设置 token 预算的会话追踪。 灵感来自 Playwright 的
trace.zip,但专为 LLM Agent 会话设计:记录工具调用、参数、结果、耗时和 token 估算的时间线,可针对新的应用实例重放,并设有预算,让 Agent 可以限制失控循环。 - 对已签名、公证并打包的
.app包进行端到端验证——codesign、Gatekeeper 评估、autoUpdater 源检查、URL scheme 声明检查以及崩溃报告机制。覆盖完整的生产环境功能,而不只是开发环境。
Microsoft 官方 Playwright MCP 团队明确拒绝支持 Electron(“你们可以为 Electron 发布自己的服务”——负责人 Pavel Feldman)。本项目认真接受了这一邀请。
快速开始
需要 Node.js 24 或更高版本(node -v);在 Linux 上,服务还需要显示环境(DISPLAY、WAYLAND_DISPLAY 或 xvfb-run -a)。默认启动传输使用 Playwright 和 Electron 运行时。若要在当前项目中进行私有配置,请将服务保留在该项目本地,并固定经过发布测试的软件包集合。
配置 MCP 宿主之前,先在终端中准备一次相同的软件包集合。Electron 会在首次加载时下载其二进制文件,而不是在安装期间下载;下载过程会向 stdout 输出进度行,在 MCP 会话中,这一行会进入协议流。使用 Electron 的 install-electron bin 获取二进制文件,然后运行 doctor;所有必需检查均通过时,它会报告 "ok": true 并以 0 退出:
npx -y --prefix ~/ --package @electron-stagewright/[email protected] \
--package [email protected] --package [email protected] install-electron
npx -y --prefix ~/ --package @electron-stagewright/[email protected] \
--package [email protected] --package [email protected] electron-stagewright doctor --json
claude mcp add electron-stagewright -- \
npx -y --prefix ~/ --package @electron-stagewright/[email protected] \
--package [email protected] --package [email protected] \
electron-stagewright --tool-profile essential
随后,claude mcp list 应显示服务已连接(也可以在会话中运行 /mcp),其工具会显示为 mcp__electron-stagewright__electron_launch 等名称。确保三个命令中的 --package 列表完全一致:npx 会分别缓存每个列表,因此添加 demo 或插件包后,必须使用新列表再次运行 install-electron 和 doctor。也要保留 --prefix ~/:如果不加,npx 会跳过当前项目中已安装且版本匹配的任何列出软件包(Electron 应用通常同时包含 Playwright 和 Electron),而从 npx 缓存运行的服务将无法加载它。服务仍会在当前目录中运行。之后如需升级到较新的版本,请参阅更新到新版本。
Claude Code 默认使用本地作用域:它只在当前项目中可用,不会影响无关工作区。如要与团队共享经过审核的配置,请使用 --scope project,它会将相同的 mcpServers 结构写入 .mcp.json。有关宿主特定行为,请参阅 Claude Code MCP 作用域。
如要在将 MCP 宿主连接到你的应用之前验证宿主,请添加固定版本的 @electron-stagewright/[email protected] 软件包,并使用 demo 指南。demo 为可选项,因此常规核心安装既不会加载它,也不依赖它。
如需进行本地开发,请构建代码库,并将 MCP 宿主指向构建后的 CLI:
pnpm install
pnpm build
claude mcp add electron-stagewright -- \
node /abs/path/to/electron-stagewright/packages/core/dist/cli.js
共享项目的 .mcp.json 结构:
{
"mcpServers": {
"electron-stagewright": {
"command": "npx",
"args": [
"-y",
"--prefix",
"~/",
"--package",
"@electron-stagewright/[email protected]",
"--package",
"[email protected]",
"--package",
"[email protected]",
"electron-stagewright",
"--tool-profile",
"essential"
]
}
}
}
然后,在任何兼容 MCP 的 Agent 中运行(此处的工具名称采用 Claude Code 显示的形式;其他宿主会使用不同的前缀):
// Launch
mcp__electron-stagewright__electron_launch({
main: "/abs/path/to/.vite/build/main.js",
env: { MY_ENV_VAR: "value" }
})
// Inspect with full state per ref
mcp__electron-stagewright__electron_snapshot()
// → [1] button "Open File" enabled=true visible=true
// [2] button "Settings" enabled=true visible=true
// [3] textbox "Email" value="" focused=false
// [4] heading "Welcome"
// Interact by ref
mcp__electron-stagewright__electron_click({ ref: 2 })
// Wait for a composite state in one call
mcp__electron-stagewright__electron_wait_for_state({
ref: 3, state: { focused: true, enabled: true }, timeoutMs: 2000
})
// Assert + retry in one call instead of read-compare-retry chain
mcp__electron-stagewright__electron_expect_text({ ref: 4, equals: "Welcome back" })
// Stop
mcp__electron-stagewright__electron_stop()
完整工具列表——包括每个工具、其参数和操作类型——请参阅 TOOL-REFERENCE.md。该文件根据实时调度器清单生成(pnpm docs:tools)。
文档
- 快速入门 — 从干净检出开始,使用捆绑的示例应用完成一次完整的驱动会话。
- 试用打包的演示 — 针对本地的多窗口 Electron 任务看板,验证已发布的 MCP 主机配置,无需提供自己的应用路径。
- 连接你的 MCP 客户端 — 将已发布的软件包接入 Claude Code、Codex、Claude Desktop、Cursor、VS Code、opencode 或任何 MCP 主机,确认连接成功、更新或移除它。
- 启动、附加或注入 — 如何针对你自己的应用建立会话,包括已在运行的应用。
- 断言 UI 状态 — refs 与选择器、
expect_*系列、等待和快照差异。 - 在代码编辑器中输入 — 可靠的 Monaco / EditContext 输入路径、
replace、自动配对注意事项,以及如何确认文本已成功输入。 - 捕获诊断信息 — 屏幕截图、控制台、对话框和会话跟踪。
- 加载、配置和诊断插件 — 显式加载插件,授予其范围最窄的权限,并使用
electron_plugins检查已启用的工具和安全配置。 - 从 electron-driver 迁移 — 逐工具映射和概念上的变化。
- 选择 Electron MCP 服务 — 根据能力、信任边界、恢复证据以及你自己的应用比较 Electron 自动化工作流。
- 兼容性 — 查看哪些 Node、Electron、操作系统和传输组合已通过单元测试或真实运行时 CI 验证。
- 概念 — Agent 原生模型,以及服务采用当前设计的原因:响应封套、refs、快照、重试断言、会话和 eval/插件信任模型,每项都链接到确立该设计的决策。
- 安全模型 — 信任模型、
--allow-eval背后的控制措施,以及部署检查清单。 - 指南索引 · TOOL-REFERENCE.md · 架构决策记录。
服务标志
在 MCP 主机配置中,CLI 路径之后传入这些标志(即 args 数组)。所有标志默认采用安全选项;诊断信息输出到 stderr(stdout 保留给 JSON-RPC 协议通道)。
| 标志 | 效果 |
|---|---|
--allow-eval[=main|renderer] | 注册 electron_eval_main / electron_eval_renderer 工具,这些工具会在主进程 / 渲染进程中运行任意 JavaScript。默认关闭——隐藏这些 eval 工具,且无法调用。不带参数的 --allow-eval 会启用两者;--allow-eval=renderer(或 =main)则仅授予相应目标的权限,遵循最小权限原则。此选项也控制直接调用 eval 接口的插件工具,例如 IPC 主进程工具(main)和存储 IndexedDB 工具(renderer)。 |
--app-root <dir> | 将宿主机路径限制在 <dir> 内:包括 electron_launch 的 main、executablePath 和 cwd,以及 electron_set_files / electron_drop_file 读取的文件。默认未设置(不限制路径)。将其设为应用 / 项目根目录,这样工具调用就不能启动宿主机上其他位置的二进制文件,也不能将项目外的文件读取到被测应用中。此选项还会启用 electron_launch({ main, runtime: "project" }),仅从操作员配置的根目录解析 Electron;显式指定的 executablePath 仍具有最高优先级。 |
--screenshot-dir <dir> | 当调用未提供显式路径时,electron_screenshot 写入文件的默认目录。默认值:OS 临时目录。 |
--operation-timeout-ms <n> | 每次分发操作的兜底超时时间(ms);若处理程序始终未完成,则返回可重试的 OPERATION_TIMEOUT,而不是让 Agent 因应用冻结而卡住。默认值为 120000;0 表示禁用。 |
--tool-profile <profile> | 选择核心工具集:essential(专注于启动 / 快照 / 交互 / 断言的流程)、testing(更全面的测试驱动工具及截图证据采集)、debug(附加 / 检查 / 诊断)或 full。默认值:full,保留完整的核心工具目录。eval 授权和显式加载的插件可独立组合使用。 |
--demo | 解析已安装的 @electron-stagewright/demo 包,并在 electron_launch 未提供 main 和 executablePath 时使用该包的 Electron 入口。此选项需主动启用,不会成为常规核心依赖。配置已发布的 npx 或全局安装时,请将固定版本的 demo 安装在核心包旁边。不能与 --app-root 同时使用。 |
doctor [--json] | 在不启动 MCP stdio 的情况下运行启动前检查:Node、Playwright、Electron、Linux 显示环境、已配置路径、eval 策略、项目运行时对齐情况,以及精确的服务配置。请传入计划用于启动服务的相同插件 / 配置 / profile / 超时 / demo 标志;doctor 只会导入并简要设置那些明确受信任的插件,验证完整的服务对象图,然后将其拆除。JSON 模式会包含范围受限的运行时 / 配置事实;必需检查失败时退出码非零。请以 electron-stagewright doctor --json 运行,切勿将其作为 MCP 服务参数。 |
production validate --app <path> [--json] | 验证已打包的 macOS .app、Windows .exe / .msi 或 Linux .AppImage,而不启动 MCP stdio。需要在核心包旁安装 @electron-stagewright/plugin-production。根据制品类型选择相应的信任检查默认项。JSON 模式会生成一份带版本号的报告;检查均通过时退出码为 0,存在已确认的失败项时为 1,用法或输入无效时为 2。 |
--plugin <name|path> | 按包名、第一方简称或文件路径加载插件。可重复使用;单个值可用逗号分隔。例如,--plugin trace 会展开为 @electron-stagewright/plugin-trace。加载后,调用 electron_plugins 查看已启用或已禁用的工具及其门控要求。 |
--plugin-config <name>=<json> | 将插件配置作为内联 JSON 提供,并根据其架构进行验证。按插件名称关联;输入无效时会报告其 Zod 字段路径及修正后的输入。electron_plugins 仅返回插件明确标记为安全的字段。 |
服务器在正常关闭(SIGINT、SIGTERM,或宿主关闭 stdin)后以 0 退出;启动或关闭清理失败时以 1 退出;用法无效(例如未知标志)时以 2 退出。 |
将此工具接入其他项目时,值得了解以下安全默认设置:任意 JS(--allow-eval 策略)和宿主路径启动(--app-root)均需显式启用;electron_launch 会拒绝可能改变运行时的环境变量(ELECTRON_RUN_AS_NODE、NODE_OPTIONS、LD_*、DYLD_*);用户提供的正则表达式、文本和按键参数均有长度与复杂度限制,因此恶意工具调用无法使服务器卡死。
当 Agent 需要常见的启动、快照、交互、等待和断言工作流,并希望初始清单更小时,请使用 --tool-profile essential。需要更广泛的交互、读取和截图证据能力时,选择 testing;需要附加、发现、窗口、控制台、截图和对话框操作时,选择 debug。
在基准测试证明任务成功率相当且能显著节省上下文之前,full 仍是默认配置。有关经过测量的预算策略,请参阅 ADR-021。
每个响应的样子(Agent 体验细节)
例如,electron_expect_text 的成功响应:
{
"ok": true,
"session_id": "pw-...",
"matched": true,
"actual": "Welcome back",
"_meta": {
"estimated_tokens": 24,
"elapsed_ms": 142,
"session_id": "pw-...",
},
}
错误:
{
"ok": false,
"error": "ref 7 not found in current snapshot",
"code": "REF_NOT_FOUND",
"hint": "The DOM may have rerendered since the last snapshot.",
"next_actions": ["electron_snapshot()", "electron_find({ role: \"button\" })"],
"similar_refs": [
{ "ref": 9, "role": "button", "name": "Submit" },
{ "ref": 12, "role": "button", "name": "Cancel" },
],
"retryable": false,
"http": 404,
"_meta": { "estimated_tokens": 89, "elapsed_ms": 23 },
}
Agent 无需询问上下文,即可获得决定下一步操作所需的全部信息。
架构
三种传输实现共用一个 ITransport 接口,因此即使 Playwright 的实验性 _electron API 发生变化或被弃用,项目也能继续运行:
PlaywrightElectronTransport—_electron.launch(),快速路径(默认)。CDPTransport— 直接使用 Chrome DevTools Protocol,不依赖 Playwright;通过受管理的环回端点启动打包后的可执行文件,或附加到现有端点;支持 iframe、webview 和WebContentsView表面定位,以及在所选表面上进行快照/查找、求值、观察和交互。InjectorTransport— 与运行中进程进行 Node Inspector 握手;当应用启动时未提供 CDP 端点,可用于主进程求值、窗口发现和控制台捕获。
插件模型:核心保持精简,领域能力以独立的 @electron-stagewright/plugin-* 包形式提供,并通过 --plugin 显式加载(核心不会自动扫描)。目前已提供:plugin-a11y(针对指定表面的 axe-core 审计,违规项数量受限,并检查审计是否完整;使用固定引擎而非 Agent JavaScript,因此无需授予 --allow-eval)、plugin-visual(BrowserWindow 视觉基线,支持显式确认更新、环境元数据、受限的制品根目录,以及实际效果/差异证据)、plugin-trace(会话跟踪 + 确定性重放 + 每种工具的令牌预算)、plugin-ipc(捕获/调用/模拟 Electron IPC,需通过主进程求值权限控制:--allow-eval=main,或直接使用 --allow-eval)、plugin-production(通过 MCP、公共库 API 或 CI JSON CLI 验证打包后的 macOS、Windows 和 Linux 制品:捆绑完整性、更新/崩溃处理机制、macOS 签名/公证/Gatekeeper、Windows Authenticode,以及 AppImage 内嵌签名)、plugin-network(通过传输层接口捕获渲染进程请求/响应及其正文,并进行模拟)、plugin-clock(通过 Playwright 时钟接口实现确定性的渲染进程虚拟时间)、plugin-storage(通过无需求值的传输接口读取、写入并断言 Cookie、存储快照及逐键 localStorage / sessionStorage;通过渲染进程求值权限读取 IndexedDB 记录;Cookie 值默认会被隐藏,IndexedDB 值可通过配置隐藏),以及 plugin-native-ui(读取、断言并调用应用菜单——即 macOS 菜单栏——捕获应用显示的通知,包括启动时的通知;读取系统托盘状态并触发托盘事件,以上均通过启动时插桩和传输层原生 UI 接口实现,无需求值)。
试用目标
此 MCP 基于作者维护的两个真实 Electron 应用构建,覆盖不同领域,避免设计意外偏向某一种应用形态:
- 代码编辑器形态 — 带有运行时沙箱、许可管理和大量 IPC 状态的代码编辑器。可测试键盘驱动的流程、编辑器状态和许可证验证。
- POS 形态 — 多租户的销售点桌面应用,内嵌 Fastify 服务和 SQLite。可测试表单、大型表格、内嵌后端和自动更新源。
如果你的 Electron 应用不属于以上形态,欢迎提交 issue——我们很乐意将其添加为示例夹具。
安全
此服务是一个拥有特权的本地工具,而非沙箱:它会驱动真实应用,并且在选择启用 eval(--allow-eval 或特定目标的变体)后,会在应用内部运行任意 JavaScript,因此只有可信的 Agent 宿主才能调用它。安全模型介绍了信任边界、各项控制(选择启用 eval + 阻止列表、通道允许列表、启动限制、结构化脱敏)以及部署检查清单;安全态势记录在 ADR-014 中。若要报告漏洞,请参阅 SECURITY.md。
贡献
此项目刚刚起步。欢迎提交 issue 和参与讨论。工作流程请参阅 CONTRIBUTING.md,了解项目的运作方式以及成为共同维护者的途径,请参阅 GOVERNANCE.md。
选择测试项目
pnpm test 和 pnpm test:coverage 选择普通的 unit 项目,该项目会在全部六个 OS/Node CI 环境组合中保留。pnpm test:real 选择串行运行的 real-electron 项目,并根据 scripts/real-test-inventory.json 检查实际 JSON 结果(25 个已审核文件,36 个场景)。如果缺少二进制文件或必需的原生插件夹具输入,此命令会拒绝运行;它还会在每个平台上拒绝缺失、跳过或执行次数为零的情况。使用 node scripts/prepare-native-addon-fixture.mjs 准备原生插件输入,并导出它打印的变量(在 Windows 上,它还会获取 Electron 的 node.lib,并指向 npm 内置的 node-gyp,该工具需要 MSVC)。CLI 打包验证仍单独进行。
许可证
MIT——详见 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。