@fusengine/browser-mcp 0.1.5 → 0.1.6

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/README.md CHANGED
@@ -84,7 +84,7 @@ Supported: `FUSE_ENGINE`, `FUSE_CHANNEL`, `FUSE_CDP_ENDPOINT`, `FUSE_EXECUTABLE_
84
84
  `FUSE_HEADLESS`, `FUSE_COUNTRY`, `FUSE_CURRENCY`, `FUSE_USER_DATA_DIR`,
85
85
  `FUSE_STORAGE_STATE`, `FUSE_OUTPUT_DIR`.
86
86
 
87
- ### Tools (23)
87
+ ### Tools (24)
88
88
 
89
89
  | Group | Tools |
90
90
  | --- | --- |
@@ -94,6 +94,7 @@ Supported: `FUSE_ENGINE`, `FUSE_CHANNEL`, `FUSE_CDP_ENDPOINT`, `FUSE_EXECUTABLE_
94
94
  | **Act** | `browser_click`, `browser_fill`, `browser_login`, `browser_scroll`, `browser_press`, `browser_select` |
95
95
  | **Agentic** | `browser_snapshot` (indexed refs), `browser_act` (by ref + page diff), `browser_run` (multi-step plan) |
96
96
  | **Extract** | `browser_extract` (text/prices/hotels/challenges), `browser_extract_schema` (typed, by CSS selectors) |
97
+ | **SERP** | `browser_serp_batch` — multi-query Google search in one session, per-query organic results + domain rank |
97
98
  | **Vision** | `browser_screenshot` (page or single element by `ref`) |
98
99
 
99
100
  Key agentic patterns:
@@ -0,0 +1,15 @@
1
+ import type { SerpBatchRow } from "../interfaces/extraction.js";
2
+ import type { ResolvedConfig } from "./config.js";
3
+ /** Options for {@link serpBatch}. */
4
+ export interface SerpBatchOptions {
5
+ queries: string[];
6
+ rankDomain?: string;
7
+ pages?: number;
8
+ hl?: string;
9
+ gl?: string;
10
+ /** Fixed inter-query delay (ms); defaults to a 2–4s jitter. */
11
+ delayMs?: number;
12
+ }
13
+ /** Search each query sequentially in one context; one row per query. */
14
+ export declare function serpBatch(config: ResolvedConfig, opts: SerpBatchOptions): Promise<SerpBatchRow[]>;
15
+ //# sourceMappingURL=serp-batch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serp-batch.d.ts","sourceRoot":"","sources":["../../src/agent/serp-batch.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAIhE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,qCAAqC;AACrC,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAWD,wEAAwE;AACxE,wBAAsB,SAAS,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAoBvG"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Run several Google searches in ONE browser session, sequentially (lower
3
+ * anti-bot risk than parallel), with a jittered delay between queries. Returns
4
+ * one row per query (SERP organic + optional domain rank). For small batches;
5
+ * high volume needs rotating proxies.
6
+ * @module agent/serp-batch
7
+ */
8
+ import { selectEngineForConfig } from "../engine/registry.js";
9
+ import { teardownOpened } from "../engine/teardown.js";
10
+ import { findDomainRanks } from "../extraction/serp-rank.js";
11
+ import { sleep } from "../lib/retry.js";
12
+ import { randInt } from "../lib/text.js";
13
+ import { gotoWithRetry } from "../net/navigate.js";
14
+ import { collectSerp } from "./serp-paged.js";
15
+ /** Build a Google search URL. */
16
+ function googleUrl(query, hl, gl) {
17
+ const u = new URL("https://www.google.com/search");
18
+ u.searchParams.set("q", query);
19
+ u.searchParams.set("hl", hl);
20
+ u.searchParams.set("gl", gl);
21
+ return u.toString();
22
+ }
23
+ /** Search each query sequentially in one context; one row per query. */
24
+ export async function serpBatch(config, opts) {
25
+ const opened = await selectEngineForConfig(config).open(config);
26
+ const page = opened.page ?? (await opened.context.newPage());
27
+ const rows = [];
28
+ try {
29
+ for (const [i, query] of opts.queries.entries()) {
30
+ if (i > 0)
31
+ await sleep(opts.delayMs ?? randInt(2_000, 4_000));
32
+ try {
33
+ const url = googleUrl(query, opts.hl ?? "en", opts.gl ?? "us");
34
+ await gotoWithRetry(page, url, { waitUntil: "domcontentloaded", timeout: 30_000 }, config.retry);
35
+ const serp = await collectSerp(page, opts.pages ?? 1, config.retry);
36
+ rows.push({ query, results: serp.organic, rank: opts.rankDomain ? findDomainRanks(serp, opts.rankDomain) : undefined });
37
+ }
38
+ catch (error) {
39
+ rows.push({ query, results: [], error: String(error) });
40
+ }
41
+ }
42
+ }
43
+ finally {
44
+ await teardownOpened(opened);
45
+ }
46
+ return rows;
47
+ }
48
+ //# sourceMappingURL=serp-batch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serp-batch.js","sourceRoot":"","sources":["../../src/agent/serp-batch.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE7D,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAa9C,iCAAiC;AACjC,SAAS,SAAS,CAAC,KAAa,EAAE,EAAU,EAAE,EAAU;IACtD,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,+BAA+B,CAAC,CAAC;IACnD,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC/B,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAC7B,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAC7B,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC;AACtB,CAAC;AAED,wEAAwE;AACxE,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,MAAsB,EAAE,IAAsB;IAC5E,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAChE,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7D,MAAM,IAAI,GAAmB,EAAE,CAAC;IAChC,IAAI,CAAC;QACH,KAAK,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YAChD,IAAI,CAAC,GAAG,CAAC;gBAAE,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;YAC9D,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,IAAI,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC;gBAC/D,MAAM,aAAa,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;gBACjG,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,IAAI,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;gBACpE,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;YAC1H,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC;IACH,CAAC;YAAS,CAAC;QACT,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Tear down an opened context safely. A CDP-attached (`connected`) context must
3
+ * NOT be closed — only the browser link is dropped — otherwise the user's real
4
+ * browser default context/pages would be destroyed.
5
+ * @module engine/teardown
6
+ */
7
+ import type { OpenedContext } from "../interfaces/engine.js";
8
+ /** Close a launched context+browser, or just drop the link for a CDP attach. */
9
+ export declare function teardownOpened(opened: OpenedContext): Promise<void>;
10
+ //# sourceMappingURL=teardown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"teardown.d.ts","sourceRoot":"","sources":["../../src/engine/teardown.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAE7D,gFAAgF;AAChF,wBAAsB,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAOzE"}
@@ -0,0 +1,11 @@
1
+ /** Close a launched context+browser, or just drop the link for a CDP attach. */
2
+ export async function teardownOpened(opened) {
3
+ if (opened.connected) {
4
+ await opened.browser?.close().catch(() => { });
5
+ return;
6
+ }
7
+ await opened.context.close().catch(() => { });
8
+ if (opened.browser)
9
+ await opened.browser.close().catch(() => { });
10
+ }
11
+ //# sourceMappingURL=teardown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"teardown.js","sourceRoot":"","sources":["../../src/engine/teardown.ts"],"names":[],"mappings":"AAQA,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAAqB;IACxD,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACrB,MAAM,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC9C,OAAO;IACT,CAAC;IACD,MAAM,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAC7C,IAAI,MAAM,CAAC,OAAO;QAAE,MAAM,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;AACnE,CAAC"}
@@ -83,4 +83,11 @@ export interface Serp {
83
83
  related: string[];
84
84
  rank?: DomainRank;
85
85
  }
86
+ /** One query's outcome in a SERP batch. */
87
+ export interface SerpBatchRow {
88
+ query: string;
89
+ rank?: DomainRank;
90
+ results: SerpResult[];
91
+ error?: string;
92
+ }
86
93
  //# sourceMappingURL=extraction.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"extraction.d.ts","sourceRoot":"","sources":["../../src/interfaces/extraction.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,yCAAyC;AACzC,MAAM,WAAW,KAAK;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,oDAAoD;AACpD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,kDAAkD;AAClD,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACtD,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,SAAS,EAAE,UAAU,GAAG,IAAI,CAAC;CAC9B;AAED,2CAA2C;AAC3C,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;CACd;AAED,gDAAgD;AAChD,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9D;AAED,8DAA8D;AAC9D,MAAM,WAAW,MAAM;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,mBAAmB,CAAC,EAAE,kBAAkB,EAAE,CAAC;CAC5C;AAED,yDAAyD;AACzD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,0CAA0C;AAC1C,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,yCAAyC;AACzC,MAAM,WAAW,IAAI;IACnB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,GAAG,EAAE,UAAU,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB"}
1
+ {"version":3,"file":"extraction.d.ts","sourceRoot":"","sources":["../../src/interfaces/extraction.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,yCAAyC;AACzC,MAAM,WAAW,KAAK;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,oDAAoD;AACpD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,kDAAkD;AAClD,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACtD,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,SAAS,EAAE,UAAU,GAAG,IAAI,CAAC;CAC9B;AAED,2CAA2C;AAC3C,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;CACd;AAED,gDAAgD;AAChD,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9D;AAED,8DAA8D;AAC9D,MAAM,WAAW,MAAM;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,mBAAmB,CAAC,EAAE,kBAAkB,EAAE,CAAC;CAC5C;AAED,yDAAyD;AACzD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,0CAA0C;AAC1C,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,yCAAyC;AACzC,MAAM,WAAW,IAAI;IACnB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,GAAG,EAAE,UAAU,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED,2CAA2C;AAC3C,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAcvD,+DAA+D;AAC/D,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,cAAc,CAAC;CAC1B;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,IAAI,WAAW,CAgB1C"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAevD,+DAA+D;AAC/D,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,cAAc,CAAC;CAC1B;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,IAAI,WAAW,CAiB1C"}
@@ -12,6 +12,7 @@ import { registerExtractTool } from "./tools/extract.js";
12
12
  import { registerExtractSchemaTool } from "./tools/extract-schema.js";
13
13
  import { registerNavigateTool } from "./tools/navigate.js";
14
14
  import { registerProbeTools } from "./tools/probe.js";
15
+ import { registerSerpBatchTool } from "./tools/serp-batch.js";
15
16
  import { registerRunTool } from "./tools/run.js";
16
17
  import { registerScreenshotTool } from "./tools/screenshot.js";
17
18
  import { registerSessionTools } from "./tools/session.js";
@@ -22,6 +23,7 @@ export function createServer() {
22
23
  const server = new McpServer({ name: "fuse-browser", version: VERSION });
23
24
  const sessions = new SessionManager();
24
25
  registerProbeTools(server);
26
+ registerSerpBatchTool(server);
25
27
  registerSessionTools(server, sessions);
26
28
  registerConnectTool(server, sessions);
27
29
  registerNavigateTool(server, sessions);
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAQnD,6EAA6E;AAC7E,MAAM,UAAU,YAAY;IAC1B,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IACzE,MAAM,QAAQ,GAAG,IAAI,cAAc,EAAE,CAAC;IACtC,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC3B,oBAAoB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACvC,mBAAmB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACtC,oBAAoB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACvC,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACnC,qBAAqB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACxC,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACnC,eAAe,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAClC,mBAAmB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACtC,yBAAyB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC5C,sBAAsB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACzC,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1B,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAC9B,CAAC"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAQnD,6EAA6E;AAC7E,MAAM,UAAU,YAAY;IAC1B,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IACzE,MAAM,QAAQ,GAAG,IAAI,cAAc,EAAE,CAAC;IACtC,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC3B,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC9B,oBAAoB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACvC,mBAAmB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACtC,oBAAoB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACvC,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACnC,qBAAqB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACxC,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACnC,eAAe,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAClC,mBAAmB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACtC,yBAAyB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC5C,sBAAsB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACzC,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1B,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * `browser_serp_batch` tool: run multiple Google searches in one session.
3
+ * @module server/tools/serp-batch
4
+ */
5
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
6
+ /** Register `browser_serp_batch`. */
7
+ export declare function registerSerpBatchTool(server: McpServer): void;
8
+ //# sourceMappingURL=serp-batch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serp-batch.d.ts","sourceRoot":"","sources":["../../../src/server/tools/serp-batch.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAQzE,qCAAqC;AACrC,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA+B7D"}
@@ -0,0 +1,35 @@
1
+ import { z } from "zod";
2
+ import { resolveConfig } from "../../agent/config.js";
3
+ import { serpBatch } from "../../agent/serp-batch.js";
4
+ import { toAgentOptions } from "../map-options.js";
5
+ import { jsonResult } from "../result.js";
6
+ import { agentOptionShape } from "../schemas.js";
7
+ /** Register `browser_serp_batch`. */
8
+ export function registerSerpBatchTool(server) {
9
+ server.registerTool("browser_serp_batch", {
10
+ title: "Google SERP batch",
11
+ description: "Run several Google searches in one session; returns per-query organic results and optional domain rank. Sequential + throttled (small batches; high volume needs proxies).",
12
+ inputSchema: {
13
+ queries: z.array(z.string()),
14
+ rankDomain: z.string().optional(),
15
+ pages: z.number().int().optional(),
16
+ hl: z.string().optional(),
17
+ gl: z.string().optional(),
18
+ delayMs: z.number().int().optional(),
19
+ ...agentOptionShape,
20
+ },
21
+ }, async (args) => {
22
+ const a = args;
23
+ const config = resolveConfig(toAgentOptions(a));
24
+ const rows = await serpBatch(config, {
25
+ queries: a.queries,
26
+ rankDomain: a.rankDomain,
27
+ pages: a.pages,
28
+ hl: a.hl,
29
+ gl: a.gl,
30
+ delayMs: a.delayMs,
31
+ });
32
+ return jsonResult({ rows });
33
+ });
34
+ }
35
+ //# sourceMappingURL=serp-batch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serp-batch.js","sourceRoot":"","sources":["../../../src/server/tools/serp-batch.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,qCAAqC;AACrC,MAAM,UAAU,qBAAqB,CAAC,MAAiB;IACrD,MAAM,CAAC,YAAY,CACjB,oBAAoB,EACpB;QACE,KAAK,EAAE,mBAAmB;QAC1B,WAAW,EACT,4KAA4K;QAC9K,WAAW,EAAE;YACX,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;YAC5B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YACjC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;YAClC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YACzB,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YACzB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;YACpC,GAAG,gBAAgB;SACpB;KACF,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,MAAM,CAAC,GAAG,IAA+B,CAAC;QAC1C,MAAM,MAAM,GAAG,aAAa,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE;YACnC,OAAO,EAAE,CAAC,CAAC,OAAmB;YAC9B,UAAU,EAAE,CAAC,CAAC,UAAgC;YAC9C,KAAK,EAAE,CAAC,CAAC,KAA2B;YACpC,EAAE,EAAE,CAAC,CAAC,EAAwB;YAC9B,EAAE,EAAE,CAAC,CAAC,EAAwB;YAC9B,OAAO,EAAE,CAAC,CAAC,OAA6B;SACzC,CAAC,CAAC;QACH,OAAO,UAAU,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9B,CAAC,CACF,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusengine/browser-mcp",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "MCP server + CLI giving AI agents a real, stealth browser (Patchright/Playwright) — per-country identity, self-healing actions, snapshots, multi-step plans, structured extraction, CDP attach.",
5
5
  "license": "MIT",
6
6
  "author": "Fusengine",