mcp-scraper 0.3.42 → 0.3.44
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/bin/api-server.cjs +1469 -1255
- package/dist/bin/api-server.cjs.map +1 -1
- package/dist/bin/api-server.js +2 -2
- package/dist/bin/mcp-scraper-cli.cjs +1 -1
- package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
- package/dist/bin/mcp-scraper-cli.js +1 -1
- 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 +58 -12
- package/dist/bin/mcp-stdio-server.cjs.map +1 -1
- package/dist/bin/mcp-stdio-server.js +2 -2
- package/dist/chunk-3Q2NSHSR.js +7 -0
- package/dist/chunk-3Q2NSHSR.js.map +1 -0
- package/dist/{chunk-KPF64WST.js → chunk-NONBSIES.js} +59 -13
- package/dist/chunk-NONBSIES.js.map +1 -0
- package/dist/{chunk-RXJHXBGG.js → chunk-X53SOJSL.js} +20 -3
- package/dist/chunk-X53SOJSL.js.map +1 -0
- package/dist/{server-CZT7EULY.js → server-AN6QUH6C.js} +503 -368
- package/dist/server-AN6QUH6C.js.map +1 -0
- package/dist/{worker-FNSBPP7Y.js → worker-H4EUD2Q5.js} +2 -2
- package/package.json +4 -2
- package/dist/chunk-KPF64WST.js.map +0 -1
- package/dist/chunk-OUZZNW3I.js +0 -7
- package/dist/chunk-OUZZNW3I.js.map +0 -1
- package/dist/chunk-RXJHXBGG.js.map +0 -1
- package/dist/server-CZT7EULY.js.map +0 -1
- /package/dist/{worker-FNSBPP7Y.js.map → worker-H4EUD2Q5.js.map} +0 -0
|
@@ -5,13 +5,13 @@ import {
|
|
|
5
5
|
registerBrowserAgentMcpTools,
|
|
6
6
|
registerPaaExtractorMcpTools,
|
|
7
7
|
registerSerpIntelligenceCaptureTools
|
|
8
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-NONBSIES.js";
|
|
9
9
|
import {
|
|
10
10
|
renderInstallTerminal
|
|
11
11
|
} from "../chunk-T3VZD2I4.js";
|
|
12
12
|
import {
|
|
13
13
|
PACKAGE_VERSION
|
|
14
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-3Q2NSHSR.js";
|
|
15
15
|
import "../chunk-3PRO376E.js";
|
|
16
16
|
import "../chunk-BP27CZ5Q.js";
|
|
17
17
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/version.ts"],"sourcesContent":["export const PACKAGE_VERSION = '0.3.44'\n"],"mappings":";AAAO,IAAM,kBAAkB;","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
PACKAGE_VERSION
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-3Q2NSHSR.js";
|
|
4
4
|
import {
|
|
5
5
|
browserServiceProfileName,
|
|
6
6
|
browserServiceProfileSaveChanges,
|
|
@@ -2789,14 +2789,14 @@ ${rows}` : ""
|
|
|
2789
2789
|
// src/mcp/mcp-tool-schemas.ts
|
|
2790
2790
|
import { z } from "zod";
|
|
2791
2791
|
var HarvestPaaInputSchema = {
|
|
2792
|
-
query: z.string().min(1).describe('
|
|
2793
|
-
location: z.string().optional().describe('City, region, or country for geo
|
|
2792
|
+
query: z.string().min(1).describe('The search query. For localized results, KEEP the place in the query text \u2014 if the user says "best hvac company in Denver CO", use query="best hvac company Denver CO" (and also set location="Denver, CO"). City-in-query is what localizes results reliably; do not strip it out.'),
|
|
2793
|
+
location: z.string().optional().describe('City, region, or country for geo signals (uule + location evidence), e.g. "Denver, CO", "Tokyo, Japan". Set it alongside a city-in-query wording; on its own it does NOT reliably localize results.'),
|
|
2794
2794
|
maxQuestions: z.number().int().min(1).max(200).default(30).describe("Number of PAA questions to extract. Default 30. Maximum 200. Use 10 for quick probes, 30 for normal research, 100-200 when the user asks for everything/full/deep research. Larger harvests get a longer server time budget (151-200 questions \u2192 up to 280s). Credits are charged by extracted question; unused request hold is refunded."),
|
|
2795
2795
|
gl: z.string().length(2).default("us").describe("Google country code inferred from location or user language. Examples: United States us, United Kingdom gb, Japan jp, Canada ca, Australia au."),
|
|
2796
2796
|
hl: z.string().default("en").describe("Google interface/content language inferred from the user request. Use en unless the user asks for another language or locale."),
|
|
2797
2797
|
device: z.enum(["desktop", "mobile"]).default("desktop").describe("SERP device context. Use desktop by default; use mobile only when the user asks for mobile rankings."),
|
|
2798
|
-
proxyMode: z.enum(["location", "configured", "none"]).default(DEFAULT_PROXY_MODE).describe('Leave unset \u2014
|
|
2799
|
-
proxyZip: z.string().regex(/^\d{5}$/).optional().describe(
|
|
2798
|
+
proxyMode: z.enum(["location", "configured", "none"]).default(DEFAULT_PROXY_MODE).describe('Leave unset (clean egress \u2014 reliable). Do NOT set "location" just because the user named a city; localized results come from city-in-query wording. "location" forces a residential geo-IP for rank-tracking fidelity only, is frequently CAPTCHA-blocked, and should be used only when the user explicitly demands as-seen-from-the-city results and accepts failures.'),
|
|
2799
|
+
proxyZip: z.string().regex(/^\d{5}$/).optional().describe('US ZIP for residential geo-IP targeting. Only meaningful with proxyMode "location" (see its warning); ignored otherwise.'),
|
|
2800
2800
|
debug: z.boolean().default(false).describe("Include sanitized browser/session/location diagnostics in the response. Use true when debugging localization, CAPTCHA, or proxy behavior.")
|
|
2801
2801
|
};
|
|
2802
2802
|
var ExtractUrlInputSchema = {
|
|
@@ -2853,6 +2853,16 @@ var RedditThreadInputSchema = {
|
|
|
2853
2853
|
url: z.string().min(1).describe("A reddit.com thread/post URL (www, old, or new Reddit, or a redd.it link). The service fetches it via old.reddit through a residential proxy and returns the post plus its comment tree."),
|
|
2854
2854
|
maxComments: z.number().int().min(1).max(2e3).optional().describe("Optional cap on comments returned. Omit to return all captured comments.")
|
|
2855
2855
|
};
|
|
2856
|
+
var VideoFrameAnalysisInputSchema = {
|
|
2857
|
+
sourceUrl: z.string().min(1).describe("A DIRECT video file URL (.mp4/.webm/.mov). Not a YouTube/Facebook/Instagram page URL \u2014 resolve those to a direct media URL first. Videos up to 30 minutes are supported."),
|
|
2858
|
+
intervalS: z.number().min(1).max(30).optional().describe("Preferred seconds between sampled frames (1-30, default 2). Automatically widened for long videos so the whole duration is covered within the frame budget."),
|
|
2859
|
+
maxFrames: z.number().int().min(1).max(120).optional().describe("Max frames analyzed (<=120, default 120). Frames are spread evenly across the whole video."),
|
|
2860
|
+
detail: z.enum(["fast", "standard", "deep"]).optional().describe("Analysis depth. Default standard."),
|
|
2861
|
+
vault: z.string().min(1).optional().describe('Memory vault to save the finished breakdown into. Default "Library".')
|
|
2862
|
+
};
|
|
2863
|
+
var VideoFrameAnalysisStatusInputSchema = {
|
|
2864
|
+
runId: z.string().min(1).describe("The runId returned by video_frame_analysis.")
|
|
2865
|
+
};
|
|
2856
2866
|
var FacebookAdTranscribeInputSchema = {
|
|
2857
2867
|
videoUrl: z.string().url().describe("Direct Facebook CDN video URL from a facebook_page_intel ad result. Do not pass a public Facebook reel/post/share URL here; use facebook_video_transcribe for organic Facebook URLs.")
|
|
2858
2868
|
};
|
|
@@ -3282,6 +3292,22 @@ var FacebookAdSearchOutputSchema = {
|
|
|
3282
3292
|
sampleLibraryId: NullableString
|
|
3283
3293
|
}))
|
|
3284
3294
|
};
|
|
3295
|
+
var VideoFrameAnalysisOutputSchema = {
|
|
3296
|
+
ok: z.boolean(),
|
|
3297
|
+
runId: NullableString,
|
|
3298
|
+
status: NullableString,
|
|
3299
|
+
message: NullableString
|
|
3300
|
+
};
|
|
3301
|
+
var VideoFrameAnalysisStatusOutputSchema = {
|
|
3302
|
+
ok: z.boolean(),
|
|
3303
|
+
runId: NullableString,
|
|
3304
|
+
status: NullableString,
|
|
3305
|
+
progress: z.object({ analyzed: z.number().int(), total: z.number().int() }).nullable().optional(),
|
|
3306
|
+
frameCount: z.number().int().nullable().optional(),
|
|
3307
|
+
artifactPath: NullableString,
|
|
3308
|
+
report: NullableString,
|
|
3309
|
+
error: NullableString
|
|
3310
|
+
};
|
|
3285
3311
|
var RedditThreadOutputSchema = {
|
|
3286
3312
|
sourceUrl: NullableString,
|
|
3287
3313
|
oldRedditUrl: NullableString,
|
|
@@ -3629,24 +3655,24 @@ var WorkflowArtifactReadOutputSchema = {
|
|
|
3629
3655
|
text: z.string()
|
|
3630
3656
|
};
|
|
3631
3657
|
var SearchSerpInputSchema = {
|
|
3632
|
-
query: z.string().min(1).describe('
|
|
3633
|
-
location: z.string().optional().describe("City, region, or country for geo-
|
|
3658
|
+
query: z.string().min(1).describe('The search query. For localized results, KEEP the place in the query text \u2014 "best dentist in Brooklyn NY" stays query="best dentist Brooklyn NY" (and also set location="Brooklyn, NY"). City-in-query is what localizes results reliably; do not strip it out.'),
|
|
3659
|
+
location: z.string().optional().describe("City, region, or country for geo signals (uule + location evidence). Set it alongside a city-in-query wording; on its own it does NOT reliably localize results."),
|
|
3634
3660
|
gl: z.string().length(2).default("us").describe("Google country code inferred from location or user language."),
|
|
3635
3661
|
hl: z.string().default("en").describe("Google interface/content language inferred from user request."),
|
|
3636
3662
|
device: z.enum(["desktop", "mobile"]).default("desktop").describe("SERP device context. Use desktop by default; use mobile only when the user asks for mobile rankings."),
|
|
3637
|
-
proxyMode: z.enum(["location", "configured", "none"]).default(DEFAULT_PROXY_MODE).describe('Leave unset \u2014
|
|
3638
|
-
proxyZip: z.string().regex(/^\d{5}$/).optional().describe(
|
|
3663
|
+
proxyMode: z.enum(["location", "configured", "none"]).default(DEFAULT_PROXY_MODE).describe('Leave unset (clean egress \u2014 reliable). Do NOT set "location" just because the user named a city; localized results come from city-in-query wording. "location" forces a residential geo-IP for rank-tracking fidelity only, is frequently CAPTCHA-blocked, and should be used only when the user explicitly demands as-seen-from-the-city results and accepts failures.'),
|
|
3664
|
+
proxyZip: z.string().regex(/^\d{5}$/).optional().describe('US ZIP for residential geo-IP targeting. Only meaningful with proxyMode "location" (see its warning); ignored otherwise.'),
|
|
3639
3665
|
debug: z.boolean().default(false).describe("Include sanitized browser/session/location diagnostics in the response. Use true when debugging localization, CAPTCHA, or proxy behavior."),
|
|
3640
3666
|
pages: z.number().int().min(1).max(2).default(1).describe("Number of result pages to fetch (1\u20132)")
|
|
3641
3667
|
};
|
|
3642
3668
|
var CaptureSerpSnapshotInputSchema = {
|
|
3643
|
-
query: z.string().min(1).describe(
|
|
3669
|
+
query: z.string().min(1).describe('Search query to capture as a structured SERP Intelligence snapshot. For localized captures, KEEP the place in the query text (e.g. "botox clinic austin tx") and also set location; city-in-query is what localizes results reliably.'),
|
|
3644
3670
|
location: z.string().optional().describe("City, region, country, or service area used for localized Google results. MCP Scraper records location evidence; UULE alone is not proof of localization."),
|
|
3645
3671
|
gl: z.string().length(2).default("us").describe("Google country code inferred from the requested market, e.g. us, gb, ca, au."),
|
|
3646
3672
|
hl: z.string().default("en").describe("Google interface/content language inferred from the user request."),
|
|
3647
3673
|
device: z.enum(["desktop", "mobile"]).default("desktop").describe("SERP device context. Use mobile only when the user asks for mobile rankings or mobile SERP evidence."),
|
|
3648
|
-
proxyMode: z.enum(["location", "configured", "none"]).default(DEFAULT_PROXY_MODE).describe('Leave unset \u2014
|
|
3649
|
-
proxyZip: z.string().regex(/^\d{5}$/).optional().describe(
|
|
3674
|
+
proxyMode: z.enum(["location", "configured", "none"]).default(DEFAULT_PROXY_MODE).describe('Leave unset (clean egress \u2014 reliable). Do NOT set "location" just because a city was named; localized captures come from city-in-query wording. "location" forces a residential geo-IP (rank-tracking fidelity only), is frequently CAPTCHA-blocked, and should be used only when the user explicitly needs as-seen-from-the-city evidence and accepts failures.'),
|
|
3675
|
+
proxyZip: z.string().regex(/^\d{5}$/).optional().describe('US ZIP for residential geo-IP targeting. Only meaningful with proxyMode "location" (see its warning); ignored otherwise.'),
|
|
3650
3676
|
pages: z.number().int().min(1).max(2).default(1).describe("Number of Google result pages to capture. Use 1 normally and 2 only when the user needs deeper ranking evidence."),
|
|
3651
3677
|
debug: z.boolean().default(false).describe("Include sanitized browser, proxy, and location diagnostics. Use true when debugging localization, CAPTCHA, proxy selection, or capture reliability."),
|
|
3652
3678
|
includePageSnapshots: z.boolean().default(false).describe("Also capture ranking-page snapshots for selected SERP URLs through the same product capture path."),
|
|
@@ -4148,6 +4174,20 @@ function registerPaaExtractorMcpTools(server, executor, options = {}) {
|
|
|
4148
4174
|
outputSchema: RedditThreadOutputSchema,
|
|
4149
4175
|
annotations: liveWebToolAnnotations("Reddit Thread + Comments")
|
|
4150
4176
|
}, async (input) => formatRedditThread(await executor.redditThread(input), input));
|
|
4177
|
+
server.registerTool("video_frame_analysis", {
|
|
4178
|
+
title: "Video Breakdown (frame-by-frame + transcript)",
|
|
4179
|
+
description: `Produce a deep, structured breakdown of a video: what happens on screen, what is said, how it is paced, and how to make one like it. Use this when the user wants to analyze, break down, study, reverse-engineer, or "figure out how they made" a video (an ad, a YouTube video, a reel, a competitor's content). It samples up to 120 frames spread across the whole video (up to 30 minutes), runs vision AI on every frame, transcribes the audio, and returns a report with: Summary, Pacing & Energy, Words-per-Minute & delivery, Topic Outline, Key Points, Hook Analysis, Visual Style, and a step-by-step "How to Replicate This Video" recipe \u2014 all quality-checked. Pass a DIRECT video file URL (.mp4/.webm/.mov); for a YouTube/Facebook/Instagram link, resolve it to a direct media URL first (e.g. facebook_page_intel returns a videoUrl). This runs asynchronously and costs a flat $1 (refunded if it fails): it returns a runId immediately \u2014 then call video_frame_analysis_status with that runId every few seconds until status is "done" to get the finished report.`,
|
|
4180
|
+
inputSchema: VideoFrameAnalysisInputSchema,
|
|
4181
|
+
outputSchema: VideoFrameAnalysisOutputSchema,
|
|
4182
|
+
annotations: { title: "Video Breakdown", readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true }
|
|
4183
|
+
}, async (input) => executor.videoFrameAnalysis(input));
|
|
4184
|
+
server.registerTool("video_frame_analysis_status", {
|
|
4185
|
+
title: "Video Breakdown Status",
|
|
4186
|
+
description: 'Check the progress of a video breakdown started with video_frame_analysis, using the runId it returned. Poll this every few seconds. While running it reports the current phase and how many frames have been analyzed; when status is "done" it returns the full breakdown report (Markdown) and the memory vault path where it was saved. Free to call. Stop polling when status is "done" or "failed".',
|
|
4187
|
+
inputSchema: VideoFrameAnalysisStatusInputSchema,
|
|
4188
|
+
outputSchema: VideoFrameAnalysisStatusOutputSchema,
|
|
4189
|
+
annotations: { title: "Video Breakdown Status", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }
|
|
4190
|
+
}, async (input) => executor.videoFrameAnalysisStatus(input));
|
|
4151
4191
|
server.registerTool("facebook_ad_transcribe", {
|
|
4152
4192
|
title: "Facebook Ad Transcription",
|
|
4153
4193
|
description: "Transcribe audio from a Facebook ad video CDN URL. Use this when facebook_page_intel returned a direct videoUrl and the user asks what the ad says, what claims it makes, or wants ad-message extraction. Returns full transcript, timestamped chunks, word count, and resolvedInputs. Use only with the direct videoUrl value from facebook_page_intel results; do not pass public Facebook post/reel/share URLs. Use facebook_video_transcribe for organic Facebook URLs, and facebook_page_intel first when you only have a brand/page/ad library handle.",
|
|
@@ -4489,6 +4529,12 @@ var HttpMcpToolExecutor = class {
|
|
|
4489
4529
|
redditThread(input) {
|
|
4490
4530
|
return this.call("/reddit/thread", input, this.httpTimeoutOverrideMs ?? 24e4);
|
|
4491
4531
|
}
|
|
4532
|
+
videoFrameAnalysis(input) {
|
|
4533
|
+
return this.call("/video/analyze", input);
|
|
4534
|
+
}
|
|
4535
|
+
videoFrameAnalysisStatus(input) {
|
|
4536
|
+
return this.call("/video/status", input);
|
|
4537
|
+
}
|
|
4492
4538
|
facebookAdTranscribe(input) {
|
|
4493
4539
|
return this.call("/facebook/transcribe", input);
|
|
4494
4540
|
}
|
|
@@ -6048,4 +6094,4 @@ export {
|
|
|
6048
6094
|
exportFanout,
|
|
6049
6095
|
registerBrowserAgentMcpTools
|
|
6050
6096
|
};
|
|
6051
|
-
//# sourceMappingURL=chunk-
|
|
6097
|
+
//# sourceMappingURL=chunk-NONBSIES.js.map
|