mcp-scraper 0.43.2 → 0.43.4

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 (39) hide show
  1. package/README.md +1 -1
  2. package/dist/bin/api-server.cjs +92 -52
  3. package/dist/bin/api-server.cjs.map +1 -1
  4. package/dist/bin/api-server.js +2 -2
  5. package/dist/bin/mcp-scraper-cli.cjs +1 -1
  6. package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
  7. package/dist/bin/mcp-scraper-cli.js +1 -1
  8. package/dist/bin/mcp-scraper-install.cjs +1 -1
  9. package/dist/bin/mcp-scraper-install.cjs.map +1 -1
  10. package/dist/bin/mcp-scraper-install.js +1 -1
  11. package/dist/bin/mcp-stdio-server.cjs +1 -1
  12. package/dist/bin/mcp-stdio-server.cjs.map +1 -1
  13. package/dist/bin/mcp-stdio-server.js +3 -3
  14. package/dist/bin/paa-harvest.cjs +42 -22
  15. package/dist/bin/paa-harvest.cjs.map +1 -1
  16. package/dist/bin/paa-harvest.js +2 -2
  17. package/dist/{chunk-H7LQ6PTI.js → chunk-6TAQ2MXK.js} +50 -24
  18. package/dist/chunk-6TAQ2MXK.js.map +1 -0
  19. package/dist/{chunk-YJNGNMDO.js → chunk-SXLQZKWC.js} +3 -3
  20. package/dist/chunk-XQIVXIAL.js +7 -0
  21. package/dist/chunk-XQIVXIAL.js.map +1 -0
  22. package/dist/{chunk-DAS7L4SF.js → chunk-ZDVQARDQ.js} +3 -1
  23. package/dist/chunk-ZDVQARDQ.js.map +1 -0
  24. package/dist/index.cjs +42 -22
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.cts +1 -1
  27. package/dist/index.d.ts +1 -1
  28. package/dist/index.js +2 -2
  29. package/dist/{server-BPEXEKA6.js → server-K76DL4S7.js} +39 -32
  30. package/dist/server-K76DL4S7.js.map +1 -0
  31. package/dist/{worker-2LIOH744.js → worker-OB6WSWOD.js} +3 -3
  32. package/package.json +2 -1
  33. package/dist/chunk-DAS7L4SF.js.map +0 -1
  34. package/dist/chunk-H7LQ6PTI.js.map +0 -1
  35. package/dist/chunk-MD75M2L5.js +0 -7
  36. package/dist/chunk-MD75M2L5.js.map +0 -1
  37. package/dist/server-BPEXEKA6.js.map +0 -1
  38. /package/dist/{chunk-YJNGNMDO.js.map → chunk-SXLQZKWC.js.map} +0 -0
  39. /package/dist/{worker-2LIOH744.js.map → worker-OB6WSWOD.js.map} +0 -0
package/dist/index.d.cts CHANGED
@@ -150,7 +150,7 @@ interface BrowserContextDebug {
150
150
  };
151
151
  locale: string;
152
152
  device: SerpDevice;
153
- userAgent: string;
153
+ userAgent: string | null;
154
154
  deviceScaleFactor: number | null;
155
155
  isMobile: boolean;
156
156
  hasTouch: boolean;
package/dist/index.d.ts CHANGED
@@ -150,7 +150,7 @@ interface BrowserContextDebug {
150
150
  };
151
151
  locale: string;
152
152
  device: SerpDevice;
153
- userAgent: string;
153
+ userAgent: string | null;
154
154
  deviceScaleFactor: number | null;
155
155
  isMobile: boolean;
156
156
  hasTouch: boolean;
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  harvest
3
- } from "./chunk-H7LQ6PTI.js";
3
+ } from "./chunk-6TAQ2MXK.js";
4
4
  import {
5
5
  recordVendorUsage
6
- } from "./chunk-DAS7L4SF.js";
6
+ } from "./chunk-ZDVQARDQ.js";
7
7
  import "./chunk-3ZUBQQPQ.js";
8
8
  import "./chunk-5UN33CGU.js";
9
9
  import "./chunk-FCFQ634B.js";
@@ -35,13 +35,16 @@ import {
35
35
  cleanupBackupProxyId,
36
36
  createBackupProxyIdSafe,
37
37
  deleteKernelProxyId,
38
+ detectPageUserAgent,
39
+ detectRuntimeUserAgent,
38
40
  encodeUule,
39
41
  harvest,
40
42
  normalizeLocation,
41
43
  resolveBackupKernelProxyId,
42
44
  resolveKernelProxyId,
43
- serpArrivalUrl
44
- } from "./chunk-H7LQ6PTI.js";
45
+ serpArrivalUrl,
46
+ withRuntimeUserAgent
47
+ } from "./chunk-6TAQ2MXK.js";
45
48
  import {
46
49
  ApiErrorResponseSchema,
47
50
  ArtifactTemplateConfigSchema,
@@ -83,7 +86,7 @@ import {
83
86
  renewDirectoryArtifactDownload,
84
87
  resolveDeploymentProfile,
85
88
  transcribeMediaUrl
86
- } from "./chunk-YJNGNMDO.js";
89
+ } from "./chunk-SXLQZKWC.js";
87
90
  import {
88
91
  auditImageUrls,
89
92
  auditImages,
@@ -111,7 +114,7 @@ import {
111
114
  recordKernelSession,
112
115
  recordVendorUsage,
113
116
  runWithCostContext
114
- } from "./chunk-DAS7L4SF.js";
117
+ } from "./chunk-ZDVQARDQ.js";
115
118
  import {
116
119
  listWorkflowDefinitions,
117
120
  runWorkflow,
@@ -139,7 +142,7 @@ import {
139
142
  } from "./chunk-3ZUBQQPQ.js";
140
143
  import {
141
144
  PACKAGE_VERSION
142
- } from "./chunk-MD75M2L5.js";
145
+ } from "./chunk-XQIVXIAL.js";
143
146
  import {
144
147
  abandonExtractSettlement,
145
148
  countSuccessfulPages,
@@ -3749,10 +3752,10 @@ async function fetchWithKernel(url) {
3749
3752
  const kb = await client2.browsers.create({ stealth: true, ...useHeadless ? { headless: true } : {}, timeout_seconds: 60 });
3750
3753
  const browser = await chromium.connectOverCDP(kb.cdp_ws_url);
3751
3754
  try {
3752
- const context = await browser.newContext({
3753
- userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
3755
+ const runtimeUserAgent = await detectRuntimeUserAgent(browser);
3756
+ const context = await browser.newContext(withRuntimeUserAgent({
3754
3757
  serviceWorkers: "block"
3755
- });
3758
+ }, runtimeUserAgent));
3756
3759
  const page = context.pages()[0] ?? await context.newPage();
3757
3760
  const guard = await installBrowserRequestGuard(page, auditedUrl);
3758
3761
  await page.goto(auditedUrl, { waitUntil: "domcontentloaded", timeout: 3e4 });
@@ -4296,8 +4299,6 @@ async function extractBrandingFromPage(page) {
4296
4299
  // src/lib/screenshot.ts
4297
4300
  var DESKTOP_VIEWPORT = { width: 1440, height: 900 };
4298
4301
  var MOBILE_VIEWPORT = { width: 390, height: 844 };
4299
- var DESKTOP_UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36";
4300
- var MOBILE_UA = "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1";
4301
4302
  var SCROLL_STEP = 900;
4302
4303
  var SETTLE_MS = 400;
4303
4304
  async function scrollAndStitch(page, device = "desktop") {
@@ -4348,14 +4349,13 @@ async function scrollAndStitch(page, device = "desktop") {
4348
4349
  }
4349
4350
  async function captureLocal(url, device, wantScreenshot, wantBranding) {
4350
4351
  const vp = device === "mobile" ? MOBILE_VIEWPORT : DESKTOP_VIEWPORT;
4351
- const ua = device === "mobile" ? MOBILE_UA : DESKTOP_UA;
4352
4352
  const browser = await chromium2.launch({ headless: true });
4353
- const context = await browser.newContext({
4353
+ const runtimeUserAgent = await detectRuntimeUserAgent(browser);
4354
+ const context = await browser.newContext(withRuntimeUserAgent({
4354
4355
  viewport: vp,
4355
4356
  locale: "en-US",
4356
- userAgent: ua,
4357
4357
  isMobile: device === "mobile"
4358
- });
4358
+ }, runtimeUserAgent));
4359
4359
  const page = await context.newPage();
4360
4360
  try {
4361
4361
  await page.goto(url, { waitUntil: "networkidle", timeout: 6e4 });
@@ -4374,12 +4374,11 @@ async function captureKernel(url, kernelApiKey, device, wantScreenshot, wantBran
4374
4374
  const session = await kernel.browsers.create({ stealth: true, timeout_seconds: 240 });
4375
4375
  const browser = await chromium2.connectOverCDP(session.cdp_ws_url);
4376
4376
  const vp = device === "mobile" ? MOBILE_VIEWPORT : DESKTOP_VIEWPORT;
4377
- const ua = device === "mobile" ? MOBILE_UA : DESKTOP_UA;
4378
- const context = browser.contexts()[0] ?? await browser.newContext({
4377
+ const runtimeUserAgent = await detectRuntimeUserAgent(browser);
4378
+ const context = browser.contexts()[0] ?? await browser.newContext(withRuntimeUserAgent({
4379
4379
  viewport: vp,
4380
- userAgent: ua,
4381
4380
  isMobile: device === "mobile"
4382
- });
4381
+ }, runtimeUserAgent));
4383
4382
  const page = context.pages()[0] ?? await context.newPage();
4384
4383
  try {
4385
4384
  await page.goto(url, { waitUntil: "networkidle", timeout: 6e4 });
@@ -4885,6 +4884,7 @@ async function crawlWithRotation(urls, opts) {
4885
4884
  const worker = async () => {
4886
4885
  let kb = null;
4887
4886
  let browser = null;
4887
+ let runtimeUserAgent = null;
4888
4888
  let inBrowser = 0;
4889
4889
  let kbOpenedAtMs = 0;
4890
4890
  const retire = async () => {
@@ -4892,6 +4892,7 @@ async function crawlWithRotation(urls, opts) {
4892
4892
  browser = null;
4893
4893
  kb = null;
4894
4894
  kbOpenedAtMs = 0;
4895
+ runtimeUserAgent = null;
4895
4896
  if (b) await b.close().catch(() => {
4896
4897
  });
4897
4898
  if (k) {
@@ -4913,9 +4914,10 @@ async function crawlWithRotation(urls, opts) {
4913
4914
  kb = await createBrowserWithRetry(client2, headless);
4914
4915
  kbOpenedAtMs = Date.now();
4915
4916
  browser = await withTimeout(chromium3.connectOverCDP(kb.cdp_ws_url), 3e4);
4917
+ runtimeUserAgent = await detectRuntimeUserAgent(browser);
4916
4918
  inBrowser = 0;
4917
4919
  }
4918
- const context = await browser.newContext({ serviceWorkers: "block" });
4920
+ const context = await browser.newContext(withRuntimeUserAgent({ serviceWorkers: "block" }, runtimeUserAgent));
4919
4921
  try {
4920
4922
  r = await crawlPage(context, url);
4921
4923
  } finally {
@@ -16681,7 +16683,6 @@ facebookAdApp.post("/media", createApiKeyAuth(), async (c) => {
16681
16683
  try {
16682
16684
  res = await fetch(parsedUrl.href, {
16683
16685
  headers: {
16684
- "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
16685
16686
  "Referer": "https://www.facebook.com/"
16686
16687
  },
16687
16688
  signal: AbortSignal.timeout(6e4)
@@ -17998,10 +17999,10 @@ function blobKeyPrefix(shortcode, sourceUrl) {
17998
17999
  const slug = shortcode ? `instagram-${shortcode}` : safeFilePart(sourceUrl);
17999
18000
  return `instagram/${stamp}-${slug}`;
18000
18001
  }
18001
- async function fetchMediaBytes(url, referer) {
18002
+ async function fetchMediaBytes(url, referer, runtimeUserAgent) {
18002
18003
  const res = await fetch(url, {
18003
18004
  headers: {
18004
- "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
18005
+ ...runtimeUserAgent ? { "User-Agent": runtimeUserAgent } : {},
18005
18006
  "Referer": referer
18006
18007
  },
18007
18008
  signal: AbortSignal.timeout(9e4)
@@ -18121,6 +18122,7 @@ instagramApp.post("/media-download", createApiKeyAuth(), async (c) => {
18121
18122
  const launch = await resolveInstagramLaunch(body);
18122
18123
  await driver.launch(launch.config);
18123
18124
  const page = driver.getPage();
18125
+ const runtimeUserAgent = await detectPageUserAgent(page);
18124
18126
  const capturedMediaUrls = [];
18125
18127
  page.on("response", (response) => {
18126
18128
  const url = normalizeInstagramMediaUrl(response.url());
@@ -18149,7 +18151,7 @@ instagramApp.post("/media-download", createApiKeyAuth(), async (c) => {
18149
18151
  downloads.push({ kind: "text", url: null, savedPath: storedText.url, sizeBytes: storedText.bytes, mimeType: "text/plain", error: null });
18150
18152
  if (mediaTypes.has("image") && extraction.imageUrl) {
18151
18153
  try {
18152
- const { bytes, mimeType } = await fetchMediaBytes(extraction.imageUrl, extraction.pageUrl);
18154
+ const { bytes, mimeType } = await fetchMediaBytes(extraction.imageUrl, extraction.pageUrl, runtimeUserAgent);
18153
18155
  const ext = extFromMime(mimeType, "jpg");
18154
18156
  const stored = await store.put(`${prefix}/image.${ext}`, bytes, mimeType ?? "application/octet-stream");
18155
18157
  downloads.push({ kind: "image", url: extraction.imageUrl, savedPath: stored.url, sizeBytes: stored.bytes, mimeType, error: null });
@@ -18165,7 +18167,7 @@ instagramApp.post("/media-download", createApiKeyAuth(), async (c) => {
18165
18167
  if (track.streamType === "audio" && !mediaTypes.has("audio")) continue;
18166
18168
  const kind = track.streamType === "audio" ? "audio" : "video";
18167
18169
  try {
18168
- const { bytes, mimeType } = await fetchMediaBytes(track.url, extraction.pageUrl);
18170
+ const { bytes, mimeType } = await fetchMediaBytes(track.url, extraction.pageUrl, runtimeUserAgent);
18169
18171
  const stored = await store.put(`${prefix}/${trackFilename(track, index, extraction.shortcode)}`, bytes, mimeType ?? "video/mp4");
18170
18172
  downloads.push({ kind, url: track.url, savedPath: stored.url, sizeBytes: stored.bytes, mimeType, error: null });
18171
18173
  const isMuxInput = muxEligible && (track.url === extraction.selectedVideoTrack.url || track.url === extraction.selectedAudioTrack.url);
@@ -24041,6 +24043,12 @@ async function runFanoutCapture(page, input) {
24041
24043
  // src/services/browser-agent/browser-agent-service.ts
24042
24044
  function keepHostedBrowserAlive(_browser) {
24043
24045
  }
24046
+ async function currentOrRuntimeContext(browser) {
24047
+ const current = browser.contexts()[0];
24048
+ if (current) return current;
24049
+ const runtimeUserAgent = await detectRuntimeUserAgent(browser);
24050
+ return browser.newContext(withRuntimeUserAgent({}, runtimeUserAgent));
24051
+ }
24044
24052
  var DEFAULT_TIMEOUT_SECONDS = 600;
24045
24053
  function client() {
24046
24054
  const apiKey = browserServiceApiKey();
@@ -24165,7 +24173,7 @@ async function pressKeys(runtimeSessionId, keys) {
24165
24173
  async function goto(cdpWsUrl, url) {
24166
24174
  const browser = await playwrightChromium.connectOverCDP(cdpWsUrl);
24167
24175
  try {
24168
- const context = browser.contexts()[0] ?? await browser.newContext();
24176
+ const context = await currentOrRuntimeContext(browser);
24169
24177
  const page = context.pages()[0] ?? await context.newPage();
24170
24178
  await page.goto(url, { waitUntil: "domcontentloaded", timeout: 45e3 });
24171
24179
  return { url: page.url(), title: await page.title() };
@@ -24176,7 +24184,7 @@ async function goto(cdpWsUrl, url) {
24176
24184
  async function captureFanout(cdpWsUrl, input) {
24177
24185
  const browser = await playwrightChromium.connectOverCDP(cdpWsUrl);
24178
24186
  try {
24179
- const context = browser.contexts()[0] ?? await browser.newContext();
24187
+ const context = await currentOrRuntimeContext(browser);
24180
24188
  const page = context.pages()[0] ?? await context.newPage();
24181
24189
  return await runFanoutCapture(page, input);
24182
24190
  } finally {
@@ -24186,7 +24194,7 @@ async function captureFanout(cdpWsUrl, input) {
24186
24194
  async function readPage(cdpWsUrl) {
24187
24195
  const browser = await playwrightChromium.connectOverCDP(cdpWsUrl);
24188
24196
  try {
24189
- const context = browser.contexts()[0] ?? await browser.newContext();
24197
+ const context = await currentOrRuntimeContext(browser);
24190
24198
  const page = context.pages()[0] ?? await context.newPage();
24191
24199
  const url = page.url();
24192
24200
  const title = await page.title().catch(() => "");
@@ -24241,7 +24249,7 @@ async function readPage(cdpWsUrl) {
24241
24249
  async function locatePageTargets(cdpWsUrl, targets) {
24242
24250
  const browser = await playwrightChromium.connectOverCDP(cdpWsUrl);
24243
24251
  try {
24244
- const context = browser.contexts()[0] ?? await browser.newContext();
24252
+ const context = await currentOrRuntimeContext(browser);
24245
24253
  const page = context.pages()[0] ?? await context.newPage();
24246
24254
  const url = page.url();
24247
24255
  const title = await page.title().catch(() => "");
@@ -34346,8 +34354,7 @@ app.use("*", (c, next) => {
34346
34354
  const op = opForCostPath(new URL(c.req.url).pathname);
34347
34355
  if (!op) return next();
34348
34356
  const probeRunId = c.req.header("x-cost-probe-id") ?? null;
34349
- const forceHeadless = c.req.header("x-kernel-headless") === "true";
34350
- return runWithCostContext({ op, probeRunId, forceHeadless }, () => next());
34357
+ return runWithCostContext({ op, probeRunId }, () => next());
34351
34358
  });
34352
34359
  app.post("/auth/register", requireAllowedOrigin, async (c) => {
34353
34360
  const { email, password } = await c.req.json();
@@ -37165,7 +37172,7 @@ app.get("/cron/tick", async (c) => {
37165
37172
  if (!process.env.CRON_SECRET || secret2 !== `Bearer ${process.env.CRON_SECRET}`) {
37166
37173
  return c.json({ error: "Unauthorized" }, 401);
37167
37174
  }
37168
- const { drainQueue } = await import("./worker-2LIOH744.js");
37175
+ const { drainQueue } = await import("./worker-OB6WSWOD.js");
37169
37176
  const budget = { maxJobs: 10, deadlineMs: Date.now() + 28e4 };
37170
37177
  const workflowDispatchResult = await dispatchDueWorkflowSchedules(`${new URL(c.req.url).protocol}//${new URL(c.req.url).host}`);
37171
37178
  const [results, sweepResult, reapResult, expiredResult, blobCleanup, connectedDataArtifactCleanup, connectedAccountBilling, directoryWorkflowDispatch, directoryWorkflowReconciliation, directoryArtifactCleanup, siteExtractArtifactCleanup, siteExtractRedispatch, siteExtractReconciliation, paaHarvestRedispatch, paaHarvestReconciliation] = await Promise.all([
@@ -37425,4 +37432,4 @@ app.get("/blog/:slug/", (c) => {
37425
37432
  export {
37426
37433
  app
37427
37434
  };
37428
- //# sourceMappingURL=server-BPEXEKA6.js.map
37435
+ //# sourceMappingURL=server-K76DL4S7.js.map