mcp-scraper 0.2.14 → 0.2.16

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.
Files changed (33) hide show
  1. package/README.md +6 -5
  2. package/dist/bin/api-server.cjs +321 -29
  3. package/dist/bin/api-server.cjs.map +1 -1
  4. package/dist/bin/api-server.js +1 -1
  5. package/dist/bin/browser-agent-stdio-server.cjs +1 -1
  6. package/dist/bin/browser-agent-stdio-server.cjs.map +1 -1
  7. package/dist/bin/browser-agent-stdio-server.js +2 -2
  8. package/dist/bin/mcp-scraper-cli.cjs +1 -1
  9. package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
  10. package/dist/bin/mcp-scraper-cli.js +1 -1
  11. package/dist/bin/mcp-scraper-combined-stdio-server.cjs +95 -6
  12. package/dist/bin/mcp-scraper-combined-stdio-server.cjs.map +1 -1
  13. package/dist/bin/mcp-scraper-combined-stdio-server.js +3 -3
  14. package/dist/bin/mcp-scraper-install.cjs +4 -4
  15. package/dist/bin/mcp-scraper-install.cjs.map +1 -1
  16. package/dist/bin/mcp-scraper-install.js +4 -4
  17. package/dist/bin/mcp-scraper-install.js.map +1 -1
  18. package/dist/bin/mcp-stdio-server.cjs +95 -6
  19. package/dist/bin/mcp-stdio-server.cjs.map +1 -1
  20. package/dist/bin/mcp-stdio-server.js +2 -2
  21. package/dist/{chunk-ZV2XXYR7.js → chunk-ATJAINML.js} +2 -2
  22. package/dist/{chunk-IWQTNY2E.js → chunk-FMC3V54I.js} +96 -7
  23. package/dist/chunk-FMC3V54I.js.map +1 -0
  24. package/dist/chunk-KE4JZDLV.js +7 -0
  25. package/dist/chunk-KE4JZDLV.js.map +1 -0
  26. package/dist/{server-7QP6HQJJ.js → server-KSEQLZNP.js} +221 -24
  27. package/dist/server-KSEQLZNP.js.map +1 -0
  28. package/package.json +1 -1
  29. package/dist/chunk-IWQTNY2E.js.map +0 -1
  30. package/dist/chunk-ROCXJOVY.js +0 -7
  31. package/dist/chunk-ROCXJOVY.js.map +0 -1
  32. package/dist/server-7QP6HQJJ.js.map +0 -1
  33. /package/dist/{chunk-ZV2XXYR7.js.map → chunk-ATJAINML.js.map} +0 -0
@@ -9,7 +9,7 @@ import {
9
9
  } from "../chunk-F44RBOJ5.js";
10
10
  import {
11
11
  PACKAGE_VERSION
12
- } from "../chunk-ROCXJOVY.js";
12
+ } from "../chunk-KE4JZDLV.js";
13
13
 
14
14
  // src/cli/human-cli.ts
15
15
  import { Command } from "commander";
@@ -108,6 +108,9 @@ var HttpMcpToolExecutor = class {
108
108
  facebookAdTranscribe(input) {
109
109
  return this.call("/facebook/transcribe", input);
110
110
  }
111
+ facebookVideoTranscribe(input) {
112
+ return this.call("/facebook/video-transcribe", input, this.httpTimeoutOverrideMs ?? 24e4);
113
+ }
111
114
  mapsPlaceIntel(input) {
112
115
  return this.call("/maps/place", input);
113
116
  }
@@ -138,7 +141,7 @@ var import_node_os2 = require("os");
138
141
  var import_node_path2 = require("path");
139
142
 
140
143
  // src/version.ts
141
- var PACKAGE_VERSION = "0.2.14";
144
+ var PACKAGE_VERSION = "0.2.16";
142
145
 
143
146
  // src/mcp/browser-agent-tool-schemas.ts
144
147
  var import_zod = require("zod");
@@ -1468,7 +1471,8 @@ ${adBlocks}`,
1468
1471
  `
1469
1472
  ---
1470
1473
  \u{1F4A1} **Tips**
1471
- - Transcribe video ads: use \`facebook_ad_transcribe\` with the \`videoUrl\` above
1474
+ - Transcribe video ads: use \`facebook_ad_transcribe\` with the direct \`videoUrl\` above
1475
+ - Transcribe organic Facebook reels/posts: use \`facebook_video_transcribe\` with the public Facebook URL
1472
1476
  - Find other advertisers: use \`facebook_ad_search\``
1473
1477
  ].filter(Boolean).join("\n");
1474
1478
  return {
@@ -1914,10 +1918,66 @@ ${text}`,
1914
1918
  ${chunkRows}` : "",
1915
1919
  `
1916
1920
  ---
1917
- \u{1F4A1} Get more ads from this advertiser: use \`facebook_page_intel\``
1921
+ \u{1F4A1} Get more ads from this advertiser: use \`facebook_page_intel\`. For public Facebook reel/post URLs, use \`facebook_video_transcribe\`.`
1918
1922
  ].filter(Boolean).join("\n");
1919
1923
  return oneBlock(full);
1920
1924
  }
1925
+ function formatFacebookVideoTranscribe(raw, input) {
1926
+ const parsed = parseData(raw);
1927
+ if ("error" in parsed) return { content: [{ type: "text", text: parsed.error }], isError: true };
1928
+ const d = parsed.data;
1929
+ const text = d.text ?? "";
1930
+ const chunks = d.chunks ?? [];
1931
+ const wordCount = text.trim() ? text.trim().split(/\s+/).length : 0;
1932
+ const durSec = d.durationMs ? (d.durationMs / 1e3).toFixed(0) : "\u2014";
1933
+ const videoDuration = typeof d.videoDurationSec === "number" ? `${Math.round(d.videoDurationSec)}s` : "\u2014";
1934
+ const label = d.videoId ? `Facebook Organic Video \`${d.videoId}\`` : "Facebook Organic Video";
1935
+ const chunkRows = chunks.slice(0, 50).map((c) => {
1936
+ const sec = Number.isFinite(c.timestamp[0]) ? Math.floor(c.timestamp[0]) : 0;
1937
+ const mm = String(Math.floor(sec / 60)).padStart(2, "0");
1938
+ const ss = String(sec % 60).padStart(2, "0");
1939
+ return `| ${mm}:${ss} | ${cell(truncate(c.text, 120))} |`;
1940
+ }).join("\n");
1941
+ const full = [
1942
+ `# ${label} Transcript`,
1943
+ d.ownerName ? `**Owner:** ${d.ownerName}` : "",
1944
+ `**Video duration:** ${videoDuration} \xB7 **Transcribed in:** ${durSec}s \xB7 **${wordCount} words**`,
1945
+ d.pageUrl ? `**Page URL:** ${d.pageUrl}` : `**Page URL:** ${input.url}`,
1946
+ d.videoUrl ? `**Extracted MP4:** \`${d.videoUrl}\`` : "",
1947
+ `
1948
+ ## Full Transcript
1949
+ ${text}`,
1950
+ chunks.length ? `
1951
+ ## Timestamped Chunks
1952
+ | Time | Text |
1953
+ |------|------|
1954
+ ${chunkRows}` : "",
1955
+ `
1956
+ ---
1957
+ \u{1F4A1} Use \`videoUrl\` as the extracted MP4 for download or follow-up processing. Use \`facebook_ad_transcribe\` only for Ad Library videoUrl values.`
1958
+ ].filter(Boolean).join("\n");
1959
+ return {
1960
+ ...oneBlock(full),
1961
+ structuredContent: {
1962
+ sourceUrl: d.sourceUrl ?? input.url,
1963
+ pageUrl: d.pageUrl ?? input.url,
1964
+ videoId: d.videoId ?? null,
1965
+ ownerName: d.ownerName ?? null,
1966
+ selectedQuality: d.selectedQuality ?? input.quality ?? "best",
1967
+ bitrate: typeof d.bitrate === "number" ? d.bitrate : null,
1968
+ videoDurationSec: typeof d.videoDurationSec === "number" ? d.videoDurationSec : null,
1969
+ videoUrl: d.videoUrl ?? "",
1970
+ wordCount,
1971
+ chunkCount: chunks.length,
1972
+ transcriptText: text,
1973
+ chunks: chunks.map((c) => ({
1974
+ startSec: Number.isFinite(c.timestamp[0]) ? c.timestamp[0] : 0,
1975
+ endSec: Number.isFinite(c.timestamp[1]) ? c.timestamp[1] : 0,
1976
+ text: c.text
1977
+ }))
1978
+ }
1979
+ };
1980
+ }
1921
1981
 
1922
1982
  // src/mcp/mcp-tool-schemas.ts
1923
1983
  var import_zod2 = require("zod");
@@ -1971,7 +2031,11 @@ var FacebookAdSearchInputSchema = {
1971
2031
  maxResults: import_zod2.z.number().int().min(1).max(20).default(10)
1972
2032
  };
1973
2033
  var FacebookAdTranscribeInputSchema = {
1974
- videoUrl: import_zod2.z.string().url().describe("Facebook CDN video URL from a facebook_page_intel result")
2034
+ videoUrl: import_zod2.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.")
2035
+ };
2036
+ var FacebookVideoTranscribeInputSchema = {
2037
+ url: import_zod2.z.string().url().describe("Organic Facebook reel, video, watch, post, or share URL from facebook.com, m.facebook.com, or fb.watch. The tool renders the page, extracts the best matching public Facebook CDN MP4 URL, then transcribes it. Use this when the user pastes a normal Facebook video page URL and asks for the transcript or downloadable MP4."),
2038
+ quality: import_zod2.z.enum(["best", "hd", "sd"]).default("best").describe("Preferred progressive MP4 quality. Use best by default; hd prefers the highest HD progressive URL; sd forces the SD URL.")
1975
2039
  };
1976
2040
  var MapsPlaceIntelInputSchema = {
1977
2041
  businessName: import_zod2.z.string().min(1).describe('Business name only. If user says "Elite Roofing Denver CO", use businessName="Elite Roofing" and location="Denver, CO".'),
@@ -2338,6 +2402,24 @@ var FacebookPageIntelOutputSchema = {
2338
2402
  variations: import_zod2.z.number().int().nullable()
2339
2403
  }))
2340
2404
  };
2405
+ var FacebookVideoTranscribeOutputSchema = {
2406
+ sourceUrl: import_zod2.z.string().url(),
2407
+ pageUrl: import_zod2.z.string().url(),
2408
+ videoId: NullableString,
2409
+ ownerName: NullableString,
2410
+ selectedQuality: import_zod2.z.string(),
2411
+ bitrate: import_zod2.z.number().int().nullable(),
2412
+ videoDurationSec: import_zod2.z.number().nullable(),
2413
+ videoUrl: import_zod2.z.string().url(),
2414
+ wordCount: import_zod2.z.number().int().min(0),
2415
+ chunkCount: import_zod2.z.number().int().min(0),
2416
+ transcriptText: import_zod2.z.string(),
2417
+ chunks: import_zod2.z.array(import_zod2.z.object({
2418
+ startSec: import_zod2.z.number(),
2419
+ endSec: import_zod2.z.number(),
2420
+ text: import_zod2.z.string()
2421
+ }))
2422
+ };
2341
2423
  var CreditsInfoInputSchema = {
2342
2424
  item: import_zod2.z.string().optional().describe('Optional tool, action, or feature to look up, e.g. "maps reviews", "extract_url", "YouTube transcription", or "concurrency"'),
2343
2425
  includeLedger: import_zod2.z.boolean().default(false).describe("Whether to include recent credit ledger entries")
@@ -2814,7 +2896,7 @@ function registerPaaExtractorMcpTools(server2, executor, options = {}) {
2814
2896
  }, async (input) => formatYoutubeTranscribe(await executor.youtubeTranscribe(input), input));
2815
2897
  server2.registerTool("facebook_page_intel", {
2816
2898
  title: "Facebook Advertiser Ad Intel",
2817
- description: withReportNote("Harvest ads from a Facebook advertiser. Returns ad copy, headlines, CTAs, creative type, status, landing URLs, and video URLs ready for transcription. Accepts pageId, libraryId, or a brand/advertiser name as query. Use after facebook_ad_search when possible."),
2899
+ description: withReportNote("Harvest ads from a Facebook advertiser. Returns ad copy, headlines, CTAs, creative type, status, landing URLs, and direct ad video URLs ready for facebook_ad_transcribe. Accepts pageId, libraryId, or a brand/advertiser name as query. Use after facebook_ad_search when possible. For normal public Facebook reels/posts/watch/share URLs, use facebook_video_transcribe instead."),
2818
2900
  inputSchema: FacebookPageIntelInputSchema,
2819
2901
  outputSchema: FacebookPageIntelOutputSchema,
2820
2902
  annotations: liveWebToolAnnotations("Facebook Advertiser Ad Intel")
@@ -2828,10 +2910,17 @@ function registerPaaExtractorMcpTools(server2, executor, options = {}) {
2828
2910
  }, async (input) => formatFacebookAdSearch(await executor.facebookAdSearch(input), input));
2829
2911
  server2.registerTool("facebook_ad_transcribe", {
2830
2912
  title: "Facebook Ad Transcription",
2831
- description: "Transcribe audio from a Facebook ad video. Returns full transcript and timestamped chunks. Use the videoUrl value from facebook_page_intel results.",
2913
+ description: "Transcribe audio from a Facebook ad video CDN URL. Returns full transcript and timestamped chunks. Use only with the direct videoUrl value from facebook_page_intel results, not public Facebook post/reel/share URLs.",
2832
2914
  inputSchema: FacebookAdTranscribeInputSchema,
2833
2915
  annotations: liveWebToolAnnotations("Facebook Ad Transcription")
2834
2916
  }, async (input) => formatFacebookAdTranscribe(await executor.facebookAdTranscribe(input), input));
2917
+ server2.registerTool("facebook_video_transcribe", {
2918
+ title: "Facebook Organic Video Transcription",
2919
+ description: withReportNote("Transcribe audio from an organic Facebook reel, video, watch, post, or share URL, including fb.watch links. Use this when the user pastes a normal Facebook video page URL and wants the transcript or downloadable MP4. Renders the Facebook page in a browser, selects the best matching public Facebook CDN MP4 URL from page state, then returns sourceUrl, resolved pageUrl, videoId, ownerName, selectedQuality, bitrate, videoDurationSec, extracted MP4 URL, full transcript, and timestamped chunks."),
2920
+ inputSchema: FacebookVideoTranscribeInputSchema,
2921
+ outputSchema: FacebookVideoTranscribeOutputSchema,
2922
+ annotations: liveWebToolAnnotations("Facebook Organic Video Transcription")
2923
+ }, async (input) => formatFacebookVideoTranscribe(await executor.facebookVideoTranscribe(input), input));
2835
2924
  server2.registerTool("maps_place_intel", {
2836
2925
  title: "Google Maps Business Profile Details",
2837
2926
  description: withReportNote('Extract Google Maps business intelligence for one known/named business: rating, review count, category, address, phone, website, hours, booking URL, review histogram, review topics, about attributes, entity IDs, and optional review cards. Do not use this for category searches, local market prospect lists, or requests for multiple GMB/GBP profiles; use maps_search first for those. Split business name from location (e.g. "Elite Roofing Denver CO" => businessName "Elite Roofing", location "Denver, CO"). Pass includeReviews true when the user asks for reviews/customer pain.'),