mcp-scraper 0.32.3 → 0.33.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/README.md +1 -1
- package/dist/bin/api-server.cjs +20 -19
- package/dist/bin/api-server.cjs.map +1 -1
- package/dist/bin/api-server.js +2 -2
- package/dist/bin/mcp-scraper-cli.cjs +5 -5
- package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
- package/dist/bin/mcp-scraper-cli.js +2 -2
- package/dist/bin/mcp-scraper-install.cjs +1 -1
- package/dist/bin/mcp-scraper-install.cjs.map +1 -1
- package/dist/bin/mcp-scraper-install.js +1 -1
- package/dist/bin/mcp-stdio-server.cjs +6 -6
- package/dist/bin/mcp-stdio-server.cjs.map +1 -1
- package/dist/bin/mcp-stdio-server.js +2 -2
- package/dist/bin/paa-harvest.js +1 -1
- package/dist/{chunk-MKZIL4EA.js → chunk-AT2PFWHW.js} +5 -5
- package/dist/chunk-AT2PFWHW.js.map +1 -0
- package/dist/{chunk-AEMABLEL.js → chunk-ERORC7AP.js} +1 -3
- package/dist/chunk-RHD6Z42L.js +7 -0
- package/dist/chunk-RHD6Z42L.js.map +1 -0
- package/dist/{chunk-GNRHBIYZ.js → chunk-Z3KL7WQ5.js} +7 -7
- package/dist/chunk-Z3KL7WQ5.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/{server-NHLEIKDZ.js → server-M5N6JVZ5.js} +15 -15
- package/dist/server-M5N6JVZ5.js.map +1 -0
- package/dist/{worker-ZZCZNY3R.js → worker-JU5FX3NE.js} +2 -2
- package/docs/adr/0003-waive-unrecoverable-scheduled-model-cost.md +22 -0
- package/docs/adr/README.md +1 -0
- package/docs/mcp-tool-manifest.generated.json +7 -12
- package/package.json +1 -1
- package/dist/chunk-GNRHBIYZ.js.map +0 -1
- package/dist/chunk-MKZIL4EA.js.map +0 -1
- package/dist/chunk-XF46AB5C.js +0 -7
- package/dist/chunk-XF46AB5C.js.map +0 -1
- package/dist/server-NHLEIKDZ.js.map +0 -1
- /package/dist/{chunk-AEMABLEL.js.map → chunk-ERORC7AP.js.map} +0 -0
- /package/dist/{worker-ZZCZNY3R.js.map → worker-JU5FX3NE.js.map} +0 -0
package/README.md
CHANGED
|
@@ -88,7 +88,7 @@ Build the branded one-click bundle:
|
|
|
88
88
|
npm run build:mcpb
|
|
89
89
|
```
|
|
90
90
|
|
|
91
|
-
The generated bundle is written to `build/mcpb/mcp-scraper-<version>.mcpb` and copied to `public/downloads/` for the hosted download. The current public bundle is `https://mcpscraper.dev/downloads/mcp-scraper.mcpb` (`0.
|
|
91
|
+
The generated bundle is written to `build/mcpb/mcp-scraper-<version>.mcpb` and copied to `public/downloads/` for the hosted download. The current public bundle is `https://mcpscraper.dev/downloads/mcp-scraper.mcpb` (`0.33.1`, SHA-256 `c9122255263b899e7ac95825d0212c54f63059be0370dabd67aea57af82f5754`). Install it by opening or dragging it into Claude Desktop. Claude displays the `MCP Scraper` install card, icon, and API-key configuration field from the bundle manifest.
|
|
92
92
|
|
|
93
93
|
The MCPB install exposes every tool — web-intelligence plus all `browser_*` tools — through the one `mcp-scraper` server.
|
|
94
94
|
|
package/dist/bin/api-server.cjs
CHANGED
|
@@ -15945,7 +15945,7 @@ var init_server_schemas = __esm({
|
|
|
15945
15945
|
gl: import_zod15.z.string().optional(),
|
|
15946
15946
|
hl: import_zod15.z.string().optional(),
|
|
15947
15947
|
device: import_zod15.z.enum(["desktop", "mobile"]).optional(),
|
|
15948
|
-
proxyMode: import_zod15.z.enum(["
|
|
15948
|
+
proxyMode: import_zod15.z.enum(["configured", "none"]).optional(),
|
|
15949
15949
|
proxyZip: import_zod15.z.string().regex(/^\d{5}$/).optional(),
|
|
15950
15950
|
debug: import_zod15.z.boolean().optional(),
|
|
15951
15951
|
serpOnly: import_zod15.z.boolean().optional(),
|
|
@@ -19253,13 +19253,11 @@ var init_video_routes = __esm({
|
|
|
19253
19253
|
function buildGoogleLocalResultsUrl(input) {
|
|
19254
19254
|
const query = [input.query, input.location].filter(Boolean).join(" ");
|
|
19255
19255
|
const params = new URLSearchParams({ q: query, udm: "1", gl: input.gl, hl: input.hl, pws: "0" });
|
|
19256
|
-
if (input.location) params.set("uule", encodeUule(normalizeLocation(input.location)));
|
|
19257
19256
|
return `https://www.google.com/search?${params.toString()}`;
|
|
19258
19257
|
}
|
|
19259
19258
|
function buildGoogleOrganicSearchUrl(input) {
|
|
19260
19259
|
const query = [input.query, input.location].filter(Boolean).join(" ");
|
|
19261
19260
|
const params = new URLSearchParams({ q: query, gl: input.gl, hl: input.hl, pws: "0" });
|
|
19262
|
-
if (input.location) params.set("uule", encodeUule(normalizeLocation(input.location)));
|
|
19263
19261
|
return `https://www.google.com/search?${params.toString()}`;
|
|
19264
19262
|
}
|
|
19265
19263
|
function mapsIdentifiersFromUrl(url) {
|
|
@@ -19284,7 +19282,6 @@ var init_MapsSearchExtractor = __esm({
|
|
|
19284
19282
|
"use strict";
|
|
19285
19283
|
init_errors();
|
|
19286
19284
|
init_BrowserDriver();
|
|
19287
|
-
init_uule();
|
|
19288
19285
|
LOCAL_RESULTS_PAGE_LIMIT = 8;
|
|
19289
19286
|
LOCAL_RESULTS_WAIT_MS = 1e3;
|
|
19290
19287
|
MAPS_REDIRECT_BASE = "https://serp-redirector.vercel.app";
|
|
@@ -20092,7 +20089,9 @@ var init_MapsExtractor = __esm({
|
|
|
20092
20089
|
|
|
20093
20090
|
// src/maps-search-rotation.ts
|
|
20094
20091
|
function mapsSearchMaxAttemptsForProxyMode(proxyMode) {
|
|
20095
|
-
|
|
20092
|
+
if (proxyMode === "location") return MAPS_SEARCH_LOCATION_PROXY_MAX_ATTEMPTS;
|
|
20093
|
+
if (proxyMode === "none") return MAPS_SEARCH_NONE_MAX_ATTEMPTS;
|
|
20094
|
+
return MAPS_SEARCH_MAX_ATTEMPTS;
|
|
20096
20095
|
}
|
|
20097
20096
|
function mapsSearchErrorMessage(err) {
|
|
20098
20097
|
return sanitizeVendorName(err instanceof Error ? err.message : String(err));
|
|
@@ -20163,6 +20162,7 @@ async function cleanupDisposableProxy(kernelApiKey, proxyId, eventName) {
|
|
|
20163
20162
|
}
|
|
20164
20163
|
}
|
|
20165
20164
|
async function runMapsSearchWithRotation(options) {
|
|
20165
|
+
if (options.proxyMode === "location") options = { ...options, proxyMode: "none" };
|
|
20166
20166
|
const attempts = [];
|
|
20167
20167
|
const maxAttempts = mapsSearchMaxAttemptsForProxyMode(options.proxyMode) + 1;
|
|
20168
20168
|
const started = Date.now();
|
|
@@ -20191,8 +20191,8 @@ async function runMapsSearchWithRotation(options) {
|
|
|
20191
20191
|
proxyZip,
|
|
20192
20192
|
kernelProxyId: options.proxyMode === "none" ? void 0 : resolution2.kernelProxyId,
|
|
20193
20193
|
kernelProxyResolution: resolution2.resolution,
|
|
20194
|
-
serpRedirect: options.proxyMode === "none" && attemptIndex >=
|
|
20195
|
-
forceDirectEgress: options.proxyMode === "none" && attemptIndex >=
|
|
20194
|
+
serpRedirect: options.proxyMode === "none" && attemptIndex >= 2 && attemptIndex < 6,
|
|
20195
|
+
forceDirectEgress: options.proxyMode === "none" && attemptIndex >= 4
|
|
20196
20196
|
};
|
|
20197
20197
|
const isHeadfulEscalation = attemptIndex === maxAttempts - 1;
|
|
20198
20198
|
const baseCtx = currentCostContext();
|
|
@@ -20267,7 +20267,7 @@ async function runMapsSearchWithRotation(options) {
|
|
|
20267
20267
|
true
|
|
20268
20268
|
);
|
|
20269
20269
|
}
|
|
20270
|
-
var MAPS_SEARCH_MAX_ATTEMPTS, MAPS_SEARCH_LOCATION_PROXY_MAX_ATTEMPTS, MapsSearchRotationError;
|
|
20270
|
+
var MAPS_SEARCH_MAX_ATTEMPTS, MAPS_SEARCH_NONE_MAX_ATTEMPTS, MAPS_SEARCH_LOCATION_PROXY_MAX_ATTEMPTS, MapsSearchRotationError;
|
|
20271
20271
|
var init_maps_search_rotation = __esm({
|
|
20272
20272
|
"src/maps-search-rotation.ts"() {
|
|
20273
20273
|
"use strict";
|
|
@@ -20277,6 +20277,7 @@ var init_maps_search_rotation = __esm({
|
|
|
20277
20277
|
init_kernel_proxy_resolver();
|
|
20278
20278
|
init_cost_context();
|
|
20279
20279
|
MAPS_SEARCH_MAX_ATTEMPTS = 3;
|
|
20280
|
+
MAPS_SEARCH_NONE_MAX_ATTEMPTS = 7;
|
|
20280
20281
|
MAPS_SEARCH_LOCATION_PROXY_MAX_ATTEMPTS = 5;
|
|
20281
20282
|
MapsSearchRotationError = class extends Error {
|
|
20282
20283
|
constructor(message, attempts, retryable, errorCode = "maps_search_failed") {
|
|
@@ -24138,7 +24139,7 @@ var init_directory_workflow = __esm({
|
|
|
24138
24139
|
saveCsv: import_zod26.z.boolean().default(true),
|
|
24139
24140
|
gl: import_zod26.z.string().length(2).default("us"),
|
|
24140
24141
|
hl: import_zod26.z.string().length(2).default("en"),
|
|
24141
|
-
proxyMode: import_zod26.z.enum(["
|
|
24142
|
+
proxyMode: import_zod26.z.enum(["configured", "none"]).default(DEFAULT_MAPS_PROXY_MODE),
|
|
24142
24143
|
proxyZip: import_zod26.z.string().regex(/^\d{5}$/).optional(),
|
|
24143
24144
|
debug: import_zod26.z.boolean().default(false),
|
|
24144
24145
|
headless: import_zod26.z.boolean().default(true),
|
|
@@ -24794,7 +24795,7 @@ var init_directory = __esm({
|
|
|
24794
24795
|
maxCities: import_zod28.z.number().int().min(1).max(100).default(25),
|
|
24795
24796
|
maxResultsPerCity: import_zod28.z.number().int().min(1).max(50).default(20),
|
|
24796
24797
|
concurrency: import_zod28.z.number().int().min(1).max(5).default(5),
|
|
24797
|
-
proxyMode: import_zod28.z.enum(["
|
|
24798
|
+
proxyMode: import_zod28.z.enum(["configured", "none"]).default(DEFAULT_MAPS_PROXY_MODE),
|
|
24798
24799
|
saveCsv: import_zod28.z.boolean().default(true)
|
|
24799
24800
|
});
|
|
24800
24801
|
DIRECTORY_CSV_HEADERS = [
|
|
@@ -24949,7 +24950,7 @@ var init_get_leads = __esm({
|
|
|
24949
24950
|
enrichWebsites: import_zod29.z.boolean().default(true).describe("Visit each business website (home + contact pages) to harvest email and social links. Uses the proxy/browser-backed extractor so blocked sites still resolve."),
|
|
24950
24951
|
hydrateReviewCounts: import_zod29.z.boolean().default(true).describe("Deep-dive each profile to confirm the review count and booking URL that the Maps search list omits."),
|
|
24951
24952
|
concurrency: import_zod29.z.number().int().min(1).max(4).default(3).describe("How many businesses to enrich in parallel. Keep low to respect per-account concurrency limits."),
|
|
24952
|
-
proxyMode: import_zod29.z.enum(["
|
|
24953
|
+
proxyMode: import_zod29.z.enum(["configured", "none"]).default(DEFAULT_MAPS_PROXY_MODE).describe("Proxy behavior for the Maps search. Leave unset for clean egress; country/region localization comes from gl/hl plus the city or region in the query.")
|
|
24953
24954
|
});
|
|
24954
24955
|
LEADS_CSV_HEADERS = [
|
|
24955
24956
|
"position",
|
|
@@ -25168,7 +25169,7 @@ var init_local_competitive_audit = __esm({
|
|
|
25168
25169
|
hydrateTop: import_zod30.z.number().int().min(0).max(10).default(5),
|
|
25169
25170
|
maxReviews: import_zod30.z.number().int().min(0).max(500).default(50),
|
|
25170
25171
|
concurrency: import_zod30.z.number().int().min(1).max(5).default(5),
|
|
25171
|
-
proxyMode: import_zod30.z.enum(["
|
|
25172
|
+
proxyMode: import_zod30.z.enum(["configured", "none"]).default(DEFAULT_MAPS_PROXY_MODE),
|
|
25172
25173
|
returnPartial: import_zod30.z.boolean().default(true)
|
|
25173
25174
|
});
|
|
25174
25175
|
localCompetitiveAuditWorkflowDefinition = {
|
|
@@ -25621,7 +25622,7 @@ var init_comparison_briefs = __esm({
|
|
|
25621
25622
|
init_directory();
|
|
25622
25623
|
init_seo_workflow_utils();
|
|
25623
25624
|
init_schemas3();
|
|
25624
|
-
ProxyModeSchema = import_zod31.z.enum(["
|
|
25625
|
+
ProxyModeSchema = import_zod31.z.enum(["configured", "none"]);
|
|
25625
25626
|
MapComparisonInputSchema = import_zod31.z.object({
|
|
25626
25627
|
query: import_zod31.z.string().min(1),
|
|
25627
25628
|
location: import_zod31.z.string().optional(),
|
|
@@ -29814,7 +29815,7 @@ var PACKAGE_VERSION;
|
|
|
29814
29815
|
var init_version = __esm({
|
|
29815
29816
|
"src/version.ts"() {
|
|
29816
29817
|
"use strict";
|
|
29817
|
-
PACKAGE_VERSION = "0.
|
|
29818
|
+
PACKAGE_VERSION = "0.33.1";
|
|
29818
29819
|
}
|
|
29819
29820
|
});
|
|
29820
29821
|
|
|
@@ -30278,7 +30279,7 @@ var init_mcp_tool_schemas = __esm({
|
|
|
30278
30279
|
gl: import_zod35.z.string().length(2).default("us").describe("Google country code inferred from location or user language."),
|
|
30279
30280
|
hl: import_zod35.z.string().default("en").describe("Google interface/content language inferred from the user request."),
|
|
30280
30281
|
device: import_zod35.z.enum(["desktop", "mobile"]).default("desktop").describe("SERP device context. Use mobile only for mobile rankings."),
|
|
30281
|
-
proxyMode: import_zod35.z.enum(["
|
|
30282
|
+
proxyMode: import_zod35.z.enum(["configured", "none"]).default(DEFAULT_PROXY_MODE).describe("Leave unset for clean egress (the default). Country/region localization comes from gl/hl plus the city or region in the query \u2014 not from a proxy."),
|
|
30282
30283
|
proxyZip: import_zod35.z.string().regex(/^\d{5}$/).optional().describe('US ZIP for residential geo-IP targeting. Only meaningful with proxyMode "location".'),
|
|
30283
30284
|
debug: import_zod35.z.boolean().default(false).describe("Include sanitized diagnostics for debugging localization, CAPTCHA, or proxy behavior.")
|
|
30284
30285
|
};
|
|
@@ -30447,7 +30448,7 @@ var init_mcp_tool_schemas = __esm({
|
|
|
30447
30448
|
hl: import_zod35.z.string().length(2).default("en").describe("Language inferred from user request."),
|
|
30448
30449
|
maxResults: import_zod35.z.number().int().min(1).max(50).default(10).describe("Number of candidates to return. Default 10, maximum 50."),
|
|
30449
30450
|
includeServices: import_zod35.z.boolean().default(false).describe("Open each returned business profile to include its configured services and areas served when available. Adds a page visit per business; does not collect review cards."),
|
|
30450
|
-
proxyMode: import_zod35.z.enum(["
|
|
30451
|
+
proxyMode: import_zod35.z.enum(["configured", "none"]).default(DEFAULT_MAPS_PROXY_MODE).describe("Leave unset for the default route (stealth browser on the managed ISP proxy, retried on a fresh session when Google blocks). Country/region localization comes from the city or region in the query plus gl/hl \u2014 not from a proxy."),
|
|
30451
30452
|
proxyZip: import_zod35.z.string().regex(/^\d{5}$/).optional().describe("Optional US ZIP override, only used when proxyMode is location."),
|
|
30452
30453
|
debug: import_zod35.z.boolean().default(false).describe("Include sanitized browser/proxy diagnostics.")
|
|
30453
30454
|
};
|
|
@@ -30462,7 +30463,7 @@ var init_mcp_tool_schemas = __esm({
|
|
|
30462
30463
|
includeZipGroups: import_zod35.z.boolean().default(true).describe("Attach ZIP groups from a configured US ZIPS CSV when available (MCP_SCRAPER_USZIPS_CSV_PATH or usZipsCsvPath)."),
|
|
30463
30464
|
usZipsCsvPath: import_zod35.z.string().optional().describe("Local/test-only path to a US ZIPS CSV (state_abbr, zipcode, county, city columns). Deployed APIs should use MCP_SCRAPER_USZIPS_CSV_PATH instead. For ZIP enrichment, set MCP_SCRAPER_USZIPS_CSV_PATH on the server, or pass this in local/test mode."),
|
|
30464
30465
|
saveCsv: import_zod35.z.boolean().default(true).describe("Save a directory-ready CSV of results to the MCP Scraper output directory and return its path."),
|
|
30465
|
-
proxyMode: import_zod35.z.enum(["
|
|
30466
|
+
proxyMode: import_zod35.z.enum(["configured", "none"]).default(DEFAULT_MAPS_PROXY_MODE).describe("Proxy behavior per city search. Leave unset for the default route (stealth browser on the managed ISP proxy, retried fresh on a Google block). Country/region localization comes from the city or region in the query plus gl/hl \u2014 not from a proxy."),
|
|
30466
30467
|
proxyZip: import_zod35.z.string().regex(/^\d{5}$/).optional().describe("Optional ZIP override for proxy targeting; normally omitted."),
|
|
30467
30468
|
debug: import_zod35.z.boolean().default(false).describe("Include sanitized browser/proxy diagnostics.")
|
|
30468
30469
|
};
|
|
@@ -31302,7 +31303,7 @@ var init_mcp_tool_schemas = __esm({
|
|
|
31302
31303
|
gl: import_zod35.z.string().length(2).default("us").describe("Google country code inferred from location or user language."),
|
|
31303
31304
|
hl: import_zod35.z.string().default("en").describe("Google interface/content language inferred from user request."),
|
|
31304
31305
|
device: import_zod35.z.enum(["desktop", "mobile"]).default("desktop").describe("SERP device context. Use mobile only for mobile rankings."),
|
|
31305
|
-
proxyMode: import_zod35.z.enum(["
|
|
31306
|
+
proxyMode: import_zod35.z.enum(["configured", "none"]).default(DEFAULT_PROXY_MODE).describe("Leave unset for clean egress (the default). Country/region localization comes from gl/hl plus the city or region in the query \u2014 not from a proxy."),
|
|
31306
31307
|
proxyZip: import_zod35.z.string().regex(/^\d{5}$/).optional().describe('US ZIP for residential geo-IP targeting. Only meaningful with proxyMode "location".'),
|
|
31307
31308
|
debug: import_zod35.z.boolean().default(false).describe("Include sanitized diagnostics for debugging localization, CAPTCHA, or proxy behavior."),
|
|
31308
31309
|
pages: import_zod35.z.number().int().min(1).max(2).default(1).describe("Number of result pages to fetch (1\u20132).")
|
|
@@ -31313,7 +31314,7 @@ var init_mcp_tool_schemas = __esm({
|
|
|
31313
31314
|
gl: import_zod35.z.string().length(2).default("us").describe("Google country code inferred from the requested market."),
|
|
31314
31315
|
hl: import_zod35.z.string().default("en").describe("Google interface/content language inferred from the user request."),
|
|
31315
31316
|
device: import_zod35.z.enum(["desktop", "mobile"]).default("desktop").describe("SERP device context. Use mobile only for mobile rankings/evidence."),
|
|
31316
|
-
proxyMode: import_zod35.z.enum(["
|
|
31317
|
+
proxyMode: import_zod35.z.enum(["configured", "none"]).default(DEFAULT_PROXY_MODE).describe("Leave unset for clean egress (the default). Country/region localization comes from gl/hl plus the city or region in the query \u2014 not from a proxy."),
|
|
31317
31318
|
proxyZip: import_zod35.z.string().regex(/^\d{5}$/).optional().describe('US ZIP for residential geo-IP targeting. Only meaningful with proxyMode "location".'),
|
|
31318
31319
|
pages: import_zod35.z.number().int().min(1).max(2).default(1).describe("Google result pages to capture. Use 2 only for deeper ranking evidence."),
|
|
31319
31320
|
debug: import_zod35.z.boolean().default(false).describe("Include sanitized browser/proxy/location diagnostics."),
|