mcp-scraper 0.31.0 → 0.32.0

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 (42) hide show
  1. package/README.md +1 -1
  2. package/dist/bin/api-server.cjs +55 -11
  3. package/dist/bin/api-server.cjs.map +1 -1
  4. package/dist/bin/api-server.js +2 -2
  5. package/dist/bin/mcp-scraper-cli.cjs +4 -1
  6. package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
  7. package/dist/bin/mcp-scraper-cli.js +3 -3
  8. package/dist/bin/mcp-scraper-install.cjs +1 -1
  9. package/dist/bin/mcp-scraper-install.cjs.map +1 -1
  10. package/dist/bin/mcp-scraper-install.js +1 -1
  11. package/dist/bin/mcp-stdio-server.cjs +9 -6
  12. package/dist/bin/mcp-stdio-server.cjs.map +1 -1
  13. package/dist/bin/mcp-stdio-server.js +3 -3
  14. package/dist/bin/paa-harvest.cjs +26 -4
  15. package/dist/bin/paa-harvest.cjs.map +1 -1
  16. package/dist/bin/paa-harvest.js +2 -2
  17. package/dist/{chunk-KAMKTSJQ.js → chunk-55M5CE5L.js} +2 -2
  18. package/dist/chunk-CPQF3PYW.js +7 -0
  19. package/dist/chunk-CPQF3PYW.js.map +1 -0
  20. package/dist/{chunk-ZQSHKWV4.js → chunk-PTHY7NYD.js} +4 -1
  21. package/dist/chunk-PTHY7NYD.js.map +1 -0
  22. package/dist/{chunk-YH5DRFWQ.js → chunk-RDCCU7CQ.js} +25 -6
  23. package/dist/chunk-RDCCU7CQ.js.map +1 -0
  24. package/dist/{chunk-ZOXL3VWO.js → chunk-YOOEAXWP.js} +8 -8
  25. package/dist/chunk-YOOEAXWP.js.map +1 -0
  26. package/dist/index.cjs +26 -4
  27. package/dist/index.cjs.map +1 -1
  28. package/dist/index.d.cts +9 -0
  29. package/dist/index.d.ts +9 -0
  30. package/dist/index.js +2 -2
  31. package/dist/{server-DS3ZSNNO.js → server-OBOTNFD6.js} +31 -8
  32. package/dist/{server-DS3ZSNNO.js.map → server-OBOTNFD6.js.map} +1 -1
  33. package/dist/{worker-RYP5EOV5.js → worker-7DJYUACV.js} +3 -3
  34. package/docs/mcp-tool-manifest.generated.json +7 -7
  35. package/package.json +1 -1
  36. package/dist/chunk-W3GYPHFL.js +0 -7
  37. package/dist/chunk-W3GYPHFL.js.map +0 -1
  38. package/dist/chunk-YH5DRFWQ.js.map +0 -1
  39. package/dist/chunk-ZOXL3VWO.js.map +0 -1
  40. package/dist/chunk-ZQSHKWV4.js.map +0 -1
  41. /package/dist/{chunk-KAMKTSJQ.js.map → chunk-55M5CE5L.js.map} +0 -0
  42. /package/dist/{worker-RYP5EOV5.js.map → worker-7DJYUACV.js.map} +0 -0
@@ -7,16 +7,16 @@ import {
7
7
  registerMemoryMcpTools,
8
8
  registerPaaExtractorMcpTools,
9
9
  registerSerpIntelligenceCaptureTools
10
- } from "../chunk-ZOXL3VWO.js";
10
+ } from "../chunk-YOOEAXWP.js";
11
11
  import "../chunk-R7EETU7Z.js";
12
12
  import "../chunk-MTSBI7ZH.js";
13
13
  import {
14
14
  renderInstallTerminal
15
15
  } from "../chunk-DUS4ENOY.js";
16
- import "../chunk-ZQSHKWV4.js";
16
+ import "../chunk-PTHY7NYD.js";
17
17
  import {
18
18
  PACKAGE_VERSION
19
- } from "../chunk-W3GYPHFL.js";
19
+ } from "../chunk-CPQF3PYW.js";
20
20
  import "../chunk-4767BA2O.js";
21
21
  import "../chunk-M2S27J6Z.js";
22
22
  import "../chunk-ICT7DDHL.js";
@@ -47,6 +47,9 @@ var HarvestOptionsSchema = import_zod.z.object({
47
47
  device: import_zod.z.enum(["desktop", "mobile"]).default("desktop"),
48
48
  proxyMode: import_zod.z.enum(["location", "configured", "none"]).default(DEFAULT_PROXY_MODE),
49
49
  proxyZip: import_zod.z.string().regex(/^\d{5}$/).optional(),
50
+ keepDefaultProxy: import_zod.z.boolean().optional(),
51
+ requireUsEgress: import_zod.z.boolean().optional(),
52
+ maxAttempts: import_zod.z.number().int().min(1).max(12).optional(),
50
53
  debug: import_zod.z.boolean().default(false),
51
54
  depth: import_zod.z.number().int().min(1).max(30).default(3),
52
55
  maxQuestions: import_zod.z.number().int().min(1).max(1e3).default(100),
@@ -493,6 +496,15 @@ function positiveIntFromEnv(name, fallback) {
493
496
  function proxyIdSuffix(proxyId) {
494
497
  return proxyId ? proxyId.slice(-6) : null;
495
498
  }
499
+ function serpArrivalUrl(googleUrl) {
500
+ const base = process.env.SERP_REDIRECT_BASE?.trim().replace(/\/+$/, "");
501
+ if (!base) return googleUrl;
502
+ return `${base}/g/${Buffer.from(googleUrl, "utf8").toString("base64url")}`;
503
+ }
504
+ function isUsCountry(country) {
505
+ if (!country) return false;
506
+ return /united states|u\.?s\.?a?\.?|^us$/i.test(country.trim());
507
+ }
496
508
  function errorText(err) {
497
509
  return err instanceof Error ? err.message : String(err);
498
510
  }
@@ -626,7 +638,7 @@ var BrowserDriver = class {
626
638
  this.kernelProxyType = config.kernelProxyResolution?.proxyType ?? null;
627
639
  let defaultProxyDisabled = null;
628
640
  let defaultProxyDisableError = null;
629
- if (!config.kernelProxyId) {
641
+ if (!config.kernelProxyId && !config.keepDefaultProxy) {
630
642
  try {
631
643
  await withTimeout(
632
644
  this.kernelClient.browsers.update(this.kernelSessionId, { disable_default_proxy: true }),
@@ -676,9 +688,15 @@ var BrowserDriver = class {
676
688
  await this.installEsbuildHelperShims(this.context);
677
689
  this.page = await this.context.newPage();
678
690
  await this.page.setViewportSize(config.viewport);
679
- if (this.debugEnabled) {
691
+ if (this.debugEnabled || config.requireUsEgress) {
680
692
  this.debugSnapshot.networkLocation = await this.captureBrowserNetworkLocation();
681
693
  }
694
+ if (config.requireUsEgress) {
695
+ const country = this.debugSnapshot.networkLocation?.country ?? null;
696
+ if (!isUsCountry(country)) {
697
+ throw new CaptchaError(`Non-US egress (${country ?? "unknown"}) \u2014 retrying with a fresh session`);
698
+ }
699
+ }
682
700
  return;
683
701
  }
684
702
  const launchOpts = {
@@ -818,6 +836,7 @@ var BrowserDriver = class {
818
836
  if (options?.num) params.set("num", String(options.num));
819
837
  if (uule) params.set("uule", uule);
820
838
  const url = "https://www.google.com/search?" + params.toString();
839
+ const navUrl = serpArrivalUrl(url);
821
840
  const navDebug = options?.debug ? {
822
841
  requestedUrl: url,
823
842
  finalUrl: null,
@@ -830,7 +849,7 @@ var BrowserDriver = class {
830
849
  } : null;
831
850
  if (navDebug) this.debugSnapshot.serpNavigation = navDebug;
832
851
  try {
833
- await this.page.goto(url, { waitUntil: "domcontentloaded", timeout: 45e3 });
852
+ await this.page.goto(navUrl, { waitUntil: "domcontentloaded", timeout: 45e3 });
834
853
  } catch (err) {
835
854
  await this.updateSerpNavigationDebug(navDebug, url, { hasPaa: null, captchaDetected: null });
836
855
  const diag = await this.captureDiagnostics(url);
@@ -2356,6 +2375,8 @@ var PAAExtractor = class {
2356
2375
  kernelProxyId: options.kernelProxyId,
2357
2376
  kernelProxyResolution: options.kernelProxyResolution,
2358
2377
  proxyMode: options.proxyMode,
2378
+ keepDefaultProxy: options.keepDefaultProxy,
2379
+ requireUsEgress: options.requireUsEgress,
2359
2380
  viewport: isMobile ? { width: 390, height: 844 } : { width: 1280, height: 800 },
2360
2381
  locale: `${options.hl}-${options.gl.toUpperCase()}`,
2361
2382
  userAgent: isMobile ? MOBILE_USER_AGENT2 : DESKTOP_USER_AGENT2,
@@ -3306,7 +3327,8 @@ async function harvest(rawOptions) {
3306
3327
  };
3307
3328
  const requestedDebug = typeof raw.debug === "boolean" ? raw.debug : false;
3308
3329
  const needsLocationEvidence = proxyMode === "location" && Boolean(proxyOpts.location);
3309
- const maxAttempts = maxAttemptsForProxyMode(proxyMode) + 1;
3330
+ const requestedMaxAttempts = raw.maxAttempts;
3331
+ const maxAttempts = typeof requestedMaxAttempts === "number" && Number.isInteger(requestedMaxAttempts) && requestedMaxAttempts >= 1 ? requestedMaxAttempts : maxAttemptsForProxyMode(proxyMode) + 1;
3310
3332
  const serializer = new OutputSerializer();
3311
3333
  let lastError = null;
3312
3334
  let effectiveProxyMode = proxyMode;