mcpscraper-sdk 0.28.0 → 0.30.0

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.
package/README.md CHANGED
@@ -45,7 +45,7 @@ Current Google search pricing is 60 Credits per SERP search and 400 Credits plus
45
45
 
46
46
  ## API surface
47
47
 
48
- `client.tools` is the generated, typed 252-tool MCP surface. It includes 151 MCP Scraper tools and all 101 mirrored Memory tools from `contracts/mcp.tools.json`.
48
+ `client.tools` is the generated, typed 259-tool MCP surface. It includes 158 MCP Scraper tools and all 101 mirrored Memory tools from `contracts/mcp.tools.json`.
49
49
 
50
50
  For multimodal results such as `meta_ad_creative_media`, call `client.tools.callToolResult(...)` to preserve native MCP image/audio/resource blocks. `callTool(...)` remains backward-compatible and returns the parsed structured or text value.
51
51
 
@@ -66,13 +66,28 @@ const inbox = await client.tools.schedule.listScheduledRuns({ view: 'inbox' })
66
66
  const templates = await client.tools.schedule.listArtifactTemplates({ status: 'active' })
67
67
  ```
68
68
 
69
+ Lead enrichment is available through the same generated surface. Supply mapped rows directly, or call `client.tools.leads.import(...)` first for CSV/TSV/XLSX input:
70
+
71
+ ```ts
72
+ const job = await client.tools.leads.enrich({
73
+ idempotencyKey: crypto.randomUUID(),
74
+ source: { kind: 'rows', rows: [{ Business: 'White Rock Roofing', City: 'Dallas', Website: 'https://roofwhiterock.com' }] },
75
+ columnMap: { name: 'Business', city: 'City', websiteUrl: 'Website' },
76
+ defaultEntityType: 'business',
77
+ emailSearchFallback: 'serp_snippets',
78
+ peopleDiscovery: 'owners',
79
+ peopleQueryTemplates: ['{business} owner of company {city}', '{business} founder {city}'],
80
+ outputFormats: ['csv', 'xlsx'],
81
+ })
82
+ ```
83
+
69
84
  The connected-data export performs bounded Gmail, Calendar, Google Search Console, Zoom, Meta Marketing, or Resend pagination server-side and returns small results inline or a private seven-day JSONL artifact. Use `exportConnectedServiceData({ dataset: 'search_console_performance' })` for a fresh Search Console API extract. A scheduled `connection_sync` maintains a typed `gsc_performance_*` table exposed as `listServiceConnections().tableName`; use `exportSearchConsoleTableData` for a server-filtered download from that persisted table. Use `meta_ads_insights` for daily account, campaign, ad-set, and ad reporting across connected Meta ad accounts. Resend can aggregate sent/received mail, logs, contacts, broadcasts, and templates with `resend_data`. Resume partial exports with the returned `continuation` object; renew an expired signed URL with `client.tools.connections.renewConnectedDataDownload({ artifactId })`. Use `listServiceConnections` for verified grants and per-tool permission blockers, then `describeServiceConnectionTool` for the exact provider-native schema before calling through the generic connection bridges.
70
85
 
71
86
  Search Console also provides six API-only batches through those connection bridges: reads `inspect-urls` and `query-search-analytics-batch`, and gated actions `add-sites-batch`, `submit-sitemaps-batch`, `delete-sites-batch`, and `delete-sitemaps-batch`. They require no database, return per-item receipts, and can be bound to scheduled agent runs. Delete batches default to dry-run and require the live schema's exact confirmation token for execution; all actions require the connection's action switch.
72
87
 
73
88
  Integrations are included with an active Starter plan or higher: OAuth connect/reconnect and direct connected-service reads, approved actions, exports, and snapshots do not currently have an extra connection-operation debit. Scheduled Actions use the shared Credit balance at 75 Credits per started occurrence; agent-mode runs also add 1.5 times OpenRouter's actual reported model cost. Inspect the live policy with `await client.tools.schedule.getScheduleStatus()`.
74
89
 
75
- Core operations are flat on the client: `searchSerp`, `harvestPaa`, `extractUrl`, `mapSiteUrls`, `extractSite`, `auditSite`, `getExtractSiteStatus`, `listJobs`, `getJob`, `getHistory`, `getLedger`.
90
+ Core operations are flat on the client: `searchSerp`, `harvestPaa`, `extractUrl`, `mapSiteUrls`, `extractSite`, `auditSite`, `getExtractSiteStatus`, `readExtractSiteExport`, `readExtractSiteImage`, `listJobs`, `getJob`, `getHistory`, `getLedger`.
76
91
 
77
92
  Everything else is namespaced by product area, matching the OpenAPI spec's tags: `client.youtube`, `client.screenshot`, `client.facebook`, `client.googleAds`, `client.instagram`, `client.reddit`, `client.video`, `client.maps`, `client.directory`, `client.serpIntelligence`, `client.workflows`.
78
93
 
package/dist/index.cjs CHANGED
@@ -48,14 +48,31 @@ var PUBLIC_ERROR_CODES = /* @__PURE__ */ new Set([
48
48
  "proxy_unavailable",
49
49
  "harvest_timeout",
50
50
  "mcp_request_timeout",
51
+ "mcp_http_error",
51
52
  "extraction_failed",
52
53
  "concurrency_limit_exceeded",
53
54
  "unauthorized",
54
55
  "forbidden",
55
56
  "invalid_request",
56
57
  "rate_limited",
58
+ "upstream_rate_limited",
57
59
  "insufficient_balance",
58
- "service_unavailable"
60
+ "service_unavailable",
61
+ "response_lost",
62
+ "vendor_unavailable",
63
+ "page_not_found",
64
+ "page_forbidden",
65
+ "page_rate_limited",
66
+ "page_server_error",
67
+ "page_http_error",
68
+ "bot_check_unresolved",
69
+ "page_too_large",
70
+ "page_unreachable",
71
+ "browser_session_interrupted",
72
+ "site_export_not_found",
73
+ "site_export_format_unavailable",
74
+ "site_export_read_failed",
75
+ "site_export_image_not_found"
59
76
  ]);
60
77
  var PUBLIC_ERROR_FIELDS = /* @__PURE__ */ new Set([
61
78
  "error",
@@ -153,19 +170,37 @@ var ScraperApiError = class extends Error {
153
170
  // src/client.ts
154
171
  var import_mcpscraper_memory_sdk = require("mcpscraper-memory-sdk");
155
172
  var Requester = class {
156
- constructor(apiKey, baseUrl, fetchImpl) {
173
+ constructor(apiKey, baseUrl, fetchImpl, timeoutMs) {
157
174
  this.apiKey = apiKey;
158
175
  this.baseUrl = baseUrl;
159
176
  this.fetchImpl = fetchImpl;
177
+ this.timeoutMs = timeoutMs;
160
178
  }
161
179
  apiKey;
162
180
  baseUrl;
163
181
  fetchImpl;
182
+ timeoutMs;
183
+ async request(url, init) {
184
+ try {
185
+ return await this.fetchImpl(url, { ...init, signal: AbortSignal.timeout(this.timeoutMs) });
186
+ } catch (error) {
187
+ if (error instanceof DOMException && (error.name === "TimeoutError" || error.name === "AbortError")) {
188
+ throw new ScraperApiError(408, {
189
+ error: "mcp_request_timeout",
190
+ error_code: "mcp_request_timeout",
191
+ error_type: "timeout",
192
+ message: `MCP Scraper request exceeded ${Math.round(this.timeoutMs / 1e3)}s and was cancelled client-side. The operation may still be running; use the same Idempotency-Key or poll a returned job before starting a new paid run.`,
193
+ retryable: true
194
+ });
195
+ }
196
+ throw error;
197
+ }
198
+ }
164
199
  async call(method, path, body, extraHeaders = {}) {
165
200
  return (await this.callWithReceipt(method, path, body, extraHeaders)).data;
166
201
  }
167
202
  async callWithReceipt(method, path, body, extraHeaders = {}) {
168
- const res = await this.fetchImpl(`${this.baseUrl}${path}`, {
203
+ const res = await this.request(`${this.baseUrl}${path}`, {
169
204
  method,
170
205
  headers: {
171
206
  "x-api-key": this.apiKey,
@@ -179,7 +214,7 @@ var Requester = class {
179
214
  return { data, headers: res.headers };
180
215
  }
181
216
  async callRaw(method, path) {
182
- const res = await this.fetchImpl(`${this.baseUrl}${path}`, { method, headers: { "x-api-key": this.apiKey } });
217
+ const res = await this.request(`${this.baseUrl}${path}`, { method, headers: { "x-api-key": this.apiKey } });
183
218
  if (!res.ok) {
184
219
  const data = await res.json().catch(() => void 0);
185
220
  throw new ScraperApiError(res.status, data);
@@ -422,7 +457,9 @@ var ScraperClient = class {
422
457
  memoryTools;
423
458
  tools;
424
459
  constructor(options) {
425
- this.r = new Requester(options.apiKey, options.baseUrl ?? "https://mcpscraper.dev", options.fetch ?? globalThis.fetch);
460
+ const requestTimeoutMs = options.requestTimeoutMs ?? 3e5;
461
+ if (!Number.isFinite(requestTimeoutMs) || requestTimeoutMs <= 0) throw new TypeError("requestTimeoutMs must be a positive number");
462
+ this.r = new Requester(options.apiKey, options.baseUrl ?? "https://mcpscraper.dev", options.fetch ?? globalThis.fetch, requestTimeoutMs);
426
463
  this.youtube = new YoutubeNamespace(this.r);
427
464
  this.screenshot = new ScreenshotNamespace(this.r);
428
465
  this.facebook = new FacebookNamespace(this.r);
@@ -438,7 +475,8 @@ var ScraperClient = class {
438
475
  this.tools = new import_mcpscraper_memory_sdk.McpToolsClient({
439
476
  apiKey: options.apiKey,
440
477
  baseUrl: options.baseUrl ?? "https://mcpscraper.dev",
441
- fetch: options.fetch
478
+ fetch: options.fetch,
479
+ requestTimeoutMs
442
480
  });
443
481
  }
444
482
  async callMemoryTool(toolName, args) {
@@ -458,21 +496,27 @@ var ScraperClient = class {
458
496
  harvestPaa(params) {
459
497
  return this.r.call("POST", "/harvest/sync", params);
460
498
  }
461
- extractUrl(params) {
462
- return this.r.call("POST", "/extract-url", params);
499
+ extractUrl(params, options = {}) {
500
+ return this.r.call("POST", "/extract-url", params, options.idempotencyKey ? { "Idempotency-Key": options.idempotencyKey } : {});
463
501
  }
464
502
  mapSiteUrls(params) {
465
503
  return this.r.call("POST", "/map-urls", params);
466
504
  }
467
- extractSite(params) {
468
- return this.r.call("POST", "/extract-site", params);
505
+ extractSite(params, options = {}) {
506
+ return this.r.call("POST", "/extract-site", params, options.idempotencyKey ? { "Idempotency-Key": options.idempotencyKey } : {});
469
507
  }
470
- auditSite(params) {
471
- return this.extractSite(params);
508
+ auditSite(params, options = {}) {
509
+ return this.extractSite(params, options);
472
510
  }
473
511
  getExtractSiteStatus(id) {
474
512
  return this.r.call("GET", `/extract-site/status/${encodeURIComponent(id)}`);
475
513
  }
514
+ readExtractSiteExport(params) {
515
+ return this.r.call("POST", "/extract-site/read", params);
516
+ }
517
+ readExtractSiteImage(params) {
518
+ return this.r.call("POST", "/extract-site/image", params);
519
+ }
476
520
  listJobs() {
477
521
  return this.r.call("GET", "/jobs");
478
522
  }
package/dist/index.d.cts CHANGED
@@ -178,6 +178,40 @@ interface paths {
178
178
  patch?: never;
179
179
  trace?: never;
180
180
  };
181
+ "/extract-site/read": {
182
+ parameters: {
183
+ query?: never;
184
+ header?: never;
185
+ path?: never;
186
+ cookie?: never;
187
+ };
188
+ get?: never;
189
+ put?: never;
190
+ /** List a site export or read complete page JSON, HTML, or Markdown */
191
+ post: operations["readExtractSiteExport"];
192
+ delete?: never;
193
+ options?: never;
194
+ head?: never;
195
+ patch?: never;
196
+ trace?: never;
197
+ };
198
+ "/extract-site/image": {
199
+ parameters: {
200
+ query?: never;
201
+ header?: never;
202
+ path?: never;
203
+ cookie?: never;
204
+ };
205
+ get?: never;
206
+ put?: never;
207
+ /** Read one owner-scoped downloaded image with provenance */
208
+ post: operations["readExtractSiteImage"];
209
+ delete?: never;
210
+ options?: never;
211
+ head?: never;
212
+ patch?: never;
213
+ trace?: never;
214
+ };
181
215
  "/youtube/harvest": {
182
216
  parameters: {
183
217
  query?: never;
@@ -844,7 +878,7 @@ interface components {
844
878
  details?: components["schemas"]["PublicErrorDetails"];
845
879
  };
846
880
  /** @enum {string} */
847
- PublicChargeStatus: "not_charged" | "refunded" | "charged";
881
+ PublicChargeStatus: "not_charged" | "refund_pending" | "refunded" | "charged";
848
882
  /** @description Bounded, vendor-neutral recovery and account details safe for public clients. */
849
883
  PublicErrorDetails: {
850
884
  [key: string]: string | number | boolean | (string | null);
@@ -852,7 +886,7 @@ interface components {
852
886
  /** @description Stable public failure envelope shared across REST and MCP operations. */
853
887
  PublicErrorEnvelope: {
854
888
  /** @enum {string} */
855
- error_code: "request_aborted" | "captcha_exhausted" | "captcha_or_blocked" | "location_mismatch" | "proxy_tunnel_failed" | "proxy_unavailable" | "harvest_timeout" | "mcp_request_timeout" | "extraction_failed" | "concurrency_limit_exceeded" | "unauthorized" | "forbidden" | "invalid_request" | "rate_limited" | "insufficient_balance" | "service_unavailable";
889
+ error_code: "request_aborted" | "captcha_exhausted" | "captcha_or_blocked" | "location_mismatch" | "proxy_tunnel_failed" | "proxy_unavailable" | "harvest_timeout" | "mcp_request_timeout" | "mcp_http_error" | "extraction_failed" | "concurrency_limit_exceeded" | "unauthorized" | "forbidden" | "invalid_request" | "rate_limited" | "upstream_rate_limited" | "insufficient_balance" | "service_unavailable" | "response_lost" | "vendor_unavailable" | "page_not_found" | "page_forbidden" | "page_rate_limited" | "page_server_error" | "page_http_error" | "bot_check_unresolved" | "page_too_large" | "page_unreachable" | "browser_session_interrupted" | "site_export_not_found" | "site_export_format_unavailable" | "site_export_read_failed" | "site_export_image_not_found";
856
890
  /** @enum {string} */
857
891
  error_type: "request_aborted" | "captcha" | "location_mismatch" | "connection" | "timeout" | "extraction" | "concurrency_limit" | "unauthorized" | "forbidden" | "invalid_request" | "rate_limit" | "billing" | "service_unavailable";
858
892
  message: string;
@@ -1042,9 +1076,19 @@ interface components {
1042
1076
  [key: string]: unknown;
1043
1077
  } | null;
1044
1078
  memory?: components["schemas"]["VaultDepositResult"];
1079
+ warnings?: components["schemas"]["PublicWarning"][];
1045
1080
  } & {
1046
1081
  [key: string]: unknown;
1047
1082
  };
1083
+ /** @description A component-scoped optional-capability failure that does not invalidate the core extraction. */
1084
+ PublicWarning: {
1085
+ /** @enum {string} */
1086
+ code: "render_unavailable" | "screenshot_unavailable" | "branding_unavailable" | "media_partial" | "media_packaging_failed";
1087
+ /** @enum {string} */
1088
+ component: "rendering" | "screenshot" | "branding" | "media";
1089
+ message: string;
1090
+ retryable: boolean;
1091
+ };
1048
1092
  /**
1049
1093
  * @description Present on ExtractUrlResponse only when the request set depositToVault: true.
1050
1094
  * Result of depositing a scrape into the caller's mcp-memory vault. Falls back to a
@@ -1104,6 +1148,11 @@ interface components {
1104
1148
  * @default false
1105
1149
  */
1106
1150
  downloadImages: boolean;
1151
+ /**
1152
+ * @description Preferred alias for downloadImages. Downloads supported images into owner-scoped artifacts and the ZIP.
1153
+ * @default false
1154
+ */
1155
+ preserveMedia: boolean;
1107
1156
  /** @default false */
1108
1157
  rotateProxies: boolean;
1109
1158
  /** @default 30 */
@@ -1116,7 +1165,7 @@ interface components {
1116
1165
  * `images` performs the image audit and returns `imageAudit` — on the synchronous
1117
1166
  * path too, not just background jobs.
1118
1167
  */
1119
- formats?: ("markdown" | "links" | "json" | "images" | "branding" | "issues")[];
1168
+ formats?: ("markdown" | "html" | "links" | "json" | "images" | "branding" | "issues")[];
1120
1169
  };
1121
1170
  /** @description Full synchronous crawl result. */
1122
1171
  ExtractSiteResponse: {
@@ -1254,8 +1303,52 @@ interface components {
1254
1303
  [key: string]: unknown;
1255
1304
  }[];
1256
1305
  error?: string | null;
1306
+ error_code?: string;
1307
+ error_type?: string;
1308
+ retryable?: boolean;
1309
+ retry_after_seconds?: number;
1310
+ charge_status?: components["schemas"]["PublicChargeStatus"];
1257
1311
  updatedAt?: string;
1258
1312
  };
1313
+ SiteExportReadRequest: {
1314
+ jobId: string;
1315
+ pageId?: string;
1316
+ /**
1317
+ * @default manifest
1318
+ * @enum {string}
1319
+ */
1320
+ format: "manifest" | "json" | "html" | "markdown";
1321
+ /** @default 0 */
1322
+ offset: number;
1323
+ /** @default 64000 */
1324
+ maxBytes: number;
1325
+ };
1326
+ SiteExportReadResponse: {
1327
+ jobId: string;
1328
+ pageId: string | null;
1329
+ /** @enum {string} */
1330
+ format: "manifest" | "json" | "html" | "markdown";
1331
+ sha256: string;
1332
+ text: string;
1333
+ offset: number;
1334
+ totalBytes: number;
1335
+ nextOffset: number | null;
1336
+ };
1337
+ SiteExportImageRequest: {
1338
+ jobId: string;
1339
+ imageId: string;
1340
+ };
1341
+ SiteExportImageResponse: {
1342
+ jobId: string;
1343
+ imageId: string;
1344
+ sourcePage?: string;
1345
+ sourceUrl?: string;
1346
+ mimeType: string;
1347
+ bytes: number;
1348
+ sha256?: string;
1349
+ /** Format: byte */
1350
+ dataBase64: string;
1351
+ };
1259
1352
  YoutubeHarvestRequest: {
1260
1353
  /** @enum {string} */
1261
1354
  mode: "search" | "channel";
@@ -1878,6 +1971,60 @@ interface operations {
1878
1971
  404: components["responses"]["NotFound"];
1879
1972
  };
1880
1973
  };
1974
+ readExtractSiteExport: {
1975
+ parameters: {
1976
+ query?: never;
1977
+ header?: never;
1978
+ path?: never;
1979
+ cookie?: never;
1980
+ };
1981
+ requestBody: {
1982
+ content: {
1983
+ "application/json": components["schemas"]["SiteExportReadRequest"];
1984
+ };
1985
+ };
1986
+ responses: {
1987
+ /** @description One bounded UTF-8 window. Continue from nextOffset until null. */
1988
+ 200: {
1989
+ headers: {
1990
+ [name: string]: unknown;
1991
+ };
1992
+ content: {
1993
+ "application/json": components["schemas"]["SiteExportReadResponse"];
1994
+ };
1995
+ };
1996
+ 400: components["responses"]["BadRequest"];
1997
+ 404: components["responses"]["NotFound"];
1998
+ 500: components["responses"]["ServerError"];
1999
+ };
2000
+ };
2001
+ readExtractSiteImage: {
2002
+ parameters: {
2003
+ query?: never;
2004
+ header?: never;
2005
+ path?: never;
2006
+ cookie?: never;
2007
+ };
2008
+ requestBody: {
2009
+ content: {
2010
+ "application/json": components["schemas"]["SiteExportImageRequest"];
2011
+ };
2012
+ };
2013
+ responses: {
2014
+ /** @description Downloaded image bytes encoded as base64 plus source provenance. */
2015
+ 200: {
2016
+ headers: {
2017
+ [name: string]: unknown;
2018
+ };
2019
+ content: {
2020
+ "application/json": components["schemas"]["SiteExportImageResponse"];
2021
+ };
2022
+ };
2023
+ 400: components["responses"]["BadRequest"];
2024
+ 404: components["responses"]["NotFound"];
2025
+ 500: components["responses"]["ServerError"];
2026
+ };
2027
+ };
1881
2028
  youtubeHarvest: {
1882
2029
  parameters: {
1883
2030
  query?: never;
@@ -3337,6 +3484,11 @@ interface ScraperClientOptions {
3337
3484
  apiKey: string;
3338
3485
  baseUrl?: string;
3339
3486
  fetch?: typeof globalThis.fetch;
3487
+ /** Bounded HTTP deadline for every request. Defaults to 300 seconds. */
3488
+ requestTimeoutMs?: number;
3489
+ }
3490
+ interface IdempotentRequestOptions {
3491
+ idempotencyKey?: string;
3340
3492
  }
3341
3493
  type SerpIntelligenceCaptureDefaultedKey = 'gl' | 'hl' | 'device' | 'proxyMode' | 'pages' | 'debug' | 'includePageSnapshots' | 'pageSnapshotLimit';
3342
3494
  type SerpIntelligenceCaptureParams = Omit<RequestBodyOf<'serpIntelligenceCapture'>, SerpIntelligenceCaptureDefaultedKey> & Partial<Pick<RequestBodyOf<'serpIntelligenceCapture'>, SerpIntelligenceCaptureDefaultedKey>>;
@@ -3351,7 +3503,9 @@ declare class Requester {
3351
3503
  private readonly apiKey;
3352
3504
  private readonly baseUrl;
3353
3505
  private readonly fetchImpl;
3354
- constructor(apiKey: string, baseUrl: string, fetchImpl: typeof globalThis.fetch);
3506
+ private readonly timeoutMs;
3507
+ constructor(apiKey: string, baseUrl: string, fetchImpl: typeof globalThis.fetch, timeoutMs: number);
3508
+ private request;
3355
3509
  call<K extends OperationId>(method: string, path: string, body?: RequestBodyOf<K>, extraHeaders?: Record<string, string>): Promise<SuccessBodyOf<K>>;
3356
3510
  callWithReceipt<K extends OperationId>(method: string, path: string, body?: RequestBodyOf<K>, extraHeaders?: Record<string, string>): Promise<{
3357
3511
  data: SuccessBodyOf<K>;
@@ -3667,7 +3821,7 @@ declare class ScraperClient {
3667
3821
  };
3668
3822
  error?: string;
3669
3823
  }>;
3670
- extractUrl(params: RequestBodyOf<'extractUrl'>): Promise<{
3824
+ extractUrl(params: RequestBodyOf<'extractUrl'>, options?: IdempotentRequestOptions): Promise<{
3671
3825
  title?: string | null;
3672
3826
  bodyMarkdown?: string;
3673
3827
  bodyHtml?: string;
@@ -3686,6 +3840,7 @@ declare class ScraperClient {
3686
3840
  [key: string]: unknown;
3687
3841
  } | null;
3688
3842
  memory?: components["schemas"]["VaultDepositResult"];
3843
+ warnings?: components["schemas"]["PublicWarning"][];
3689
3844
  } & {
3690
3845
  [key: string]: unknown;
3691
3846
  }>;
@@ -3694,7 +3849,7 @@ declare class ScraperClient {
3694
3849
  } & {
3695
3850
  [key: string]: unknown;
3696
3851
  }>;
3697
- extractSite(params: RequestBodyOf<'extractSite'>): Promise<({
3852
+ extractSite(params: RequestBodyOf<'extractSite'>, options?: IdempotentRequestOptions): Promise<({
3698
3853
  pages?: ({
3699
3854
  inSitemap?: boolean | null;
3700
3855
  } & {
@@ -3783,7 +3938,7 @@ declare class ScraperClient {
3783
3938
  status: "pending";
3784
3939
  statusUrl: string;
3785
3940
  }>;
3786
- auditSite(params: RequestBodyOf<'extractSite'>): Promise<({
3941
+ auditSite(params: RequestBodyOf<'extractSite'>, options?: IdempotentRequestOptions): Promise<({
3787
3942
  pages?: ({
3788
3943
  inSitemap?: boolean | null;
3789
3944
  } & {
@@ -3882,8 +4037,33 @@ declare class ScraperClient {
3882
4037
  [key: string]: unknown;
3883
4038
  }[];
3884
4039
  error?: string | null;
4040
+ error_code?: string;
4041
+ error_type?: string;
4042
+ retryable?: boolean;
4043
+ retry_after_seconds?: number;
4044
+ charge_status?: components["schemas"]["PublicChargeStatus"];
3885
4045
  updatedAt?: string;
3886
4046
  }>;
4047
+ readExtractSiteExport(params: RequestBodyOf<'readExtractSiteExport'>): Promise<{
4048
+ jobId: string;
4049
+ pageId: string | null;
4050
+ format: "manifest" | "json" | "html" | "markdown";
4051
+ sha256: string;
4052
+ text: string;
4053
+ offset: number;
4054
+ totalBytes: number;
4055
+ nextOffset: number | null;
4056
+ }>;
4057
+ readExtractSiteImage(params: RequestBodyOf<'readExtractSiteImage'>): Promise<{
4058
+ jobId: string;
4059
+ imageId: string;
4060
+ sourcePage?: string;
4061
+ sourceUrl?: string;
4062
+ mimeType: string;
4063
+ bytes: number;
4064
+ sha256?: string;
4065
+ dataBase64: string;
4066
+ }>;
3887
4067
  listJobs(): Promise<{
3888
4068
  id?: string;
3889
4069
  status?: string;
@@ -3938,4 +4118,4 @@ declare class ScraperApiError extends Error {
3938
4118
  };
3939
4119
  }
3940
4120
 
3941
- export { type ConcurrencyAccountViewBody, type ConcurrencyLimitBody, type ConcurrencyPackBody, type InsufficientBalanceBody, type PublicErrorEnvelopeBody, ScraperApiError, ScraperClient, type ScraperClientOptions, type SerpIntelligenceCaptureOptions, type SerpIntelligenceCaptureParams, type SerpIntelligenceCaptureReceipt, type StructuredErrorBody, type components, type operations, type paths };
4121
+ export { type ConcurrencyAccountViewBody, type ConcurrencyLimitBody, type ConcurrencyPackBody, type IdempotentRequestOptions, type InsufficientBalanceBody, type PublicErrorEnvelopeBody, ScraperApiError, ScraperClient, type ScraperClientOptions, type SerpIntelligenceCaptureOptions, type SerpIntelligenceCaptureParams, type SerpIntelligenceCaptureReceipt, type StructuredErrorBody, type components, type operations, type paths };
package/dist/index.d.ts CHANGED
@@ -178,6 +178,40 @@ interface paths {
178
178
  patch?: never;
179
179
  trace?: never;
180
180
  };
181
+ "/extract-site/read": {
182
+ parameters: {
183
+ query?: never;
184
+ header?: never;
185
+ path?: never;
186
+ cookie?: never;
187
+ };
188
+ get?: never;
189
+ put?: never;
190
+ /** List a site export or read complete page JSON, HTML, or Markdown */
191
+ post: operations["readExtractSiteExport"];
192
+ delete?: never;
193
+ options?: never;
194
+ head?: never;
195
+ patch?: never;
196
+ trace?: never;
197
+ };
198
+ "/extract-site/image": {
199
+ parameters: {
200
+ query?: never;
201
+ header?: never;
202
+ path?: never;
203
+ cookie?: never;
204
+ };
205
+ get?: never;
206
+ put?: never;
207
+ /** Read one owner-scoped downloaded image with provenance */
208
+ post: operations["readExtractSiteImage"];
209
+ delete?: never;
210
+ options?: never;
211
+ head?: never;
212
+ patch?: never;
213
+ trace?: never;
214
+ };
181
215
  "/youtube/harvest": {
182
216
  parameters: {
183
217
  query?: never;
@@ -844,7 +878,7 @@ interface components {
844
878
  details?: components["schemas"]["PublicErrorDetails"];
845
879
  };
846
880
  /** @enum {string} */
847
- PublicChargeStatus: "not_charged" | "refunded" | "charged";
881
+ PublicChargeStatus: "not_charged" | "refund_pending" | "refunded" | "charged";
848
882
  /** @description Bounded, vendor-neutral recovery and account details safe for public clients. */
849
883
  PublicErrorDetails: {
850
884
  [key: string]: string | number | boolean | (string | null);
@@ -852,7 +886,7 @@ interface components {
852
886
  /** @description Stable public failure envelope shared across REST and MCP operations. */
853
887
  PublicErrorEnvelope: {
854
888
  /** @enum {string} */
855
- error_code: "request_aborted" | "captcha_exhausted" | "captcha_or_blocked" | "location_mismatch" | "proxy_tunnel_failed" | "proxy_unavailable" | "harvest_timeout" | "mcp_request_timeout" | "extraction_failed" | "concurrency_limit_exceeded" | "unauthorized" | "forbidden" | "invalid_request" | "rate_limited" | "insufficient_balance" | "service_unavailable";
889
+ error_code: "request_aborted" | "captcha_exhausted" | "captcha_or_blocked" | "location_mismatch" | "proxy_tunnel_failed" | "proxy_unavailable" | "harvest_timeout" | "mcp_request_timeout" | "mcp_http_error" | "extraction_failed" | "concurrency_limit_exceeded" | "unauthorized" | "forbidden" | "invalid_request" | "rate_limited" | "upstream_rate_limited" | "insufficient_balance" | "service_unavailable" | "response_lost" | "vendor_unavailable" | "page_not_found" | "page_forbidden" | "page_rate_limited" | "page_server_error" | "page_http_error" | "bot_check_unresolved" | "page_too_large" | "page_unreachable" | "browser_session_interrupted" | "site_export_not_found" | "site_export_format_unavailable" | "site_export_read_failed" | "site_export_image_not_found";
856
890
  /** @enum {string} */
857
891
  error_type: "request_aborted" | "captcha" | "location_mismatch" | "connection" | "timeout" | "extraction" | "concurrency_limit" | "unauthorized" | "forbidden" | "invalid_request" | "rate_limit" | "billing" | "service_unavailable";
858
892
  message: string;
@@ -1042,9 +1076,19 @@ interface components {
1042
1076
  [key: string]: unknown;
1043
1077
  } | null;
1044
1078
  memory?: components["schemas"]["VaultDepositResult"];
1079
+ warnings?: components["schemas"]["PublicWarning"][];
1045
1080
  } & {
1046
1081
  [key: string]: unknown;
1047
1082
  };
1083
+ /** @description A component-scoped optional-capability failure that does not invalidate the core extraction. */
1084
+ PublicWarning: {
1085
+ /** @enum {string} */
1086
+ code: "render_unavailable" | "screenshot_unavailable" | "branding_unavailable" | "media_partial" | "media_packaging_failed";
1087
+ /** @enum {string} */
1088
+ component: "rendering" | "screenshot" | "branding" | "media";
1089
+ message: string;
1090
+ retryable: boolean;
1091
+ };
1048
1092
  /**
1049
1093
  * @description Present on ExtractUrlResponse only when the request set depositToVault: true.
1050
1094
  * Result of depositing a scrape into the caller's mcp-memory vault. Falls back to a
@@ -1104,6 +1148,11 @@ interface components {
1104
1148
  * @default false
1105
1149
  */
1106
1150
  downloadImages: boolean;
1151
+ /**
1152
+ * @description Preferred alias for downloadImages. Downloads supported images into owner-scoped artifacts and the ZIP.
1153
+ * @default false
1154
+ */
1155
+ preserveMedia: boolean;
1107
1156
  /** @default false */
1108
1157
  rotateProxies: boolean;
1109
1158
  /** @default 30 */
@@ -1116,7 +1165,7 @@ interface components {
1116
1165
  * `images` performs the image audit and returns `imageAudit` — on the synchronous
1117
1166
  * path too, not just background jobs.
1118
1167
  */
1119
- formats?: ("markdown" | "links" | "json" | "images" | "branding" | "issues")[];
1168
+ formats?: ("markdown" | "html" | "links" | "json" | "images" | "branding" | "issues")[];
1120
1169
  };
1121
1170
  /** @description Full synchronous crawl result. */
1122
1171
  ExtractSiteResponse: {
@@ -1254,8 +1303,52 @@ interface components {
1254
1303
  [key: string]: unknown;
1255
1304
  }[];
1256
1305
  error?: string | null;
1306
+ error_code?: string;
1307
+ error_type?: string;
1308
+ retryable?: boolean;
1309
+ retry_after_seconds?: number;
1310
+ charge_status?: components["schemas"]["PublicChargeStatus"];
1257
1311
  updatedAt?: string;
1258
1312
  };
1313
+ SiteExportReadRequest: {
1314
+ jobId: string;
1315
+ pageId?: string;
1316
+ /**
1317
+ * @default manifest
1318
+ * @enum {string}
1319
+ */
1320
+ format: "manifest" | "json" | "html" | "markdown";
1321
+ /** @default 0 */
1322
+ offset: number;
1323
+ /** @default 64000 */
1324
+ maxBytes: number;
1325
+ };
1326
+ SiteExportReadResponse: {
1327
+ jobId: string;
1328
+ pageId: string | null;
1329
+ /** @enum {string} */
1330
+ format: "manifest" | "json" | "html" | "markdown";
1331
+ sha256: string;
1332
+ text: string;
1333
+ offset: number;
1334
+ totalBytes: number;
1335
+ nextOffset: number | null;
1336
+ };
1337
+ SiteExportImageRequest: {
1338
+ jobId: string;
1339
+ imageId: string;
1340
+ };
1341
+ SiteExportImageResponse: {
1342
+ jobId: string;
1343
+ imageId: string;
1344
+ sourcePage?: string;
1345
+ sourceUrl?: string;
1346
+ mimeType: string;
1347
+ bytes: number;
1348
+ sha256?: string;
1349
+ /** Format: byte */
1350
+ dataBase64: string;
1351
+ };
1259
1352
  YoutubeHarvestRequest: {
1260
1353
  /** @enum {string} */
1261
1354
  mode: "search" | "channel";
@@ -1878,6 +1971,60 @@ interface operations {
1878
1971
  404: components["responses"]["NotFound"];
1879
1972
  };
1880
1973
  };
1974
+ readExtractSiteExport: {
1975
+ parameters: {
1976
+ query?: never;
1977
+ header?: never;
1978
+ path?: never;
1979
+ cookie?: never;
1980
+ };
1981
+ requestBody: {
1982
+ content: {
1983
+ "application/json": components["schemas"]["SiteExportReadRequest"];
1984
+ };
1985
+ };
1986
+ responses: {
1987
+ /** @description One bounded UTF-8 window. Continue from nextOffset until null. */
1988
+ 200: {
1989
+ headers: {
1990
+ [name: string]: unknown;
1991
+ };
1992
+ content: {
1993
+ "application/json": components["schemas"]["SiteExportReadResponse"];
1994
+ };
1995
+ };
1996
+ 400: components["responses"]["BadRequest"];
1997
+ 404: components["responses"]["NotFound"];
1998
+ 500: components["responses"]["ServerError"];
1999
+ };
2000
+ };
2001
+ readExtractSiteImage: {
2002
+ parameters: {
2003
+ query?: never;
2004
+ header?: never;
2005
+ path?: never;
2006
+ cookie?: never;
2007
+ };
2008
+ requestBody: {
2009
+ content: {
2010
+ "application/json": components["schemas"]["SiteExportImageRequest"];
2011
+ };
2012
+ };
2013
+ responses: {
2014
+ /** @description Downloaded image bytes encoded as base64 plus source provenance. */
2015
+ 200: {
2016
+ headers: {
2017
+ [name: string]: unknown;
2018
+ };
2019
+ content: {
2020
+ "application/json": components["schemas"]["SiteExportImageResponse"];
2021
+ };
2022
+ };
2023
+ 400: components["responses"]["BadRequest"];
2024
+ 404: components["responses"]["NotFound"];
2025
+ 500: components["responses"]["ServerError"];
2026
+ };
2027
+ };
1881
2028
  youtubeHarvest: {
1882
2029
  parameters: {
1883
2030
  query?: never;
@@ -3337,6 +3484,11 @@ interface ScraperClientOptions {
3337
3484
  apiKey: string;
3338
3485
  baseUrl?: string;
3339
3486
  fetch?: typeof globalThis.fetch;
3487
+ /** Bounded HTTP deadline for every request. Defaults to 300 seconds. */
3488
+ requestTimeoutMs?: number;
3489
+ }
3490
+ interface IdempotentRequestOptions {
3491
+ idempotencyKey?: string;
3340
3492
  }
3341
3493
  type SerpIntelligenceCaptureDefaultedKey = 'gl' | 'hl' | 'device' | 'proxyMode' | 'pages' | 'debug' | 'includePageSnapshots' | 'pageSnapshotLimit';
3342
3494
  type SerpIntelligenceCaptureParams = Omit<RequestBodyOf<'serpIntelligenceCapture'>, SerpIntelligenceCaptureDefaultedKey> & Partial<Pick<RequestBodyOf<'serpIntelligenceCapture'>, SerpIntelligenceCaptureDefaultedKey>>;
@@ -3351,7 +3503,9 @@ declare class Requester {
3351
3503
  private readonly apiKey;
3352
3504
  private readonly baseUrl;
3353
3505
  private readonly fetchImpl;
3354
- constructor(apiKey: string, baseUrl: string, fetchImpl: typeof globalThis.fetch);
3506
+ private readonly timeoutMs;
3507
+ constructor(apiKey: string, baseUrl: string, fetchImpl: typeof globalThis.fetch, timeoutMs: number);
3508
+ private request;
3355
3509
  call<K extends OperationId>(method: string, path: string, body?: RequestBodyOf<K>, extraHeaders?: Record<string, string>): Promise<SuccessBodyOf<K>>;
3356
3510
  callWithReceipt<K extends OperationId>(method: string, path: string, body?: RequestBodyOf<K>, extraHeaders?: Record<string, string>): Promise<{
3357
3511
  data: SuccessBodyOf<K>;
@@ -3667,7 +3821,7 @@ declare class ScraperClient {
3667
3821
  };
3668
3822
  error?: string;
3669
3823
  }>;
3670
- extractUrl(params: RequestBodyOf<'extractUrl'>): Promise<{
3824
+ extractUrl(params: RequestBodyOf<'extractUrl'>, options?: IdempotentRequestOptions): Promise<{
3671
3825
  title?: string | null;
3672
3826
  bodyMarkdown?: string;
3673
3827
  bodyHtml?: string;
@@ -3686,6 +3840,7 @@ declare class ScraperClient {
3686
3840
  [key: string]: unknown;
3687
3841
  } | null;
3688
3842
  memory?: components["schemas"]["VaultDepositResult"];
3843
+ warnings?: components["schemas"]["PublicWarning"][];
3689
3844
  } & {
3690
3845
  [key: string]: unknown;
3691
3846
  }>;
@@ -3694,7 +3849,7 @@ declare class ScraperClient {
3694
3849
  } & {
3695
3850
  [key: string]: unknown;
3696
3851
  }>;
3697
- extractSite(params: RequestBodyOf<'extractSite'>): Promise<({
3852
+ extractSite(params: RequestBodyOf<'extractSite'>, options?: IdempotentRequestOptions): Promise<({
3698
3853
  pages?: ({
3699
3854
  inSitemap?: boolean | null;
3700
3855
  } & {
@@ -3783,7 +3938,7 @@ declare class ScraperClient {
3783
3938
  status: "pending";
3784
3939
  statusUrl: string;
3785
3940
  }>;
3786
- auditSite(params: RequestBodyOf<'extractSite'>): Promise<({
3941
+ auditSite(params: RequestBodyOf<'extractSite'>, options?: IdempotentRequestOptions): Promise<({
3787
3942
  pages?: ({
3788
3943
  inSitemap?: boolean | null;
3789
3944
  } & {
@@ -3882,8 +4037,33 @@ declare class ScraperClient {
3882
4037
  [key: string]: unknown;
3883
4038
  }[];
3884
4039
  error?: string | null;
4040
+ error_code?: string;
4041
+ error_type?: string;
4042
+ retryable?: boolean;
4043
+ retry_after_seconds?: number;
4044
+ charge_status?: components["schemas"]["PublicChargeStatus"];
3885
4045
  updatedAt?: string;
3886
4046
  }>;
4047
+ readExtractSiteExport(params: RequestBodyOf<'readExtractSiteExport'>): Promise<{
4048
+ jobId: string;
4049
+ pageId: string | null;
4050
+ format: "manifest" | "json" | "html" | "markdown";
4051
+ sha256: string;
4052
+ text: string;
4053
+ offset: number;
4054
+ totalBytes: number;
4055
+ nextOffset: number | null;
4056
+ }>;
4057
+ readExtractSiteImage(params: RequestBodyOf<'readExtractSiteImage'>): Promise<{
4058
+ jobId: string;
4059
+ imageId: string;
4060
+ sourcePage?: string;
4061
+ sourceUrl?: string;
4062
+ mimeType: string;
4063
+ bytes: number;
4064
+ sha256?: string;
4065
+ dataBase64: string;
4066
+ }>;
3887
4067
  listJobs(): Promise<{
3888
4068
  id?: string;
3889
4069
  status?: string;
@@ -3938,4 +4118,4 @@ declare class ScraperApiError extends Error {
3938
4118
  };
3939
4119
  }
3940
4120
 
3941
- export { type ConcurrencyAccountViewBody, type ConcurrencyLimitBody, type ConcurrencyPackBody, type InsufficientBalanceBody, type PublicErrorEnvelopeBody, ScraperApiError, ScraperClient, type ScraperClientOptions, type SerpIntelligenceCaptureOptions, type SerpIntelligenceCaptureParams, type SerpIntelligenceCaptureReceipt, type StructuredErrorBody, type components, type operations, type paths };
4121
+ export { type ConcurrencyAccountViewBody, type ConcurrencyLimitBody, type ConcurrencyPackBody, type IdempotentRequestOptions, type InsufficientBalanceBody, type PublicErrorEnvelopeBody, ScraperApiError, ScraperClient, type ScraperClientOptions, type SerpIntelligenceCaptureOptions, type SerpIntelligenceCaptureParams, type SerpIntelligenceCaptureReceipt, type StructuredErrorBody, type components, type operations, type paths };
package/dist/index.js CHANGED
@@ -16,14 +16,31 @@ var PUBLIC_ERROR_CODES = /* @__PURE__ */ new Set([
16
16
  "proxy_unavailable",
17
17
  "harvest_timeout",
18
18
  "mcp_request_timeout",
19
+ "mcp_http_error",
19
20
  "extraction_failed",
20
21
  "concurrency_limit_exceeded",
21
22
  "unauthorized",
22
23
  "forbidden",
23
24
  "invalid_request",
24
25
  "rate_limited",
26
+ "upstream_rate_limited",
25
27
  "insufficient_balance",
26
- "service_unavailable"
28
+ "service_unavailable",
29
+ "response_lost",
30
+ "vendor_unavailable",
31
+ "page_not_found",
32
+ "page_forbidden",
33
+ "page_rate_limited",
34
+ "page_server_error",
35
+ "page_http_error",
36
+ "bot_check_unresolved",
37
+ "page_too_large",
38
+ "page_unreachable",
39
+ "browser_session_interrupted",
40
+ "site_export_not_found",
41
+ "site_export_format_unavailable",
42
+ "site_export_read_failed",
43
+ "site_export_image_not_found"
27
44
  ]);
28
45
  var PUBLIC_ERROR_FIELDS = /* @__PURE__ */ new Set([
29
46
  "error",
@@ -138,19 +155,37 @@ import {
138
155
  McpToolsClient
139
156
  } from "mcpscraper-memory-sdk";
140
157
  var Requester = class {
141
- constructor(apiKey, baseUrl, fetchImpl) {
158
+ constructor(apiKey, baseUrl, fetchImpl, timeoutMs) {
142
159
  this.apiKey = apiKey;
143
160
  this.baseUrl = baseUrl;
144
161
  this.fetchImpl = fetchImpl;
162
+ this.timeoutMs = timeoutMs;
145
163
  }
146
164
  apiKey;
147
165
  baseUrl;
148
166
  fetchImpl;
167
+ timeoutMs;
168
+ async request(url, init) {
169
+ try {
170
+ return await this.fetchImpl(url, { ...init, signal: AbortSignal.timeout(this.timeoutMs) });
171
+ } catch (error) {
172
+ if (error instanceof DOMException && (error.name === "TimeoutError" || error.name === "AbortError")) {
173
+ throw new ScraperApiError(408, {
174
+ error: "mcp_request_timeout",
175
+ error_code: "mcp_request_timeout",
176
+ error_type: "timeout",
177
+ message: `MCP Scraper request exceeded ${Math.round(this.timeoutMs / 1e3)}s and was cancelled client-side. The operation may still be running; use the same Idempotency-Key or poll a returned job before starting a new paid run.`,
178
+ retryable: true
179
+ });
180
+ }
181
+ throw error;
182
+ }
183
+ }
149
184
  async call(method, path, body, extraHeaders = {}) {
150
185
  return (await this.callWithReceipt(method, path, body, extraHeaders)).data;
151
186
  }
152
187
  async callWithReceipt(method, path, body, extraHeaders = {}) {
153
- const res = await this.fetchImpl(`${this.baseUrl}${path}`, {
188
+ const res = await this.request(`${this.baseUrl}${path}`, {
154
189
  method,
155
190
  headers: {
156
191
  "x-api-key": this.apiKey,
@@ -164,7 +199,7 @@ var Requester = class {
164
199
  return { data, headers: res.headers };
165
200
  }
166
201
  async callRaw(method, path) {
167
- const res = await this.fetchImpl(`${this.baseUrl}${path}`, { method, headers: { "x-api-key": this.apiKey } });
202
+ const res = await this.request(`${this.baseUrl}${path}`, { method, headers: { "x-api-key": this.apiKey } });
168
203
  if (!res.ok) {
169
204
  const data = await res.json().catch(() => void 0);
170
205
  throw new ScraperApiError(res.status, data);
@@ -407,7 +442,9 @@ var ScraperClient = class {
407
442
  memoryTools;
408
443
  tools;
409
444
  constructor(options) {
410
- this.r = new Requester(options.apiKey, options.baseUrl ?? "https://mcpscraper.dev", options.fetch ?? globalThis.fetch);
445
+ const requestTimeoutMs = options.requestTimeoutMs ?? 3e5;
446
+ if (!Number.isFinite(requestTimeoutMs) || requestTimeoutMs <= 0) throw new TypeError("requestTimeoutMs must be a positive number");
447
+ this.r = new Requester(options.apiKey, options.baseUrl ?? "https://mcpscraper.dev", options.fetch ?? globalThis.fetch, requestTimeoutMs);
411
448
  this.youtube = new YoutubeNamespace(this.r);
412
449
  this.screenshot = new ScreenshotNamespace(this.r);
413
450
  this.facebook = new FacebookNamespace(this.r);
@@ -423,7 +460,8 @@ var ScraperClient = class {
423
460
  this.tools = new McpToolsClient({
424
461
  apiKey: options.apiKey,
425
462
  baseUrl: options.baseUrl ?? "https://mcpscraper.dev",
426
- fetch: options.fetch
463
+ fetch: options.fetch,
464
+ requestTimeoutMs
427
465
  });
428
466
  }
429
467
  async callMemoryTool(toolName, args) {
@@ -443,21 +481,27 @@ var ScraperClient = class {
443
481
  harvestPaa(params) {
444
482
  return this.r.call("POST", "/harvest/sync", params);
445
483
  }
446
- extractUrl(params) {
447
- return this.r.call("POST", "/extract-url", params);
484
+ extractUrl(params, options = {}) {
485
+ return this.r.call("POST", "/extract-url", params, options.idempotencyKey ? { "Idempotency-Key": options.idempotencyKey } : {});
448
486
  }
449
487
  mapSiteUrls(params) {
450
488
  return this.r.call("POST", "/map-urls", params);
451
489
  }
452
- extractSite(params) {
453
- return this.r.call("POST", "/extract-site", params);
490
+ extractSite(params, options = {}) {
491
+ return this.r.call("POST", "/extract-site", params, options.idempotencyKey ? { "Idempotency-Key": options.idempotencyKey } : {});
454
492
  }
455
- auditSite(params) {
456
- return this.extractSite(params);
493
+ auditSite(params, options = {}) {
494
+ return this.extractSite(params, options);
457
495
  }
458
496
  getExtractSiteStatus(id) {
459
497
  return this.r.call("GET", `/extract-site/status/${encodeURIComponent(id)}`);
460
498
  }
499
+ readExtractSiteExport(params) {
500
+ return this.r.call("POST", "/extract-site/read", params);
501
+ }
502
+ readExtractSiteImage(params) {
503
+ return this.r.call("POST", "/extract-site/image", params);
504
+ }
461
505
  listJobs() {
462
506
  return this.r.call("GET", "/jobs");
463
507
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mcpscraper-sdk",
3
- "version": "0.28.0",
4
- "description": "Official Node.js client for all 252 mcpscraper.dev MCP tools and the REST API",
3
+ "version": "0.30.0",
4
+ "description": "Official Node.js client for all 259 mcpscraper.dev MCP tools and the REST API",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "main": "./dist/index.cjs",
@@ -32,7 +32,7 @@
32
32
  "seo-api"
33
33
  ],
34
34
  "dependencies": {
35
- "mcpscraper-memory-sdk": "^0.28.0"
35
+ "mcpscraper-memory-sdk": "^0.31.0"
36
36
  },
37
37
  "devDependencies": {
38
38
  "openapi-typescript": "^7.13.0"