mcp-scraper 0.3.45 → 0.3.46
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 +378 -157
- package/dist/bin/api-server.cjs.map +1 -1
- package/dist/bin/api-server.js +1 -1
- 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 +435 -180
- package/dist/bin/mcp-stdio-server.cjs.map +1 -1
- package/dist/bin/mcp-stdio-server.js +2 -2
- package/dist/{chunk-E7BZFMWB.js → chunk-SS5YBZVI.js} +472 -212
- package/dist/chunk-SS5YBZVI.js.map +1 -0
- package/dist/chunk-WT6OT2T3.js +7 -0
- package/dist/chunk-WT6OT2T3.js.map +1 -0
- package/dist/{server-MKUN6NQZ.js → server-MGE3GYJW.js} +26 -76
- package/dist/server-MGE3GYJW.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-E7BZFMWB.js.map +0 -1
- package/dist/chunk-NVTFLLEG.js +0 -7
- package/dist/chunk-NVTFLLEG.js.map +0 -1
- package/dist/server-MKUN6NQZ.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/version.ts"],"sourcesContent":["export const PACKAGE_VERSION = '0.3.46'\n"],"mappings":";AAAO,IAAM,kBAAkB;","names":[]}
|
|
@@ -7,7 +7,9 @@ import {
|
|
|
7
7
|
computeIssues,
|
|
8
8
|
configureReportSaving,
|
|
9
9
|
exportFanout,
|
|
10
|
+
getBlobStore,
|
|
10
11
|
harvestTimeoutBudget,
|
|
12
|
+
hashOwnerId,
|
|
11
13
|
outputBaseDir,
|
|
12
14
|
registerBrowserAgentMcpTools,
|
|
13
15
|
registerSerpIntelligenceCaptureTools,
|
|
@@ -16,7 +18,7 @@ import {
|
|
|
16
18
|
renderLinkReport,
|
|
17
19
|
sanitizeAttempts,
|
|
18
20
|
sanitizeHarvestResult
|
|
19
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-SS5YBZVI.js";
|
|
20
22
|
import {
|
|
21
23
|
csvRecords,
|
|
22
24
|
listWorkflowDefinitions,
|
|
@@ -29,7 +31,7 @@ import {
|
|
|
29
31
|
workflowStepCount,
|
|
30
32
|
workflowSupportsSteps
|
|
31
33
|
} from "./chunk-NNEIXK5L.js";
|
|
32
|
-
import "./chunk-
|
|
34
|
+
import "./chunk-WT6OT2T3.js";
|
|
33
35
|
import {
|
|
34
36
|
BROWSER_OPEN_MIN_BALANCE_MC,
|
|
35
37
|
CONCURRENCY_PRICE_ID,
|
|
@@ -7420,58 +7422,6 @@ var siteAuditFn = inngest.createFunction(
|
|
|
7420
7422
|
}
|
|
7421
7423
|
);
|
|
7422
7424
|
|
|
7423
|
-
// src/api/blob-store.ts
|
|
7424
|
-
import { mkdirSync as mkdirSync2, writeFileSync } from "fs";
|
|
7425
|
-
import { homedir as homedir2 } from "os";
|
|
7426
|
-
import { join as join4, dirname as dirname2 } from "path";
|
|
7427
|
-
function byteLength(data) {
|
|
7428
|
-
return Buffer.isBuffer(data) ? data.length : Buffer.byteLength(data);
|
|
7429
|
-
}
|
|
7430
|
-
var LocalBlobStore = class {
|
|
7431
|
-
constructor(baseDir) {
|
|
7432
|
-
this.baseDir = baseDir;
|
|
7433
|
-
}
|
|
7434
|
-
baseDir;
|
|
7435
|
-
kind = "local";
|
|
7436
|
-
async put(key, data, contentType = "application/octet-stream") {
|
|
7437
|
-
const path5 = join4(this.baseDir, "blobs", key);
|
|
7438
|
-
mkdirSync2(dirname2(path5), { recursive: true });
|
|
7439
|
-
writeFileSync(path5, data);
|
|
7440
|
-
return { key, url: `file://${path5}`, bytes: byteLength(data), contentType };
|
|
7441
|
-
}
|
|
7442
|
-
};
|
|
7443
|
-
function localBaseDir() {
|
|
7444
|
-
return process.env.MCP_SCRAPER_OUTPUT_DIR?.trim() || join4(homedir2(), "Downloads", "mcp-scraper");
|
|
7445
|
-
}
|
|
7446
|
-
var cached = null;
|
|
7447
|
-
function getBlobStore() {
|
|
7448
|
-
if (cached) return cached;
|
|
7449
|
-
if (process.env.BLOB_READ_WRITE_TOKEN) {
|
|
7450
|
-
cached = new VercelBlobStore(process.env.BLOB_READ_WRITE_TOKEN);
|
|
7451
|
-
} else {
|
|
7452
|
-
cached = new LocalBlobStore(localBaseDir());
|
|
7453
|
-
}
|
|
7454
|
-
return cached;
|
|
7455
|
-
}
|
|
7456
|
-
var VercelBlobStore = class {
|
|
7457
|
-
constructor(token) {
|
|
7458
|
-
this.token = token;
|
|
7459
|
-
}
|
|
7460
|
-
token;
|
|
7461
|
-
kind = "vercel-blob";
|
|
7462
|
-
async put(key, data, contentType = "application/octet-stream") {
|
|
7463
|
-
const { put } = await import("@vercel/blob");
|
|
7464
|
-
const body = Buffer.isBuffer(data) ? data : Buffer.from(data);
|
|
7465
|
-
const result = await put(key, body, {
|
|
7466
|
-
access: "public",
|
|
7467
|
-
token: this.token,
|
|
7468
|
-
contentType,
|
|
7469
|
-
addRandomSuffix: true
|
|
7470
|
-
});
|
|
7471
|
-
return { key, url: result.url, bytes: byteLength(data), contentType };
|
|
7472
|
-
}
|
|
7473
|
-
};
|
|
7474
|
-
|
|
7475
7425
|
// src/api/site-extract-repository.ts
|
|
7476
7426
|
function rowToJob(r) {
|
|
7477
7427
|
return {
|
|
@@ -11180,9 +11130,9 @@ googleAdsApp.post("/transcribe", createApiKeyAuth(), async (c) => {
|
|
|
11180
11130
|
// src/api/instagram-routes.ts
|
|
11181
11131
|
import { Hono as Hono7 } from "hono";
|
|
11182
11132
|
import { z as z15 } from "zod";
|
|
11183
|
-
import { createWriteStream as createWriteStream2, mkdirSync as
|
|
11184
|
-
import { homedir as
|
|
11185
|
-
import { join as
|
|
11133
|
+
import { createWriteStream as createWriteStream2, mkdirSync as mkdirSync2, statSync, writeFileSync } from "fs";
|
|
11134
|
+
import { homedir as homedir2 } from "os";
|
|
11135
|
+
import { join as join4 } from "path";
|
|
11186
11136
|
import { Readable as Readable2 } from "stream";
|
|
11187
11137
|
import { pipeline as pipeline2 } from "stream/promises";
|
|
11188
11138
|
import { spawn } from "child_process";
|
|
@@ -11609,7 +11559,7 @@ async function resolveInstagramLaunch(body) {
|
|
|
11609
11559
|
};
|
|
11610
11560
|
}
|
|
11611
11561
|
function outputBaseDir2() {
|
|
11612
|
-
return process.env.MCP_SCRAPER_OUTPUT_DIR?.trim() ||
|
|
11562
|
+
return process.env.MCP_SCRAPER_OUTPUT_DIR?.trim() || join4(homedir2(), "Downloads", "mcp-scraper");
|
|
11613
11563
|
}
|
|
11614
11564
|
function safeFilePart(input) {
|
|
11615
11565
|
return input.replace(/^https?:\/\//, "").replace(/[^a-z0-9._-]+/gi, "-").replace(/^-+|-+$/g, "").slice(0, 80) || "instagram";
|
|
@@ -11617,8 +11567,8 @@ function safeFilePart(input) {
|
|
|
11617
11567
|
function mediaOutputDir(shortcode, sourceUrl) {
|
|
11618
11568
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
11619
11569
|
const slug = shortcode ? `instagram-${shortcode}` : safeFilePart(sourceUrl);
|
|
11620
|
-
const dir =
|
|
11621
|
-
|
|
11570
|
+
const dir = join4(outputBaseDir2(), "instagram", `${stamp}-${slug}`);
|
|
11571
|
+
mkdirSync2(dir, { recursive: true });
|
|
11622
11572
|
return dir;
|
|
11623
11573
|
}
|
|
11624
11574
|
async function downloadToFile(url, destPath, referer) {
|
|
@@ -11758,8 +11708,8 @@ instagramApp.post("/media-download", createApiKeyAuth(), async (c) => {
|
|
|
11758
11708
|
let outputDir = null;
|
|
11759
11709
|
if (body.downloadMedia) {
|
|
11760
11710
|
outputDir = mediaOutputDir(extraction.shortcode, sourceUrl.href);
|
|
11761
|
-
const textPath =
|
|
11762
|
-
|
|
11711
|
+
const textPath = join4(outputDir, `${extraction.shortcode ?? "instagram"}-text.txt`);
|
|
11712
|
+
writeFileSync(textPath, [
|
|
11763
11713
|
`URL: ${extraction.pageUrl}`,
|
|
11764
11714
|
extraction.caption ? `Caption: ${extraction.caption}` : "",
|
|
11765
11715
|
"",
|
|
@@ -11767,7 +11717,7 @@ instagramApp.post("/media-download", createApiKeyAuth(), async (c) => {
|
|
|
11767
11717
|
].filter(Boolean).join("\n"), "utf8");
|
|
11768
11718
|
downloads.push({ kind: "text", url: null, savedPath: textPath, sizeBytes: statSync(textPath).size, mimeType: "text/plain", error: null });
|
|
11769
11719
|
if (mediaTypes.has("image") && extraction.imageUrl) {
|
|
11770
|
-
const imagePathBase =
|
|
11720
|
+
const imagePathBase = join4(outputDir, `${extraction.shortcode ?? "instagram"}-image`);
|
|
11771
11721
|
try {
|
|
11772
11722
|
const downloaded = await downloadToFile(extraction.imageUrl, imagePathBase, extraction.pageUrl);
|
|
11773
11723
|
const ext = extFromMime(downloaded.mimeType, "jpg");
|
|
@@ -11787,7 +11737,7 @@ instagramApp.post("/media-download", createApiKeyAuth(), async (c) => {
|
|
|
11787
11737
|
if (track.streamType === "video" && !mediaTypes.has("video")) continue;
|
|
11788
11738
|
if (track.streamType === "audio" && !mediaTypes.has("audio")) continue;
|
|
11789
11739
|
const kind = track.streamType === "audio" ? "audio" : "video";
|
|
11790
|
-
const target =
|
|
11740
|
+
const target = join4(outputDir, trackFilename(track, index, extraction.shortcode));
|
|
11791
11741
|
try {
|
|
11792
11742
|
const downloaded = await downloadToFile(track.url, target, extraction.pageUrl);
|
|
11793
11743
|
downloads.push({ kind, url: track.url, savedPath: downloaded.savedPath, sizeBytes: downloaded.sizeBytes, mimeType: downloaded.mimeType, error: null });
|
|
@@ -11797,7 +11747,7 @@ instagramApp.post("/media-download", createApiKeyAuth(), async (c) => {
|
|
|
11797
11747
|
}
|
|
11798
11748
|
}
|
|
11799
11749
|
if (body.mux && mediaTypes.has("video") && mediaTypes.has("audio") && extraction.selectedVideoTrack && extraction.selectedAudioTrack && savedByUrl.has(extraction.selectedVideoTrack.url) && savedByUrl.has(extraction.selectedAudioTrack.url)) {
|
|
11800
|
-
const outPath =
|
|
11750
|
+
const outPath = join4(outputDir, `${extraction.shortcode ?? "instagram"}-muxed.mp4`);
|
|
11801
11751
|
const muxed = await runFfmpegMux(savedByUrl.get(extraction.selectedVideoTrack.url), savedByUrl.get(extraction.selectedAudioTrack.url), outPath);
|
|
11802
11752
|
if (muxed.ok) {
|
|
11803
11753
|
downloads.push({ kind: "muxed_video", url: null, savedPath: outPath, sizeBytes: statSync(outPath).size, mimeType: "video/mp4", error: null });
|
|
@@ -13136,7 +13086,7 @@ import { Hono as Hono11 } from "hono";
|
|
|
13136
13086
|
|
|
13137
13087
|
// src/directory/directory-workflow.ts
|
|
13138
13088
|
import { mkdir as mkdir2, writeFile } from "fs/promises";
|
|
13139
|
-
import { join as
|
|
13089
|
+
import { join as join5 } from "path";
|
|
13140
13090
|
import { z as z19 } from "zod";
|
|
13141
13091
|
|
|
13142
13092
|
// src/directory/location-db.ts
|
|
@@ -13472,11 +13422,11 @@ function csvRowsFor(result) {
|
|
|
13472
13422
|
return rows;
|
|
13473
13423
|
}
|
|
13474
13424
|
async function saveDirectoryCsv(result) {
|
|
13475
|
-
const outDir =
|
|
13425
|
+
const outDir = join5(outputBaseDir(), "directory-workflows");
|
|
13476
13426
|
await mkdir2(outDir, { recursive: true });
|
|
13477
13427
|
const stamp = result.extractedAt.replace(/[:.]/g, "-");
|
|
13478
13428
|
const slug = `${result.state}-${result.query}`.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
|
|
13479
|
-
const path5 =
|
|
13429
|
+
const path5 = join5(outDir, `${stamp}-${slug}-directory-workflow.csv`);
|
|
13480
13430
|
const headers = [
|
|
13481
13431
|
"source_query",
|
|
13482
13432
|
"source_location",
|
|
@@ -15117,9 +15067,9 @@ mcpApp.all("/", async (c) => {
|
|
|
15117
15067
|
enableJsonResponse: true
|
|
15118
15068
|
});
|
|
15119
15069
|
const consoleBaseUrl = process.env.BROWSER_AGENT_CONSOLE_URL?.trim() || baseUrl;
|
|
15120
|
-
const server = buildPaaExtractorMcpServer(executor, { savesReportsLocally: false });
|
|
15070
|
+
const server = buildPaaExtractorMcpServer(executor, { savesReportsLocally: false, ownerId: hashOwnerId(callerKey) });
|
|
15121
15071
|
registerSerpIntelligenceCaptureTools(server, executor);
|
|
15122
|
-
registerBrowserAgentMcpTools(server, { baseUrl, apiKey: callerKey, consoleBaseUrl });
|
|
15072
|
+
registerBrowserAgentMcpTools(server, { baseUrl, apiKey: callerKey, consoleBaseUrl, savesReportsLocally: false });
|
|
15123
15073
|
await server.connect(transport);
|
|
15124
15074
|
return transport.handleRequest(c.req.raw);
|
|
15125
15075
|
} catch {
|
|
@@ -18876,8 +18826,8 @@ async function persistScrapeBody(user, opts) {
|
|
|
18876
18826
|
|
|
18877
18827
|
// src/api/scrape-blob-cleanup.ts
|
|
18878
18828
|
import { readdir, stat, unlink } from "fs/promises";
|
|
18879
|
-
import { homedir as
|
|
18880
|
-
import { join as
|
|
18829
|
+
import { homedir as homedir3 } from "os";
|
|
18830
|
+
import { join as join6 } from "path";
|
|
18881
18831
|
async function cleanupVercel(token, cutoff) {
|
|
18882
18832
|
const { list, del } = await import("@vercel/blob");
|
|
18883
18833
|
let cursor;
|
|
@@ -18894,8 +18844,8 @@ async function cleanupVercel(token, cutoff) {
|
|
|
18894
18844
|
return { deleted, store: "vercel-blob" };
|
|
18895
18845
|
}
|
|
18896
18846
|
async function cleanupLocal(cutoff) {
|
|
18897
|
-
const baseDir = process.env.MCP_SCRAPER_OUTPUT_DIR?.trim() ||
|
|
18898
|
-
const dir =
|
|
18847
|
+
const baseDir = process.env.MCP_SCRAPER_OUTPUT_DIR?.trim() || join6(homedir3(), "Downloads", "mcp-scraper");
|
|
18848
|
+
const dir = join6(baseDir, "blobs", SCRAPE_FALLBACK_PREFIX.replace(/\/$/, ""));
|
|
18899
18849
|
let deleted = 0;
|
|
18900
18850
|
let entries;
|
|
18901
18851
|
try {
|
|
@@ -18904,7 +18854,7 @@ async function cleanupLocal(cutoff) {
|
|
|
18904
18854
|
return { deleted: 0, store: "local" };
|
|
18905
18855
|
}
|
|
18906
18856
|
for (const name of entries) {
|
|
18907
|
-
const path5 =
|
|
18857
|
+
const path5 = join6(dir, name);
|
|
18908
18858
|
try {
|
|
18909
18859
|
const s = await stat(path5);
|
|
18910
18860
|
if (s.isFile() && s.mtimeMs < cutoff) {
|
|
@@ -20725,4 +20675,4 @@ app.get("/blog/:slug/", (c) => {
|
|
|
20725
20675
|
export {
|
|
20726
20676
|
app
|
|
20727
20677
|
};
|
|
20728
|
-
//# sourceMappingURL=server-
|
|
20678
|
+
//# sourceMappingURL=server-MGE3GYJW.js.map
|