mcp-scraper 0.38.1 → 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 +718 -276
  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-C5UGV7RM.js → chunk-EGJKUB4Q.js} +3 -3
  20. package/dist/{chunk-C5UGV7RM.js.map → chunk-EGJKUB4Q.js.map} +1 -1
  21. package/dist/{chunk-WS2E7HA5.js → chunk-FRYT3ID4.js} +2 -2
  22. package/dist/{chunk-XKCZOPZN.js → chunk-N7KUTTCC.js} +235 -40
  23. package/dist/chunk-N7KUTTCC.js.map +1 -0
  24. package/dist/{chunk-BSD2Z5A6.js → chunk-NGM237OO.js} +66 -5
  25. package/dist/chunk-NGM237OO.js.map +1 -0
  26. package/dist/{chunk-YAW3AUTP.js → chunk-NKCCGADE.js} +23 -8
  27. package/dist/chunk-NKCCGADE.js.map +1 -0
  28. package/dist/{chunk-OLRRIA4H.js → chunk-SFRMFGQ6.js} +2 -2
  29. package/dist/{chunk-4YAFJWFG.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-JRFMBTRD.js → db-C5KVCOYT.js} +8 -4
  33. package/dist/{extract-bundle-DSFOHMAT.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-OBJYZEGE.js → location-data-repository-TTWF3OTM.js} +3 -3
  38. package/dist/{server-2UDB6PTC.js → server-5EX6XBIA.js} +312 -151
  39. package/dist/server-5EX6XBIA.js.map +1 -0
  40. package/dist/{site-extract-repository-2YJ33J5C.js → site-extract-repository-XSPJTCIL.js} +4 -4
  41. package/dist/{worker-ESF3HCNJ.js → worker-XCPU4YSN.js} +6 -6
  42. package/docs/mcp-tool-manifest.generated.json +66 -9
  43. package/package.json +1 -1
  44. package/dist/chunk-BSD2Z5A6.js.map +0 -1
  45. package/dist/chunk-FFBPWVWC.js +0 -7
  46. package/dist/chunk-FFBPWVWC.js.map +0 -1
  47. package/dist/chunk-PWPUKR5U.js.map +0 -1
  48. package/dist/chunk-XKCZOPZN.js.map +0 -1
  49. package/dist/chunk-YAW3AUTP.js.map +0 -1
  50. package/dist/server-2UDB6PTC.js.map +0 -1
  51. /package/dist/{chunk-WS2E7HA5.js.map → chunk-FRYT3ID4.js.map} +0 -0
  52. /package/dist/{chunk-OLRRIA4H.js.map → chunk-SFRMFGQ6.js.map} +0 -0
  53. /package/dist/{chunk-4YAFJWFG.js.map → chunk-YCI2PNCS.js.map} +0 -0
  54. /package/dist/{db-JRFMBTRD.js.map → db-C5KVCOYT.js.map} +0 -0
  55. /package/dist/{extract-bundle-DSFOHMAT.js.map → extract-bundle-KUBX6N6Z.js.map} +0 -0
  56. /package/dist/{location-data-repository-OBJYZEGE.js.map → location-data-repository-TTWF3OTM.js.map} +0 -0
  57. /package/dist/{site-extract-repository-2YJ33J5C.js.map → site-extract-repository-XSPJTCIL.js.map} +0 -0
  58. /package/dist/{worker-ESF3HCNJ.js.map → worker-XCPU4YSN.js.map} +0 -0
@@ -6,7 +6,7 @@ import {
6
6
  import {
7
7
  finishHarvestAttempt,
8
8
  startHarvestAttempt
9
- } from "./chunk-XKCZOPZN.js";
9
+ } from "./chunk-N7KUTTCC.js";
10
10
 
11
11
  // src/api/harvest-problems.ts
12
12
  function errorMessage(err) {
@@ -155,4 +155,4 @@ export {
155
155
  harvestProblemResponse,
156
156
  createHarvestAttemptRecorder
157
157
  };
158
- //# sourceMappingURL=chunk-OLRRIA4H.js.map
158
+ //# sourceMappingURL=chunk-SFRMFGQ6.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  LedgerOperation
3
- } from "./chunk-PWPUKR5U.js";
3
+ } from "./chunk-AZRPG43B.js";
4
4
  import {
5
5
  sanitizeVendorName
6
6
  } from "./chunk-44HZLHDV.js";
@@ -8,7 +8,7 @@ import {
8
8
  CREDIT_LOT_TTL,
9
9
  getDb,
10
10
  settleDebitMcIdempotent
11
- } from "./chunk-XKCZOPZN.js";
11
+ } from "./chunk-N7KUTTCC.js";
12
12
 
13
13
  // src/api/site-extract-repository.ts
14
14
  function extractJobLimitInfo(job) {
@@ -496,4 +496,4 @@ export {
496
496
  failUnfundedExtractJob,
497
497
  settleExtractJob
498
498
  };
499
- //# sourceMappingURL=chunk-4YAFJWFG.js.map
499
+ //# sourceMappingURL=chunk-YCI2PNCS.js.map
@@ -0,0 +1,7 @@
1
+ // src/version.ts
2
+ var PACKAGE_VERSION = "0.38.2";
3
+
4
+ export {
5
+ PACKAGE_VERSION
6
+ };
7
+ //# sourceMappingURL=chunk-YODBNTTN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/version.ts"],"sourcesContent":["export const PACKAGE_VERSION = '0.38.2'\n"],"mappings":";AAAO,IAAM,kBAAkB;","names":[]}
@@ -11,8 +11,10 @@ import {
11
11
  claimMonthlyFreeRefresh,
12
12
  claimPendingJob,
13
13
  claimPendingKpoJob,
14
+ claimStripeEvent,
14
15
  completeJob,
15
16
  completeKpoJob,
17
+ completeStripeEvent,
16
18
  completeWorkflowRunRecord,
17
19
  consumeCode,
18
20
  consumePasswordResetToken,
@@ -34,6 +36,7 @@ import {
34
36
  expireOldLots,
35
37
  failJob,
36
38
  failKpoJob,
39
+ failStripeEvent,
37
40
  failWorkflowRunRecord,
38
41
  finishHarvestAttempt,
39
42
  generateApiKey,
@@ -88,7 +91,6 @@ import {
88
91
  putCode,
89
92
  putRefresh,
90
93
  reconcileBalanceMc,
91
- recordStripeEvent,
92
94
  recordWorkflowWebhookDelivery,
93
95
  registerClient,
94
96
  replaceWorkflowArtifacts,
@@ -114,7 +116,7 @@ import {
114
116
  updateKpoJobState,
115
117
  upsertPageSnapshot,
116
118
  verifyPassword
117
- } from "./chunk-XKCZOPZN.js";
119
+ } from "./chunk-N7KUTTCC.js";
118
120
  export {
119
121
  CORE_SCHEMA_VERSION,
120
122
  CREDIT_LOTS_EPOCH,
@@ -128,8 +130,10 @@ export {
128
130
  claimMonthlyFreeRefresh,
129
131
  claimPendingJob,
130
132
  claimPendingKpoJob,
133
+ claimStripeEvent,
131
134
  completeJob,
132
135
  completeKpoJob,
136
+ completeStripeEvent,
133
137
  completeWorkflowRunRecord,
134
138
  consumeCode,
135
139
  consumePasswordResetToken,
@@ -151,6 +155,7 @@ export {
151
155
  expireOldLots,
152
156
  failJob,
153
157
  failKpoJob,
158
+ failStripeEvent,
154
159
  failWorkflowRunRecord,
155
160
  finishHarvestAttempt,
156
161
  generateApiKey,
@@ -205,7 +210,6 @@ export {
205
210
  putCode,
206
211
  putRefresh,
207
212
  reconcileBalanceMc,
208
- recordStripeEvent,
209
213
  recordWorkflowWebhookDelivery,
210
214
  registerClient,
211
215
  replaceWorkflowArtifacts,
@@ -232,4 +236,4 @@ export {
232
236
  upsertPageSnapshot,
233
237
  verifyPassword
234
238
  };
235
- //# sourceMappingURL=db-JRFMBTRD.js.map
239
+ //# sourceMappingURL=db-C5KVCOYT.js.map
@@ -10,12 +10,12 @@ import {
10
10
  } from "./chunk-345BQXZH.js";
11
11
  import {
12
12
  extractJobLimitInfo
13
- } from "./chunk-4YAFJWFG.js";
14
- import "./chunk-PWPUKR5U.js";
13
+ } from "./chunk-YCI2PNCS.js";
14
+ import "./chunk-AZRPG43B.js";
15
15
  import "./chunk-44HZLHDV.js";
16
16
  import {
17
17
  getDb
18
- } from "./chunk-XKCZOPZN.js";
18
+ } from "./chunk-N7KUTTCC.js";
19
19
 
20
20
  // src/api/extract-bundle.ts
21
21
  import { createWriteStream, mkdirSync, readdirSync, rmSync, statSync, writeFileSync } from "fs";
@@ -565,4 +565,4 @@ export {
565
565
  SITE_EXTRACT_PAGE_CHUNK,
566
566
  assembleExtractArtifacts
567
567
  };
568
- //# sourceMappingURL=extract-bundle-DSFOHMAT.js.map
568
+ //# sourceMappingURL=extract-bundle-KUBX6N6Z.js.map
package/dist/index.cjs CHANGED
@@ -337,7 +337,7 @@ function currentCostContext() {
337
337
  // src/api/cost-rates.ts
338
338
  var KERNEL_HEADLESS_USD_PER_SEC = 166667e-10;
339
339
  var KERNEL_HEADFUL_USD_PER_SEC = 1333336e-10;
340
- var HEADLESS_OPS = /* @__PURE__ */ new Set(["serp", "maps_search", "yt_channel", "yt_transcription", "fb_search", "fb_ad", "instagram"]);
340
+ var HEADLESS_OPS = /* @__PURE__ */ new Set(["serp", "fb_search", "fb_ad", "instagram"]);
341
341
  var FAL_WIZPER_USD_PER_COMPUTE_SEC = 111e-5;
342
342
  var FAL_WIZPER_WALLCLOCK_TO_COMPUTE_SEC_FACTOR = 4;
343
343
  var DEEPINFRA_QWEN_USD_PER_1K_OUT_TOKENS = 4e-4;
@@ -1020,8 +1020,10 @@ var BrowserDriver = class {
1020
1020
  return this.kernelClient ? "Google returned a CAPTCHA on this session \u2014 retrying with a fresh session." : RECAPTCHA_INSTRUCTIONS;
1021
1021
  }
1022
1022
  async navigateTo(url) {
1023
+ const arrivalBase = process.env.ADS_ARRIVAL_REDIRECT_BASE?.trim();
1024
+ const navUrl = arrivalBase ? serpArrivalUrl(url, arrivalBase) : url;
1023
1025
  try {
1024
- await this.page.goto(url, { waitUntil: "domcontentloaded", timeout: 45e3 });
1026
+ await this.page.goto(navUrl, { waitUntil: "domcontentloaded", timeout: 45e3 });
1025
1027
  if (/google\.[^/]+\/search\?/i.test(url) && await this.isSerpChallengeVisible()) {
1026
1028
  throw new CaptchaError(this.captchaMessage());
1027
1029
  }
@@ -1736,6 +1738,8 @@ var PAAExtractor = class {
1736
1738
  aioShareCaptured: null
1737
1739
  };
1738
1740
  aioShareUrlEarly = null;
1741
+ collectedRows = [];
1742
+ partialContext = null;
1739
1743
  normalizeQuestion(q) {
1740
1744
  return q.toLowerCase().replace(/[^\w\s]/g, "").replace(/\s+/g, " ").trim();
1741
1745
  }
@@ -1840,11 +1844,50 @@ var PAAExtractor = class {
1840
1844
  extracted_at: (/* @__PURE__ */ new Date()).toISOString()
1841
1845
  };
1842
1846
  }
1847
+ getPartialResult() {
1848
+ const ctx = this.partialContext;
1849
+ if (!ctx || this.collectedRows.length === 0) return null;
1850
+ const flat = [...this.collectedRows];
1851
+ const stats = {
1852
+ seed: ctx.seed,
1853
+ totalQuestions: flat.length,
1854
+ maxDepthReached: flat.reduce((m, r) => Math.max(m, r.depth), 0),
1855
+ durationMs: Date.now() - ctx.startMs,
1856
+ errorCount: 0
1857
+ };
1858
+ return {
1859
+ seed: ctx.seed,
1860
+ location: ctx.location,
1861
+ extractedAt: (/* @__PURE__ */ new Date()).toISOString(),
1862
+ diagnostics: {
1863
+ completionStatus: "paa_found",
1864
+ problem: null,
1865
+ completeness: { ...this.completeness },
1866
+ warnings: [{
1867
+ code: "paa_partial",
1868
+ surface: "paa",
1869
+ message: `Harvest stopped before finishing; returning the ${flat.length} question(s) collected up to that point.`,
1870
+ retryable: true
1871
+ }]
1872
+ },
1873
+ totalQuestions: flat.length,
1874
+ whatPeopleSaying: [],
1875
+ tree: this.buildTree(flat, ctx.seed),
1876
+ flat,
1877
+ videos: [],
1878
+ forums: [],
1879
+ organicResults: [],
1880
+ localPack: [],
1881
+ entityIds: {},
1882
+ stats
1883
+ };
1884
+ }
1843
1885
  async runBFS(page, options, signal) {
1844
1886
  const seenKeys = /* @__PURE__ */ new Set();
1845
1887
  const seenQs = /* @__PURE__ */ new Set();
1846
1888
  const orderedQs = [];
1847
- const results = [];
1889
+ this.collectedRows = [];
1890
+ const results = this.collectedRows;
1848
1891
  const abandonedNeverReclick = /* @__PURE__ */ new Set();
1849
1892
  const clickedOnceEver = /* @__PURE__ */ new Set();
1850
1893
  const itemArgs = {
@@ -2456,6 +2499,8 @@ var PAAExtractor = class {
2456
2499
  const startMs = Date.now();
2457
2500
  this.completeness = { paaWithoutAnswer: 0, paaWithoutSource: 0, paaAnswersRecovered: 0, aioShareCaptured: null };
2458
2501
  this.aioShareUrlEarly = null;
2502
+ this.collectedRows = [];
2503
+ this.partialContext = { seed: options.query, location: options.location ?? null, startMs };
2459
2504
  const isMobile = options.device === "mobile";
2460
2505
  const config = {
2461
2506
  headless: options.headless,
@@ -3517,7 +3562,23 @@ async function extractOnce(options, signal) {
3517
3562
  } : null);
3518
3563
  cleanup = await driver.close();
3519
3564
  }
3520
- return error ? { result: null, error, cleanup, debug } : { result, error: null, cleanup, debug };
3565
+ if (error) {
3566
+ const outcome = classifyAttemptError(error);
3567
+ const budgetExhausted = outcome === "timeout" || outcome === "request_aborted";
3568
+ let salvaged = null;
3569
+ if (budgetExhausted) {
3570
+ try {
3571
+ salvaged = typeof extractor.getPartialResult === "function" ? extractor.getPartialResult() : null;
3572
+ } catch {
3573
+ salvaged = null;
3574
+ }
3575
+ }
3576
+ if (salvaged) {
3577
+ return { result: salvaged, error: null, cleanup, debug, salvagedFrom: error };
3578
+ }
3579
+ return { result: null, error, cleanup, debug };
3580
+ }
3581
+ return { result, error: null, cleanup, debug };
3521
3582
  }
3522
3583
  async function harvest(rawOptions) {
3523
3584
  const raw = typeof rawOptions === "object" && rawOptions !== null ? rawOptions : {};