mcpscraper-sdk 0.51.0 → 0.53.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 +13 -6
- package/dist/index.cjs +119 -24
- package/dist/index.d.cts +875 -166
- package/dist/index.d.ts +875 -166
- package/dist/index.js +123 -25
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ Official TypeScript/JavaScript client for the [mcpscraper.dev](https://mcpscrape
|
|
|
4
4
|
|
|
5
5
|
[Release history](https://github.com/VilovietaSEO/mcpscraper-sdk/blob/main/CHANGELOG.md)
|
|
6
6
|
|
|
7
|
-
This is a thin HTTP client generated against [`../../contracts/scraper.openapi.
|
|
7
|
+
This is a thin HTTP client generated against [`../../contracts/scraper.openapi.generated.json`](../../contracts/scraper.openapi.generated.json), the complete public REST contract for the hosted API. It contains no scraping, proxy, or billing logic — only typed request/response plumbing.
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
@@ -41,11 +41,11 @@ Every non-2xx response throws a `ScraperApiError` with `status`, `code`, and the
|
|
|
41
41
|
- `err.isConcurrencyLimitExceeded()` — narrows `err.body` to `{ active, limit, retryable, upgrade, ... }`.
|
|
42
42
|
- `err.isVerificationChallenge()` / `err.isTimeout()` — preserve actionable, vendor-neutral retry and charge details returned by the service.
|
|
43
43
|
|
|
44
|
-
Google Search light mode returns organic positions, URLs, titles, and descriptions for 20 Credits per delivered SERP page, or 35 Credits when the backup supplies the result. One-page full mode adds available same-page SERP features for 35 Credits. Both modes default to one page; an unfiltered two-page search costs 40 Credits when the normal provider returns both pages. Past-week and past-month searches use a managed browser for organic results at 35 Credits per delivered page,
|
|
44
|
+
Google Search light mode returns organic positions, URLs, titles, and descriptions for 20 Credits per delivered SERP page, or 35 Credits when the backup supplies the result. One-page full mode adds available same-page SERP features for 35 Credits. Both modes default to one page; an unfiltered two-page search costs 40 Credits when the normal provider returns both pages. Past-week and past-month searches use a managed browser for organic results at 35 Credits per delivered page. Unfiltered light searches try the primary path twice, then one API fallback; an unfiltered one-page full search uses the feature-capable API directly. If page 2 cannot be delivered, an available page 1 is returned as partial and billed at the one-page rate. A 35-Credit-per-requested-page hold is settled after delivery. PAA costs 400 Credits plus 10 Credits per returned question. One optional concurrency pack adds two browser slots for $5/month; quantity `n` adds `2n` slots for `$5n` without changing the base plan.
|
|
45
45
|
|
|
46
46
|
## API surface
|
|
47
47
|
|
|
48
|
-
`client.tools` is the generated, typed
|
|
48
|
+
`client.tools` is the generated, typed 367-tool MCP surface from `contracts/mcp.tools.json`, including provider-neutral X-Ray surveys, attribution-impact reporting, and truthful evidence-status operations.
|
|
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
|
|
|
@@ -181,14 +181,21 @@ Use `mcpscraper-memory-sdk`'s `MemoryClient` when you prefer its Memory-first na
|
|
|
181
181
|
|
|
182
182
|
## Regenerating types
|
|
183
183
|
|
|
184
|
-
`src/schema.ts` is generated from the OpenAPI
|
|
184
|
+
`src/schema.ts` is generated from the complete OpenAPI projection and checked in. For server-owned Maps search and directory routes, update `contracts/server-rest.v1.json` from the server artifact. Other public routes remain in the curated `contracts/scraper.openapi.yaml` base. Regenerate both language models from the repository root:
|
|
185
185
|
|
|
186
186
|
```bash
|
|
187
|
-
npm run generate
|
|
187
|
+
npm run generate:rest
|
|
188
|
+
npm run verify:rest-contract
|
|
188
189
|
```
|
|
189
190
|
|
|
190
191
|
## See also
|
|
191
192
|
|
|
192
193
|
[Repo README](../../README.md) (multi-language examples with real sample output) · [`mcpscraper-memory-sdk`](../memory) (Node, full 121-tool direct-memory surface) · [`mcpscraper-sdk` on PyPI](https://pypi.org/project/mcpscraper-sdk/) · [`mcpscraper-cli`](../cli)
|
|
193
194
|
|
|
194
|
-
Release changes: [SDK 0.
|
|
195
|
+
Release changes: [SDK 0.53.0 release notes](https://github.com/VilovietaSEO/mcpscraper-sdk/releases/tag/v0.53.0).
|
|
196
|
+
|
|
197
|
+
## Client attribution and full results
|
|
198
|
+
|
|
199
|
+
Clients accept `clientAttribution: { installChannel?, aiClient?, aiModel? }` and default to calling surface `sdk`. Set only known caller labels; unspecified labels stay unknown. `onResponse({ requestId, status })` receives per-response correlation without changing results, and errors keep their own `requestId`. These options also apply to `McpToolsClient` and `MemoryClient`; labels are reporting declarations, not authorization.
|
|
200
|
+
|
|
201
|
+
Large tool outputs may be delivery envelopes instead of inline domain values. Preserve `delivery`, `scope` and `recovery`, then use `tools.artifacts.describe`, `readRetained` (follow `nextOffset` to null), or `download` with the returned artifact ID. The legacy `artifacts.read` method remains the report reader. `callToolResult` preserves native content/resource links. Download URL expiry differs from artifact retention; renew a URL through `download` without rerunning acquisition. Use the returned capability for binary files.
|
package/dist/index.cjs
CHANGED
|
@@ -72,7 +72,29 @@ var PUBLIC_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
|
72
72
|
"site_export_not_found",
|
|
73
73
|
"site_export_format_unavailable",
|
|
74
74
|
"site_export_read_failed",
|
|
75
|
-
"site_export_image_not_found"
|
|
75
|
+
"site_export_image_not_found",
|
|
76
|
+
"directory_job_not_found",
|
|
77
|
+
"idempotency_in_progress",
|
|
78
|
+
"idempotency_conflict",
|
|
79
|
+
"image_url_invalid",
|
|
80
|
+
"image_url_not_https",
|
|
81
|
+
"image_host_unresolvable",
|
|
82
|
+
"image_host_blocked",
|
|
83
|
+
"image_redirect_invalid",
|
|
84
|
+
"image_source_unavailable",
|
|
85
|
+
"image_too_large",
|
|
86
|
+
"image_redirect_limit",
|
|
87
|
+
"image_base64_invalid",
|
|
88
|
+
"image_source_missing",
|
|
89
|
+
"image_source_ambiguous",
|
|
90
|
+
"image_source_type_invalid",
|
|
91
|
+
"image_artifact_not_found",
|
|
92
|
+
"image_page_too_large",
|
|
93
|
+
"page_image_not_found",
|
|
94
|
+
"page_image_candidates_unusable",
|
|
95
|
+
"image_format_unsupported",
|
|
96
|
+
"image_storage_unconfigured",
|
|
97
|
+
"featured_image_unhostable"
|
|
76
98
|
]);
|
|
77
99
|
var PUBLIC_ERROR_FIELDS = /* @__PURE__ */ new Set([
|
|
78
100
|
"error",
|
|
@@ -103,13 +125,51 @@ var PUBLIC_DETAIL_FIELDS = /* @__PURE__ */ new Set([
|
|
|
103
125
|
"slots_per_pack",
|
|
104
126
|
"pack_price_usd",
|
|
105
127
|
"balance_credits",
|
|
106
|
-
"required_credits"
|
|
128
|
+
"required_credits",
|
|
129
|
+
"retry_guidance",
|
|
130
|
+
"http_status",
|
|
131
|
+
"job_id"
|
|
107
132
|
]);
|
|
133
|
+
function boundedString(value, limit) {
|
|
134
|
+
return typeof value === "string" && value.length > 0 && value.length <= limit;
|
|
135
|
+
}
|
|
136
|
+
function publicRecoveryFields(body) {
|
|
137
|
+
if (!body || typeof body !== "object" || Array.isArray(body)) return {};
|
|
138
|
+
const row = body;
|
|
139
|
+
const safe = {};
|
|
140
|
+
if (boundedString(row.idempotencyKey, 512)) safe.idempotencyKey = row.idempotencyKey;
|
|
141
|
+
if (typeof row.idempotencyFingerprint === "string" && /^[a-f0-9]{16}$/.test(row.idempotencyFingerprint)) safe.idempotencyFingerprint = row.idempotencyFingerprint;
|
|
142
|
+
const operation = row.operation;
|
|
143
|
+
if (operation && typeof operation === "object" && !Array.isArray(operation)) {
|
|
144
|
+
const op = operation;
|
|
145
|
+
if ((op.runId === null || boundedString(op.runId, 200)) && boundedString(op.idempotencyKey, 512) && boundedString(op.state, 100)) {
|
|
146
|
+
safe.operation = { runId: op.runId, idempotencyKey: op.idempotencyKey, state: op.state };
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
const recovery = row.recovery;
|
|
150
|
+
if (recovery && typeof recovery === "object" && !Array.isArray(recovery)) {
|
|
151
|
+
const receipt = recovery;
|
|
152
|
+
if (typeof receipt.jobId === "string" && /^[a-zA-Z0-9-]{1,100}$/.test(receipt.jobId) && typeof receipt.statusTool === "string" && /^[a-z][a-z0-9_]{0,99}$/.test(receipt.statusTool) && receipt.executionState === "unknown" && ["held", "unconfirmed"].includes(String(receipt.holdState))) {
|
|
153
|
+
safe.recovery = { jobId: receipt.jobId, statusTool: receipt.statusTool, executionState: receipt.executionState, holdState: receipt.holdState };
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (typeof row.job_id === "string" && /^[a-zA-Z0-9-]{1,100}$/.test(row.job_id)) safe.job_id = row.job_id;
|
|
157
|
+
if (typeof row.status_tool === "string" && /^[a-z][a-z0-9_]{0,99}$/.test(row.status_tool)) safe.status_tool = row.status_tool;
|
|
158
|
+
if (row.executionState === "unknown") safe.executionState = row.executionState;
|
|
159
|
+
if (row.hold_state === "held" || row.hold_state === "unconfirmed") safe.hold_state = row.hold_state;
|
|
160
|
+
if (typeof row.runId === "string" && /^[a-zA-Z0-9_-]{1,200}$/.test(row.runId)) {
|
|
161
|
+
safe.runId = row.runId;
|
|
162
|
+
if (["queued", "running", "interrupted", "complete", "partial", "failed", "cancelled"].includes(String(row.runStatus))) safe.runStatus = row.runStatus;
|
|
163
|
+
if (["unreserved", "held", "settling", "settled", "refunded", "pending_reconciliation"].includes(String(row.billingState))) safe.billingState = row.billingState;
|
|
164
|
+
if (row.statusPath === `/maps/place/runs/${row.runId}`) safe.statusPath = row.statusPath;
|
|
165
|
+
}
|
|
166
|
+
return safe;
|
|
167
|
+
}
|
|
108
168
|
function recognizedPublicDetails(value) {
|
|
109
169
|
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
110
170
|
const details = Object.fromEntries(
|
|
111
171
|
Object.entries(value).filter(
|
|
112
|
-
([key, child]) => PUBLIC_DETAIL_FIELDS.has(key) && (child === null ||
|
|
172
|
+
([key, child]) => PUBLIC_DETAIL_FIELDS.has(key) && (child === null || typeof child === "boolean" || typeof child === "number" && Number.isFinite(child) || typeof child === "string" && child.length <= (key === "job_id" ? 200 : 500))
|
|
113
173
|
)
|
|
114
174
|
);
|
|
115
175
|
return Object.keys(details).length > 0 ? details : void 0;
|
|
@@ -119,10 +179,13 @@ function recognizedPublicErrorBody(body) {
|
|
|
119
179
|
const record = body;
|
|
120
180
|
const code = readString(record, "error_code");
|
|
121
181
|
if (!code || !PUBLIC_ERROR_CODES.has(code)) return void 0;
|
|
122
|
-
const safe = Object.fromEntries(Object.entries(record).filter(([key]) => PUBLIC_ERROR_FIELDS.has(key)));
|
|
182
|
+
const safe = Object.fromEntries(Object.entries(record).filter(([key, value]) => PUBLIC_ERROR_FIELDS.has(key) && (value === null || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value) || typeof value === "string" && value.length <= 1e3)));
|
|
183
|
+
Object.assign(safe, publicRecoveryFields(record));
|
|
123
184
|
const details = recognizedPublicDetails(record.details);
|
|
124
185
|
if (details) safe.details = details;
|
|
125
186
|
else delete safe.details;
|
|
187
|
+
const upgrade = recognizedPublicDetails(record.upgrade);
|
|
188
|
+
if (upgrade) safe.upgrade = upgrade;
|
|
126
189
|
return safe;
|
|
127
190
|
}
|
|
128
191
|
function publicErrorBody(status, body) {
|
|
@@ -135,20 +198,23 @@ function publicErrorBody(status, body) {
|
|
|
135
198
|
error_type: "service_unavailable",
|
|
136
199
|
retryable: true,
|
|
137
200
|
status,
|
|
138
|
-
message: PUBLIC_SERVICE_UNAVAILABLE_MESSAGE
|
|
201
|
+
message: PUBLIC_SERVICE_UNAVAILABLE_MESSAGE,
|
|
202
|
+
...publicRecoveryFields(body)
|
|
139
203
|
};
|
|
140
204
|
}
|
|
141
205
|
var ScraperApiError = class extends Error {
|
|
142
206
|
status;
|
|
143
207
|
code;
|
|
144
208
|
body;
|
|
145
|
-
|
|
209
|
+
requestId;
|
|
210
|
+
constructor(status, body, details = {}) {
|
|
146
211
|
const safeBody = publicErrorBody(status, body);
|
|
147
212
|
super(readString(safeBody, "message") ?? `mcpscraper.dev API request failed with status ${status}`);
|
|
148
213
|
this.name = "ScraperApiError";
|
|
149
214
|
this.status = status;
|
|
150
215
|
this.code = readString(safeBody, "error_code") ?? readString(safeBody, "error");
|
|
151
216
|
this.body = safeBody;
|
|
217
|
+
this.requestId = details.requestId;
|
|
152
218
|
}
|
|
153
219
|
isInsufficientBalance() {
|
|
154
220
|
return this.code === "insufficient_balance";
|
|
@@ -170,19 +236,29 @@ var ScraperApiError = class extends Error {
|
|
|
170
236
|
// src/client.ts
|
|
171
237
|
var import_mcpscraper_memory_sdk = require("mcpscraper-memory-sdk");
|
|
172
238
|
var Requester = class {
|
|
173
|
-
constructor(apiKey, baseUrl, fetchImpl, timeoutMs) {
|
|
239
|
+
constructor(apiKey, baseUrl, fetchImpl, timeoutMs, metadataOptions = {}) {
|
|
174
240
|
this.apiKey = apiKey;
|
|
175
241
|
this.baseUrl = baseUrl;
|
|
176
242
|
this.fetchImpl = fetchImpl;
|
|
177
243
|
this.timeoutMs = timeoutMs;
|
|
244
|
+
this.metadataOptions = metadataOptions;
|
|
178
245
|
}
|
|
179
246
|
apiKey;
|
|
180
247
|
baseUrl;
|
|
181
248
|
fetchImpl;
|
|
182
249
|
timeoutMs;
|
|
250
|
+
metadataOptions;
|
|
251
|
+
headers(extra = {}) {
|
|
252
|
+
return { ...(0, import_mcpscraper_memory_sdk.clientAttributionHeaders)(this.metadataOptions.clientAttribution), ...extra, "x-api-key": this.apiKey };
|
|
253
|
+
}
|
|
254
|
+
received(res) {
|
|
255
|
+
(0, import_mcpscraper_memory_sdk.notifyResponse)(this.metadataOptions.onResponse, (0, import_mcpscraper_memory_sdk.responseMetadata)(res));
|
|
256
|
+
}
|
|
183
257
|
async request(url, init) {
|
|
184
258
|
try {
|
|
185
|
-
|
|
259
|
+
const response = await this.fetchImpl(url, { ...init, signal: AbortSignal.timeout(this.timeoutMs) });
|
|
260
|
+
this.received(response);
|
|
261
|
+
return response;
|
|
186
262
|
} catch (error) {
|
|
187
263
|
if (error instanceof DOMException && (error.name === "TimeoutError" || error.name === "AbortError")) {
|
|
188
264
|
throw new ScraperApiError(408, {
|
|
@@ -207,14 +283,14 @@ var Requester = class {
|
|
|
207
283
|
try {
|
|
208
284
|
res = await this.fetchImpl(`${this.baseUrl}${path}`, {
|
|
209
285
|
method,
|
|
210
|
-
headers: {
|
|
211
|
-
"x-api-key": this.apiKey,
|
|
286
|
+
headers: this.headers({
|
|
212
287
|
...body !== void 0 ? { "content-type": "application/json" } : {},
|
|
213
288
|
...extraHeaders
|
|
214
|
-
},
|
|
289
|
+
}),
|
|
215
290
|
body: body !== void 0 ? JSON.stringify(body) : void 0,
|
|
216
291
|
signal
|
|
217
292
|
});
|
|
293
|
+
this.received(res);
|
|
218
294
|
} catch (error) {
|
|
219
295
|
if (error instanceof DOMException && (error.name === "TimeoutError" || error.name === "AbortError")) {
|
|
220
296
|
if (options.signal?.aborted && !timeoutSignal.aborted) throw error;
|
|
@@ -229,14 +305,14 @@ var Requester = class {
|
|
|
229
305
|
throw error;
|
|
230
306
|
}
|
|
231
307
|
const data = await res.json().catch(() => void 0);
|
|
232
|
-
if (!res.ok) throw new ScraperApiError(res.status, data);
|
|
308
|
+
if (!res.ok) throw new ScraperApiError(res.status, data, { requestId: (0, import_mcpscraper_memory_sdk.responseMetadata)(res).requestId });
|
|
233
309
|
return { data, headers: res.headers };
|
|
234
310
|
}
|
|
235
311
|
async callRaw(method, path) {
|
|
236
|
-
const res = await this.request(`${this.baseUrl}${path}`, { method, headers:
|
|
312
|
+
const res = await this.request(`${this.baseUrl}${path}`, { method, headers: this.headers() });
|
|
237
313
|
if (!res.ok) {
|
|
238
314
|
const data = await res.json().catch(() => void 0);
|
|
239
|
-
throw new ScraperApiError(res.status, data);
|
|
315
|
+
throw new ScraperApiError(res.status, data, { requestId: (0, import_mcpscraper_memory_sdk.responseMetadata)(res).requestId });
|
|
240
316
|
}
|
|
241
317
|
return res.arrayBuffer();
|
|
242
318
|
}
|
|
@@ -318,8 +394,14 @@ var RedditNamespace = class {
|
|
|
318
394
|
this.r = r;
|
|
319
395
|
}
|
|
320
396
|
r;
|
|
321
|
-
thread(params) {
|
|
322
|
-
return this.r.call(
|
|
397
|
+
thread(params, options = {}) {
|
|
398
|
+
return this.r.call(
|
|
399
|
+
"POST",
|
|
400
|
+
"/reddit/thread",
|
|
401
|
+
params,
|
|
402
|
+
options.idempotencyKey === void 0 ? {} : { "Idempotency-Key": options.idempotencyKey },
|
|
403
|
+
options
|
|
404
|
+
);
|
|
323
405
|
}
|
|
324
406
|
};
|
|
325
407
|
var VideoNamespace = class {
|
|
@@ -340,7 +422,8 @@ var MapsNamespace = class {
|
|
|
340
422
|
}
|
|
341
423
|
r;
|
|
342
424
|
search(params, options = {}) {
|
|
343
|
-
|
|
425
|
+
const headers = options.idempotencyKey ? { "Idempotency-Key": options.idempotencyKey } : {};
|
|
426
|
+
return this.r.call("POST", "/maps/search", params, headers, options);
|
|
344
427
|
}
|
|
345
428
|
place(params, options = {}) {
|
|
346
429
|
const headers = {
|
|
@@ -386,8 +469,17 @@ var DirectoryNamespace = class {
|
|
|
386
469
|
this.r = r;
|
|
387
470
|
}
|
|
388
471
|
r;
|
|
389
|
-
run(params) {
|
|
390
|
-
return this.r.call(
|
|
472
|
+
run(params, options = {}) {
|
|
473
|
+
return this.r.call(
|
|
474
|
+
"POST",
|
|
475
|
+
"/directory/run",
|
|
476
|
+
params,
|
|
477
|
+
options.idempotencyKey ? { "Idempotency-Key": options.idempotencyKey } : {},
|
|
478
|
+
options
|
|
479
|
+
);
|
|
480
|
+
}
|
|
481
|
+
status(jobId, options = {}) {
|
|
482
|
+
return this.r.call("GET", `/directory/jobs/${encodeURIComponent(jobId)}`, void 0, {}, options);
|
|
391
483
|
}
|
|
392
484
|
};
|
|
393
485
|
var SerpIntelligenceNamespace = class {
|
|
@@ -412,7 +504,8 @@ var SerpIntelligenceNamespace = class {
|
|
|
412
504
|
);
|
|
413
505
|
return {
|
|
414
506
|
data: result.data,
|
|
415
|
-
idempotencyKey: result.headers.get("Idempotency-Key")
|
|
507
|
+
idempotencyKey: result.headers.get("Idempotency-Key"),
|
|
508
|
+
...result.headers.get("x-mcp-request-id") ? { requestId: result.headers.get("x-mcp-request-id") } : {}
|
|
416
509
|
};
|
|
417
510
|
}
|
|
418
511
|
pageSnapshots(params) {
|
|
@@ -552,7 +645,7 @@ var ScraperClient = class {
|
|
|
552
645
|
constructor(options) {
|
|
553
646
|
const requestTimeoutMs = options.requestTimeoutMs ?? 59e4;
|
|
554
647
|
if (!Number.isFinite(requestTimeoutMs) || requestTimeoutMs <= 0) throw new TypeError("requestTimeoutMs must be a positive number");
|
|
555
|
-
this.r = new Requester(options.apiKey, options.baseUrl ?? "https://mcpscraper.dev", options.fetch ?? globalThis.fetch, requestTimeoutMs);
|
|
648
|
+
this.r = new Requester(options.apiKey, options.baseUrl ?? "https://mcpscraper.dev", options.fetch ?? globalThis.fetch, requestTimeoutMs, options);
|
|
556
649
|
this.youtube = new YoutubeNamespace(this.r);
|
|
557
650
|
this.screenshot = new ScreenshotNamespace(this.r);
|
|
558
651
|
this.facebook = new FacebookNamespace(this.r);
|
|
@@ -570,17 +663,19 @@ var ScraperClient = class {
|
|
|
570
663
|
apiKey: options.apiKey,
|
|
571
664
|
baseUrl: options.baseUrl ?? "https://mcpscraper.dev",
|
|
572
665
|
fetch: options.fetch,
|
|
573
|
-
requestTimeoutMs
|
|
666
|
+
requestTimeoutMs,
|
|
667
|
+
clientAttribution: options.clientAttribution,
|
|
668
|
+
onResponse: options.onResponse
|
|
574
669
|
});
|
|
575
670
|
}
|
|
576
671
|
async callMemoryTool(toolName, args) {
|
|
577
|
-
const result = await this.r.
|
|
672
|
+
const { data: result, headers } = await this.r.callWithReceipt("POST", "/memory/mcp-call", {
|
|
578
673
|
toolName,
|
|
579
674
|
args: args ?? {}
|
|
580
675
|
});
|
|
581
676
|
if (result && typeof result === "object" && result.ok === false) {
|
|
582
677
|
const failure = result;
|
|
583
|
-
throw new ScraperApiError(200, { message: failure.error, ...failure });
|
|
678
|
+
throw new ScraperApiError(200, { message: failure.error, ...failure }, { requestId: headers.get("x-mcp-request-id") ?? void 0 });
|
|
584
679
|
}
|
|
585
680
|
return result;
|
|
586
681
|
}
|