mcp-scraper 0.43.2 → 0.43.4

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 (39) hide show
  1. package/README.md +1 -1
  2. package/dist/bin/api-server.cjs +92 -52
  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 +1 -1
  6. package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
  7. package/dist/bin/mcp-scraper-cli.js +1 -1
  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 +1 -1
  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 +42 -22
  15. package/dist/bin/paa-harvest.cjs.map +1 -1
  16. package/dist/bin/paa-harvest.js +2 -2
  17. package/dist/{chunk-H7LQ6PTI.js → chunk-6TAQ2MXK.js} +50 -24
  18. package/dist/chunk-6TAQ2MXK.js.map +1 -0
  19. package/dist/{chunk-YJNGNMDO.js → chunk-SXLQZKWC.js} +3 -3
  20. package/dist/chunk-XQIVXIAL.js +7 -0
  21. package/dist/chunk-XQIVXIAL.js.map +1 -0
  22. package/dist/{chunk-DAS7L4SF.js → chunk-ZDVQARDQ.js} +3 -1
  23. package/dist/chunk-ZDVQARDQ.js.map +1 -0
  24. package/dist/index.cjs +42 -22
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.cts +1 -1
  27. package/dist/index.d.ts +1 -1
  28. package/dist/index.js +2 -2
  29. package/dist/{server-BPEXEKA6.js → server-K76DL4S7.js} +39 -32
  30. package/dist/server-K76DL4S7.js.map +1 -0
  31. package/dist/{worker-2LIOH744.js → worker-OB6WSWOD.js} +3 -3
  32. package/package.json +2 -1
  33. package/dist/chunk-DAS7L4SF.js.map +0 -1
  34. package/dist/chunk-H7LQ6PTI.js.map +0 -1
  35. package/dist/chunk-MD75M2L5.js +0 -7
  36. package/dist/chunk-MD75M2L5.js.map +0 -1
  37. package/dist/server-BPEXEKA6.js.map +0 -1
  38. /package/dist/{chunk-YJNGNMDO.js.map → chunk-SXLQZKWC.js.map} +0 -0
  39. /package/dist/{worker-2LIOH744.js.map → worker-OB6WSWOD.js.map} +0 -0
@@ -11,16 +11,16 @@ import {
11
11
  registerScheduledResultsMcpTools,
12
12
  registerSerpIntelligenceCaptureTools,
13
13
  resolveDeploymentProfile
14
- } from "../chunk-YJNGNMDO.js";
14
+ } from "../chunk-SXLQZKWC.js";
15
15
  import "../chunk-2K74LVV7.js";
16
16
  import "../chunk-BBI7RGOT.js";
17
- import "../chunk-DAS7L4SF.js";
17
+ import "../chunk-ZDVQARDQ.js";
18
18
  import {
19
19
  renderInstallTerminal
20
20
  } from "../chunk-TC4GDB2Q.js";
21
21
  import {
22
22
  PACKAGE_VERSION
23
- } from "../chunk-MD75M2L5.js";
23
+ } from "../chunk-XQIVXIAL.js";
24
24
  import "../chunk-X5WDJ7D7.js";
25
25
  import "../chunk-5UN33CGU.js";
26
26
  import "../chunk-FCFQ634B.js";
@@ -319,6 +319,7 @@ var SiteAuditPhaseLogRowSchema = import_zod2.z.object({
319
319
 
320
320
  // src/api/cost-context.ts
321
321
  var import_node_async_hooks = require("async_hooks");
322
+ var HEADLESS_HARVEST_TEST_ENV = "MCP_SCRAPER_ALLOW_HEADLESS_HARVEST_TEST";
322
323
  var storage = new import_node_async_hooks.AsyncLocalStorage();
323
324
  function runWithCostContext(ctx, fn) {
324
325
  return storage.run(ctx, fn);
@@ -508,10 +509,35 @@ function boolToInt(v) {
508
509
  return v ? 1 : 0;
509
510
  }
510
511
 
512
+ // src/lib/browser-user-agent.ts
513
+ var RUNTIME_BROWSER_UA = /\b(?:HeadlessChrome|Chrome|Chromium|Firefox)\/\d+|\bVersion\/\d+.*\bSafari\//;
514
+ async function detectPageUserAgent(page) {
515
+ try {
516
+ const value = await page.evaluate(() => navigator.userAgent);
517
+ return typeof value === "string" && RUNTIME_BROWSER_UA.test(value) ? value : null;
518
+ } catch {
519
+ return null;
520
+ }
521
+ }
522
+ async function detectRuntimeUserAgent(browser) {
523
+ let probeContext = null;
524
+ try {
525
+ let page = browser.contexts().flatMap((context) => context.pages())[0];
526
+ if (!page) {
527
+ probeContext = await browser.newContext();
528
+ page = probeContext.pages()[0] ?? await probeContext.newPage();
529
+ }
530
+ return await detectPageUserAgent(page);
531
+ } catch {
532
+ return null;
533
+ } finally {
534
+ if (probeContext) await probeContext.close().catch(() => {
535
+ });
536
+ }
537
+ }
538
+
511
539
  // src/driver/BrowserDriver.ts
512
540
  import_playwright_extra.chromium.use((0, import_puppeteer_extra_plugin_stealth.default)());
513
- var DESKTOP_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36";
514
- var MOBILE_USER_AGENT = "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1";
515
541
  var DEFAULT_KERNEL_BROWSER_TIMEOUT_SECONDS = 180;
516
542
  var KERNEL_BROWSER_CLOSE_TIMEOUT_MS = 3e3;
517
543
  var KERNEL_SESSION_DELETE_TIMEOUT_MS = 5e3;
@@ -546,21 +572,11 @@ async function ensureKernelProfile(kernelClient, name) {
546
572
  if (!isKernelProfileConflict(err)) throw err;
547
573
  }
548
574
  }
549
- async function detectRuntimeUserAgent(browser) {
550
- try {
551
- const page = browser.contexts()[0]?.pages()[0];
552
- if (!page) return null;
553
- const ua = await page.evaluate(() => navigator.userAgent);
554
- return typeof ua === "string" && /Chrome\/\d+/.test(ua) ? ua : null;
555
- } catch {
556
- return null;
557
- }
558
- }
559
575
  function rankCheckContextOptions(config, runtimeUserAgent) {
560
576
  return {
561
577
  viewport: config.viewport,
562
578
  locale: config.locale,
563
- userAgent: config.userAgent ?? (config.isMobile ? MOBILE_USER_AGENT : runtimeUserAgent ?? DESKTOP_USER_AGENT),
579
+ ...runtimeUserAgent ? { userAgent: runtimeUserAgent } : {},
564
580
  ...config.deviceScaleFactor ? { deviceScaleFactor: config.deviceScaleFactor } : {},
565
581
  ...config.isMobile !== void 0 ? { isMobile: config.isMobile } : {},
566
582
  ...config.hasTouch !== void 0 ? { hasTouch: config.hasTouch } : {}
@@ -635,7 +651,7 @@ var BrowserDriver = class {
635
651
  viewport: config.viewport,
636
652
  locale: config.locale,
637
653
  device,
638
- userAgent: config.userAgent ?? (config.isMobile ? MOBILE_USER_AGENT : DESKTOP_USER_AGENT),
654
+ userAgent: null,
639
655
  deviceScaleFactor: config.deviceScaleFactor ?? null,
640
656
  isMobile: config.isMobile === true,
641
657
  hasTouch: config.hasTouch === true
@@ -723,7 +739,7 @@ var BrowserDriver = class {
723
739
  }
724
740
  this.browser = await import_playwright.chromium.connectOverCDP(kernelBrowser.cdp_ws_url);
725
741
  const runtimeUserAgent = await detectRuntimeUserAgent(this.browser);
726
- this.debugSnapshot.context.userAgent = config.userAgent ?? (config.isMobile ? MOBILE_USER_AGENT : runtimeUserAgent ?? DESKTOP_USER_AGENT);
742
+ this.debugSnapshot.context.userAgent = runtimeUserAgent;
727
743
  this.context = await this.browser.newContext(rankCheckContextOptions(config, runtimeUserAgent));
728
744
  await this.installEsbuildHelperShims(this.context);
729
745
  this.page = await this.context.newPage();
@@ -745,17 +761,19 @@ var BrowserDriver = class {
745
761
  ...config.browserExecutablePath ? { executablePath: config.browserExecutablePath } : {},
746
762
  ...config.ignoreDefaultArgs ? { ignoreDefaultArgs: config.ignoreDefaultArgs } : {}
747
763
  };
748
- const ctxOpts = rankCheckContextOptions(config);
749
764
  if (config.profileDir) {
750
765
  this.context = await import_playwright_extra.chromium.launchPersistentContext(config.profileDir, {
751
766
  ...launchOpts,
752
- ...ctxOpts
767
+ ...rankCheckContextOptions(config)
753
768
  });
754
769
  await this.installEsbuildHelperShims(this.context);
755
770
  this.page = await this.context.newPage();
771
+ this.debugSnapshot.context.userAgent = await detectPageUserAgent(this.page);
756
772
  } else {
757
773
  this.browser = await import_playwright_extra.chromium.launch(launchOpts);
758
- this.context = await this.browser.newContext(ctxOpts);
774
+ const runtimeUserAgent = await detectRuntimeUserAgent(this.browser);
775
+ this.debugSnapshot.context.userAgent = runtimeUserAgent;
776
+ this.context = await this.browser.newContext(rankCheckContextOptions(config, runtimeUserAgent));
759
777
  await this.installEsbuildHelperShims(this.context);
760
778
  this.page = await this.context.newPage();
761
779
  }
@@ -1682,8 +1700,6 @@ async function extractAISurfacesFromDocument(config) {
1682
1700
  }
1683
1701
 
1684
1702
  // src/extractor/PAAExtractor.ts
1685
- var DESKTOP_USER_AGENT2 = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36";
1686
- var MOBILE_USER_AGENT2 = "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1";
1687
1703
  var PAAExtractor = class {
1688
1704
  constructor(driver, reporter) {
1689
1705
  this.driver = driver;
@@ -2493,7 +2509,6 @@ var PAAExtractor = class {
2493
2509
  requireUsEgress: options.requireUsEgress,
2494
2510
  viewport: isMobile ? { width: 390, height: 844 } : { width: 1280, height: 800 },
2495
2511
  locale: `${options.hl}-${options.gl.toUpperCase()}`,
2496
- userAgent: isMobile ? MOBILE_USER_AGENT2 : DESKTOP_USER_AGENT2,
2497
2512
  deviceScaleFactor: isMobile ? 3 : 1,
2498
2513
  isMobile,
2499
2514
  hasTouch: isMobile,
@@ -3616,7 +3631,12 @@ async function harvest(rawOptions) {
3616
3631
  max_questions: attemptOptions.maxQuestions
3617
3632
  }));
3618
3633
  const baseCtx = currentCostContext();
3619
- const attempt = baseCtx ? await runWithCostContext({ ...baseCtx, forceHeadful: true }, () => extractOnce(attemptOptions, signal)) : await extractOnce(attemptOptions, signal);
3634
+ const allowHeadlessTest = baseCtx?.harvestBrowserMode === "headless-test" && process.env[HEADLESS_HARVEST_TEST_ENV] === "true";
3635
+ const attempt = baseCtx ? await runWithCostContext({
3636
+ ...baseCtx,
3637
+ forceHeadless: allowHeadlessTest,
3638
+ forceHeadful: !allowHeadlessTest
3639
+ }, () => extractOnce(attemptOptions, signal)) : await extractOnce(attemptOptions, signal);
3620
3640
  if (attempt.error) {
3621
3641
  const err = attempt.error;
3622
3642
  const outcome2 = classifyAttemptError(err);