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
@@ -6,7 +6,7 @@ import {
6
6
  import {
7
7
  finishHarvestAttempt,
8
8
  startHarvestAttempt
9
- } from "./chunk-CSCD2HNS.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-FSAXLDB3.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-CSCD2HNS.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-Q35WZJJK.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":[]}
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  CORE_SCHEMA_VERSION,
3
+ CREDIT_LOTS_EPOCH,
3
4
  CREDIT_LOT_TTL,
4
5
  SiteAuditJobRowSchema,
5
6
  SiteAuditPhaseLogRowSchema,
@@ -10,8 +11,10 @@ import {
10
11
  claimMonthlyFreeRefresh,
11
12
  claimPendingJob,
12
13
  claimPendingKpoJob,
14
+ claimStripeEvent,
13
15
  completeJob,
14
16
  completeKpoJob,
17
+ completeStripeEvent,
15
18
  completeWorkflowRunRecord,
16
19
  consumeCode,
17
20
  consumePasswordResetToken,
@@ -33,6 +36,7 @@ import {
33
36
  expireOldLots,
34
37
  failJob,
35
38
  failKpoJob,
39
+ failStripeEvent,
36
40
  failWorkflowRunRecord,
37
41
  finishHarvestAttempt,
38
42
  generateApiKey,
@@ -87,7 +91,6 @@ import {
87
91
  putCode,
88
92
  putRefresh,
89
93
  reconcileBalanceMc,
90
- recordStripeEvent,
91
94
  recordWorkflowWebhookDelivery,
92
95
  registerClient,
93
96
  replaceWorkflowArtifacts,
@@ -113,9 +116,10 @@ import {
113
116
  updateKpoJobState,
114
117
  upsertPageSnapshot,
115
118
  verifyPassword
116
- } from "./chunk-CSCD2HNS.js";
119
+ } from "./chunk-N7KUTTCC.js";
117
120
  export {
118
121
  CORE_SCHEMA_VERSION,
122
+ CREDIT_LOTS_EPOCH,
119
123
  CREDIT_LOT_TTL,
120
124
  SiteAuditJobRowSchema,
121
125
  SiteAuditPhaseLogRowSchema,
@@ -126,8 +130,10 @@ export {
126
130
  claimMonthlyFreeRefresh,
127
131
  claimPendingJob,
128
132
  claimPendingKpoJob,
133
+ claimStripeEvent,
129
134
  completeJob,
130
135
  completeKpoJob,
136
+ completeStripeEvent,
131
137
  completeWorkflowRunRecord,
132
138
  consumeCode,
133
139
  consumePasswordResetToken,
@@ -149,6 +155,7 @@ export {
149
155
  expireOldLots,
150
156
  failJob,
151
157
  failKpoJob,
158
+ failStripeEvent,
152
159
  failWorkflowRunRecord,
153
160
  finishHarvestAttempt,
154
161
  generateApiKey,
@@ -203,7 +210,6 @@ export {
203
210
  putCode,
204
211
  putRefresh,
205
212
  reconcileBalanceMc,
206
- recordStripeEvent,
207
213
  recordWorkflowWebhookDelivery,
208
214
  registerClient,
209
215
  replaceWorkflowArtifacts,
@@ -230,4 +236,4 @@ export {
230
236
  upsertPageSnapshot,
231
237
  verifyPassword
232
238
  };
233
- //# sourceMappingURL=db-N3YECFWR.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-Q35WZJJK.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-CSCD2HNS.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-346R6MXD.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 : {};