@mearl/mcp-server 2.7.0 → 2.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +46 -26
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -27,7 +27,7 @@ import { RESPONSE_SIZE_SMALL, RESPONSE_SIZE_MEDIUM, RESPONSE_SIZE_LARGE, RESPONS
27
27
  const require = createRequire(import.meta.url);
28
28
  const MCP_SERVER_VERSION = require('../package.json').version;
29
29
  const MCP_TOOL_ACTIONS = {
30
- browser_capture_checkpoint: 'capture_checkpoint',
30
+ browser_tab_checkpoint: 'tab_checkpoint',
31
31
  browser_get_requests: 'get_requests',
32
32
  browser_get_events: 'get_events',
33
33
  browser_get_logs: 'get_logs',
@@ -365,12 +365,13 @@ async function main() {
365
365
  capabilities: {
366
366
  tools: {},
367
367
  },
368
- instructions: '浏览器交互默认工作流:首次进入页面时使用 browser_page_snapshot 建立页面基线;后续点击、拖动、输入、悬停、滚动、按键和上传直接使用 browser_page_click/drag/type/hover/scroll/press/upload,它们默认内置观察与原子诊断,动作、异步稳定判断、新增 error logs 和业务 requests 在一次调用内完成,返回 { action, observation, diagnostics };传 observe:false 只关闭 DOM/导航观察并保留诊断,同时传 diagnostics:false 才执行裸动作。观察结果不替代完整页面理解:observation.mode 为 delta 时确认 scope="main-document",再读取 effects.notifications、effects.interactives 和 effects.focus;interactives/focus 节点有 ref 时优先直接用于后续动作,没有 ref 时使用 selector;notifications 中 change=transient 表示已经消失的 Toast、状态或错误提示。为 navigation 时先检查 ready,ready=true 表示文档、相关业务请求和可见骨架状态已经稳定,可在新页面重建 snapshot。observation.openedTabs 表示动作直接打开的关联标签页,可显式使用返回的 tabId 继续操作,无需调用 browser_tab_list。其他情况下通常仅当 fullSnapshotRecommended 为 true 时根据 snapshotReasons 回退,并选择最小范围:已有区域 ref 用 rootRef,已有 CSS 根节点用 rootSelector,只需查找特定目标时加 query,长列表用 mode="viewport",只需当前视口内的控件用 mode="interactive";滚动动作的 moved 只证明位置变化,下一步需要读取新视口内容时可按需获取 viewport 快照。视口内缺少 AX 控件语义时 interactive 会在同一次调用中回退到 viewport,并返回 fallbackMode。重复文本点击用 scope 限定区域,ref 指向滚动容器子节点时用 containerPolicy="nearest"。轮播图、滑块和拖放使用 page_drag;不要用 page_eval 合成 DragEvent/PointerEvent。page_eval 默认裸执行且应作为结构化能力无法表达时的补充;需要页面变化信号时传 observe 对象,需要原子诊断时传 diagnostics:true 或对象。视觉任务再使用 screenshot。不要在每次动作后固定调用 browser_page_wait、snapshot 或 screenshot。',
368
+ instructions: '浏览器交互默认工作流:首次进入页面或导航后用 browser_page_snapshot 建立基线;后续页面动作默认返回 { action, observation }。先检查 action.success;action.stage=precondition 表示尚未派发,应按 error 修正输入或刷新快照,且不读取已省略的 observation/diagnostics。动作成功后再按 observation 处理:delta 读取 effects,navigation 在 ready=true 后重建快照,openedTabs 直接使用其 tabId。仅在 fullSnapshotRecommended=true 或需要读取滚动后的新视口时补最小范围快照;视觉任务使用 screenshot。无需页面观察时传 observe:false;需要动作期间的日志、请求或埋点时显式开启 diagnostics。page_eval 仅作为结构化 action 无法表达时的补充;不要在每次动作后固定追加 wait、snapshot 或 screenshot。',
369
369
  });
370
370
  // 页面交互工具共享的 observe 参数 schema:默认开启内置观察,传 false 关闭
371
371
  const OBSERVE_INPUT_SCHEMA = {
372
372
  type: ['object', 'boolean'],
373
- description: '观察选项。默认开启内置观察(等待相关 DOM、XHR/Fetch/MTop 请求或导航稳定后返回页面变化信号);传 false 只关闭 DOM/导航观察,默认诊断增量仍会返回',
373
+ default: {},
374
+ description: '观察选项。默认开启内置观察(等待相关 DOM、XHR/Fetch/MTop 请求或导航稳定后返回页面变化信号);传 false 关闭,不影响显式请求的 diagnostics',
374
375
  properties: {
375
376
  quietMs: {
376
377
  type: 'number',
@@ -404,7 +405,8 @@ async function main() {
404
405
  };
405
406
  const DIAGNOSTICS_INPUT_SCHEMA = {
406
407
  type: ['object', 'boolean'],
407
- description: '页面交互默认在动作真正执行前建立原子边界,并在稳定后返回新增 error logs 和全部业务 requests。传 false 关闭;传 true 使用默认配置;传对象自定义通道与过滤。page_eval 默认关闭',
408
+ default: false,
409
+ description: '默认关闭。传 true 在动作执行前建立边界,并返回新增 error logs 和业务 requests;传对象可自定义通道与过滤,并按需开启 events',
408
410
  properties: {
409
411
  logs: {
410
412
  type: ['object', 'boolean'],
@@ -424,13 +426,23 @@ async function main() {
424
426
  includeHeaders: { type: 'boolean', default: false },
425
427
  },
426
428
  },
429
+ events: {
430
+ type: ['object', 'boolean'],
431
+ properties: {
432
+ source: { type: 'string', enum: ['rum', 'aplus', 'arms', 'all'] },
433
+ event_type: { type: 'string' },
434
+ filter: { type: 'string' },
435
+ limit: { type: 'number', default: 100 },
436
+ includeRaw: { type: 'boolean', default: false },
437
+ },
438
+ },
427
439
  },
428
440
  };
429
441
  // 定义工具列表
430
442
  const tools = defineMcpTools([
431
443
  {
432
- name: 'browser_capture_checkpoint',
433
- description: '为目标标签页当前已采集的 console/network 建立可靠增量边界。返回的 cursor 可传给 browser_get_logs/browser_get_requests 的 after。',
444
+ name: 'browser_tab_checkpoint',
445
+ description: '为目标标签页建立日志、请求和埋点的可靠增量边界,对应 mearl tab_checkpoint。返回的 cursor 可传给 browser_get_logs/browser_get_requests/browser_get_events 的 after。',
434
446
  inputSchema: {
435
447
  type: 'object',
436
448
  properties: {
@@ -466,7 +478,7 @@ async function main() {
466
478
  },
467
479
  after: {
468
480
  type: 'string',
469
- description: 'capture checkpoint 或上一次查询返回的 cursor,仅返回其后的请求',
481
+ description: 'tab checkpoint 或上一次查询返回的 cursor,仅返回其后的请求',
470
482
  },
471
483
  includeBody: {
472
484
  type: 'boolean',
@@ -505,7 +517,7 @@ async function main() {
505
517
  },
506
518
  {
507
519
  name: 'browser_get_events',
508
- description: '获取目标标签页后台采集的 RUM/aplus/ARMS 埋点事件,无需打开 DevTools panel。包含页面资源性能指标、用户行为埋点、SPM 点击事件等。',
520
+ description: '获取目标标签页后台采集的 RUM/aplus/ARMS 埋点事件,无需打开 DevTools panel。不传 after 时返回最新事件,传 after 时按完整上报批次从最早未读项开始分页。',
509
521
  inputSchema: {
510
522
  type: 'object',
511
523
  properties: {
@@ -531,6 +543,10 @@ async function main() {
531
543
  type: 'number',
532
544
  description: '从多久之前开始获取(秒)。例如: 60 表示获取最近 1 分钟内的事件',
533
545
  },
546
+ after: {
547
+ type: 'string',
548
+ description: 'tab checkpoint 或上一次查询返回的 cursor,仅返回其后的埋点事件',
549
+ },
534
550
  limit: {
535
551
  type: 'number',
536
552
  description: '返回条数上限,默认 20',
@@ -566,7 +582,7 @@ async function main() {
566
582
  },
567
583
  after: {
568
584
  type: 'string',
569
- description: 'capture checkpoint 或上一次查询返回的 cursor,仅返回其后的日志',
585
+ description: 'tab checkpoint 或上一次查询返回的 cursor,仅返回其后的日志',
570
586
  },
571
587
  limit: {
572
588
  type: 'number',
@@ -1243,7 +1259,7 @@ async function main() {
1243
1259
  },
1244
1260
  {
1245
1261
  name: 'browser_page_click',
1246
- description: '点击页面元素,默认内置观察与原子诊断:同一次调用内等待相关 DOM、XHR/Fetch/MTop 请求或导航稳定,返回 { action, observation, diagnostics };diagnostics 默认包含新增 error logs 和全部业务 requests。点击直接打开新标签页时 observation.openedTabs 返回可继续操作的 tabId、URL、标题和加载状态。传 observe:false 只关闭观察并保留诊断,同时传 diagnostics:false 才执行裸点击。定位方式三选一:selector(CSS 或 @eN snapshot ref)、text(按可见文本匹配 accessibility name,可用 scope 限定子树)、point(视口坐标)。clickMode 默认 auto:可见页按设备模拟状态使用可信 mouse/touch,隐藏页不切换标签或还原窗口并自动使用 DOM fallback;checkbox/radio 使用带状态校验的 DOM 路径。可用 dom/mouse/touch 强制派发方式。响应返回实际 dispatchMode,可信输入还返回 pointerType。',
1262
+ description: '点击页面元素;selector、text、point 三种定位方式必须且只能提供一种。',
1247
1263
  inputSchema: {
1248
1264
  type: 'object',
1249
1265
  properties: {
@@ -1284,7 +1300,7 @@ async function main() {
1284
1300
  clickMode: {
1285
1301
  type: 'string',
1286
1302
  enum: ['auto', 'dom', 'mouse', 'touch'],
1287
- description: '点击模式。auto 在可见页按设备模拟状态选择可信 mouse/touch,在隐藏页使用 DOM fallback,checkbox/radio 使用带状态校验的 DOM 路径;dom/mouse/touch 强制指定派发方式',
1303
+ description: '默认 auto:可见页使用匹配设备的可信输入,隐藏页使用 DOM;dom/mouse/touch 可强制指定派发方式',
1288
1304
  default: 'auto',
1289
1305
  },
1290
1306
  observe: OBSERVE_INPUT_SCHEMA,
@@ -1295,7 +1311,7 @@ async function main() {
1295
1311
  },
1296
1312
  {
1297
1313
  name: 'browser_page_drag',
1298
- description: '在页面内执行连续可信拖动,并默认内置观察与原子诊断,返回 { action, observation, diagnostics }。from/to 均可传原生 CSS、"@eN" snapshot ref 或 {x,y} 视口坐标;选择器端点需要同时位于当前视口。dragMode 默认 auto:移动模拟页使用 touch,其余使用 mouse;内部按 durationMs 分段派发按下、移动和松开事件,不使用不可靠的 DOM 合成拖拽。适合轮播图滑动、滑块、画布手势和拖放。',
1314
+ description: '连续拖动页面元素或视口坐标,适用于轮播图、滑块、Canvas 手势和拖放。',
1299
1315
  inputSchema: {
1300
1316
  type: 'object',
1301
1317
  properties: {
@@ -1327,8 +1343,8 @@ async function main() {
1327
1343
  },
1328
1344
  dragMode: {
1329
1345
  type: 'string',
1330
- enum: ['auto', 'mouse', 'touch'],
1331
- description: '输入类型;auto 按设备模拟状态选择 touch 或 mouse',
1346
+ enum: ['auto', 'dom', 'mouse', 'touch'],
1347
+ description: '默认 auto:可见页使用匹配设备的可信输入,隐藏页使用 DOM;dom/mouse/touch 可强制指定派发方式',
1332
1348
  default: 'auto',
1333
1349
  },
1334
1350
  durationMs: {
@@ -1346,7 +1362,7 @@ async function main() {
1346
1362
  },
1347
1363
  {
1348
1364
  name: 'browser_page_type',
1349
- description: '向输入框填写文本,默认内置观察与原子诊断(校验提示、error logs、业务 requests 等),返回 { action, observation, diagnostics };传 observe:false 只关闭观察并保留诊断,同时传 diagnostics:false 才执行裸输入。兼容 React 等框架的受控组件,会自动触发 input 和 change 事件。selector 支持原生 CSS 或 "@eN" snapshot ref。',
1365
+ description: '向输入框填写文本,兼容 React 等框架的受控组件。',
1350
1366
  inputSchema: {
1351
1367
  type: 'object',
1352
1368
  properties: {
@@ -1375,7 +1391,7 @@ async function main() {
1375
1391
  },
1376
1392
  {
1377
1393
  name: 'browser_page_scroll',
1378
- description: '滚动页面或指定滚动容器,默认内置观察与原子诊断(懒加载内容、error logs、业务 requests 等),返回 { action, observation, diagnostics };传 observe:false 只关闭观察并保留诊断,同时传 diagnostics:false 才执行裸滚动。支持 up、down、top、bottom 四个方向;containerPolicy="nearest" 可从目标子节点解析最近可滚动祖先。动作结果包含前后位置、是否移动和边界状态。',
1394
+ description: '按方向滚动页面或指定容器;containerPolicy="nearest" 可从子节点解析最近的可滚动祖先。',
1379
1395
  inputSchema: {
1380
1396
  type: 'object',
1381
1397
  properties: {
@@ -1410,7 +1426,7 @@ async function main() {
1410
1426
  },
1411
1427
  {
1412
1428
  name: 'browser_page_hover',
1413
- description: '将鼠标悬停在元素上,默认内置观察与原子诊断(下拉菜单、提示、error logs、业务 requests 等),返回 { action, observation, diagnostics };传 observe:false 只关闭观察并保留诊断,同时传 diagnostics:false 才执行裸悬停。使用 CDP Input.dispatchMouseEvent 发送真实鼠标移动事件,selector 支持原生 CSS 或 "@eN" snapshot ref。',
1429
+ description: '将鼠标悬停在页面元素上。',
1414
1430
  inputSchema: {
1415
1431
  type: 'object',
1416
1432
  properties: {
@@ -1430,7 +1446,7 @@ async function main() {
1430
1446
  },
1431
1447
  {
1432
1448
  name: 'browser_page_eval',
1433
- description: '在页面上下文中执行 JavaScript 表达式并返回结果,作为结构化页面能力无法表达时的补充。默认裸执行;需要页面变化信号时显式传 observe 对象,需要原子返回新增 error logs/业务 requests 时传 diagnostics:true 或过滤对象。',
1449
+ description: '在页面上下文中执行 JavaScript 表达式,作为结构化页面 action 无法表达时的补充。',
1434
1450
  inputSchema: {
1435
1451
  type: 'object',
1436
1452
  properties: {
@@ -1463,7 +1479,7 @@ async function main() {
1463
1479
  },
1464
1480
  {
1465
1481
  name: 'browser_page_snapshot',
1466
- description: '获取页面无障碍树,返回角色、名称、值、状态和 @ref。默认 mode="full" 建立完整基线;长列表可用 mode="viewport",只看当前视口内的表单控件可用 mode="interactive",已知 CSS 区域可用 rootSelector,已有 ref 可用 rootRef + ancestorDepth 获取局部上下文,只查找特定文本/角色时用 query 服务端裁剪。视口内缺少 AX 控件语义时 interactive 会自动回退到 viewport,并返回 fallbackMode="viewport"。后续交互依赖页面交互工具内置的观察结果,仅在建议回退、导航或 ref 失效时再次调用。',
1482
+ description: '获取带 @ref 的页面无障碍树;支持完整、当前视口、交互控件、指定区域或查询结果。',
1467
1483
  inputSchema: {
1468
1484
  type: 'object',
1469
1485
  properties: {
@@ -1527,7 +1543,7 @@ async function main() {
1527
1543
  },
1528
1544
  {
1529
1545
  name: 'browser_page_press',
1530
- description: '在页面中按下键盘按键,默认内置观察与原子诊断(提交、关闭弹窗、error logs、业务 requests 等),返回 { action, observation, diagnostics };传 observe:false 只关闭观察并保留诊断,同时传 diagnostics:false 才执行裸按键。支持单个按键和组合键。',
1546
+ description: '在页面中按下键盘按键或组合键。',
1531
1547
  inputSchema: {
1532
1548
  type: 'object',
1533
1549
  properties: {
@@ -1616,7 +1632,7 @@ async function main() {
1616
1632
  },
1617
1633
  {
1618
1634
  name: 'browser_page_upload',
1619
- description: '向 <input type="file"> 上传单个或多个文件(通过 CDP DOM.setFileInputFiles),默认内置观察与原子诊断(上传状态、error logs、业务 requests 等),返回 { action, observation, diagnostics };传 observe:false 只关闭观察并保留诊断,同时传 diagnostics:false 才执行裸上传。selector 支持原生 CSS 或 "@eN" snapshot ref。',
1635
+ description: '向 <input type="file"> 元素上传一个或多个本地文件。',
1620
1636
  inputSchema: {
1621
1637
  type: 'object',
1622
1638
  properties: {
@@ -1641,7 +1657,7 @@ async function main() {
1641
1657
  },
1642
1658
  {
1643
1659
  name: 'browser_page_frames',
1644
- description: '列出当前页面中所有 frame(主 frame + iframe)。返回每个 frame 的 frameId、URL、名称等信息。适用于:了解页面是否包含 iframe、获取 iframe 的 frameId 以便在 browser_page_eval 中指定执行上下文。',
1660
+ description: '列出主 frame 和 iframe,返回可供 browser_page_eval 使用的 frameId。',
1645
1661
  inputSchema: {
1646
1662
  type: 'object',
1647
1663
  properties: {
@@ -1776,16 +1792,19 @@ async function main() {
1776
1792
  });
1777
1793
  // 处理工具调用请求
1778
1794
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
1779
- const { name, arguments: args } = request.params;
1795
+ const { arguments: args } = request.params;
1796
+ const name = request.params.name === 'browser_capture_checkpoint'
1797
+ ? 'browser_tab_checkpoint'
1798
+ : request.params.name;
1780
1799
  try {
1781
1800
  if (!(name in MCP_TOOL_ACTIONS))
1782
1801
  throw new Error(`Unknown tool: ${name}`);
1783
1802
  const toolName = name;
1784
1803
  let result;
1785
1804
  switch (toolName) {
1786
- case 'browser_capture_checkpoint': {
1805
+ case 'browser_tab_checkpoint': {
1787
1806
  const { tabId } = args;
1788
- result = await client.captureCheckpoint({ tabId });
1807
+ result = await client.tabCheckpoint({ tabId });
1789
1808
  break;
1790
1809
  }
1791
1810
  case 'browser_get_requests': {
@@ -1806,13 +1825,14 @@ async function main() {
1806
1825
  break;
1807
1826
  }
1808
1827
  case 'browser_get_events': {
1809
- const { tabId, source = 'all', event_type, filter, since, limit = 20, includeRaw = false, } = args;
1828
+ const { tabId, source = 'all', event_type, filter, since, after, limit = 20, includeRaw = false, } = args;
1810
1829
  result = await client.getEvents({
1811
1830
  tabId,
1812
1831
  source,
1813
1832
  event_type,
1814
1833
  filter,
1815
1834
  since,
1835
+ after,
1816
1836
  limit,
1817
1837
  includeRaw,
1818
1838
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mearl/mcp-server",
3
- "version": "2.7.0",
3
+ "version": "2.7.2",
4
4
  "description": "MCP Server for Mearl - enables AI to interact with Chrome browser requests and logs",
5
5
  "mcpName": "io.github.F-loat/mearl",
6
6
  "type": "module",
@@ -30,8 +30,8 @@
30
30
  "dependencies": {
31
31
  "@modelcontextprotocol/sdk": "^1.0.4",
32
32
  "prompts": "^2.4.2",
33
- "@mearl/client": "2.7.0",
34
- "@mearl/native-host": "2.7.0"
33
+ "@mearl/client": "2.7.2",
34
+ "@mearl/native-host": "2.7.2"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@types/node": "^24.9.1",