mcp-scraper 0.21.3 → 0.21.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 (56) hide show
  1. package/README.md +1 -1
  2. package/dist/bin/api-server.cjs +728 -181
  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 +97 -32
  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 +21 -0
  15. package/dist/bin/paa-harvest.cjs.map +1 -1
  16. package/dist/bin/paa-harvest.js +3 -3
  17. package/dist/{chunk-JJ5RMEGX.js → chunk-E5J4HJBO.js} +2 -2
  18. package/dist/{chunk-H7APH5UG.js → chunk-ICT7DDHL.js} +366 -50
  19. package/dist/chunk-ICT7DDHL.js.map +1 -0
  20. package/dist/{chunk-OBNKOYOE.js → chunk-JHI373VB.js} +7 -5
  21. package/dist/chunk-JHI373VB.js.map +1 -0
  22. package/dist/{chunk-5IU5ZFVO.js → chunk-MTSBI7ZH.js} +23 -6
  23. package/dist/chunk-MTSBI7ZH.js.map +1 -0
  24. package/dist/{chunk-7LO6KLKD.js → chunk-N4JHXPW6.js} +89 -27
  25. package/dist/chunk-N4JHXPW6.js.map +1 -0
  26. package/dist/{chunk-XDRHBGJR.js → chunk-PNBYYAEK.js} +3 -3
  27. package/dist/{chunk-2P5VFIJM.js → chunk-SDHPQTFM.js} +2 -2
  28. package/dist/chunk-WQI7JIIN.js +7 -0
  29. package/dist/chunk-WQI7JIIN.js.map +1 -0
  30. package/dist/{db-Z35S224E.js → db-WRILVOFY.js} +4 -2
  31. package/dist/{extract-bundle-4RO3YU4Q.js → extract-bundle-NFFVMUMT.js} +2 -2
  32. package/dist/index.cjs +21 -0
  33. package/dist/index.cjs.map +1 -1
  34. package/dist/index.js +3 -3
  35. package/dist/{server-PBBRSLBP.js → server-OLOOFN5W.js} +246 -100
  36. package/dist/server-OLOOFN5W.js.map +1 -0
  37. package/dist/{site-extract-repository-FDH6ZXKT.js → site-extract-repository-2QQSL2QC.js} +4 -4
  38. package/dist/{worker-BXJQ7J4N.js → worker-RV2TYXE3.js} +9 -8
  39. package/dist/worker-RV2TYXE3.js.map +1 -0
  40. package/docs/mcp-tool-manifest.generated.json +90 -11
  41. package/docs/specs/oauth-mcp-spec.md +2 -2
  42. package/package.json +1 -1
  43. package/dist/chunk-5IU5ZFVO.js.map +0 -1
  44. package/dist/chunk-7LO6KLKD.js.map +0 -1
  45. package/dist/chunk-H7APH5UG.js.map +0 -1
  46. package/dist/chunk-OBNKOYOE.js.map +0 -1
  47. package/dist/chunk-VYUWWIVR.js +0 -7
  48. package/dist/chunk-VYUWWIVR.js.map +0 -1
  49. package/dist/server-PBBRSLBP.js.map +0 -1
  50. package/dist/worker-BXJQ7J4N.js.map +0 -1
  51. /package/dist/{chunk-JJ5RMEGX.js.map → chunk-E5J4HJBO.js.map} +0 -0
  52. /package/dist/{chunk-XDRHBGJR.js.map → chunk-PNBYYAEK.js.map} +0 -0
  53. /package/dist/{chunk-2P5VFIJM.js.map → chunk-SDHPQTFM.js.map} +0 -0
  54. /package/dist/{db-Z35S224E.js.map → db-WRILVOFY.js.map} +0 -0
  55. /package/dist/{extract-bundle-4RO3YU4Q.js.map → extract-bundle-NFFVMUMT.js.map} +0 -0
  56. /package/dist/{site-extract-repository-FDH6ZXKT.js.map → site-extract-repository-2QQSL2QC.js.map} +0 -0
@@ -12,17 +12,17 @@ import {
12
12
  browserServiceProfileSaveChanges,
13
13
  recordVendorUsage,
14
14
  vendorCostUsd
15
- } from "./chunk-5IU5ZFVO.js";
15
+ } from "./chunk-MTSBI7ZH.js";
16
16
  import {
17
17
  DEFAULT_MAPS_PROXY_MODE,
18
18
  DEFAULT_PROXY_MODE
19
19
  } from "./chunk-XGIPATLV.js";
20
20
  import {
21
21
  PACKAGE_VERSION
22
- } from "./chunk-VYUWWIVR.js";
22
+ } from "./chunk-WQI7JIIN.js";
23
23
  import {
24
24
  MC_PER_CREDIT
25
- } from "./chunk-OBNKOYOE.js";
25
+ } from "./chunk-JHI373VB.js";
26
26
  import {
27
27
  sanitizeVendorName
28
28
  } from "./chunk-M2S27J6Z.js";
@@ -3076,21 +3076,33 @@ function formatCaptureSerpSnapshot(raw, input) {
3076
3076
  const parsed = parseData(raw);
3077
3077
  if ("error" in parsed) return { content: [{ type: "text", text: parsed.error }], isError: true };
3078
3078
  const d = parsed.data;
3079
+ const harvestResult = d.harvestResult && typeof d.harvestResult === "object" ? d.harvestResult : d;
3079
3080
  const providerPayload = d;
3080
- const organic = Array.isArray(d.organicResults) ? d.organicResults : Array.isArray(d.organic) ? d.organic : [];
3081
- const localPack = Array.isArray(d.localPack) ? d.localPack : [];
3082
- const artifacts = Array.isArray(d.artifacts) ? d.artifacts : [];
3083
- const status = String(d.status ?? d.captureStatus ?? "captured");
3084
- const query = typeof d.query === "string" ? d.query : typeof input.query === "string" ? input.query : null;
3085
- const location = typeof d.location === "string" ? d.location : typeof input.location === "string" ? input.location : null;
3086
- const capturedAt = typeof d.capturedAt === "string" ? d.capturedAt : typeof d.extractedAt === "string" ? d.extractedAt : null;
3081
+ const organic = Array.isArray(harvestResult.organicResults) ? harvestResult.organicResults : Array.isArray(harvestResult.organic) ? harvestResult.organic : [];
3082
+ const localPack = Array.isArray(harvestResult.localPack) ? harvestResult.localPack : [];
3083
+ const artifacts = Array.isArray(d.pageSnapshotArtifacts) ? d.pageSnapshotArtifacts : Array.isArray(d.artifacts) ? d.artifacts : [];
3084
+ const attempts = Array.isArray(d.attempts) ? d.attempts : [];
3085
+ const diagnostics = harvestResult.diagnostics && typeof harvestResult.diagnostics === "object" ? harvestResult.diagnostics : d.diagnostics && typeof d.diagnostics === "object" ? d.diagnostics : null;
3086
+ const completionStatus = diagnostics && typeof diagnostics.completionStatus === "string" ? diagnostics.completionStatus : null;
3087
+ const status = String(d.status ?? d.captureStatus ?? completionStatus ?? "captured");
3088
+ const query = typeof harvestResult.seed === "string" ? harvestResult.seed : typeof harvestResult.query === "string" ? harvestResult.query : typeof input.query === "string" ? input.query : null;
3089
+ const location = typeof harvestResult.location === "string" ? harvestResult.location : typeof input.location === "string" ? input.location : null;
3090
+ const capturedAt = typeof harvestResult.extractedAt === "string" ? harvestResult.extractedAt : typeof harvestResult.capturedAt === "string" ? harvestResult.capturedAt : null;
3087
3091
  const resultCount = organic.length + localPack.length;
3092
+ const pageSnapshotFailedCount = artifacts.filter((artifact) => artifact.status === "failed" || Boolean(artifact.error)).length;
3093
+ const rawBilling = d.billing && typeof d.billing === "object" ? d.billing : null;
3094
+ const billing = rawBilling ? {
3095
+ creditsUsed: typeof rawBilling.creditsUsed === "number" ? rawBilling.creditsUsed : null,
3096
+ requestId: typeof rawBilling.requestId === "string" ? rawBilling.requestId : null,
3097
+ jobId: typeof rawBilling.jobId === "string" ? rawBilling.jobId : null
3098
+ } : null;
3088
3099
  const full = [
3089
3100
  `# SERP Intelligence Snapshot: ${query ?? "query"}`,
3090
3101
  `**Status:** ${status}`,
3091
3102
  location ? `**Location:** ${location}` : "",
3092
- `**Result count:** ${resultCount}`,
3093
- artifacts.length ? `**Artifacts:** ${artifacts.length}` : "",
3103
+ `**SERP results:** ${resultCount} (${organic.length} organic, ${localPack.length} local pack)`,
3104
+ `**Page snapshots:** ${artifacts.length} (${pageSnapshotFailedCount} failed)`,
3105
+ billing?.creditsUsed !== null && billing?.creditsUsed !== void 0 ? `**Credits used:** ${billing.creditsUsed}` : "",
3094
3106
  "",
3095
3107
  "Use `capture_serp_page_snapshots` when you need page-level evidence for ranking URLs."
3096
3108
  ].filter(Boolean).join("\n");
@@ -3103,6 +3115,10 @@ function formatCaptureSerpSnapshot(raw, input) {
3103
3115
  location,
3104
3116
  capturedAt,
3105
3117
  resultCount,
3118
+ organicResultCount: organic.length,
3119
+ localPackResultCount: localPack.length,
3120
+ pageSnapshotCount: artifacts.length,
3121
+ pageSnapshotFailedCount,
3106
3122
  snapshotId: typeof d.snapshotId === "string" ? d.snapshotId : typeof d.snapshot_id === "string" ? d.snapshot_id : typeof d.id === "string" ? d.id : null,
3107
3123
  resolvedInputs: {
3108
3124
  query: input.query ?? null,
@@ -3115,7 +3131,9 @@ function formatCaptureSerpSnapshot(raw, input) {
3115
3131
  pages: input.pages ?? null
3116
3132
  },
3117
3133
  artifacts,
3118
- diagnostics: d.diagnostics && typeof d.diagnostics === "object" ? d.diagnostics : null,
3134
+ attempts,
3135
+ billing,
3136
+ diagnostics,
3119
3137
  providerPayload
3120
3138
  }
3121
3139
  };
@@ -3124,9 +3142,13 @@ function formatCaptureSerpPageSnapshots(raw, input) {
3124
3142
  const parsed = parseData(raw);
3125
3143
  if ("error" in parsed) return { content: [{ type: "text", text: parsed.error }], isError: true };
3126
3144
  const d = parsed.data;
3127
- const captures = Array.isArray(d.captures) ? d.captures : Array.isArray(d.results) ? d.results : [];
3145
+ const captures = Array.isArray(d.pageSnapshotArtifacts) ? d.pageSnapshotArtifacts : Array.isArray(d.captures) ? d.captures : Array.isArray(d.results) ? d.results : [];
3128
3146
  const failedCount = captures.filter((c) => c.status === "failed" || c.error).length;
3129
- const status = String(d.status ?? (failedCount ? "partial" : "captured"));
3147
+ const capturedCount = captures.filter((c) => c.status === "captured" || c.status === "ok").length;
3148
+ const skippedCount = captures.filter((c) => c.status === "skipped").length;
3149
+ const attempts = Array.isArray(d.attempts) ? d.attempts : [];
3150
+ const inferredStatus = captures.length === 0 ? "empty" : failedCount === captures.length ? "failed" : failedCount > 0 || skippedCount > 0 ? "partial" : "captured";
3151
+ const status = String(d.status ?? inferredStatus);
3130
3152
  const rows = captures.slice(0, 25).map((capture, i) => {
3131
3153
  const url = typeof capture.url === "string" ? capture.url : "";
3132
3154
  const sourceKind = typeof capture.sourceKind === "string" ? capture.sourceKind : typeof capture.source_kind === "string" ? capture.source_kind : "configured_target";
@@ -3135,8 +3157,10 @@ function formatCaptureSerpPageSnapshots(raw, input) {
3135
3157
  const full = [
3136
3158
  "# SERP Intelligence Page Snapshots",
3137
3159
  `**Status:** ${status}`,
3138
- `**Captured:** ${captures.length}`,
3160
+ `**Attempted:** ${captures.length}`,
3161
+ `**Captured:** ${capturedCount}`,
3139
3162
  `**Failed:** ${failedCount}`,
3163
+ skippedCount ? `**Skipped:** ${skippedCount}` : "",
3140
3164
  captures.length ? `
3141
3165
  | # | URL | Source | Status |
3142
3166
  |---|-----|--------|--------|
@@ -3148,8 +3172,11 @@ ${rows}` : ""
3148
3172
  schemaVersion: "serp-intelligence.page-snapshots.v1",
3149
3173
  status,
3150
3174
  count: captures.length,
3175
+ capturedCount,
3151
3176
  failedCount,
3177
+ skippedCount,
3152
3178
  captures,
3179
+ attempts,
3153
3180
  resolvedInputs: {
3154
3181
  urls: input.urls ?? null,
3155
3182
  targets: input.targets ?? null,
@@ -4268,9 +4295,19 @@ var CaptureSerpSnapshotOutputSchema = {
4268
4295
  location: NullableString,
4269
4296
  capturedAt: NullableString,
4270
4297
  resultCount: z.number().int().min(0).nullable(),
4298
+ organicResultCount: z.number().int().min(0),
4299
+ localPackResultCount: z.number().int().min(0),
4300
+ pageSnapshotCount: z.number().int().min(0),
4301
+ pageSnapshotFailedCount: z.number().int().min(0),
4271
4302
  snapshotId: NullableString,
4272
4303
  resolvedInputs: z.record(z.unknown()),
4273
4304
  artifacts: z.array(z.record(z.unknown())),
4305
+ attempts: z.array(z.record(z.unknown())),
4306
+ billing: z.object({
4307
+ creditsUsed: z.number().min(0).nullable(),
4308
+ requestId: NullableString,
4309
+ jobId: NullableString
4310
+ }).nullable(),
4274
4311
  diagnostics: z.record(z.unknown()).nullable(),
4275
4312
  providerPayload: z.record(z.unknown())
4276
4313
  };
@@ -4278,8 +4315,11 @@ var CaptureSerpPageSnapshotsOutputSchema = {
4278
4315
  schemaVersion: z.literal("serp-intelligence.page-snapshots.v1"),
4279
4316
  status: z.string(),
4280
4317
  count: z.number().int().min(0),
4318
+ capturedCount: z.number().int().min(0),
4281
4319
  failedCount: z.number().int().min(0),
4320
+ skippedCount: z.number().int().min(0),
4282
4321
  captures: z.array(z.record(z.unknown())),
4322
+ attempts: z.array(z.record(z.unknown())),
4283
4323
  resolvedInputs: z.record(z.unknown()),
4284
4324
  diagnostics: z.record(z.unknown()).nullable(),
4285
4325
  providerPayload: z.record(z.unknown())
@@ -4404,8 +4444,8 @@ var CaptureSerpSnapshotInputSchema = {
4404
4444
  proxyZip: z.string().regex(/^\d{5}$/).optional().describe('US ZIP for residential geo-IP targeting. Only meaningful with proxyMode "location".'),
4405
4445
  pages: z.number().int().min(1).max(2).default(1).describe("Google result pages to capture. Use 2 only for deeper ranking evidence."),
4406
4446
  debug: z.boolean().default(false).describe("Include sanitized browser/proxy/location diagnostics."),
4407
- includePageSnapshots: z.boolean().default(false).describe("Also capture ranking-page snapshots for selected SERP URLs."),
4408
- pageSnapshotLimit: z.number().int().min(0).max(10).default(0).describe("Maximum ranking-page snapshots when includePageSnapshots is true.")
4447
+ includePageSnapshots: z.boolean().default(false).describe("Also capture ranking-page snapshots for selected SERP URLs. Each attempted snapshot adds 1 Credit."),
4448
+ pageSnapshotLimit: z.number().int().min(0).max(10).default(0).describe("Maximum ranking-page snapshots when includePageSnapshots is true. This capacity is held up front and unused capacity is refunded.")
4409
4449
  };
4410
4450
  var ScreenshotInputSchema = {
4411
4451
  url: z.string().url().describe("URL to capture as a full-page screenshot. Use http or https. Pass allowLocal: true to capture localhost or private-network URLs during development."),
@@ -4413,12 +4453,12 @@ var ScreenshotInputSchema = {
4413
4453
  allowLocal: z.boolean().default(false).describe("Allow localhost and private-network URLs (127.x, 192.168.x, 10.x, etc.). For local development only \u2014 not for production use.")
4414
4454
  };
4415
4455
  var CaptureSerpPageSnapshotsInputSchema = {
4416
- urls: z.array(z.string().url()).min(1).max(25).describe("Public HTTP/HTTPS URLs to capture. Do not pass localhost, private IPs, file URLs, or internal admin URLs."),
4456
+ urls: z.array(z.string().url()).min(1).max(25).optional().describe("Public HTTP/HTTPS URLs to capture. Provide exactly one of urls or targets. Do not pass localhost, private IPs, file URLs, or internal admin URLs."),
4417
4457
  targets: z.array(z.object({
4418
4458
  url: z.string().url().describe("Public HTTP/HTTPS URL to capture."),
4419
4459
  sourceKind: z.enum(["organic", "ai_citation", "local_pack_website", "configured_target", "site_subject"]).default("configured_target").describe("Why this page is being captured."),
4420
4460
  sourcePosition: z.number().int().min(1).optional().describe("Ranking or citation position when the page came from SERP evidence.")
4421
- }).strict()).min(1).max(25).optional().describe("Structured targets. Use instead of urls when source kind or position should be preserved."),
4461
+ }).strict()).min(1).max(25).optional().describe("Structured targets. Provide exactly one of targets or urls; use targets when source kind or position should be preserved."),
4422
4462
  maxConcurrency: z.number().int().min(1).max(5).default(2).describe("Parallel page captures."),
4423
4463
  timeoutMs: z.number().int().min(1e3).max(6e4).default(15e3).describe("Per-page capture timeout in milliseconds; timeouts return as structured capture failures."),
4424
4464
  debug: z.boolean().default(false).describe("Include sanitized browser/proxy diagnostics.")
@@ -5060,14 +5100,14 @@ function liveWebToolAnnotations(title) {
5060
5100
  function registerSerpIntelligenceCaptureTools(server, executor) {
5061
5101
  server.registerTool("capture_serp_snapshot", {
5062
5102
  title: "SERP Intelligence Snapshot",
5063
- description: "Capture a structured SERP Intelligence snapshot of a Google query \u2014 the persistent evidence format used by rank-tracking and comparison pipelines. Split query from location; leave proxyMode unset.",
5103
+ description: "Capture a structured SERP Intelligence snapshot of a Google query \u2014 the persistent evidence format used by rank-tracking and comparison pipelines. Split query from location; leave proxyMode unset. Costs 4 Credits when headless or 14 if anti-bot escalation requires headful mode; the 14-Credit hold is settled to the mode used. Optional page snapshots add 1 Credit per attempted URL.",
5064
5104
  inputSchema: CaptureSerpSnapshotInputSchema,
5065
5105
  outputSchema: recordOutputSchema("capture_serp_snapshot", CaptureSerpSnapshotOutputSchema),
5066
5106
  annotations: liveWebToolAnnotations("SERP Intelligence Snapshot")
5067
5107
  }, async (input) => formatCaptureSerpSnapshot(await executor.captureSerpSnapshot(input), input));
5068
5108
  server.registerTool("capture_serp_page_snapshots", {
5069
5109
  title: "SERP Intelligence Page Snapshots",
5070
- description: "Capture public ranking pages as SERP Intelligence page snapshots \u2014 persistent page evidence linked to a captured SERP. Provide urls, or targets to preserve source metadata. Private IPs, localhost, file, and internal URLs are rejected.",
5110
+ description: "Capture public ranking pages as SERP Intelligence page snapshots \u2014 persistent page evidence linked to a captured SERP. Provide exactly one of urls or targets; use targets to preserve source metadata. Private IPs, localhost, file, and internal URLs are rejected. Costs 1 Credit per attempted URL.",
5071
5111
  inputSchema: CaptureSerpPageSnapshotsInputSchema,
5072
5112
  outputSchema: recordOutputSchema("capture_serp_page_snapshots", CaptureSerpPageSnapshotsOutputSchema),
5073
5113
  annotations: liveWebToolAnnotations("SERP Intelligence Page Snapshots")
@@ -5492,6 +5532,7 @@ function registerPaaExtractorMcpTools(server, executor, options = {}) {
5492
5532
  }
5493
5533
 
5494
5534
  // src/mcp/http-mcp-tool-executor.ts
5535
+ import { createHash as createHash3, randomUUID as randomUUID2 } from "crypto";
5495
5536
  function youtubeVideoIdFromUrl(url) {
5496
5537
  if (!url) return null;
5497
5538
  try {
@@ -5554,6 +5595,7 @@ var HttpMcpToolExecutor = class {
5554
5595
  timeoutMs;
5555
5596
  httpTimeoutOverrideMs;
5556
5597
  serpIntelligenceTimeoutMs;
5598
+ pendingSerpCaptureBillingKeys = /* @__PURE__ */ new Map();
5557
5599
  constructor(baseUrl, apiKey) {
5558
5600
  this.baseUrl = baseUrl.replace(/\/$/, "");
5559
5601
  this.apiKey = apiKey;
@@ -5564,13 +5606,14 @@ var HttpMcpToolExecutor = class {
5564
5606
  const configuredSerpIntelligenceTimeoutMs = Number(process.env.MCP_SCRAPER_SERP_INTELLIGENCE_HTTP_TIMEOUT_MS ?? this.timeoutMs);
5565
5607
  this.serpIntelligenceTimeoutMs = Number.isFinite(configuredSerpIntelligenceTimeoutMs) && configuredSerpIntelligenceTimeoutMs > 0 ? configuredSerpIntelligenceTimeoutMs : this.timeoutMs;
5566
5608
  }
5567
- async call(path, body, timeoutMs = this.timeoutMs, method = "POST") {
5609
+ async call(path, body, timeoutMs = this.timeoutMs, method = "POST", requestHeaders = {}) {
5568
5610
  try {
5569
5611
  const res = await fetch(`${this.baseUrl}${path}`, {
5570
5612
  method,
5571
5613
  headers: {
5572
5614
  "Content-Type": "application/json",
5573
- "x-api-key": this.apiKey
5615
+ "x-api-key": this.apiKey,
5616
+ ...requestHeaders
5574
5617
  },
5575
5618
  body: JSON.stringify(body),
5576
5619
  signal: AbortSignal.timeout(timeoutMs)
@@ -5818,8 +5861,27 @@ var HttpMcpToolExecutor = class {
5818
5861
  connections: input.connections
5819
5862
  }, void 0, "PUT");
5820
5863
  }
5821
- captureSerpSnapshot(input) {
5822
- return this.call("/serp-intelligence/capture", input, this.serpIntelligenceTimeoutMs);
5864
+ async captureSerpSnapshot(input) {
5865
+ const fingerprint = createHash3("sha256").update(JSON.stringify(input)).digest("hex");
5866
+ const now = Date.now();
5867
+ for (const [pendingFingerprint, pendingEntry] of this.pendingSerpCaptureBillingKeys) {
5868
+ if (pendingEntry.expiresAt <= now) this.pendingSerpCaptureBillingKeys.delete(pendingFingerprint);
5869
+ }
5870
+ const pending = this.pendingSerpCaptureBillingKeys.get(fingerprint);
5871
+ const idempotencyKey = pending && pending.expiresAt > now ? pending.key : randomUUID2();
5872
+ this.pendingSerpCaptureBillingKeys.set(fingerprint, {
5873
+ key: idempotencyKey,
5874
+ expiresAt: now + 15 * 6e4
5875
+ });
5876
+ const result = await this.call(
5877
+ "/serp-intelligence/capture",
5878
+ input,
5879
+ this.serpIntelligenceTimeoutMs,
5880
+ "POST",
5881
+ { "Idempotency-Key": idempotencyKey }
5882
+ );
5883
+ if (!result.isError) this.pendingSerpCaptureBillingKeys.delete(fingerprint);
5884
+ return result;
5823
5885
  }
5824
5886
  captureSerpPageSnapshots(input) {
5825
5887
  return this.call("/serp-intelligence/page-snapshots", input, this.serpIntelligenceTimeoutMs);
@@ -9786,4 +9848,4 @@ export {
9786
9848
  registerMemoryMcpTools,
9787
9849
  MemoryMcpToolExecutor
9788
9850
  };
9789
- //# sourceMappingURL=chunk-7LO6KLKD.js.map
9851
+ //# sourceMappingURL=chunk-N4JHXPW6.js.map