mcp-scraper 0.38.0 → 0.38.2

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 (58) hide show
  1. package/README.md +1 -1
  2. package/dist/bin/api-server.cjs +813 -338
  3. package/dist/bin/api-server.cjs.map +1 -1
  4. package/dist/bin/api-server.js +3 -3
  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 +25 -7
  12. package/dist/bin/mcp-stdio-server.cjs.map +1 -1
  13. package/dist/bin/mcp-stdio-server.js +5 -5
  14. package/dist/bin/paa-harvest.cjs +65 -4
  15. package/dist/bin/paa-harvest.cjs.map +1 -1
  16. package/dist/bin/paa-harvest.js +3 -3
  17. package/dist/{chunk-PWPUKR5U.js → chunk-AZRPG43B.js} +12 -3
  18. package/dist/chunk-AZRPG43B.js.map +1 -0
  19. package/dist/{chunk-MA5JBAUZ.js → chunk-EGJKUB4Q.js} +3 -3
  20. package/dist/{chunk-MA5JBAUZ.js.map → chunk-EGJKUB4Q.js.map} +1 -1
  21. package/dist/{chunk-PUJFYJXB.js → chunk-FRYT3ID4.js} +2 -2
  22. package/dist/{chunk-CSCD2HNS.js → chunk-N7KUTTCC.js} +312 -101
  23. package/dist/chunk-N7KUTTCC.js.map +1 -0
  24. package/dist/{chunk-LOPKN3YL.js → chunk-NGM237OO.js} +66 -5
  25. package/dist/chunk-NGM237OO.js.map +1 -0
  26. package/dist/{chunk-P64PZUCA.js → chunk-NKCCGADE.js} +23 -8
  27. package/dist/chunk-NKCCGADE.js.map +1 -0
  28. package/dist/{chunk-FSAXLDB3.js → chunk-SFRMFGQ6.js} +2 -2
  29. package/dist/{chunk-Q35WZJJK.js → chunk-YCI2PNCS.js} +3 -3
  30. package/dist/chunk-YODBNTTN.js +7 -0
  31. package/dist/chunk-YODBNTTN.js.map +1 -0
  32. package/dist/{db-N3YECFWR.js → db-C5KVCOYT.js} +10 -4
  33. package/dist/{extract-bundle-346R6MXD.js → extract-bundle-KUBX6N6Z.js} +4 -4
  34. package/dist/index.cjs +65 -4
  35. package/dist/index.cjs.map +1 -1
  36. package/dist/index.js +3 -3
  37. package/dist/{location-data-repository-O2VII3ON.js → location-data-repository-TTWF3OTM.js} +3 -3
  38. package/dist/{server-3Q6XIJPF.js → server-5EX6XBIA.js} +320 -152
  39. package/dist/server-5EX6XBIA.js.map +1 -0
  40. package/dist/{site-extract-repository-I3VM6WXN.js → site-extract-repository-XSPJTCIL.js} +4 -4
  41. package/dist/{worker-TTFXPPDK.js → worker-XCPU4YSN.js} +6 -6
  42. package/docs/mcp-tool-manifest.generated.json +66 -9
  43. package/package.json +4 -2
  44. package/dist/chunk-CSCD2HNS.js.map +0 -1
  45. package/dist/chunk-H3M3O457.js +0 -7
  46. package/dist/chunk-H3M3O457.js.map +0 -1
  47. package/dist/chunk-LOPKN3YL.js.map +0 -1
  48. package/dist/chunk-P64PZUCA.js.map +0 -1
  49. package/dist/chunk-PWPUKR5U.js.map +0 -1
  50. package/dist/server-3Q6XIJPF.js.map +0 -1
  51. /package/dist/{chunk-PUJFYJXB.js.map → chunk-FRYT3ID4.js.map} +0 -0
  52. /package/dist/{chunk-FSAXLDB3.js.map → chunk-SFRMFGQ6.js.map} +0 -0
  53. /package/dist/{chunk-Q35WZJJK.js.map → chunk-YCI2PNCS.js.map} +0 -0
  54. /package/dist/{db-N3YECFWR.js.map → db-C5KVCOYT.js.map} +0 -0
  55. /package/dist/{extract-bundle-346R6MXD.js.map → extract-bundle-KUBX6N6Z.js.map} +0 -0
  56. /package/dist/{location-data-repository-O2VII3ON.js.map → location-data-repository-TTWF3OTM.js.map} +0 -0
  57. /package/dist/{site-extract-repository-I3VM6WXN.js.map → site-extract-repository-XSPJTCIL.js.map} +0 -0
  58. /package/dist/{worker-TTFXPPDK.js.map → worker-XCPU4YSN.js.map} +0 -0
@@ -7,19 +7,19 @@ import {
7
7
  registerMemoryMcpTools,
8
8
  registerPaaExtractorMcpTools,
9
9
  registerSerpIntelligenceCaptureTools
10
- } from "../chunk-P64PZUCA.js";
10
+ } from "../chunk-NKCCGADE.js";
11
11
  import "../chunk-345BQXZH.js";
12
- import "../chunk-MA5JBAUZ.js";
12
+ import "../chunk-EGJKUB4Q.js";
13
13
  import {
14
14
  renderInstallTerminal
15
15
  } from "../chunk-NNW3O6ZD.js";
16
16
  import "../chunk-CB5C3BPB.js";
17
17
  import {
18
18
  PACKAGE_VERSION
19
- } from "../chunk-H3M3O457.js";
20
- import "../chunk-PWPUKR5U.js";
19
+ } from "../chunk-YODBNTTN.js";
20
+ import "../chunk-AZRPG43B.js";
21
21
  import "../chunk-44HZLHDV.js";
22
- import "../chunk-CSCD2HNS.js";
22
+ import "../chunk-N7KUTTCC.js";
23
23
 
24
24
  // bin/mcp-stdio-server.ts
25
25
  import { readFileSync } from "fs";
@@ -327,7 +327,7 @@ function currentCostContext() {
327
327
  // src/api/cost-rates.ts
328
328
  var KERNEL_HEADLESS_USD_PER_SEC = 166667e-10;
329
329
  var KERNEL_HEADFUL_USD_PER_SEC = 1333336e-10;
330
- var HEADLESS_OPS = /* @__PURE__ */ new Set(["serp", "maps_search", "yt_channel", "yt_transcription", "fb_search", "fb_ad", "instagram"]);
330
+ var HEADLESS_OPS = /* @__PURE__ */ new Set(["serp", "fb_search", "fb_ad", "instagram"]);
331
331
  function envRate(name, fallback) {
332
332
  const raw = process.env[name]?.trim();
333
333
  if (!raw) return fallback;
@@ -965,8 +965,10 @@ var BrowserDriver = class {
965
965
  return this.kernelClient ? "Google returned a CAPTCHA on this session \u2014 retrying with a fresh session." : RECAPTCHA_INSTRUCTIONS;
966
966
  }
967
967
  async navigateTo(url) {
968
+ const arrivalBase = process.env.ADS_ARRIVAL_REDIRECT_BASE?.trim();
969
+ const navUrl = arrivalBase ? serpArrivalUrl(url, arrivalBase) : url;
968
970
  try {
969
- await this.page.goto(url, { waitUntil: "domcontentloaded", timeout: 45e3 });
971
+ await this.page.goto(navUrl, { waitUntil: "domcontentloaded", timeout: 45e3 });
970
972
  if (/google\.[^/]+\/search\?/i.test(url) && await this.isSerpChallengeVisible()) {
971
973
  throw new CaptchaError(this.captchaMessage());
972
974
  }
@@ -1681,6 +1683,8 @@ var PAAExtractor = class {
1681
1683
  aioShareCaptured: null
1682
1684
  };
1683
1685
  aioShareUrlEarly = null;
1686
+ collectedRows = [];
1687
+ partialContext = null;
1684
1688
  normalizeQuestion(q) {
1685
1689
  return q.toLowerCase().replace(/[^\w\s]/g, "").replace(/\s+/g, " ").trim();
1686
1690
  }
@@ -1785,11 +1789,50 @@ var PAAExtractor = class {
1785
1789
  extracted_at: (/* @__PURE__ */ new Date()).toISOString()
1786
1790
  };
1787
1791
  }
1792
+ getPartialResult() {
1793
+ const ctx = this.partialContext;
1794
+ if (!ctx || this.collectedRows.length === 0) return null;
1795
+ const flat = [...this.collectedRows];
1796
+ const stats = {
1797
+ seed: ctx.seed,
1798
+ totalQuestions: flat.length,
1799
+ maxDepthReached: flat.reduce((m, r) => Math.max(m, r.depth), 0),
1800
+ durationMs: Date.now() - ctx.startMs,
1801
+ errorCount: 0
1802
+ };
1803
+ return {
1804
+ seed: ctx.seed,
1805
+ location: ctx.location,
1806
+ extractedAt: (/* @__PURE__ */ new Date()).toISOString(),
1807
+ diagnostics: {
1808
+ completionStatus: "paa_found",
1809
+ problem: null,
1810
+ completeness: { ...this.completeness },
1811
+ warnings: [{
1812
+ code: "paa_partial",
1813
+ surface: "paa",
1814
+ message: `Harvest stopped before finishing; returning the ${flat.length} question(s) collected up to that point.`,
1815
+ retryable: true
1816
+ }]
1817
+ },
1818
+ totalQuestions: flat.length,
1819
+ whatPeopleSaying: [],
1820
+ tree: this.buildTree(flat, ctx.seed),
1821
+ flat,
1822
+ videos: [],
1823
+ forums: [],
1824
+ organicResults: [],
1825
+ localPack: [],
1826
+ entityIds: {},
1827
+ stats
1828
+ };
1829
+ }
1788
1830
  async runBFS(page, options, signal) {
1789
1831
  const seenKeys = /* @__PURE__ */ new Set();
1790
1832
  const seenQs = /* @__PURE__ */ new Set();
1791
1833
  const orderedQs = [];
1792
- const results = [];
1834
+ this.collectedRows = [];
1835
+ const results = this.collectedRows;
1793
1836
  const abandonedNeverReclick = /* @__PURE__ */ new Set();
1794
1837
  const clickedOnceEver = /* @__PURE__ */ new Set();
1795
1838
  const itemArgs = {
@@ -2401,6 +2444,8 @@ var PAAExtractor = class {
2401
2444
  const startMs = Date.now();
2402
2445
  this.completeness = { paaWithoutAnswer: 0, paaWithoutSource: 0, paaAnswersRecovered: 0, aioShareCaptured: null };
2403
2446
  this.aioShareUrlEarly = null;
2447
+ this.collectedRows = [];
2448
+ this.partialContext = { seed: options.query, location: options.location ?? null, startMs };
2404
2449
  const isMobile = options.device === "mobile";
2405
2450
  const config = {
2406
2451
  headless: options.headless,
@@ -3462,7 +3507,23 @@ async function extractOnce(options, signal) {
3462
3507
  } : null);
3463
3508
  cleanup = await driver.close();
3464
3509
  }
3465
- return error ? { result: null, error, cleanup, debug } : { result, error: null, cleanup, debug };
3510
+ if (error) {
3511
+ const outcome = classifyAttemptError(error);
3512
+ const budgetExhausted = outcome === "timeout" || outcome === "request_aborted";
3513
+ let salvaged = null;
3514
+ if (budgetExhausted) {
3515
+ try {
3516
+ salvaged = typeof extractor.getPartialResult === "function" ? extractor.getPartialResult() : null;
3517
+ } catch {
3518
+ salvaged = null;
3519
+ }
3520
+ }
3521
+ if (salvaged) {
3522
+ return { result: salvaged, error: null, cleanup, debug, salvagedFrom: error };
3523
+ }
3524
+ return { result: null, error, cleanup, debug };
3525
+ }
3526
+ return { result, error: null, cleanup, debug };
3466
3527
  }
3467
3528
  async function harvest(rawOptions) {
3468
3529
  const raw = typeof rawOptions === "object" && rawOptions !== null ? rawOptions : {};