mcp-scraper 0.33.6 → 0.33.7

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 (59) hide show
  1. package/README.md +2 -2
  2. package/dist/bin/api-server.cjs +4088 -3097
  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 +12 -2
  6. package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
  7. package/dist/bin/mcp-scraper-cli.js +12 -2
  8. package/dist/bin/mcp-scraper-cli.js.map +1 -1
  9. package/dist/bin/mcp-scraper-install.cjs +2 -2
  10. package/dist/bin/mcp-scraper-install.cjs.map +1 -1
  11. package/dist/bin/mcp-scraper-install.js +2 -2
  12. package/dist/bin/mcp-stdio-server.cjs +109 -6
  13. package/dist/bin/mcp-stdio-server.cjs.map +1 -1
  14. package/dist/bin/mcp-stdio-server.js +6 -6
  15. package/dist/bin/paa-harvest.cjs +106 -13
  16. package/dist/bin/paa-harvest.cjs.map +1 -1
  17. package/dist/bin/paa-harvest.js +3 -3
  18. package/dist/{chunk-DUS4ENOY.js → chunk-2EDFOQD7.js} +2 -2
  19. package/dist/{chunk-DUS4ENOY.js.map → chunk-2EDFOQD7.js.map} +1 -1
  20. package/dist/{chunk-C2OD4ELT.js → chunk-3HBPKR5G.js} +2 -2
  21. package/dist/{chunk-AIK7WQD5.js → chunk-62DQAWPF.js} +141 -3
  22. package/dist/chunk-62DQAWPF.js.map +1 -0
  23. package/dist/{chunk-6ZUK4H66.js → chunk-H6QECE2U.js} +109 -6
  24. package/dist/chunk-H6QECE2U.js.map +1 -0
  25. package/dist/chunk-HAMN42SP.js +7 -0
  26. package/dist/chunk-HAMN42SP.js.map +1 -0
  27. package/dist/{chunk-LKIP7VDN.js → chunk-JBSGBSGT.js} +46 -3
  28. package/dist/chunk-JBSGBSGT.js.map +1 -0
  29. package/dist/{chunk-XL6YIWJ3.js → chunk-SUOHUXQS.js} +3 -3
  30. package/dist/{chunk-WJJTGRK4.js → chunk-V36LS5YV.js} +2 -2
  31. package/dist/{chunk-A54ELKJK.js → chunk-XVCETVYY.js} +129 -15
  32. package/dist/chunk-XVCETVYY.js.map +1 -0
  33. package/dist/{db-5SZQUI7A.js → db-YAI5AQOI.js} +16 -2
  34. package/dist/{extract-bundle-YNXTFCC3.js → extract-bundle-GPZRLBVY.js} +2 -2
  35. package/dist/index.cjs +106 -13
  36. package/dist/index.cjs.map +1 -1
  37. package/dist/index.d.cts +1 -1
  38. package/dist/index.d.ts +1 -1
  39. package/dist/index.js +3 -3
  40. package/dist/{server-SHOYO52X.js → server-B35CQJB3.js} +1358 -772
  41. package/dist/server-B35CQJB3.js.map +1 -0
  42. package/dist/{site-extract-repository-ZDTO7ODZ.js → site-extract-repository-JHMVHENZ.js} +4 -4
  43. package/dist/{worker-BJ64GCDE.js → worker-3LYNVGLF.js} +6 -6
  44. package/docs/mcp-tool-manifest.generated.json +185 -3
  45. package/package.json +1 -1
  46. package/dist/chunk-6ZUK4H66.js.map +0 -1
  47. package/dist/chunk-A54ELKJK.js.map +0 -1
  48. package/dist/chunk-AIK7WQD5.js.map +0 -1
  49. package/dist/chunk-F65IIUHI.js +0 -7
  50. package/dist/chunk-F65IIUHI.js.map +0 -1
  51. package/dist/chunk-LKIP7VDN.js.map +0 -1
  52. package/dist/server-SHOYO52X.js.map +0 -1
  53. /package/dist/{chunk-C2OD4ELT.js.map → chunk-3HBPKR5G.js.map} +0 -0
  54. /package/dist/{chunk-XL6YIWJ3.js.map → chunk-SUOHUXQS.js.map} +0 -0
  55. /package/dist/{chunk-WJJTGRK4.js.map → chunk-V36LS5YV.js.map} +0 -0
  56. /package/dist/{db-5SZQUI7A.js.map → db-YAI5AQOI.js.map} +0 -0
  57. /package/dist/{extract-bundle-YNXTFCC3.js.map → extract-bundle-GPZRLBVY.js.map} +0 -0
  58. /package/dist/{site-extract-repository-ZDTO7ODZ.js.map → site-extract-repository-JHMVHENZ.js.map} +0 -0
  59. /package/dist/{worker-BJ64GCDE.js.map → worker-3LYNVGLF.js.map} +0 -0
@@ -7,19 +7,19 @@ import {
7
7
  registerMemoryMcpTools,
8
8
  registerPaaExtractorMcpTools,
9
9
  registerSerpIntelligenceCaptureTools
10
- } from "../chunk-6ZUK4H66.js";
10
+ } from "../chunk-H6QECE2U.js";
11
11
  import "../chunk-R7EETU7Z.js";
12
- import "../chunk-WJJTGRK4.js";
12
+ import "../chunk-V36LS5YV.js";
13
13
  import {
14
14
  renderInstallTerminal
15
- } from "../chunk-DUS4ENOY.js";
15
+ } from "../chunk-2EDFOQD7.js";
16
16
  import "../chunk-V73MPRU6.js";
17
17
  import {
18
18
  PACKAGE_VERSION
19
- } from "../chunk-F65IIUHI.js";
20
- import "../chunk-LKIP7VDN.js";
19
+ } from "../chunk-HAMN42SP.js";
20
+ import "../chunk-JBSGBSGT.js";
21
21
  import "../chunk-M2S27J6Z.js";
22
- import "../chunk-AIK7WQD5.js";
22
+ import "../chunk-62DQAWPF.js";
23
23
 
24
24
  // bin/mcp-stdio-server.ts
25
25
  import { readFileSync } from "fs";
@@ -2731,7 +2731,76 @@ var ProgressReporter = class {
2731
2731
  };
2732
2732
 
2733
2733
  // src/kernel-proxy-resolver.ts
2734
+ var import_sdk3 = __toESM(require("@onkernel/sdk"), 1);
2735
+
2736
+ // src/backup-proxy.ts
2737
+ var import_node_crypto3 = require("crypto");
2734
2738
  var import_sdk2 = __toESM(require("@onkernel/sdk"), 1);
2739
+ var BACKUP_PROXY_HOST = "pr.oxylabs.io";
2740
+ var BACKUP_PROXY_PORT = 7777;
2741
+ var BACKUP_STICKY_SESSION_MINUTES = 10;
2742
+ var BACKUP_LAST_RESORT_ATTEMPTS = 2;
2743
+ function backupProxyUsername() {
2744
+ const value = process.env.OXYLABS_USERNAME?.trim();
2745
+ return value || void 0;
2746
+ }
2747
+ function backupProxyPassword() {
2748
+ const value = process.env.OXYLABS_PASSWORD?.trim();
2749
+ return value || void 0;
2750
+ }
2751
+ function backupProxyCountry() {
2752
+ const value = process.env.OXYLABS_COUNTRY?.trim();
2753
+ return (value || "US").toUpperCase();
2754
+ }
2755
+ function backupProxyAvailable() {
2756
+ return Boolean(backupProxyUsername() && backupProxyPassword());
2757
+ }
2758
+ function randomStickySessionId() {
2759
+ let digits = "";
2760
+ for (let i = 0; i < 10; i++) digits += String((0, import_node_crypto3.randomInt)(0, 10));
2761
+ return digits;
2762
+ }
2763
+ function buildBackupUsername(opts = {}) {
2764
+ const user = backupProxyUsername();
2765
+ if (!user) return void 0;
2766
+ const base = user.startsWith("customer-") ? user : `customer-${user}`;
2767
+ const country = (opts.country?.trim() || backupProxyCountry()).toUpperCase();
2768
+ const sticky = opts.sticky ? `-sessid-${randomStickySessionId()}-sesstime-${BACKUP_STICKY_SESSION_MINUTES}` : "";
2769
+ return `${base}-cc-${country}${sticky}`;
2770
+ }
2771
+ function scrubBackupProxyText(message) {
2772
+ return message.replace(/pr\.oxylabs\.io(:\d+)?/gi, "backup proxy").replace(/oxylabs/gi, "backup proxy");
2773
+ }
2774
+ function backupProxyName(attemptIndex) {
2775
+ const stamp = `${Date.now()}-${attemptIndex ?? 0}-${Math.random().toString(36).slice(2, 8)}`;
2776
+ return `mcp-backup-custom-${stamp}`;
2777
+ }
2778
+ async function createBackupProxyId(kernelApiKey, opts = {}) {
2779
+ const username = buildBackupUsername({ sticky: opts.sticky });
2780
+ const password = backupProxyPassword();
2781
+ if (!username || !password) throw new Error("backup proxy pool is not configured");
2782
+ const kernel = new import_sdk2.default({ apiKey: kernelApiKey });
2783
+ try {
2784
+ const created = await kernel.proxies.create({
2785
+ type: "custom",
2786
+ name: backupProxyName(opts.attemptIndex),
2787
+ protocol: "http",
2788
+ config: {
2789
+ host: BACKUP_PROXY_HOST,
2790
+ port: BACKUP_PROXY_PORT,
2791
+ username,
2792
+ password
2793
+ }
2794
+ });
2795
+ if (!created.id) throw new Error("backup proxy creation did not return a proxy id");
2796
+ return created.id;
2797
+ } catch (err) {
2798
+ const message = err instanceof Error ? err.message : String(err);
2799
+ throw new Error(scrubBackupProxyText(message));
2800
+ }
2801
+ }
2802
+
2803
+ // src/kernel-proxy-resolver.ts
2735
2804
  var US_STATE_CODES = {
2736
2805
  alabama: "AL",
2737
2806
  alaska: "AK",
@@ -2829,7 +2898,7 @@ function proxyIdSuffix2(proxyId) {
2829
2898
  return proxyId ? proxyId.slice(-6) : null;
2830
2899
  }
2831
2900
  function resolution(source, proxyMode, proxyId, target, error, disposable = false) {
2832
- const proxyType = source === "disabled" ? "none" : source === "configured_fallback" ? "configured" : source === "isp_created" ? "isp" : source === "location_created" || source === "location_reused" ? "residential" : "unknown";
2901
+ const proxyType = source === "disabled" ? "none" : source === "configured_fallback" ? "configured" : source === "isp_created" ? "isp" : source === "backup_custom" ? "custom" : source === "location_created" || source === "location_reused" ? "residential" : "unknown";
2833
2902
  return {
2834
2903
  kernelProxyId: proxyId,
2835
2904
  ...disposable && proxyId ? { disposableProxyId: proxyId } : {},
@@ -3013,6 +3082,26 @@ function freshTargetCandidates(target, explicitZip, attemptIndex) {
3013
3082
  out.push(withProxyName(fallbackTarget, freshProxyName(fallbackTarget.proxyName, attemptIndex)));
3014
3083
  return out;
3015
3084
  }
3085
+ async function settleCreateExhaustion(options, target, createErrors) {
3086
+ if (options.backupOnExhaustion && createErrors.length > 0 && options.kernelApiKey && backupProxyAvailable()) {
3087
+ try {
3088
+ const backupId = await createBackupProxyId(options.kernelApiKey, { attemptIndex: options.attemptIndex });
3089
+ return resolution("backup_custom", options.proxyMode, backupId, target, null, true);
3090
+ } catch (err) {
3091
+ createErrors.push(`backup: ${scrubBackupProxyText(errorText2(err))}`);
3092
+ }
3093
+ }
3094
+ return resolution("configured_fallback", options.proxyMode, options.configuredKernelProxyId, target, createErrors.join(" | "));
3095
+ }
3096
+ async function resolveBackupKernelProxyId(options) {
3097
+ if (!options.kernelApiKey || !backupProxyAvailable()) return null;
3098
+ try {
3099
+ const backupId = await createBackupProxyId(options.kernelApiKey, { attemptIndex: options.attemptIndex });
3100
+ return resolution("backup_custom", options.proxyMode, backupId, null, null, true);
3101
+ } catch {
3102
+ return null;
3103
+ }
3104
+ }
3016
3105
  async function createFreshLocationProxy(kernel, options, target) {
3017
3106
  const createErrors = [];
3018
3107
  for (const candidate of freshTargetCandidates(target, options.proxyZip, options.attemptIndex)) {
@@ -3046,11 +3135,11 @@ async function createFreshLocationProxy(kernel, options, target) {
3046
3135
  createErrors.push(`isp: ${errorText2(err)}`);
3047
3136
  }
3048
3137
  }
3049
- return resolution("configured_fallback", options.proxyMode, options.configuredKernelProxyId, target, createErrors.join(" | "));
3138
+ return settleCreateExhaustion(options, target, createErrors);
3050
3139
  }
3051
3140
  async function deleteKernelProxyId(kernelApiKey, proxyId) {
3052
3141
  if (!kernelApiKey || !proxyId) return;
3053
- const kernel = new import_sdk2.default({ apiKey: kernelApiKey });
3142
+ const kernel = new import_sdk3.default({ apiKey: kernelApiKey });
3054
3143
  await kernel.proxies.delete(proxyId);
3055
3144
  }
3056
3145
  async function resolveKernelProxyId(options) {
@@ -3064,7 +3153,7 @@ async function resolveKernelProxyId(options) {
3064
3153
  if (!target || !options.kernelApiKey) {
3065
3154
  return resolution("configured_fallback", options.proxyMode, options.configuredKernelProxyId, target, target ? null : "location could not be normalized to a US city/state proxy target");
3066
3155
  }
3067
- const kernel = new import_sdk2.default({ apiKey: options.kernelApiKey });
3156
+ const kernel = new import_sdk3.default({ apiKey: options.kernelApiKey });
3068
3157
  try {
3069
3158
  const attemptIndex = options.attemptIndex ?? 0;
3070
3159
  if (options.fresh) {
@@ -3086,7 +3175,7 @@ async function resolveKernelProxyId(options) {
3086
3175
  } catch (err) {
3087
3176
  createErrors2.push(`${escalatedTarget.state}: ${errorText2(err)}`);
3088
3177
  }
3089
- return resolution("configured_fallback", options.proxyMode, options.configuredKernelProxyId, escalatedTarget, createErrors2.join(" | "));
3178
+ return settleCreateExhaustion(options, escalatedTarget, createErrors2);
3090
3179
  }
3091
3180
  const proxies = await kernel.proxies.list();
3092
3181
  const zip = knownZipFor(target, options.proxyZip);
@@ -3165,7 +3254,7 @@ async function resolveKernelProxyId(options) {
3165
3254
  } catch (err) {
3166
3255
  createErrors.push(`${fallbackTarget.state}: ${errorText2(err)}`);
3167
3256
  }
3168
- return resolution("configured_fallback", options.proxyMode, options.configuredKernelProxyId, target, createErrors.join(" | "));
3257
+ return settleCreateExhaustion(options, target, createErrors);
3169
3258
  } catch (err) {
3170
3259
  return resolution("configured_fallback", options.proxyMode, options.configuredKernelProxyId, target, errorText2(err));
3171
3260
  }
@@ -3330,7 +3419,9 @@ async function harvest(rawOptions) {
3330
3419
  const requestedDebug = typeof raw.debug === "boolean" ? raw.debug : false;
3331
3420
  const needsLocationEvidence = proxyMode === "location" && Boolean(proxyOpts.location);
3332
3421
  const requestedMaxAttempts = raw.maxAttempts;
3333
- const maxAttempts = typeof requestedMaxAttempts === "number" && Number.isInteger(requestedMaxAttempts) && requestedMaxAttempts >= 1 ? requestedMaxAttempts : maxAttemptsForProxyMode(proxyMode) + 1;
3422
+ const baseMaxAttempts = typeof requestedMaxAttempts === "number" && Number.isInteger(requestedMaxAttempts) && requestedMaxAttempts >= 1 ? requestedMaxAttempts : maxAttemptsForProxyMode(proxyMode) + 1;
3423
+ const maxAttempts = baseMaxAttempts + (backupProxyAvailable() ? BACKUP_LAST_RESORT_ATTEMPTS : 0);
3424
+ const softDeadlineMs = typeof raw.softDeadlineMs === "number" ? raw.softDeadlineMs : null;
3334
3425
  const serializer = new OutputSerializer();
3335
3426
  let lastError = null;
3336
3427
  let effectiveProxyMode = proxyMode;
@@ -3340,12 +3431,16 @@ async function harvest(rawOptions) {
3340
3431
  const startedAtMs = Date.now();
3341
3432
  try {
3342
3433
  if (signal?.aborted) throw abortReason(signal);
3343
- const resolution2 = await resolveKernelProxyId({
3434
+ const isBackupAttempt = i >= baseMaxAttempts;
3435
+ if (isBackupAttempt && softDeadlineMs !== null && Date.now() >= softDeadlineMs) break;
3436
+ const resolution2 = isBackupAttempt ? await resolveBackupKernelProxyId({ kernelApiKey, proxyMode: effectiveProxyMode, attemptIndex: i }) : await resolveKernelProxyId({
3344
3437
  ...proxyOpts,
3345
3438
  proxyMode: effectiveProxyMode,
3346
3439
  attemptIndex: i,
3347
- fresh: effectiveProxyMode === "location"
3440
+ fresh: effectiveProxyMode === "location",
3441
+ backupOnExhaustion: true
3348
3442
  });
3443
+ if (!resolution2) break;
3349
3444
  const mergedAttempt = {
3350
3445
  ...raw,
3351
3446
  kernelApiKey,
@@ -3354,7 +3449,7 @@ async function harvest(rawOptions) {
3354
3449
  proxyMode: effectiveProxyMode,
3355
3450
  debug: requestedDebug || needsLocationEvidence
3356
3451
  };
3357
- if (effectiveProxyMode === "none") mergedAttempt.kernelProxyId = void 0;
3452
+ if (effectiveProxyMode === "none" && !isBackupAttempt) mergedAttempt.kernelProxyId = void 0;
3358
3453
  const attemptOptions = HarvestOptionsSchema.parse(mergedAttempt);
3359
3454
  await emitAttemptEvent(onAttemptEvent, {
3360
3455
  type: "started",
@@ -3373,10 +3468,8 @@ async function harvest(rawOptions) {
3373
3468
  location: attemptOptions.location ?? null,
3374
3469
  max_questions: attemptOptions.maxQuestions
3375
3470
  }));
3376
- const isHeadfulEscalation = i === maxAttempts - 1;
3377
- const needHeadful = isHeadfulEscalation || !attemptOptions.serpOnly;
3378
3471
  const baseCtx = currentCostContext();
3379
- const attempt = needHeadful && baseCtx ? await runWithCostContext({ ...baseCtx, forceHeadful: true }, () => extractOnce(attemptOptions, signal)) : await extractOnce(attemptOptions, signal);
3472
+ const attempt = baseCtx ? await runWithCostContext({ ...baseCtx, forceHeadful: true }, () => extractOnce(attemptOptions, signal)) : await extractOnce(attemptOptions, signal);
3380
3473
  if (attempt.error) {
3381
3474
  const err = attempt.error;
3382
3475
  const outcome = classifyAttemptError(err);