viyv-browser-mcp 0.7.3 → 0.7.5

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.
package/dist/index.js CHANGED
@@ -75,7 +75,7 @@ var BRIDGE = {
75
75
  /** Loopback address for bridge */
76
76
  TCP_HOST: "127.0.0.1",
77
77
  /** Maximum simultaneous MCP Server connections */
78
- MAX_CONNECTIONS: 10,
78
+ MAX_CONNECTIONS: 100,
79
79
  /** TTL for request routing entries (ms) */
80
80
  REQUEST_ROUTING_TTL: 6e4
81
81
  };
@@ -124,10 +124,10 @@ function syncNativeHostBinary() {
124
124
  }
125
125
  }
126
126
  function shouldUpdateBridge(bridgeVersion) {
127
- return compareSemver("0.7.3", bridgeVersion) > 0;
127
+ return compareSemver("0.7.5", bridgeVersion) > 0;
128
128
  }
129
129
  function getPackageVersion() {
130
- return "0.7.3";
130
+ return "0.7.5";
131
131
  }
132
132
  function compareSemver(a, b) {
133
133
  const pa = a.split(".").map(Number);
@@ -317,6 +317,7 @@ var LOG_PREFIX2 = "[viyv-browser:native-host]";
317
317
  var ROUTING_CLEANUP_INTERVAL = 3e4;
318
318
  function startBridge(options) {
319
319
  const { port = BRIDGE.TCP_PORT, host = BRIDGE.TCP_HOST, onError } = options;
320
+ const maxConnections = Number(process.env.VIYV_BRIDGE_MAX_CONNECTIONS) || BRIDGE.MAX_CONNECTIONS;
320
321
  const mcpConnections = /* @__PURE__ */ new Map();
321
322
  const requestOrigin = /* @__PURE__ */ new Map();
322
323
  const agentToConn = /* @__PURE__ */ new Map();
@@ -735,9 +736,9 @@ function startBridge(options) {
735
736
  });
736
737
  }
737
738
  function handleMcpConnection(socket, initialData) {
738
- if (mcpConnections.size >= BRIDGE.MAX_CONNECTIONS) {
739
+ if (mcpConnections.size >= maxConnections) {
739
740
  process.stderr.write(
740
- `${LOG_PREFIX2} Max connections (${BRIDGE.MAX_CONNECTIONS}) reached, rejecting
741
+ `${LOG_PREFIX2} Max connections (${maxConnections}) reached, rejecting
741
742
  `
742
743
  );
743
744
  socket.destroy();
@@ -1024,8 +1025,15 @@ var TOPICS = {
1024
1025
  - Don't use for: checking text values, verifying form state
1025
1026
  - Do use for: layout verification, image content, charts
1026
1027
 
1028
+ 6. indexed_page \u2192 Alternative text-based DOM representation with numbered interactive elements.
1029
+ - Returns [0]<button>Submit</>, [1]<input placeholder=Search/>, etc.
1030
+ - Use indexed_action(snapshotId, index, action) to interact by number
1031
+ - No screenshots needed \u2014 works with text-only LLMs, lower token cost
1032
+ - snapshotId expires on page change \u2014 call indexed_page again if stale
1033
+
1027
1034
  Recommended workflow:
1028
- page_outline \u2192 read_page(section) \u2192 find(specific element) \u2192 click/form_input`
1035
+ page_outline \u2192 read_page(section) \u2192 find(specific element) \u2192 click/form_input
1036
+ OR: indexed_page \u2192 indexed_action(click/type/select_option) for lower-cost automation`
1029
1037
  },
1030
1038
  interaction: {
1031
1039
  title: "Interaction \u2014 How to interact with elements",
@@ -1073,6 +1081,14 @@ file_upload \u2014 For uploading files or dropping files onto elements
1073
1081
  - Don't click file inputs \u2014 use file_upload instead
1074
1082
  - Best for: file inputs, canvas apps (Canva, Figma), custom drop zones
1075
1083
 
1084
+ indexed_action \u2014 Index-based interaction (alternative to ref-based tools above)
1085
+ - Requires snapshotId from indexed_page
1086
+ - Actions: click, type, select_option, hover, scroll_to
1087
+ - click/hover: CDP dispatch (trusted events, SPA compatible)
1088
+ - type: CDP click to focus + content script value setting
1089
+ - select_option: content script DOM manipulation
1090
+ - Best for: batch automation with text-only LLMs, lower token cost
1091
+
1076
1092
  Common patterns:
1077
1093
  Single field: find(input) \u2192 form_input(ref, value, submit: true)
1078
1094
  Multi-field form: read_page \u2192 form_fill([{ref, value}, ...], submit: true)
@@ -1081,7 +1097,8 @@ Common patterns:
1081
1097
  Dropdown: click(select ref) \u2192 key("ArrowDown ArrowDown Enter")
1082
1098
  Search: form_input(search input ref, query, submit: true)
1083
1099
  File upload: find(file input) \u2192 file_upload(ref, paths)
1084
- File drop: find(canvas) \u2192 file_upload(ref, paths) or file_upload(coordinate, paths)`
1100
+ File drop: find(canvas) \u2192 file_upload(ref, paths) or file_upload(coordinate, paths)
1101
+ Index-based: indexed_page \u2192 indexed_action(click, index=N) \u2192 wait_for(navigation)`
1085
1102
  },
1086
1103
  navigation: {
1087
1104
  title: "Navigation \u2014 How to navigate between pages",
@@ -1512,7 +1529,7 @@ var CLICK_RETURNS = `{
1512
1529
  clicked: true
1513
1530
  newTab?: { tabId, url } // only if target="_blank" link detected
1514
1531
  }`;
1515
- var CLICK_RELATED = ["form_input", "hover", "drag", "javascript_exec"];
1532
+ var CLICK_RELATED = ["form_input", "hover", "drag", "javascript_exec", "indexed_action"];
1516
1533
 
1517
1534
  // src/tools/core/drag.ts
1518
1535
  var DRAG_DESCRIPTION = `Drag from start coordinate to end coordinate.
@@ -1608,7 +1625,7 @@ var FORM_INPUT_RETURNS = `{
1608
1625
  navigated?: boolean // if page navigated after submit
1609
1626
  url?: string // new URL if navigated
1610
1627
  }`;
1611
- var FORM_INPUT_RELATED = ["click", "type", "find", "read_page"];
1628
+ var FORM_INPUT_RELATED = ["click", "type", "find", "read_page", "indexed_action"];
1612
1629
 
1613
1630
  // src/tools/core/get-page-text.ts
1614
1631
  var GET_PAGE_TEXT_DESCRIPTION = `Extract readable text from page. Use query for semantic filtering.
@@ -1628,6 +1645,66 @@ var GET_PAGE_TEXT_RETURNS = `// Without query:
1628
1645
  { sections: [{ index, tag, role, ariaLabel, heading, text, truncated }], truncated: boolean, charCount: number }`;
1629
1646
  var GET_PAGE_TEXT_RELATED = ["read_page", "find", "screenshot"];
1630
1647
 
1648
+ // src/tools/core/indexed-action.ts
1649
+ var INDEXED_ACTION_DESCRIPTION = `Interact with an element by its [index] from indexed_page. Actions: click, type, select_option, hover, scroll_to.
1650
+ Returns: { success, action, index }`;
1651
+ var INDEXED_ACTION_DETAIL = `Act on an indexed element from indexed_page output.
1652
+
1653
+ Actions:
1654
+ - click: Click the element. Supports modifier keys (ctrl, shift, alt, meta).
1655
+ - type: Set text value on input/textarea/contenteditable. Clears existing content.
1656
+ - select_option: Select a dropdown option by text match.
1657
+ - hover: Hover over the element.
1658
+ - scroll_to: Scroll the element into view.
1659
+
1660
+ The snapshotId from indexed_page is required. If the page has changed since indexed_page was called, this tool returns an error \u2014 call indexed_page again to get a fresh snapshot.
1661
+
1662
+ Examples:
1663
+ indexed_action(tabId=1, snapshotId=3, index=2, action="click")
1664
+ indexed_action(tabId=1, snapshotId=3, index=1, action="type", text="hello")
1665
+ indexed_action(tabId=1, snapshotId=3, index=5, action="select_option", option="Option A")`;
1666
+ var INDEXED_ACTION_RETURNS = `{
1667
+ action: string // the action performed
1668
+ index: number // the element index
1669
+ success: boolean // whether the action succeeded
1670
+ value?: string // set value (for type/select_option)
1671
+ tagName?: string // element tag name
1672
+ }`;
1673
+ var INDEXED_ACTION_RELATED = ["indexed_page", "click", "form_input"];
1674
+
1675
+ // src/tools/core/indexed-page.ts
1676
+ var INDEXED_PAGE_DESCRIPTION = `Get page DOM as indexed text. Interactive elements marked [0], [1], etc. Use indexed_action to act by index.
1677
+ Returns: { tree, snapshotId, elementCount, interactiveCount }`;
1678
+ var INDEXED_PAGE_DETAIL = `Alternative to read_page that returns a text-based DOM representation with numbered interactive elements.
1679
+
1680
+ Format example:
1681
+ [0]<a aria-label=Home>Home />
1682
+ [1]<input placeholder=Search />
1683
+ [2]<button>Submit />
1684
+ Some text content
1685
+ [3]<a>Learn more />
1686
+
1687
+ Each [N] marks an interactive element. Use indexed_action with the index number to click, type, or interact.
1688
+
1689
+ Options:
1690
+ - viewportOnly: only include elements visible in the viewport (default: false = full page)
1691
+ - maxChars: limit output size (default 50000)
1692
+ - includeAttributes: additional HTML attributes to include in output
1693
+
1694
+ The returned snapshotId must be passed to indexed_action. It expires after page changes \u2014 call indexed_page again if indexed_action reports a stale snapshot.
1695
+
1696
+ Advantages over read_page:
1697
+ - Lower token cost (no screenshots needed)
1698
+ - Works with text-only LLMs
1699
+ - Direct index-based interaction without ref resolution`;
1700
+ var INDEXED_PAGE_RETURNS = `{
1701
+ tree: string // indexed DOM text
1702
+ snapshotId: number // pass to indexed_action
1703
+ elementCount: number // total elements
1704
+ interactiveCount: number // indexed interactive elements
1705
+ }`;
1706
+ var INDEXED_PAGE_RELATED = ["indexed_action", "read_page", "screenshot"];
1707
+
1631
1708
  // src/tools/core/handle-dialog.ts
1632
1709
  var HANDLE_DIALOG_DESCRIPTION = `Handle JS dialog (alert/confirm/prompt) or set next auto-handle policy.
1633
1710
  Returns: { handled } or { policy_set }`;
@@ -1762,7 +1839,7 @@ var PAGE_OUTLINE_RETURNS = `{
1762
1839
  }]
1763
1840
  note?: string // only if no landmarks found
1764
1841
  }`;
1765
- var PAGE_OUTLINE_RELATED = ["read_page", "find", "get_page_text"];
1842
+ var PAGE_OUTLINE_RELATED = ["read_page", "find", "get_page_text", "indexed_page"];
1766
1843
 
1767
1844
  // src/tools/core/read-page.ts
1768
1845
  var READ_PAGE_DESCRIPTION = `Get page accessibility tree with element refs for interaction. Call page_outline first on unfamiliar pages.
@@ -1787,7 +1864,7 @@ var READ_PAGE_RETURNS = `{
1787
1864
  elementCount: number // total elements in tree
1788
1865
  truncated: boolean // whether output hit maxChars limit
1789
1866
  }`;
1790
- var READ_PAGE_RELATED = ["page_outline", "find", "get_page_text", "screenshot"];
1867
+ var READ_PAGE_RELATED = ["page_outline", "find", "get_page_text", "screenshot", "indexed_page"];
1791
1868
 
1792
1869
  // src/tools/core/read-table.ts
1793
1870
  var READ_TABLE_DESCRIPTION = `Extract HTML table data from web page by ref. Supports <table> and ARIA role="table".
@@ -3436,6 +3513,37 @@ var readPageTool = {
3436
3513
  )
3437
3514
  })
3438
3515
  };
3516
+ var indexedPageTool = {
3517
+ name: "indexed_page",
3518
+ description: INDEXED_PAGE_DESCRIPTION,
3519
+ detail: INDEXED_PAGE_DETAIL,
3520
+ returns: INDEXED_PAGE_RETURNS,
3521
+ category: "core",
3522
+ related: INDEXED_PAGE_RELATED,
3523
+ inputSchema: z.object({
3524
+ tabId: z.coerce.number().describe("Tab ID"),
3525
+ viewportOnly: z.boolean().optional().describe("Only include viewport-visible elements (default: false)"),
3526
+ maxChars: z.coerce.number().optional().describe("Max output characters (default: 50000)"),
3527
+ includeAttributes: z.array(z.string()).optional().describe("Additional HTML attributes to include in output")
3528
+ })
3529
+ };
3530
+ var indexedActionTool = {
3531
+ name: "indexed_action",
3532
+ description: INDEXED_ACTION_DESCRIPTION,
3533
+ detail: INDEXED_ACTION_DETAIL,
3534
+ returns: INDEXED_ACTION_RETURNS,
3535
+ category: "core",
3536
+ related: INDEXED_ACTION_RELATED,
3537
+ inputSchema: z.object({
3538
+ tabId: z.coerce.number().describe("Tab ID"),
3539
+ snapshotId: z.coerce.number().describe("Snapshot ID from indexed_page"),
3540
+ index: z.coerce.number().min(0).describe("Element index from indexed_page output"),
3541
+ action: z.enum(["click", "type", "select_option", "hover", "scroll_to"]).describe("Action to perform on the element"),
3542
+ text: z.string().optional().describe('Text to type (required for action: "type")'),
3543
+ option: z.string().optional().describe('Option text to select (required for action: "select_option")'),
3544
+ modifiers: z.string().optional().describe('Modifier keys for click (e.g. "ctrl+shift")')
3545
+ })
3546
+ };
3439
3547
  var findTool = {
3440
3548
  name: "find",
3441
3549
  description: FIND_DESCRIPTION,
@@ -4786,6 +4894,8 @@ var allTools = [
4786
4894
  hoverTool,
4787
4895
  dragTool,
4788
4896
  readPageTool,
4897
+ indexedPageTool,
4898
+ indexedActionTool,
4789
4899
  findTool,
4790
4900
  inspectTool,
4791
4901
  formInputTool,