mcpscraper-sdk 0.33.0 → 0.35.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 +48 -3
- package/dist/index.cjs +65 -27
- package/dist/index.d.cts +4294 -326
- package/dist/index.d.ts +4294 -326
- package/dist/index.js +65 -27
- package/package.json +4 -4
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
|
|
48
|
+
`client.tools` is the generated, typed 346-tool MCP surface from `contracts/mcp.tools.json`, including the governed personal-assistant namespace.
|
|
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
|
|
|
@@ -87,7 +87,52 @@ Search Console also provides six API-only batches through those connection bridg
|
|
|
87
87
|
|
|
88
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()`.
|
|
89
89
|
|
|
90
|
-
Core operations are flat on the client: `searchSerp`, `harvestPaa`, `extractUrl`, `mapSiteUrls`, `extractSite`, `auditSite`, `getExtractSiteStatus`, `
|
|
90
|
+
Core operations are flat on the client: `startHarvest`, `searchSerp`, `harvestPaa`, `extractUrl`, `mapSiteUrls`, `extractSite`, `auditSite`, `getExtractSiteStatus`, `archiveRead`, `listJobs`, `getJob`, `getHistory`, `getLedger`.
|
|
91
|
+
|
|
92
|
+
### Durable acquisition
|
|
93
|
+
|
|
94
|
+
Long-running agents can start SERP/PAA work once and poll the provider-owned job
|
|
95
|
+
instead of holding one synchronous request open:
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
const started = await client.startHarvest({
|
|
99
|
+
query: 'roofers dallas',
|
|
100
|
+
location: 'Dallas, TX',
|
|
101
|
+
serpOnly: true,
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
let job
|
|
105
|
+
do {
|
|
106
|
+
await new Promise(resolve => setTimeout(resolve, 2_000))
|
|
107
|
+
job = await client.getJob(started.job_id, { timeoutMs: 30_000 })
|
|
108
|
+
} while (job.status === 'pending' || job.status === 'running')
|
|
109
|
+
|
|
110
|
+
if (job.status !== 'done') throw new Error(job.error ?? `Harvest ${job.status}`)
|
|
111
|
+
console.log(job.result)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Background site extraction accepts a caller-owned idempotency key, and the
|
|
115
|
+
archive reader exposes the resulting ZIP without switching to the MCP surface:
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
const crawl = await client.extractSite(
|
|
119
|
+
{ url: 'https://example.com', background: true, formats: ['markdown', 'links', 'json'] },
|
|
120
|
+
{ idempotencyKey: 'foundation-run-123:crawl', timeoutMs: 30_000 },
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
const status = await client.getExtractSiteStatus(crawl.jobId)
|
|
124
|
+
const bundle = status.artifacts?.find(artifact => artifact.contentType === 'application/zip')
|
|
125
|
+
if (bundle?.downloadUrl) {
|
|
126
|
+
const pages = await client.archiveRead({ url: bundle.downloadUrl, path: 'pages.jsonl' })
|
|
127
|
+
const pageCorpus = await client.archiveRead({
|
|
128
|
+
url: bundle.downloadUrl,
|
|
129
|
+
pathPrefix: 'pages/',
|
|
130
|
+
maxEntries: 1000,
|
|
131
|
+
maxTotalBytes: 20_000_000,
|
|
132
|
+
})
|
|
133
|
+
console.log(pages.content)
|
|
134
|
+
}
|
|
135
|
+
```
|
|
91
136
|
|
|
92
137
|
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`, `client.gmail`. The REST Gmail namespace preserves opaque path handles and requires explicit idempotency keys for mutations; the generated `client.tools.connections.gmail*` methods expose the exact MCP input/output contracts.
|
|
93
138
|
|
|
@@ -137,4 +182,4 @@ npm run generate
|
|
|
137
182
|
|
|
138
183
|
## See also
|
|
139
184
|
|
|
140
|
-
[Repo README](../../README.md) (
|
|
185
|
+
[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)
|
package/dist/index.cjs
CHANGED
|
@@ -196,19 +196,38 @@ var Requester = class {
|
|
|
196
196
|
throw error;
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
|
-
async call(method, path, body, extraHeaders = {}) {
|
|
200
|
-
return (await this.callWithReceipt(method, path, body, extraHeaders)).data;
|
|
201
|
-
}
|
|
202
|
-
async callWithReceipt(method, path, body, extraHeaders = {}) {
|
|
203
|
-
const
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
199
|
+
async call(method, path, body, extraHeaders = {}, options = {}) {
|
|
200
|
+
return (await this.callWithReceipt(method, path, body, extraHeaders, options)).data;
|
|
201
|
+
}
|
|
202
|
+
async callWithReceipt(method, path, body, extraHeaders = {}, options = {}) {
|
|
203
|
+
const requestTimeoutMs = options.timeoutMs ?? this.timeoutMs;
|
|
204
|
+
const timeoutSignal = AbortSignal.timeout(requestTimeoutMs);
|
|
205
|
+
const signal = options.signal ? AbortSignal.any([options.signal, timeoutSignal]) : timeoutSignal;
|
|
206
|
+
let res;
|
|
207
|
+
try {
|
|
208
|
+
res = await this.fetchImpl(`${this.baseUrl}${path}`, {
|
|
209
|
+
method,
|
|
210
|
+
headers: {
|
|
211
|
+
"x-api-key": this.apiKey,
|
|
212
|
+
...body !== void 0 ? { "content-type": "application/json" } : {},
|
|
213
|
+
...extraHeaders
|
|
214
|
+
},
|
|
215
|
+
body: body !== void 0 ? JSON.stringify(body) : void 0,
|
|
216
|
+
signal
|
|
217
|
+
});
|
|
218
|
+
} catch (error) {
|
|
219
|
+
if (error instanceof DOMException && (error.name === "TimeoutError" || error.name === "AbortError")) {
|
|
220
|
+
if (options.signal?.aborted && !timeoutSignal.aborted) throw error;
|
|
221
|
+
throw new ScraperApiError(408, {
|
|
222
|
+
error: "mcp_request_timeout",
|
|
223
|
+
error_code: "mcp_request_timeout",
|
|
224
|
+
error_type: "timeout",
|
|
225
|
+
message: `The client stopped waiting after ${Math.round(requestTimeoutMs / 1e3)}s. This does not prove server-side work stopped; use the same Idempotency-Key or poll a returned job before starting a new paid run.`,
|
|
226
|
+
retryable: true
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
throw error;
|
|
230
|
+
}
|
|
212
231
|
const data = await res.json().catch(() => void 0);
|
|
213
232
|
if (!res.ok) throw new ScraperApiError(res.status, data);
|
|
214
233
|
return { data, headers: res.headers };
|
|
@@ -320,8 +339,8 @@ var MapsNamespace = class {
|
|
|
320
339
|
this.r = r;
|
|
321
340
|
}
|
|
322
341
|
r;
|
|
323
|
-
search(params) {
|
|
324
|
-
return this.r.call("POST", "/maps/search", params);
|
|
342
|
+
search(params, options = {}) {
|
|
343
|
+
return this.r.call("POST", "/maps/search", params, {}, options);
|
|
325
344
|
}
|
|
326
345
|
place(params) {
|
|
327
346
|
return this.r.call("POST", "/maps/place", params);
|
|
@@ -530,26 +549,45 @@ var ScraperClient = class {
|
|
|
530
549
|
}
|
|
531
550
|
return result;
|
|
532
551
|
}
|
|
533
|
-
|
|
534
|
-
return this.r.call(
|
|
552
|
+
startHarvest(params, options = {}) {
|
|
553
|
+
return this.r.call(
|
|
554
|
+
"POST",
|
|
555
|
+
"/harvest",
|
|
556
|
+
params,
|
|
557
|
+
{},
|
|
558
|
+
options
|
|
559
|
+
);
|
|
560
|
+
}
|
|
561
|
+
searchSerp(params, options = {}) {
|
|
562
|
+
return this.r.call("POST", "/harvest/sync", { ...params, serpOnly: true }, {}, options);
|
|
535
563
|
}
|
|
536
|
-
harvestPaa(params) {
|
|
537
|
-
return this.r.call("POST", "/harvest/sync", params);
|
|
564
|
+
harvestPaa(params, options = {}) {
|
|
565
|
+
return this.r.call("POST", "/harvest/sync", params, {}, options);
|
|
538
566
|
}
|
|
539
567
|
extractUrl(params, options = {}) {
|
|
540
|
-
return this.r.call("POST", "/extract-url", params,
|
|
568
|
+
return this.r.call("POST", "/extract-url", params, {}, options);
|
|
541
569
|
}
|
|
542
|
-
mapSiteUrls(params) {
|
|
543
|
-
return this.r.call("POST", "/map-urls", params);
|
|
570
|
+
mapSiteUrls(params, options = {}) {
|
|
571
|
+
return this.r.call("POST", "/map-urls", params, {}, options);
|
|
544
572
|
}
|
|
545
573
|
extractSite(params, options = {}) {
|
|
546
|
-
|
|
574
|
+
const headers = options.idempotencyKey === void 0 ? {} : { "Idempotency-Key": options.idempotencyKey };
|
|
575
|
+
return this.r.call("POST", "/extract-site", params, headers, options);
|
|
547
576
|
}
|
|
548
577
|
auditSite(params, options = {}) {
|
|
549
578
|
return this.extractSite(params, options);
|
|
550
579
|
}
|
|
551
|
-
getExtractSiteStatus(id) {
|
|
552
|
-
return this.r.call("GET", `/extract-site/status/${encodeURIComponent(id)}
|
|
580
|
+
getExtractSiteStatus(id, options = {}) {
|
|
581
|
+
return this.r.call("GET", `/extract-site/status/${encodeURIComponent(id)}`, void 0, {}, options);
|
|
582
|
+
}
|
|
583
|
+
archiveRead(params, options = {}) {
|
|
584
|
+
return this.r.call(
|
|
585
|
+
"POST",
|
|
586
|
+
"/archive/read",
|
|
587
|
+
params,
|
|
588
|
+
{},
|
|
589
|
+
options
|
|
590
|
+
);
|
|
553
591
|
}
|
|
554
592
|
readExtractSiteExport(params) {
|
|
555
593
|
return this.r.call("POST", "/extract-site/read", params);
|
|
@@ -560,8 +598,8 @@ var ScraperClient = class {
|
|
|
560
598
|
listJobs() {
|
|
561
599
|
return this.r.call("GET", "/jobs");
|
|
562
600
|
}
|
|
563
|
-
getJob(id) {
|
|
564
|
-
return this.r.call("GET", `/jobs/${encodeURIComponent(id)}
|
|
601
|
+
getJob(id, options = {}) {
|
|
602
|
+
return this.r.call("GET", `/jobs/${encodeURIComponent(id)}`, void 0, {}, options);
|
|
565
603
|
}
|
|
566
604
|
getHistory() {
|
|
567
605
|
return this.r.call("GET", "/history");
|