scrapeunblocker-mcp 0.2.0 → 0.2.1
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/dist/index.js +45 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
5
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
6
6
|
import { z } from "zod";
|
|
7
|
-
import { ScrapeUnblockerClient } from "scrapeunblocker";
|
|
8
|
-
var VERSION = "0.2.
|
|
7
|
+
import { APIError, ScrapeUnblockerClient } from "scrapeunblocker";
|
|
8
|
+
var VERSION = "0.2.1";
|
|
9
9
|
var DEFAULT_BASE_URL = "https://api.scrapeunblocker.com";
|
|
10
10
|
var API_KEY_HEADER = "x-scrapeunblocker-key";
|
|
11
11
|
function resolveApiKey() {
|
|
@@ -28,6 +28,31 @@ function errorText(err) {
|
|
|
28
28
|
if (err instanceof Error) return err.message;
|
|
29
29
|
return String(err);
|
|
30
30
|
}
|
|
31
|
+
var TARGET_GONE = /* @__PURE__ */ new Set([404, 410]);
|
|
32
|
+
function targetGoneStatus(status, originStatus) {
|
|
33
|
+
const origin = Number(originStatus);
|
|
34
|
+
if (TARGET_GONE.has(origin)) return origin;
|
|
35
|
+
return TARGET_GONE.has(status) ? status : null;
|
|
36
|
+
}
|
|
37
|
+
function targetGoneText(url, code, page) {
|
|
38
|
+
const reason = code === 410 ? "Gone" : "Not Found";
|
|
39
|
+
const head = `The target page does not exist: ${url} answered HTTP ${code} (${reason}). This is the website's own answer, not a block or an API failure. The call was billed, and retrying returns the same result - check the URL instead.`;
|
|
40
|
+
return page.trim() ? `${head}
|
|
41
|
+
|
|
42
|
+
The target's own ${code} page follows:
|
|
43
|
+
|
|
44
|
+
${page}` : `${head}
|
|
45
|
+
|
|
46
|
+
The target sent no page body.`;
|
|
47
|
+
}
|
|
48
|
+
function errorResult(url, err) {
|
|
49
|
+
const gone = err instanceof APIError ? targetGoneStatus(err.statusCode) : null;
|
|
50
|
+
if (gone !== null) {
|
|
51
|
+
const body = err instanceof APIError ? err.body ?? "" : "";
|
|
52
|
+
return { content: [{ type: "text", text: targetGoneText(url, gone, body) }] };
|
|
53
|
+
}
|
|
54
|
+
return { content: [{ type: "text", text: errorText(err) }], isError: true };
|
|
55
|
+
}
|
|
31
56
|
async function getPageSourceRaw(params) {
|
|
32
57
|
const apiKey = resolveApiKey();
|
|
33
58
|
if (!apiKey) throw new Error(MISSING_KEY_MESSAGE);
|
|
@@ -46,7 +71,12 @@ async function getPageSourceRaw(params) {
|
|
|
46
71
|
}
|
|
47
72
|
});
|
|
48
73
|
const text = await response.text();
|
|
49
|
-
return {
|
|
74
|
+
return {
|
|
75
|
+
status: response.status,
|
|
76
|
+
ok: response.ok,
|
|
77
|
+
text,
|
|
78
|
+
originStatus: response.headers.get("x-origin-status")
|
|
79
|
+
};
|
|
50
80
|
}
|
|
51
81
|
var server = new McpServer({
|
|
52
82
|
name: "scrapeunblocker",
|
|
@@ -159,6 +189,10 @@ server.registerTool(
|
|
|
159
189
|
time_sleep: args.sleep_seconds,
|
|
160
190
|
steps: JSON.stringify(args.steps)
|
|
161
191
|
});
|
|
192
|
+
const gone = targetGoneStatus(res.status, res.originStatus);
|
|
193
|
+
if (gone !== null) {
|
|
194
|
+
return { content: [{ type: "text", text: targetGoneText(args.url, gone, res.text) }] };
|
|
195
|
+
}
|
|
162
196
|
if (res.ok) {
|
|
163
197
|
return { content: [{ type: "text", text: res.text }] };
|
|
164
198
|
}
|
|
@@ -192,7 +226,7 @@ Fix the selector or step (use list_elements to inspect the page) and retry. The
|
|
|
192
226
|
isError: true
|
|
193
227
|
};
|
|
194
228
|
} catch (err) {
|
|
195
|
-
return
|
|
229
|
+
return errorResult(args.url, err);
|
|
196
230
|
}
|
|
197
231
|
}
|
|
198
232
|
);
|
|
@@ -213,7 +247,8 @@ server.registerTool(
|
|
|
213
247
|
list_elements: true,
|
|
214
248
|
proxy_country: args.proxy_country
|
|
215
249
|
});
|
|
216
|
-
|
|
250
|
+
const gone = targetGoneStatus(res.status, res.originStatus);
|
|
251
|
+
if (!res.ok && gone === null) {
|
|
217
252
|
return {
|
|
218
253
|
content: [
|
|
219
254
|
{
|
|
@@ -229,9 +264,12 @@ server.registerTool(
|
|
|
229
264
|
out = JSON.stringify(JSON.parse(res.text), null, 2);
|
|
230
265
|
} catch {
|
|
231
266
|
}
|
|
267
|
+
if (gone !== null) {
|
|
268
|
+
return { content: [{ type: "text", text: targetGoneText(args.url, gone, out) }] };
|
|
269
|
+
}
|
|
232
270
|
return { content: [{ type: "text", text: out }] };
|
|
233
271
|
} catch (err) {
|
|
234
|
-
return
|
|
272
|
+
return errorResult(args.url, err);
|
|
235
273
|
}
|
|
236
274
|
}
|
|
237
275
|
);
|
|
@@ -258,7 +296,7 @@ server.registerTool(
|
|
|
258
296
|
content: [{ type: "text", text: JSON.stringify(parsed, null, 2) }]
|
|
259
297
|
};
|
|
260
298
|
} catch (err) {
|
|
261
|
-
return
|
|
299
|
+
return errorResult(args.url, err);
|
|
262
300
|
}
|
|
263
301
|
}
|
|
264
302
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "scrapeunblocker-mcp",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
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) through the ScrapeUnblocker anti-bot API, using your own API key.",
|
|
6
6
|
"keywords": [
|