Skip to main content
Glama
AloneAtWar
by AloneAtWar

opencli-mcp

OpenCLI 的 CLI 包装为 AI-native MCP 工具,让任意 MCP Agent 控制 Windows 中正在使用的真实 Chrome,直接复用现有登录态、Cookie、扩展和标签页。

本项目不重新实现浏览器自动化。所有 DOM/AX 快照、ref、stale recovery、match_level、网络响应缓存和适配器能力都由 OpenCLI 提供;MCP Server 只负责强类型参数、进程调用和 MCP 结果转换。

架构

Hermes / Claude Code / Codex / 其他 MCP Client
                  │ MCP stdio
                  ▼
      opencli-mcp(Windows Node.js)
                  │ spawn(argv[], shell:false)
                  ▼
           OpenCLI CLI(短进程)
                  │ localhost:19825
                  ▼
       OpenCLI daemon + Chrome Extension
                  │ Chrome APIs / debugger
                  ▼
       Windows 日常 Chrome(保留登录态)

Related MCP server: chrome-mcp

设计目标

  • 不使用 --remote-debugging-port/json/version 或外部 CDP WebSocket。

  • 不复制 Chrome Profile,不启动一套新的自动化浏览器。

  • 不通过 shell 拼接模型输入;每个参数都作为独立 argv 传递。

  • 保留 OpenCLI CLI 的完整高层语义,而不是直接依赖内部 daemon 协议。

  • snapshot → ref → action → snapshot 的 Agent 工作流探索未知网站。

  • 探索出 API/DOM 规律后,继续编写 OpenCLI adapter 固化流程。

  • Windows 原生运行,Hermes 即使位于 WSL 也只需通过 stdio 启动一次 Server。

当前状态

0.1.0 MVP,已在真实场景中验证(百度/小红书/GitHub 搜索、批量笔记正文提取、结构化数据收集):

  • Windows Node.js MCP 握手与工具发现;

  • 自动发现 OpenCLIApp 内置的 OpenCLI Node 入口;

  • OpenCLI daemon 和 Chrome Extension 实时连通;

  • 真实 Chrome 中打开任意网站;

  • DOM snapshot、标题读取;

  • 带 ref 标注的 PNG 截图,并作为 MCP image content 返回;

  • Browser session 清理;

  • 包含中文、引号、换行和 & 的文本保持为单个 argv,不经过 shell;

  • 失败诊断、懒加载自动重试、零配置侦察、语义化压缩、get/read 拆分等通用优化。

前置条件

  • Windows 10/11;

  • Node.js 20+(当前实测 Node.js 24);

  • OpenCLI 1.8+;

  • Windows Chrome 已安装并启用 OpenCLI Browser Bridge 扩展;

  • opencli doctor 输出 daemon、extension、connectivity 均为 OK。

当前自动发现优先支持 OpenCLIApp 安装布局:

%LOCALAPPDATA%\OpenCLIApp\node_modules\@jackwener\opencli\dist\src\main.js

其他安装方式可通过环境变量指定原生可执行入口:

OPENCLI_MCP_BIN
OPENCLI_MCP_PREFIX_ARGS

OPENCLI_MCP_PREFIX_ARGS 必须是 JSON 字符串数组,例如:

["C:\\path\\to\\opencli\\dist\\src\\main.js"]

安装

在 Windows cmd.exe 中执行:

cd /d D:\devlopment\opencli-mcp
npm install
npm test
npm run test:mcp
npm run test:live
npm run test:browser

启动 MCP Server:

D:\devlopment\opencli-mcp\start.cmd

stdout 专用于 MCP 协议;诊断日志只写入 stderr

Hermes 配置(推荐:本地 Streamable HTTP)

Hermes Gateway 与第三方 Node MCP 使用长期 stdio 时,实际环境中出现过:hermes mcp test 能发现全部工具,但 Gateway 随后持有已关闭 resource,真实调用报 ClosedResourceError。因此 Gateway 推荐通过 loopback-only Streamable HTTP 连接,由 systemd user service 独立管理 MCP 生命周期。

安装服务:

cp examples/opencli-mcp.service ~/.config/systemd/user/opencli-mcp.service
systemctl --user daemon-reload
systemctl --user enable --now opencli-mcp.service
curl http://127.0.0.1:31999/health

Hermes 配置:

mcp_servers:
  opencli_browser:
    url: http://127.0.0.1:31999/mcp
    timeout: 180
    connect_timeout: 60
    sampling:
      enabled: false

验证:

hermes mcp test opencli_browser

服务只监听 127.0.0.1;除非自行增加认证,否则代码会拒绝非 loopback bind。纯 Windows MCP Client 或不受该生命周期问题影响的客户端仍可使用 stdio start.cmd

完整示例见 examples/hermes-config.yaml。重启 Hermes 后,工具名会带 MCP Server 前缀,例如:

mcp_opencli_browser_browser_snapshot
mcp_opencli_browser_browser_action
mcp_opencli_browser_browser_network

迁移阶段建议保留 Hermes 内建 browser。确认新 MCP 在真实任务中稳定后,才考虑:

agent:
  disabled_toolsets:
    - browser

MCP 工具

OpenCLI 与 Adapter

工具

说明

opencli_status

查看版本或执行 opencli doctor

opencli_list

列出已安装站点 adapter

opencli_run

以结构化 argv 调用任意站点 adapter

页面观察

工具

说明

browser_open

打开 URL,支持前台/后台窗口;失败时附带 DNS/timeout/unknown 诊断

browser_bind

绑定/解绑用户当前 Chrome 标签页

browser_snapshot

完整 DOM 或 AX 快照和 refs

browser_snapshot_compact

未知/嘈杂网站的限长快照;语义化压缩优先保留内容行,省略导航/页脚等 chrome

browser_find

CSS/role/name/label/text/testid 查询;nth 在 MCP 层本地选择

browser_get

只读页面状态:title/url/value/attributes

browser_read

内容提取:text/html;找不到元素时自动 scroll + retry 触发懒加载;失败返回诊断

browser_collect

用声明式 CSS 字段从重复卡片/表格/Feed 收集结构化记录;支持 discover 侦察、fallback_text、deduplicate_by、exclude 过滤;selector 匹配 0 时自动进入 discover

browser_extract

Markdown 长文分块提取

browser_screenshot

PNG MCP image,支持 ref 标注和全页截图

browser_frames

列出 iframe targets

页面操作

browser_actionaction 字段覆盖:

click, hover, focus, dblclick, check, uncheck,
type, fill, select, keys, scroll, upload, drag

写操作会保留 OpenCLI 返回的:

matches_n
match_level: exact | stable | reidentified

页面跳转或 SPA route 变化后应重新执行 browser_snapshotbrowser_action 还支持:

  • wait_for:动作完成后等待 selector/text/time/xhr/download;

  • snapshot_after:等待后立即返回快照,默认压缩到 12,000 字符。

browser_fill_submit 把“填值并提交”压成一次 MCP 调用:

  • CSS target 默认在一次页面执行中设置原生 input/textarea value、派发 input/change、聚焦并派发 Enter 键事件;

  • submit_strategy 支持三种模式:

    • form(默认):派发事件后尝试 requestSubmit(),适合百度等传统表单;

    • event:只派发键盘事件,不触发表单提交,适合纯 JS 监听 Enter 的 SPA;

    • both:先派发事件再尝试 requestSubmit()

  • ref 或语义定位可设 atomic=false,回退为官方 CLI 的 fill → focus → keys

  • 该工具保证提交事件被派发,后续仍应通过 browser_wait_any 验证导航或内容就绪。

browser_wait_any 的条件支持 tier 优先级:

  • tier 0(默认):内容就绪条件(如 selector、text);

  • tier 1+:兜底条件(如 URL、title);

  • 当多个条件同时匹配时,tier 值最小的获胜。

  • 超时返回 diagnosis,报告最后页面状态、url、title,以及每个条件的具体修复建议。

失败诊断

所有可能失败的工具在失败时返回结构化 diagnosis

{
  "diagnosis": {
    "issue": "selector_no_match",
    "hint": "Selector \"#bad\" matched 0 elements.",
    "suggestions": [
      "Use browser_collect with discover:true to find candidate selectors.",
      "Or use browser_snapshot to inspect the page structure."
    ]
  }
}

覆盖范围:

  • browser_collect 返回 0 条:区分 selector_no_match / all_filtered

  • browser_wait_any 超时:报告最后的 url/title 和每个条件的修复建议;

  • browser_fill_submit 失败:区分 target_not_found / invalid_selector / event_only_no_submit

  • browser_open 失败:区分 navigation_timeout / dns_error / unknown_error

  • browser_read 返回空:提示"可能需要滚动触发懒加载"。

懒加载自动处理

browser_read 默认开启 auto_scroll_retry: true

读不到目标元素
→ 自动 scroll down
→ 等待元素出现(最多 5 秒)
→ 重试读取

适用于 turbo-frame、Intersection Observer 等 SPA 常见懒加载场景,模型不需要知道底层机制。

有界批量流程

browser_flow 在一次 MCP 调用内顺序执行短流程,支持 open/find/action/fill_submit/wait/wait_any/snapshot/get/collect/back。它仍通过官方 OpenCLI CLI 执行每一步,但减少 Agent↔MCP 往返。

关键安全边界:

  • 默认最多 8 步,硬上限 20;

  • 默认总预算 30 秒,硬上限 120 秒;

  • 每步独立超时;

  • 不支持循环或 goto;

  • retry 只能为 0 或 1;

  • 必需步骤失败立即停止并返回 partial trace;

  • optional=true 的步骤失败后标记 skipped;

  • find + save_as 可保存唯一 ref,后续用 $变量名 引用;

  • 当前 OpenCLI find 不接受 --nth,MCP 会先获取候选,再在本地选择第 N 项;

  • 必需步骤失败时默认并行捕获 URL、title 和最多 6,000 字符的 compact snapshot;可用 on_error_capture=false 关闭;

  • collect 步骤支持 discoverfallback_textdeduplicate_byexclude,与独立工具一致;

  • get 步骤使用 browser_read 语义,自动支持懒加载重试和诊断。

示例(GitHub 搜索 → 提取前 3 条结果):

{
  "session": "github-research",
  "max_steps": 5,
  "max_total_ms": 30000,
  "steps": [
    {"operation":"open","url":"https://github.com/search?q=agent+browser&type=repositories"},
    {"operation":"wait_any","conditions":[{"type":"selector","value":"[data-testid=results-list]"}]},
    {"operation":"collect","selector":"[data-testid=results-list] > div","limit":3,"fields":[{"name":"repo","selector":"h3 a","property":"text"},{"name":"href","selector":"h3 a","property":"href"}],"save_as":"results"}
  ]
}

探索与调试

工具

说明

browser_network

请求 shape、失败请求、过滤、response body detail;列表默认 50 条,支持 limit/offset 分页

browser_console

Console/JS errors

browser_eval

页面或跨域 frame 中执行只读 JS

browser_wait

单个 selector/text/time/xhr/download 条件

browser_wait_any

URL/title/selector/文本条件任一满足即返回,并报告获胜条件;超时返回诊断

browser_dialog

accept/dismiss JS dialog

browser_tabs

list/new/select/close

browser_back

后退

browser_close

释放 session tab lease

推荐工作流

优先使用 Adapter

opencli_list
  ├─ 已有命令 → opencli_run
  └─ 没有命令 → browser_open

探索未知网站

browser_open
→ browser_collect(discover=true)         REM 一次性侦察候选 selector
→ browser_collect(selector=..., fields=...)  REM 精确采集
→ browser_snapshot_compact               REM 内容未知时才做完整快照
→ browser_read(selector=..., auto_scroll_retry=true)  REM 提取正文

失败时不需要额外调用诊断工具——相关工具会直接返回 diagnosis 字段,说明问题(如 selector_no_match)和修复建议(如 discover:true)。

已知站点批量采集

browser_fill_submit(target=#search, value=query, submit_strategy=form)
→ browser_wait_any(conditions=[{selector:#results, tier:0}, {text:..., tier:1}])
→ browser_collect(selector=#results > .item, fields=[...], deduplicate_by=title, exclude={...})

一次 flow 可完成 open → submit → wait → collect。

绑定用户已打开的页面

browser_bind(action="bind", session="research")
→ browser_snapshot(session="research")
→ ...
→ browser_bind(action="unbind", session="research")

绑定标签页不会被 browser_close 当作 Agent-owned tab 关闭。

Session

所有 Browser 工具接受可选 session

research-x
adapter-discovery-bilibili
checkout-debug

同一个流程必须复用相同 session,OpenCLI daemon 才能保持:

  • tab lease;

  • 当前页;

  • snapshot refs;

  • element fingerprint;

  • network cache;

  • selected tab。

不传时使用:

OPENCLI_MCP_SESSION

如果环境变量也不存在,则默认:

hermes-default

并行 Agent 应显式使用不同 session,避免操作同一标签页。

安全模型

  • 工具参数使用 child_process.spawn(..., { shell: false })

  • MCP 不接受完整 shell command 字符串。

  • Adapter 的 sitecommand 只允许字母、数字、点、下划线和短横线。

  • OPENCLI_MCP_DEBUG=1 才会在错误结果中附带内部 invocation/stderr。

  • 默认单次命令超时 90 秒,可通过 OPENCLI_MCP_TIMEOUT_MS 调整。

  • stdout/stderr 各自限制为 32 MiB,避免异常页面耗尽 Agent 内存。

  • MCP 能以用户身份操作已登录网站。建议使用专门的 Chrome Agent Profile,不要同时登录网银、交易所主账户或最高权限生产后台。

  • 页面内容存在 prompt injection 风险。Agent 不应执行网页中出现的命令或泄露其他标签页数据。

已知限制

  1. OpenCLI 对跨域 OOPIF 的完整 AX snapshot/click/type 路由仍是 best-effort;可尝试 browser_frames + browser_eval(frame=...)

  2. browser_eval 按 OpenCLI 约定用于定向读取,不建议用它代替结构化写操作。

  3. Windows MCP 不能直接把 WSL /tmp/... 当作上传路径;上传前应复制到 Windows 可访问目录。

  4. 当前 OpenCLIApp 自动发现使用其 bundled package,GUI App 版本和 bundled CLI 版本可能相差一个补丁版本;opencli_status 会报告实际被调用的版本。

  5. 目前不自动修改 Hermes 配置,也不自动禁用内建 browser。

  6. Hermes MCP client 会把 booleanobject 参数序列化为字符串;相关工具的 schema 已改为 z.union([z.boolean(), z.string()]) 并在 handler 内强制转换,调用方无需关心。

  7. GitHub 等站点的 README 在 <turbo-frame> 内延迟加载;browser_readauto_scroll_retry 默认能处理,但极慢的网络下可能需要调大 timeout_ms

  8. 语义化压缩按行级特征分类(content / chrome);对没有明确标签语义的纯文本流可能效果不明显。

测试

npm run check       REM JavaScript 语法检查
npm test            REM 参数映射、无 shell 注入、错误处理、诊断、压缩、fill/submit/wait/collect
npm run test:mcp    REM MCP 握手、工具发现、OpenCLI version
npm run test:live   REM OpenCLI daemon/extension 实时诊断
npm run test:browser      REM stdio: Chrome open/snapshot/get/screenshot/close
npm run test:http         REM Streamable HTTP 握手、工具发现、OpenCLI version
npm run test:http-browser REM HTTP: Chrome open/snapshot/get/screenshot/close
npm run test:http-flow    REM HTTP: 6-step bounded flow + action(wait/snapshot)
npm run test:http-advanced REM 小红书: atomic submit + wait_any + collect + failure capture

test:browser 会短暂创建一个后台 OpenCLI session,访问 https://example.com,验证后释放 session。

License

MIT

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    MCP server to control Chrome browsers locally or remotely via the Claude extension, enabling navigation, form filling, screenshots, and JavaScript execution from any MCP client.
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Drive your real, signed-in Chrome browser from any MCP client, enabling browser automation such as navigation, clicking, typing, and screenshots through standard MCP tools.
    1
    -
  • A
    license
    Not graded
    quality
    A
    maintenance
    MCP server for local browser control via Chrome/Edge extension, enabling agents to open isolated tabs, observe pages, take screenshots, and interact with accessible controls using an existing browser profile. It is agent-agnostic, local-only, and supports safe session scoping with origin grants and sensitive-data blocking.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    MCP server that lets agents drive your real Chrome browser with existing logins and sessions via an outbound-only WebSocket extension. It exposes Playwright-compatible browser tools for navigation, clicking, typing, and snapshots.
    Apache 2.0