mcpField
B
BrowserMesh

BrowserMesh

本地服务
github.com/scrollDynasty浏览器自动化31 天前更新

关于 BrowserMesh

BrowserMesh 是供 MCP 客户端使用的本地 Chromium 运行时,可并行运行多个相互隔离的浏览器会话。会话使用明确的 ID,各自拥有独立 Cookie 和存储。

主要功能

  1. 01并行运行隔离的 Chromium 会话
  2. 02明确指定会话和页面
  3. 03按会话顺序执行操作
  4. 04有界且可分页的浏览器读取
  5. 05保存并复用浏览器状态

适用场景

  1. 01以买家身份测试结账并以管理员身份核验
  2. 02同时运行多个独立账户的工作流
  3. 03在后续会话中复用登录状态

MCP 相关

这是通过 stdio 与外部客户端通信的 MCP 服务,提供浏览器会话、页面、导航、检查、交互和状态工具。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"scrolldynasty-browsermesh": {
"command": "npx",
"args": [
"-y",
"browsermesh"
]
}
}
}
启动命令npx -y browsermesh

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npmbrowsermesh0.2.1

工具

35

收录的工具列表 · 更新于 2 周前

此工具无需参数。

详细介绍

BrowserMesh

npm downloads CI MCP Registry license

通过一个 MCP 服务,同时运行多个彼此完全隔离的浏览器会话。

其他所有浏览器 MCP 服务都只向 AI 客户端提供一个带当前标签页的浏览器。BrowserMesh 则可根据任务需求提供任意数量的独立会话——每个会话都有自己的 Cookie、存储和身份验证,并行运行。你可以在同一段对话中,以客户身份测试结账流程,同时让管理员会话验证订单,彼此互不影响。

External AI client
        |
     MCP stdio
        |
BrowserMesh runtime
   |         |         |
Session A  Session B  Session C
Context A  Context B  Context C

外部客户端负责推理和规划。BrowserMesh 执行浏览器操作、确保隔离、管理每个会话中的工作顺序,并返回结构化结果。

可与 Claude Code、Claude Desktop、Codex、Cursor、Windsurf、Qwen 及其他任何兼容 MCP 的客户端配合使用。

何时使用 BrowserMesh,何时不使用

BrowserMesh 并非通用浏览器 MCP 服务的即插即用替代品。它专为这些服务无法实现的一项功能而构建,并为此收费。

你想要……可以选择
同时操作两个或更多账户、角色或身份验证状态BrowserMesh — 每个会话对应一个上下文,并行运行
保留已登录状态,并在之后单独的会话中重复使用BrowserMesh — browser_state_save / stateId
在较长的工作流中确定性地定位特定标签页BrowserMesh — 显式指定 sessionId + pageId,不使用“当前标签页”
限制页面可消耗的上下文(快照大小、引用、事件)BrowserMesh — 每次读取都有明确的上限,并支持分页
像普通用户一样浏览、点击并阅读一个页面Playwright MCP — 功能范围更小,需要配置的内容也更少
调试页面的性能、跟踪或 CDP 级行为Chrome DevTools MCP — 它提供的正是这些功能
在他人的云环境中运行,并使用托管代理和验证码处理Browserbase 等托管服务 — BrowserMesh 只能本地运行
在页面中执行任意 JavaScriptPlaywright MCP 或 Chrome DevTools MCP — BrowserMesh 按设计不提供此类工具
操作 Firefox 或 WebKitPlaywright MCP — 目前 BrowserMesh 仅支持 Chromium

坦诚地说,权衡之处在于发现成本。BrowserMesh 提供 35 个工具,包含完整的输入和输出架构;在某台机器上的某一天进行测量,其 tools/list 约为 94 KB,而 chrome-devtools-mcp 为 25 KB,@playwright/mcp 为 18 KB,这两者都不提供输出架构。如果你的客户端上下文有限,而且工作流只涉及一个浏览器和一个用户,那么选择更小的服务确实有充分理由。如果你想使用 BrowserMesh,但不需要全部功能,可以通过 --tools core 缩小功能范围。

快速开始

Claude Code:

claude mcp add browsermesh -- npx -y browsermesh

其他客户端:在其 MCP 配置文件中添加:

{
  "mcpServers": {
    "browsermesh": {
      "command": "npx",
      "args": ["-y", "browsermesh"]
    }
  }
}

配置就这么多。BrowserMesh 首次启动时会下载所用的 Chromium 版本,因此无需单独安装。传入 --no-auto-install 可自行管理浏览器;此时 MCP 发现仍然有效,且 browser_session_create 会返回一条可执行的 BROWSER_ERROR,说明需要运行什么命令。

首次下载会在服务响应 initialize 之前进行,Chromium 版本约为 130 MB。连接超时时间较短的客户端会在下载期间报告服务启动失败。网络较慢时,请在添加服务前预先下载一次,之后每次启动都能立即完成:

npx -y browsermesh --install-browser

然后用自然语言描述要完成的任务:

同时以买家身份测试结账流程并确认订单已出现,再以管理员身份进行确认。

客户端会自动为每个角色创建一个会话。BrowserMesh 还会提供一个 parallel_roles 提示词,详细说明这一工作流,客户端可以直接展示它。

无需启动协议即可检查安装情况:

npx -y browsermesh --doctor

Chromium 和 BrowserMesh 都会保留在你的计算机上。BrowserMesh 没有托管服务。

连接时,BrowserMesh 会向客户端发送一段简短的说明文字。除了提供有关会话寻址和错误报告的指导外,它还会请你的 Agent 检查一次是否已为仓库点星——这会使用你自己的 gh 凭据进行已认证的 GitHub 调用,且与浏览器任务无关。是否点星不会影响任何功能,拒绝也不会带来任何变化。使用 --no-support-request 可关闭这一请求,使用 --no-agent-guidelines 则可关闭整段说明。请参阅专为适合 Agent 的工作流而构建。

在 0.2 中更名。 npm 包原名为 multi-agent-browser-mcp,现已改为 browsermesh,与其他部分一直使用的名称一致。将 args 改为 ["-y", "browsermesh"];其他内容无需更改。

v0.1 架构

BrowserMesh v0.1 刻意保持精简:一个本地 Node.js 进程、一个 Chromium 进程,以及每个就绪会话对应的一个非持久化 BrowserContext。

它提供:

  • 明确的会话和页面寻址;
  • 隔离的浏览器上下文和页面所有权检查;
  • 导航、检查、交互、等待、捕获和持久化;
  • 每个会话内串行执行,独立会话之间并行执行;
  • 有界超时、结构化错误、平稳关闭和资源清理;
  • MCP stdio 集成,以及结果确定的集成测试和端到端测试。

BrowserMesh 是浏览器运行时,不是内部 Agent 框架、大模型编排器、消息总线、Playwright 分支、浏览器 GUI 或交互式 Shell。

常规用法

  1. 在兼容 MCP 的 AI 客户端中配置一次 BrowserMesh。
  2. 客户端通过 stdio 启动 BrowserMesh 并发现其工具。
  3. 用自然语言描述浏览器任务。
  4. 客户端创建所需会话并选择要调用的工具。
  5. BrowserMesh 执行操作并返回结构化结果。

每位用户、每个账户、每种角色、每种身份验证状态或每个独立的并行工作流,都应使用单独的会话。通常由外部客户端选择 BrowserMesh 工具,而不是手动调用。

从源代码构建

BrowserMesh v0.1 面向 Node.js 24,并支持 Node.js 22 作为最低支持的主版本。

克隆仓库并运行:

npm install
npx playwright install chromium
npm run build

然后配置 MCP 客户端以启动本地构建的服务:

{
  "mcpServers": {
    "browsermesh": {
      "command": "node",
      "args": ["/absolute/path/to/browsermesh/dist/cli.js"]
    }
  }
}

开发时:

npm run verify
npm run verify:package

会话模型

不存在全局的:

  • 当前会话;
  • 活动会话;
  • 当前页面;
  • 活动页面;
  • 当前标签页。

每项浏览器操作都会明确指定其会话。

每项特定于页面的操作都会明确指定其页面。

概念上:

browser_session_create
        │
        ▼
{
  sessionId,
  pageId
}
        │
        ▼
browser_navigate({
  sessionId,
  pageId,
  ...
})

新建的会话包含一个确定性的初始页面。

browser_session_create 会立即返回初始 pageId,因此 AI 客户端在首次执行浏览器操作前无需额外调用 browser_page_list。

该页面也会显示在 browser_page_list 中,并标记为 isDefault。

会话视图始终公开 sessionId;页面视图始终公开 pageId 及其所属的 sessionId。

isDefault 标记仅供参考。浏览器操作仍使用显式的 pageId 寻址。

隔离

每个就绪的 BrowserMesh 会话都映射到各自独立的非持久化 Chromium BrowserContext。

因此,独立会话绝不能意外共享:

  • Cookie;
  • 浏览器存储/身份验证状态;
  • 页面;
  • 页面引用;
  • 当前 URL;
  • DOM 快照;
  • 截图;
  • 表单状态。

属于某个会话的 pageId 不能用于另一个会话。

跨会话页面寻址会被拒绝。

并发模型

每个活动会话都有独立的串行操作队列。

针对同一会话的操作会按接受顺序确定性地执行。

例如:

Session A

navigate
   ↓
snapshot
   ↓
click
   ↓
get_url

读取类操作不会绕过正在进行的导航或交互。

失败或超时的操作不得导致队列无法继续。失败操作结束后,后续已接受的操作会正常继续执行。

每个 timeoutMs 都是一个绝对时限,从 BrowserMesh 接受操作时开始计时。在所属会话队列中等待所花的时间,以及之后每个浏览器适配器步骤所花的时间,都会消耗同一时限;任何适配器步骤都不会获得重新计时的完整超时时长。

MCP 请求取消会作为与引擎无关的操作信号传递给 BrowserMesh。在队列中取消的同一会话请求会被跳过,不会触及浏览器状态。如果 Playwright 操作已在运行且无法安全中止,BrowserMesh 会一直保留其队列槽位,直到实际操作结束,以确保后续任务不会抢先执行。被动等待会及时移除其持有的中止监听器和计时器,取消后会话队列仍可继续使用。MCP 客户端会收到其 SDK 的取消错误(通常为 AbortError,或携带该原因的 MCP 错误);协议取消后不保证会收到单独的工具结果。

不同会话不会共享全局操作锁:

Session A ═════════════════════►

Session B ═════════════════════►

Session C ═════════════════════►

这使独立的浏览器工作流能够并发运行。

会话关闭

会话关闭开始时:

  1. 会话进入 closing 状态;
  2. 拒绝针对该会话的新操作;
  3. 排空已加入队列的操作;
  4. 关闭其页面和 BrowserContext;
  5. 移除活动引擎句柄;
  6. 会话变为已关闭状态。

重复关闭已知的正在关闭/已关闭会话是安全的,并会返回幂等成功结果。

完全未知的会话 ID 仍会返回 SESSION_NOT_FOUND。

支持的 MCP 工具

会话和页面
  • browser_runtime_info
  • browser_session_create
  • browser_session_list
  • browser_session_get
  • browser_session_close
  • browser_page_create
  • browser_page_list
  • browser_page_close
导航
  • browser_navigate
  • browser_back
  • browser_forward
  • browser_reload
检查
  • browser_get_url
  • browser_get_title
  • browser_snapshot
  • browser_visible_text

browser_snapshot 默认有界,可通过语义/CSS scope、interactiveOnly、每个节点的 maxChildren、maxDepth、includeBoundingBoxes、maxChars 和 maxBytes 进行限制。其结构化结果会报告所有已应用的限制、有意省略的树结构,以及字符数/UTF-8 字节数。达到任一响应上限时,partial=true、truncation.truncated=true,且 contentFormat=aria-yaml-fragment;不要将该片段解析为完整的 ARIA YAML 文档。密码值仍会被隐藏。设置 includeRefs=true 可获取最多 maxRefs 个不透明的交互元素引用(默认值为 50,最大值为 100),以便立即执行后续操作。引用在 30 秒后过期,仅适用于确切的会话/页面,并会在导航、DOM 替换、页面关闭、过期或生成更新的引用快照后失效。非空的 nextCursor 会继续读取同一份不可变的已捕获序列化内容,而不会重新读取已更改的 DOM。游标仅适用于确切的会话/页面,在 30 秒后过期,并会在导航、页面关闭、配额清理或关闭服务后失效。每个页面最多保留 4 个分页快照,且每个已捕获快照最多保留 1,000,000 个 Unicode 码点。在进行原生 ARIA 序列化之前,BrowserMesh 还会拒绝范围超过 20,000 个 DOM/文本节点或 2,000,000 个源字符的请求。这项捕获前预算会限制浏览器端工作量,独立于较小的单次响应和保留游标限制。

可观测性
  • browser_observe

一个工具可读取全部 4 种已记录来源,通过 source 选择:console、pageError、network 或 requestFailed。它要求显式提供 sessionId 和 pageId,并会回显 source,确保读入同一缓冲区的结果仍可区分。

默认情况下,控制台和页面错误读取仅包含元数据;设置 includeText=true 可获取有界且尽力脱敏的证据。两种网络来源不包含文本,并会拒绝该标记,而不会返回看似完整的仅元数据答复。使用 nextCursor 作为下一个非破坏性的 sinceEventId 检查点。得出某事件不存在的结论前,务必检查 gap 和 droppedCount。为满足总响应字节限制,文本可能会进一步截断;事件及其游标仍会返回,因此分页不会卡住。BrowserMesh 绝不会捕获控制台参数对象或原始错误堆栈。

网络读取仅公开经过关联的请求/响应/请求失败元数据:有界的请求 ID、方法、经过清理的网址、资源类型、状态、持续时间,以及适用时的安全失败分类。存储前会移除凭据和片段,并对敏感查询值进行脱敏。标头、正文、Cookie、存储内容、服务工作线程流量、WebSocket、data: URL 和 blob: URL 均不包含在内。由页面发起的 HTTP(S) EventSource 请求会作为普通网络元数据包含在内。HTTP 错误响应(例如 500)会出现在 source: "network" 下;只有传输层失败才会出现在 source: "requestFailed" 下。

在 0.2 之前,这些是 4 个工具——browser_console_list、browser_page_errors_list、browser_network_list 和 browser_failed_requests_list——各自发布同一份契约的副本。请传入匹配的 source。

交互
  • browser_click
  • browser_double_click
  • browser_hover
  • browser_focus
  • browser_check
  • browser_uncheck
  • browser_scroll_into_view
  • browser_scroll
  • browser_drag_and_drop
  • browser_fill
  • browser_press
  • browser_select_option

这些类型化操作仅接受一个语义/CSS 定位器或短时有效的快照 ref。操作会明确指定目标,由 timeoutMs 限定,支持取消,并与所属会话中的所有浏览器操作串行执行。check 和 uncheck 会以幂等方式确保达到所请求的状态。browser_scroll 接受有界整数像素增量(deltaX 和 deltaY 的范围为 -1,000,000 至 1,000,000),而拖放操作会使用相同的严格定位器语义解析源和目标。这些工具均不提供任意页面 JavaScript 执行能力。

确定性等待
  • browser_wait
  • browser_action_and_wait

browser_wait 通过所属会话队列观察一个被动的类型化条件:精确 URL 或安全 glob URL、domcontentloaded/load、定位器状态,或有界文本的存在/缺失。文本匹配会对页面正文已渲染的 innerText 最多前 1,000,000 个字符进行区分大小写的子串检查;absent 表示该子串未出现在此有界观察范围内。不支持调用方正则表达式、JavaScript 谓词、任意时长休眠和 networkidle。

不要在同一会话中,将被动等待排在预计会满足该条件的操作之前。browser_action_and_wait 会先注册类型化的导航、HTTP 响应、弹出窗口或对话框等待器,然后在共享的截止时间内执行一次点击或按键操作。返回的响应 URL 会移除凭据和片段,并对常见敏感查询值进行脱敏。弹出窗口会在同一会话中分配新的托管 pageId,其 isDefault=false;超出限制的弹出窗口会先关闭,再返回 LIMIT_EXCEEDED。由于阻塞式对话框无法在之后安全检查,对话框会根据预期类型以及接受/取消选项进行原子处理。提示词输入和返回的对话框元数据均有长度限制。

browser_action_and_wait 使用 target 指定操作目标,其接受的语义/CSS 定位器或快照 ref 与独立交互工具完全相同。两个结果都不会重复说明请求:browser_wait 返回 satisfied,而 browser_action_and_wait 返回观察到的 event。调用方已掌握其发送的条件和操作,operationId 用于关联结果。

捕获
  • browser_screenshot

屏幕截图会作为 MCP 图像内容返回,而不是写入调用方控制的文件系统路径。可选的 capture 模式用于选择视口、完整可滚动页面或一个经过严格解析的语义/CSS 元素;默认仍为视口。结构化输出会报告实际 PNG 的宽度、高度和编码字节数。BrowserMesh 会在捕获前测量 CSS 像素尺寸,并在捕获后校验实际 PNG 的尺寸和字节数。整页和元素模式会捕获固定测量范围,因此后续页面增长不会扩大原生图像分配。超出配置限制时会返回 LIMIT_EXCEEDED,且不会影响会话队列。

持久化
  • browser_state_save
  • browser_state_list
  • browser_state_remove

browser_session_create 接受可选的 stateId。

不提供 stateId 时,它会创建一个全新的隔离上下文。

提供 stateId 时,它会使用此前保存的 BrowserMesh 状态初始化新上下文。

保存状态的数量、单个状态的字节数和总字节数均受到集中限制。所有状态 ID 的配额检查和原子替换均按序执行;被拒绝的替换会保留旧状态。现有文件会先进行大小检查,并在硬性大小限制内读取,然后才解析 JSON。

browser_session_create 还接受可选的 contextSettings 对象,用于设置独立的视口、设备缩放因子、区域设置、时区、配色方案、减少动态效果偏好和用户代理。会话结果会返回规范化后的有效设置。不同设备、无障碍或权限配置应使用不同会话。地理位置为可选项,且唯一支持的浏览器权限是针对一个绝对 HTTP(S) 源的明确授权。不接受通配符和任意权限名称。

browser_session_create({
  name: "mobile-fr",
  contextSettings: {
    viewport: { width: 390, height: 844 },
    deviceScaleFactor: 3,
    locale: "fr-FR",
    timezoneId: "Europe/Paris",
    colorScheme: "dark",
    reducedMotion: "reduce"
  }
})

地理位置访问必须限定在确切的应用源:

browser_session_create({
  name: "local-map-test",
  contextSettings: {
    geolocation: { latitude: 41.3111, longitude: 69.2797, accuracy: 25 },
    permissions: [
      { permission: "geolocation", origin: "https://maps.example.test" }
    ]
  }
})

该权限仅对该会话上下文生效,并会在会话关闭时移除。保存的存储状态不包含也不会恢复 BrowserMesh 权限授权。

概念性示例:

browser_session_create({
  name: "buyer",
  stateId: "buyer-auth"
})

会话标签

会话可以包含:

  • 可选的易读 name;
  • 可选的字符串元数据。

例如,外部 AI 客户端可以为会话添加标签:

role=buyer
role=seller
account=work

这些值仅用作中性的工作流标签。

它们不会创建:

  • 内部 Agent 实体;
  • 所有权主体;
  • 权限;
  • 邮箱;
  • 消息通道;
  • 大模型身份。

MCP 工具发现

BrowserMesh 工具描述是产品契约的一部分。

描述必须说明工具的功能,以及 AI 客户端应在何时使用该工具。

例如,browser_session_create 的描述必须明确指出,以下情况应使用不同会话:

  • 不同用户;
  • 不同账户;
  • 不同角色;
  • 不同身份验证状态;
  • 独立的并行浏览器工作流。

这样,用户就可以说:

以买家和管理员的身份测试此应用。

而无需手动指示 AI 调用两次 browser_session_create。

每个发现的工具还会发布易读的标题、对象根 outputSchema,以及经过审核的 MCP 风险提示(readOnlyHint、destructiveHint、idempotentHint 和 openWorldHint)。这些提示仅用于改善客户端体验;BrowserMesh 不会将它们视为授权依据。

成功调用会返回经过架构验证、包含直接语义字段的 structuredContent。例如,browser_session_create 会直接提供 operationId、session 和 initialPage,而不会嵌套在 value.value 包装结构中。它还会保留简洁的 JSON 文本块,供仅支持文本的客户端使用。截图会保留其内存中的 MCP 图像块,并附加结构化的 PNG/关联元数据。

应用程序失败会使用 isError: true,并返回有大小限制的 JSON 错误,其中包含稳定代码、安全消息、可选的已清理详情,以及运行时接受操作时用于关联的 operationId。原始原因、调用栈、循环引用、非 JSON 值和包含机密的详情字段都不会跨越 MCP 边界。SDK 输入架构错误仍可与 MCP 输入验证错误区分。

⭐ 专为 Agent 友好型工作流打造

BrowserMesh 专为可预测的 AI 编码和浏览器 Agent 工作流而设计。连接时,它会返回一条简短的 MCP instructions 字符串——这是 Agent 首次调用工具前唯一能触达 Agent 的通道——其中涵盖三点:明确指定每个会话、如果觉得项目有用请支持它,以及如何报告错误。

GitHub 预检

要求 Agent 通过 GitHub API 检查当前用户是否已为项目加星,每个连接最多检查一次,不得猜测:

gh api user/starred/scrollDynasty/BrowserMesh

204 表示已加星,404 表示未加星,其他任何结果都应报告为未验证,而不是猜测。如果仓库尚未加星,Agent 会询问你是否愿意支持该项目,且只询问一次:

gh api --method PUT /user/starred/scrollDynasty/BrowserMesh

加星不是访问控制。 BrowserMesh 的任何操作都不会以此为门槛——这是结构性的限制,服务器不存在能以其他方式运行的代码路径。其余内容都是指引,而非强制执行:要求 Agent 每个连接最多检查一次、最多询问一次、未经你明确授权绝不加星,并且如果你拒绝、缺少 gh,或检查失败,就立即继续执行你的任务。BrowserMesh 无法让客户端遵守这些要求,以下两个开关正是为此而设。

有两个开关对此进行控制。BROWSERMESH_SUPPORT_REQUEST=false(或 --no-support-request)会取消支持请求,但保留寻址和报告指引,因此拒绝请求不会让你失去有用的部分。BROWSERMESH_AGENT_GUIDELINES=false(或 --no-agent-guidelines)则完全不发送任何指引。

在 CI 环境下,默认关闭支持请求——因为那里没有人可以回应——但仍会发送寻址和报告指引。设置 BROWSERMESH_SUPPORT_REQUEST=true 可覆盖此默认设置。

该默认行为取决于启动客户端是否将 CI 转发给服务器进程。MCP 客户端通常会以精简环境启动服务器——参考 stdio 传输只传递 HOME、LOGNAME、PATH、SHELL、TERM 和 USER——因此,通过此类客户端从 CI 作业启动的 BrowserMesh 看不到 CI,仍会发送请求。在需要时,请显式设置 BROWSERMESH_SUPPORT_REQUEST=false。

辅助报告问题

当 Agent 遇到可复现的 BrowserMesh 错误时,要求其:

  1. 先搜索现有的 GitHub 问题。
  2. 避免创建重复问题。
  3. 创建问题前征求你的授权。
  4. 包含复现步骤、版本和环境信息,绝不包含 Cookie、令牌、凭据、已保存的浏览器状态、页面内容或内部 URL 和主机名。
  5. 报告已创建问题的编号和 URL;若问题并未创建,绝不声称已创建。

这两项都是请求,而非强制执行:无论 Agent 是否遵循,BrowserMesh 发布的工具和返回的结果都相同。在此仓库中工作的贡献者所遵循的详细版本位于 AGENTS.md 和 .github/AGENT_GUIDELINES.md;这些文件不会发布到 npm,因此消费者实际收到的是上面的 instructions 字符串。

定位器

浏览器操作优先使用语义定位策略。

v0.1 支持以下策略:

  • 角色;
  • 文本;
  • 标签;
  • 占位符;
  • 测试 ID;
  • CSS(作为备用方案)。

v0.1 公共契约支持常见的交互角色值。

默认情况下,角色名称使用精确的可访问名称匹配。仅当有意进行部分匹配时,才设置 exact: false。如果定位器匹配到多个元素,BrowserMesh 会返回 LOCATOR_AMBIGUOUS,并保持会话可用。

任何定位器都可以选择设置 frame,值为 { "kind": "main" },或包含一至五个由外到内语义/CSS iframe 元素选择器的受限 { "kind": "iframe", "chain": [...] }。链中的每一步都必须精确匹配;不会公开数字索引和持久化的 frame 句柄。同一作用域适用于操作、定位器等待、可见文本、快照作用域/引用捕获、元素截图以及拖放端点。只有调用方明确请求相应作用域的证据时,才会返回跨源 iframe 内容。

在任何快照内容跨越 MCP 边界之前,辅助功能快照都会对 input[type="password"] 元素中的非空值进行脱敏。

BrowserMesh 不会通过其公共 API 暴露 Playwright Locator 对象。

元素引用是为即时的快照到操作工作流提供的便利方式,并非持久身份标识。无效、过期、跨页面或已脱离的引用会返回 STALE_ELEMENT_REFERENCE;对于持久化测试,仍优先使用语义定位器。BrowserMesh 不使用未公开的 Playwright AI/引用选择器,也不暴露由适配器持有的元素句柄。

持久化与敏感状态

BrowserMesh 默认会在以下位置存储本地持久化数据:

.browsermesh/

已保存的浏览器状态可能包含身份验证凭据或其他等效的敏感浏览器状态。

因此:

  • .browsermesh/ 会被 Git 忽略;
  • 不得提交已保存的状态;
  • 不得发布已保存的状态;
  • 日志不得包含存储状态的内容;
  • 调用方提供逻辑状态 ID,而不是任意文件系统路径。

持久化数据表示序列化后的浏览器存储/身份验证状态。

BrowserMesh 绝不会尝试序列化活动的 BrowserContext、打开的页面、待处理操作或活动的浏览器进程状态。

配置

环境变量默认值含义
BROWSERMESH_TIMEOUT_MS10000操作默认超时时间上限
BROWSERMESH_DATA_DIR~/.browsermesh私有本地数据目录
BROWSERMESH_LOG_LEVELinfodebug、info、warn、error 或 silent
BROWSERMESH_MAX_SESSIONS50活跃会话数上限
BROWSERMESH_MAX_PAGES20每个会话管理的页面数
BROWSERMESH_PERSISTENCEtrue启用保存浏览器状态
BROWSERMESH_HEADLESSfalse启动 Chromium 时不显示窗口
BROWSERMESH_SCHEMA_REFStrue通过 $defs/$ref 共享重复的子模式
BROWSERMESH_AUTO_INSTALLtrue如果缺少 Chromium,则在首次启动时下载
BROWSERMESH_TOOLS(all)要发布的工具配置,以逗号分隔
BROWSERMESH_AGENT_GUIDELINEStrue连接时发送 MCP 指令字符串
BROWSERMESH_SUPPORT_REQUESTtrue(有人值守时)包含开源支持请求;在 CI 下关闭
BROWSERMESH_OBSERVABILITY_EVENTS200每个页面保留的混合可观测性事件数
BROWSERMESH_OBSERVABILITY_STRING_CHARS2048对外提供的事件字符串最大长度
BROWSERMESH_OBSERVABILITY_PAGE_SIZE100单次读取返回的最大事件数
BROWSERMESH_OBSERVABILITY_RESPONSE_BYTES65536可观测性响应序列化后的最大大小
BROWSERMESH_SCREENSHOT_MAX_DIMENSION10000PNG 的最大宽度或高度(CSS 像素)
BROWSERMESH_SCREENSHOT_MAX_PIXELS40000000PNG 的最大总像素数
BROWSERMESH_SCREENSHOT_MAX_BYTES16777216PNG 编码后的最大字节数
BROWSERMESH_VISIBLE_TEXT_MAX_CHARS20000返回的 Unicode 码点数上限
BROWSERMESH_VISIBLE_TEXT_MAX_BYTES65536返回的可见文本 UTF-8 字节数上限
BROWSERMESH_MAX_SAVED_STATES100持久化逻辑状态的最大数量
BROWSERMESH_MAX_STATE_BYTES1048576单个持久化状态的最大字节数
BROWSERMESH_MAX_STATE_TOTAL_BYTES16777216持久化状态的总字节数上限

命令行接受的选项包括 --headless、--headed、--timeout、--data-dir、 --log-level、--max-sessions、--max-pages、--tools、--no-persistence、--no-schema-refs、 --no-auto-install、--no-agent-guidelines 和 --no-support-request。每个选项都会设置上文对应的配置变量,且命令 行选项优先。其余变量——可观测性、截图、可见文本和持久化预算——只能通过环境变量设置。运行 browsermesh --help 查看当前选项列表。对于被拒绝的值,程序会指出其来源变量,并以状态码 2 退出,而不会打印堆栈 跟踪。 保存的状态位于用户主目录下,而不是工作目录中。MCP 客户端会从当前所在的任意目录启动 BrowserMesh,因此,相对路径默认值会将保存的身份验证信息分散到互不相关的文件夹中,并导致 browser_state_list 在没有明显原因的情况下返回空结果。传入 --data-dir .browsermesh 即可恢复之前按项目保存的行为。

配置会集中读取和验证。

发布更少的工具

在每个客户端中,每个会话的发现过程都会消耗上下文。--tools 可缩小 BrowserMesh 发布的范围,仅包含工作流实际需要的配置:

配置工具数内容
core31会话、页面、导航、读取、交互、等待、捕获
observability1browser_observe
persistence3browser_state_save、browser_state_list、browser_state_remove

省略 --tools 时会发布所有配置,因此现有配置会保留已有工具。

npx -y browsermesh --tools core,persistence

已发布的 Schema 会通过 $defs/$ref 共用重复的子 Schema,所有 JSON Schema 2020-12 验证器都会解析这些引用。如果客户端使用的验证器不支持此功能,请设置 --no-schema-refs。

提示词和资源

BrowserMesh 会发布两个 MCP 提示词,让客户端可以直接提供工作流,而不必自行推断:

  • parallel_roles — 将一项任务同时分配给多个角色,每个角色使用一个隔离会话。
  • diagnose_page — 加载页面并收集与其相关的控制台、页面错误和网络证据。

它还会发布一个只读资源 browsermesh://sessions,列出运行时当前持有的会话及其状态和标签。

两者都是静态模板。BrowserMesh 会生成并返回文本,不会调用大模型,也不会保留每个客户端的状态。客户端仍需自行推理并决定调用哪些工具。

默认情况下,BrowserMesh 会以有头模式启动 Chromium,以便用户观察浏览器自动化过程。在 CI、服务端和其他没有显示器的环境中,请设置 BROWSERMESH_HEADLESS=true。只接受字面值 true 和 false;无效值会导致配置失败,而不会被静默忽略。无论使用哪种模式,浏览器都会延迟启动,因此即使尚未安装 Chromium,MCP 发现功能和可执行的设置错误提示仍然可用。配置的 BROWSERMESH_TIMEOUT_MS 也会限制浏览器启动时间。只有预计耗时超过安全默认值的操作,才应设置较大的单工具 timeoutMs。

即使直接调用运行时,会话标签也有长度限制:名称最多允许 128 个 Unicode 码点,元数据最多允许 32 个条目,键和值均受字符数、UTF-8 字节数及总字节数限制。BrowserMesh 在分配会话 ID、上下文或页面之前,会拒绝控制字符和危险对象键。browser_visible_text 会保留其 text 字段,并添加明确的截断元数据,以便客户端区分完整证据与受长度限制的前缀。

不允许在整个代码库中直接零散访问 process.env。

browser_runtime_info 可在创建会话前安全调用。它会报告精确的 BrowserMesh、Node 和已解析的 Playwright 版本;生效的配置和限制;浏览器启动状态;可为空的实时 Chromium 版本;以及活动和失败的会话数。它不会启动 Chromium,也不会暴露路径、环境变量值、浏览器状态或原始失败信息。

日志记录

MCP stdio 将 stdout 保留给协议流量。

因此,BrowserMesh 结构化日志会输出到 stderr。

日志可能包含安全的关联信息,例如:

  • operationId;
  • sessionId;
  • pageId;
  • 工具/操作名称;
  • 耗时;
  • 安全的错误代码。

日志不得包含:

  • cookies;
  • tokens;
  • 保存的状态;
  • 页面内容;
  • 截图;
  • 表单值;
  • 密码;
  • 任意消息负载。

Chromium 断开连接时的行为

如果 Chromium 意外断开连接,BrowserMesh 不会悄悄重建活动会话。

受影响的会话会转为失败状态,其活动句柄也会失效。

BrowserMesh 绝不会悄悄重新创建现有会话,因为这样会违反 BrowserMesh 的状态保证。

如果运行时能够安全恢复,可以为之后新建的会话启动新的 Chromium 进程,但旧的活动会话仍会保持失败状态。

开发

npm run typecheck
npm run lint
npm run format:check
npm test
npm run test:integration
npm run test:e2e
npm run test:stress
npm run test:coverage
npm run build
npm run verify

浏览器集成/e2e 测试会使用真实的 Chromium 和确定性的环回 HTTP 测试服务器。

测试不依赖公共网站。

请参阅:

拉取请求标题遵循 Conventional Commits。每个 PR 都会通过完整的测试矩阵、软件包安装冒烟测试、语义标题验证和 CodeQL 检查。发布由 Release Please 准备,并且仅在维护者合并生成的 Release PR 后,才通过 GitHub OIDC 发布到 npm。

BrowserMesh 根据 Apache License 2.0 分发。

有意保留的 v0.1 限制

BrowserMesh v0.1 有意不包含:

  • Firefox/WebKit 同等支持;
  • 远程 Streamable HTTP;
  • BrowserMesh 托管的云基础设施;
  • 多租户身份验证;
  • 分布式浏览器工作器;
  • 活动操作的崩溃恢复;
  • 内部 Agent 实体;
  • 与大模型 Agent 绑定的内部会话所有权;
  • Agent 注册表;
  • 邮箱;
  • Agent 间消息传递;
  • 内部大模型调用;
  • 提示词编排;
  • Claude/Codex/Qwen 进程启动;
  • 任意 shell 执行;
  • 任意文件系统读取;
  • 由调用方控制的截图路径;
  • 下载;
  • Web 仪表板;
  • 网络允许列表;
  • 完整的 Playwright API。

如果实际的多客户端保护有此需要,未来可能会引入通用的客户端/工作流租约。

此类租约必须独立于大模型/Agent 抽象。

v0.1 核心保证

在单个 BrowserMesh 运行时内:

  • 会话通过显式地址指定;
  • 页面通过显式地址指定;
  • 每个会话都有独立的浏览器上下文;
  • 不同会话可以并发执行;
  • 针对同一会话的操作会通过该会话的队列确定性地执行;
  • 失败不会影响之后排队的操作;
  • 持久化状态通过受控的逻辑标识符处理;
  • 关闭时会清理活动浏览器资源;
  • BrowserMesh 执行浏览器操作,而推理过程留在运行时之外。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。