@fusengine/browser-mcp 0.1.6 → 0.1.8

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
@@ -47,6 +47,10 @@ npx fuse-browser probe 'https://www.booking.com/searchresults.html?ss=Tokyo' \
47
47
 
48
48
  # Use the installed Chrome
49
49
  npx fuse-browser probe https://example.com --channel chrome
50
+
51
+ # SEO rank tracking across many keywords (one session)
52
+ npx fuse-browser serp-batch "agence web vevey" "création site web lausanne" \
53
+ --rank-domain fusengine.ch --serp-pages 2 --hl fr --gl ch
50
54
  ```
51
55
 
52
56
  Sensitive actions (`pay`, `book`, `checkout`, `confirm`, …) are **blocked** unless
package/dist/bin/cli.js CHANGED
@@ -1,12 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * fuse-browser CLI entry point (`probe` subcommand).
3
+ * fuse-browser CLI entry point. Subcommands: `probe`, `serp-batch`.
4
4
  * @module bin/cli
5
5
  */
6
6
  import { parseArgs } from "node:util";
7
- import { BrowserAgent } from "../agent/browser-agent.js";
8
- import { compactReport } from "../agent/compact.js";
9
- import { GuardrailViolation } from "../lib/errors.js";
7
+ import { runProbeCli } from "./probe-cli.js";
8
+ import { runSerpBatch } from "./serp-batch-cli.js";
10
9
  const { positionals, values } = parseArgs({
11
10
  allowPositionals: true,
12
11
  options: {
@@ -21,6 +20,9 @@ const { positionals, values } = parseArgs({
21
20
  "extract-serp": { type: "boolean" },
22
21
  "serp-pages": { type: "string" },
23
22
  "rank-domain": { type: "string" },
23
+ hl: { type: "string" },
24
+ gl: { type: "string" },
25
+ "delay-ms": { type: "string" },
24
26
  "human-mode": { type: "boolean" },
25
27
  approved: { type: "boolean" },
26
28
  replay: { type: "boolean" },
@@ -35,56 +37,16 @@ const { positionals, values } = parseArgs({
35
37
  fill: { type: "string", multiple: true },
36
38
  },
37
39
  });
38
- const [command, url] = positionals;
39
- if (command !== "probe" || !url) {
40
- process.stderr.write("usage: fuse-browser probe <url> [--click TEXT] [--fill TARGET=VALUE] [--country US] [--headed] ...\n");
41
- process.exit(1);
42
- }
43
- const actions = [];
44
- for (const item of (values.fill ?? [])) {
45
- const eq = item.indexOf("=");
46
- if (eq < 0) {
47
- process.stderr.write("--fill must be TARGET=VALUE\n");
48
- process.exit(1);
49
- }
50
- actions.push({ type: "fill", target: item.slice(0, eq), value: item.slice(eq + 1) });
40
+ const [command, ...rest] = positionals;
41
+ const opts = values;
42
+ if (command === "serp-batch") {
43
+ await runSerpBatch(rest, opts);
51
44
  }
52
- for (const target of (values.click ?? []))
53
- actions.push({ type: "click", target });
54
- const agent = new BrowserAgent({
55
- engine: values.engine,
56
- countryCode: values.country,
57
- currency: values.currency,
58
- headless: !values.headed,
59
- humanMode: Boolean(values["human-mode"]),
60
- outputDir: values["output-dir"],
61
- storageStatePath: values["storage-state"],
62
- proxyUrl: values.proxy,
63
- proxyMapPath: values["proxy-map"],
64
- userDataDir: values["user-data-dir"],
65
- replayEnabled: Boolean(values.replay),
66
- siteMemoryDir: values["site-memory-dir"],
67
- });
68
- try {
69
- const report = await agent.probe(url, {
70
- actions,
71
- humanApproved: Boolean(values.approved),
72
- autoConsent: Boolean(values["auto-consent"]),
73
- extractPrices: Boolean(values["extract-prices"]),
74
- detectChallenges: Boolean(values["detect-challenges"]),
75
- observeVisual: Boolean(values["observe-visual"]),
76
- extractSerp: Boolean(values["extract-serp"]),
77
- serpPages: values["serp-pages"] ? Number(values["serp-pages"]) : undefined,
78
- rankDomain: values["rank-domain"],
79
- waitMs: values["wait-ms"] ? Number(values["wait-ms"]) : 0,
80
- });
81
- process.stdout.write(`${JSON.stringify(compactReport(report), null, 2)}\n`);
45
+ else if (command === "probe" && rest[0]) {
46
+ await runProbeCli(rest[0], opts);
82
47
  }
83
- catch (err) {
84
- if (err instanceof GuardrailViolation) {
85
- process.stderr.write(`BLOCKED: ${err.message}\n`);
86
- process.exit(2);
87
- }
88
- throw err;
48
+ else {
49
+ process.stderr.write("usage: fuse-browser probe <url> [...] | fuse-browser serp-batch <query...> --rank-domain <d> [--serp-pages N] [--hl fr] [--gl ch]\n");
50
+ process.exit(1);
89
51
  }
90
52
  //# sourceMappingURL=cli.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/bin/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/bin/cli.ts"],"names":[],"mappings":";AACA;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACxC,gBAAgB,EAAE,IAAI;IACtB,OAAO,EAAE;QACP,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC1B,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC3B,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC5B,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;QAC3B,cAAc,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;QACnC,gBAAgB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;QACrC,mBAAmB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;QACxC,gBAAgB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;QACrC,cAAc,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;QACnC,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAChC,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACjC,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACtB,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACtB,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC9B,YAAY,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;QACjC,QAAQ,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;QAC7B,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;QAC3B,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC7B,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAChC,eAAe,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACnC,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACzB,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC/B,eAAe,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACnC,iBAAiB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACrC,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;QACzC,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;KACzC;CACF,CAAC,CAAC;AAEH,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,WAAW,CAAC;AACvC,MAAM,IAAI,GAAG,MAAiC,CAAC;AAE/C,IAAI,OAAO,KAAK,YAAY,EAAE,CAAC;IAC7B,MAAM,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACjC,CAAC;KAAM,IAAI,OAAO,KAAK,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1C,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AACnC,CAAC;KAAM,CAAC;IACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,qIAAqI,CACtI,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
@@ -0,0 +1,5 @@
1
+ type Values = Record<string, unknown>;
2
+ /** Run the `probe` subcommand against `url`. */
3
+ export declare function runProbeCli(url: string, values: Values): Promise<void>;
4
+ export {};
5
+ //# sourceMappingURL=probe-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"probe-cli.d.ts","sourceRoot":"","sources":["../../src/bin/probe-cli.ts"],"names":[],"mappings":"AAUA,KAAK,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAiBtC,gDAAgD;AAChD,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoC5E"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * `probe` subcommand handler: run one probe and print the compact report.
3
+ * @module bin/probe-cli
4
+ */
5
+ import { BrowserAgent } from "../agent/browser-agent.js";
6
+ import { compactReport } from "../agent/compact.js";
7
+ import { GuardrailViolation } from "../lib/errors.js";
8
+ const str = (v) => (typeof v === "string" ? v : undefined);
9
+ function buildActions(values) {
10
+ const actions = [];
11
+ for (const item of values.fill ?? []) {
12
+ const eq = item.indexOf("=");
13
+ if (eq < 0) {
14
+ process.stderr.write("--fill must be TARGET=VALUE\n");
15
+ process.exit(1);
16
+ }
17
+ actions.push({ type: "fill", target: item.slice(0, eq), value: item.slice(eq + 1) });
18
+ }
19
+ for (const target of values.click ?? [])
20
+ actions.push({ type: "click", target });
21
+ return actions;
22
+ }
23
+ /** Run the `probe` subcommand against `url`. */
24
+ export async function runProbeCli(url, values) {
25
+ const agent = new BrowserAgent({
26
+ engine: str(values.engine),
27
+ countryCode: str(values.country),
28
+ currency: str(values.currency),
29
+ headless: !values.headed,
30
+ humanMode: Boolean(values["human-mode"]),
31
+ outputDir: str(values["output-dir"]),
32
+ storageStatePath: str(values["storage-state"]),
33
+ proxyUrl: str(values.proxy),
34
+ proxyMapPath: str(values["proxy-map"]),
35
+ userDataDir: str(values["user-data-dir"]),
36
+ replayEnabled: Boolean(values.replay),
37
+ siteMemoryDir: str(values["site-memory-dir"]),
38
+ });
39
+ try {
40
+ const report = await agent.probe(url, {
41
+ actions: buildActions(values),
42
+ humanApproved: Boolean(values.approved),
43
+ autoConsent: Boolean(values["auto-consent"]),
44
+ extractPrices: Boolean(values["extract-prices"]),
45
+ detectChallenges: Boolean(values["detect-challenges"]),
46
+ observeVisual: Boolean(values["observe-visual"]),
47
+ extractSerp: Boolean(values["extract-serp"]),
48
+ serpPages: values["serp-pages"] ? Number(values["serp-pages"]) : undefined,
49
+ rankDomain: str(values["rank-domain"]),
50
+ waitMs: values["wait-ms"] ? Number(values["wait-ms"]) : 0,
51
+ });
52
+ process.stdout.write(`${JSON.stringify(compactReport(report), null, 2)}\n`);
53
+ }
54
+ catch (err) {
55
+ if (err instanceof GuardrailViolation) {
56
+ process.stderr.write(`BLOCKED: ${err.message}\n`);
57
+ process.exit(2);
58
+ }
59
+ throw err;
60
+ }
61
+ }
62
+ //# sourceMappingURL=probe-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"probe-cli.js","sourceRoot":"","sources":["../../src/bin/probe-cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ type Values = Record<string, unknown>;
2
+ /** Run the `serp-batch` subcommand over `queries`. */
3
+ export declare function runSerpBatch(queries: string[], values: Values): Promise<void>;
4
+ export {};
5
+ //# sourceMappingURL=serp-batch-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serp-batch-cli.d.ts","sourceRoot":"","sources":["../../src/bin/serp-batch-cli.ts"],"names":[],"mappings":"AAQA,KAAK,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAGtC,sDAAsD;AACtD,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBnF"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * `serp-batch` subcommand handler: run several Google searches, print JSON rows.
3
+ * @module bin/serp-batch-cli
4
+ */
5
+ import { resolveConfig } from "../agent/config.js";
6
+ import { serpBatch } from "../agent/serp-batch.js";
7
+ const str = (v) => (typeof v === "string" ? v : undefined);
8
+ /** Run the `serp-batch` subcommand over `queries`. */
9
+ export async function runSerpBatch(queries, values) {
10
+ if (queries.length === 0) {
11
+ process.stderr.write("serp-batch needs at least one query\n");
12
+ process.exit(1);
13
+ }
14
+ const config = resolveConfig({
15
+ engine: str(values.engine),
16
+ countryCode: str(values.country),
17
+ headless: !values.headed,
18
+ outputDir: str(values["output-dir"]),
19
+ proxyUrl: str(values.proxy),
20
+ });
21
+ const rows = await serpBatch(config, {
22
+ queries,
23
+ rankDomain: str(values["rank-domain"]),
24
+ pages: values["serp-pages"] ? Number(values["serp-pages"]) : undefined,
25
+ hl: str(values.hl),
26
+ gl: str(values.gl),
27
+ delayMs: values["delay-ms"] ? Number(values["delay-ms"]) : undefined,
28
+ });
29
+ process.stdout.write(`${JSON.stringify(rows, null, 2)}\n`);
30
+ }
31
+ //# sourceMappingURL=serp-batch-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serp-batch-cli.js","sourceRoot":"","sources":["../../src/bin/serp-batch-cli.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAInD,MAAM,GAAG,GAAG,CAAC,CAAU,EAAsB,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;AAExF,sDAAsD;AACtD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAiB,EAAE,MAAc;IAClE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,MAAM,GAAG,aAAa,CAAC;QAC3B,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,CAA2B;QACpD,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC;QAChC,QAAQ,EAAE,CAAC,MAAM,CAAC,MAAM;QACxB,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QACpC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC;KAC5B,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE;QACnC,OAAO;QACP,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QACtC,KAAK,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;QACtE,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QAClB,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;KACrE,CAAC,CAAC;IACH,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AAC7D,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusengine/browser-mcp",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
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",