scrapeunblocker-mcp 0.3.5 → 0.4.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 +3 -1
- package/dist/index.js +79 -21
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,6 +18,7 @@ You bring your **own** API key. Nothing is shared or proxied through us.
|
|
|
18
18
|
| `google_search` | Run a Google search and return organic results as JSON. |
|
|
19
19
|
| `list_plugins` | List the ready-made site plugins (100+: Amazon, Walmart, Zillow, Booking.com, Indeed, Google Trends, YouTube, App Store, Ahrefs, ...) with their parameters. Free - it calls nothing. |
|
|
20
20
|
| `run_plugin` | Run one site plugin and return its structured JSON. |
|
|
21
|
+
| `amazon_search`, `amazon_product`, `amazon_reviews`, `walmart_search`, `ebay_search`, `google_shopping`, `google_local`, `maps_place_details`, `google_images`, `youtube_search`, `youtube_transcript`, `zillow_search`, `indeed_jobs`, `trustpilot_reviews`, `booking_hotels` | The most-used site plugins as tools of their own, each with its parameters in the tool schema - one call, no `list_plugins` lookup. Same JSON as `run_plugin`. |
|
|
21
22
|
|
|
22
23
|
### Site plugins (structured JSON for known sites)
|
|
23
24
|
|
|
@@ -25,7 +26,8 @@ For many popular sites there is a plugin that returns the data already
|
|
|
25
26
|
parsed - a Target search, a Zillow listing search, an app's App Store reviews,
|
|
26
27
|
Google Trends for a few keywords. The model calls `list_plugins` (optionally
|
|
27
28
|
with `search: "zillow"` or a `category`) to find the plugin and its
|
|
28
|
-
parameters, then `run_plugin` with `name` and `params
|
|
29
|
+
parameters, then `run_plugin` with `name` and `params` (the most-used plugins, listed in
|
|
30
|
+
the table above, can also be called directly as their own tools):
|
|
29
31
|
|
|
30
32
|
```json
|
|
31
33
|
{ "name": "target_search", "params": { "query": "coffee maker", "max_results": 20 } }
|
package/dist/index.js
CHANGED
|
@@ -5506,6 +5506,23 @@ var MAX_OUTPUT_CHARS = 1e5;
|
|
|
5506
5506
|
var BY_NAME = new Map(PLUGINS.map((p) => [p.name, p]));
|
|
5507
5507
|
var NAMES = PLUGINS.map((p) => p.name);
|
|
5508
5508
|
var CATEGORIES2 = CATEGORIES;
|
|
5509
|
+
var FEATURED_PLUGINS = [
|
|
5510
|
+
"amazon_search",
|
|
5511
|
+
"amazon_product",
|
|
5512
|
+
"amazon_reviews",
|
|
5513
|
+
"walmart_search",
|
|
5514
|
+
"ebay_search",
|
|
5515
|
+
"google_shopping",
|
|
5516
|
+
"google_local",
|
|
5517
|
+
"maps_place_details",
|
|
5518
|
+
"google_images",
|
|
5519
|
+
"youtube_search",
|
|
5520
|
+
"youtube_transcript",
|
|
5521
|
+
"zillow_search",
|
|
5522
|
+
"indeed_jobs",
|
|
5523
|
+
"trustpilot_reviews",
|
|
5524
|
+
"booking_hotels"
|
|
5525
|
+
];
|
|
5509
5526
|
var text = (t, isError = false) => isError ? { content: [{ type: "text", text: t }], isError: true } : { content: [{ type: "text", text: t }] };
|
|
5510
5527
|
function signature(p) {
|
|
5511
5528
|
return `${p.name}(${p.params.map((q) => q.required ? `${q.name}*` : q.name).join(", ")})`;
|
|
@@ -5564,8 +5581,49 @@ function prepare(p, params) {
|
|
|
5564
5581
|
}
|
|
5565
5582
|
return out;
|
|
5566
5583
|
}
|
|
5584
|
+
function paramType(q) {
|
|
5585
|
+
const scalar = (t) => t === "integer" ? z.number().int() : t === "number" ? z.number() : t === "boolean" ? z.boolean() : z.string();
|
|
5586
|
+
let type;
|
|
5587
|
+
if (q.type === "array") {
|
|
5588
|
+
const item = scalar(q.items);
|
|
5589
|
+
type = z.union([z.array(item), item]);
|
|
5590
|
+
} else if (q.enum && q.enum.length && q.enum.every((v) => typeof v === "string")) {
|
|
5591
|
+
type = z.enum(q.enum);
|
|
5592
|
+
if (q.join) type = z.union([type, z.array(type)]);
|
|
5593
|
+
} else {
|
|
5594
|
+
type = scalar(q.type);
|
|
5595
|
+
if (q.join) type = z.union([type, z.array(type)]);
|
|
5596
|
+
}
|
|
5597
|
+
const extras = [
|
|
5598
|
+
q.enum && !q.enum.every((v) => typeof v === "string") ? `One of: ${q.enum.join(", ")}.` : "",
|
|
5599
|
+
q.default !== void 0 ? `Default: ${String(q.default)}.` : ""
|
|
5600
|
+
].filter(Boolean);
|
|
5601
|
+
const description = [q.description, ...extras].filter(Boolean).join(" ");
|
|
5602
|
+
if (description) type = type.describe(description);
|
|
5603
|
+
return q.required ? type : type.optional();
|
|
5604
|
+
}
|
|
5567
5605
|
function registerPluginTools(server2, options) {
|
|
5568
5606
|
const annotations = { readOnlyHint: true, openWorldHint: true, destructiveHint: false, ...options.annotations };
|
|
5607
|
+
async function run(plugin, raw) {
|
|
5608
|
+
const blocked = options.blocked?.();
|
|
5609
|
+
if (blocked) return blocked;
|
|
5610
|
+
const params = prepare(plugin, raw);
|
|
5611
|
+
if (typeof params === "string") return text(`${params}
|
|
5612
|
+
|
|
5613
|
+
${details(plugin)}`, true);
|
|
5614
|
+
try {
|
|
5615
|
+
const result = await options.call(plugin.path, params);
|
|
5616
|
+
const body = JSON.stringify(result);
|
|
5617
|
+
if (body.length <= MAX_OUTPUT_CHARS) return text(body);
|
|
5618
|
+
return text(
|
|
5619
|
+
body.slice(0, MAX_OUTPUT_CHARS) + `
|
|
5620
|
+
|
|
5621
|
+
[Cut at ${MAX_OUTPUT_CHARS} of ${body.length} characters - ask for fewer results (max_results) or a narrower filter to get the whole answer.]`
|
|
5622
|
+
);
|
|
5623
|
+
} catch (err) {
|
|
5624
|
+
return text(options.errorText(err), true);
|
|
5625
|
+
}
|
|
5626
|
+
}
|
|
5569
5627
|
server2.registerTool(
|
|
5570
5628
|
"list_plugins",
|
|
5571
5629
|
{
|
|
@@ -5604,32 +5662,32 @@ function registerPluginTools(server2, options) {
|
|
|
5604
5662
|
params: z.record(z.string(), z.union([z.string(), z.number(), z.boolean(), z.array(z.union([z.string(), z.number()]))])).optional().describe(`The plugin's parameters, e.g. {"query": "coffee maker", "max_results": 20}.`)
|
|
5605
5663
|
}
|
|
5606
5664
|
},
|
|
5607
|
-
async (args) => {
|
|
5608
|
-
|
|
5609
|
-
|
|
5610
|
-
|
|
5611
|
-
|
|
5612
|
-
|
|
5613
|
-
|
|
5614
|
-
|
|
5615
|
-
|
|
5616
|
-
|
|
5617
|
-
|
|
5618
|
-
|
|
5619
|
-
|
|
5620
|
-
|
|
5621
|
-
|
|
5622
|
-
|
|
5665
|
+
async (args) => run(BY_NAME.get(args.name), args.params ?? {})
|
|
5666
|
+
);
|
|
5667
|
+
for (const name of FEATURED_PLUGINS) {
|
|
5668
|
+
const plugin = BY_NAME.get(name);
|
|
5669
|
+
if (!plugin) continue;
|
|
5670
|
+
const shape = Object.fromEntries(plugin.params.map((q) => [q.name, paramType(q)]));
|
|
5671
|
+
server2.registerTool(
|
|
5672
|
+
plugin.name,
|
|
5673
|
+
{
|
|
5674
|
+
title: plugin.title,
|
|
5675
|
+
annotations: { title: plugin.title, ...annotations },
|
|
5676
|
+
description: `${plugin.description} Returns JSON. Billed like an API request; listing plugins bill one unit per result page they fetch, so keep max_results modest.`,
|
|
5677
|
+
inputSchema: shape
|
|
5678
|
+
},
|
|
5679
|
+
async (args) => {
|
|
5680
|
+
const raw = Object.fromEntries(
|
|
5681
|
+
Object.entries(args).filter(([, v]) => v !== void 0)
|
|
5623
5682
|
);
|
|
5624
|
-
|
|
5625
|
-
return text(options.errorText(err), true);
|
|
5683
|
+
return run(plugin, raw);
|
|
5626
5684
|
}
|
|
5627
|
-
|
|
5628
|
-
|
|
5685
|
+
);
|
|
5686
|
+
}
|
|
5629
5687
|
}
|
|
5630
5688
|
|
|
5631
5689
|
// src/index.ts
|
|
5632
|
-
var VERSION = "0.
|
|
5690
|
+
var VERSION = "0.4.0";
|
|
5633
5691
|
var DEFAULT_BASE_URL = "https://api.scrapeunblocker.com";
|
|
5634
5692
|
var API_KEY_HEADER = "x-scrapeunblocker-key";
|
|
5635
5693
|
function resolveApiKey() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "scrapeunblocker-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"mcpName": "com.scrapeunblocker/scrapeunblocker-mcp",
|
|
5
5
|
"description": "Model Context Protocol (MCP) server for ScrapeUnblocker - lets Claude fetch any web page's HTML (or AI-parsed JSON) and run 100+ site plugins that return structured JSON, through the ScrapeUnblocker anti-bot API, using your own API key.",
|
|
6
6
|
"keywords": [
|