mcp-scraper 0.3.9 → 0.3.11
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 +6 -4
- package/dist/bin/api-server.cjs +138 -19
- package/dist/bin/api-server.cjs.map +1 -1
- package/dist/bin/api-server.js +1 -1
- package/dist/bin/browser-agent-stdio-server.cjs +104 -28
- package/dist/bin/browser-agent-stdio-server.cjs.map +1 -1
- package/dist/bin/browser-agent-stdio-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-combined-stdio-server.cjs +110 -34
- package/dist/bin/mcp-scraper-combined-stdio-server.cjs.map +1 -1
- package/dist/bin/mcp-scraper-combined-stdio-server.js +4 -4
- package/dist/bin/mcp-scraper-install.cjs +7 -7
- package/dist/bin/mcp-scraper-install.cjs.map +1 -1
- package/dist/bin/mcp-scraper-install.js +2 -2
- package/dist/bin/mcp-stdio-server.cjs +1 -1
- package/dist/bin/mcp-stdio-server.cjs.map +1 -1
- package/dist/bin/mcp-stdio-server.js +2 -2
- package/dist/{chunk-ELI6NDEG.js → chunk-KPXMPAJ3.js} +7 -7
- package/dist/chunk-KPXMPAJ3.js.map +1 -0
- package/dist/{chunk-BRUVQRJK.js → chunk-L27GJQV7.js} +105 -29
- package/dist/chunk-L27GJQV7.js.map +1 -0
- package/dist/chunk-RRE7WVHQ.js +7 -0
- package/dist/chunk-RRE7WVHQ.js.map +1 -0
- package/dist/{chunk-KDKQ5Y7V.js → chunk-VMH7SRWY.js} +2 -2
- package/dist/{server-ZSHE4R5Z.js → server-3SA5Q4OF.js} +140 -21
- package/dist/{server-ZSHE4R5Z.js.map → server-3SA5Q4OF.js.map} +1 -1
- package/docs/mcp-tool-craft-lint.generated.md +3 -2
- package/docs/mcp-tool-manifest.generated.json +43 -13
- package/package.json +1 -1
- package/dist/chunk-7VNTN4Q7.js +0 -7
- package/dist/chunk-7VNTN4Q7.js.map +0 -1
- package/dist/chunk-BRUVQRJK.js.map +0 -1
- package/dist/chunk-ELI6NDEG.js.map +0 -1
- /package/dist/{chunk-KDKQ5Y7V.js.map → chunk-VMH7SRWY.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/version.ts"],"sourcesContent":["export const PACKAGE_VERSION = '0.3.11'\n"],"mappings":";AAAO,IAAM,kBAAkB;","names":[]}
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "./chunk-LFATOGDF.js";
|
|
8
8
|
import {
|
|
9
9
|
PACKAGE_VERSION
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-RRE7WVHQ.js";
|
|
11
11
|
|
|
12
12
|
// src/harvest-timeout.ts
|
|
13
13
|
var VERCEL_FUNCTION_MAX_MS = 3e5;
|
|
@@ -3335,4 +3335,4 @@ export {
|
|
|
3335
3335
|
registerPaaExtractorMcpTools,
|
|
3336
3336
|
HttpMcpToolExecutor
|
|
3337
3337
|
};
|
|
3338
|
-
//# sourceMappingURL=chunk-
|
|
3338
|
+
//# sourceMappingURL=chunk-VMH7SRWY.js.map
|
|
@@ -99,7 +99,7 @@ import {
|
|
|
99
99
|
harvestTimeoutBudget,
|
|
100
100
|
liveWebToolAnnotations,
|
|
101
101
|
outputBaseDir
|
|
102
|
-
} from "./chunk-
|
|
102
|
+
} from "./chunk-VMH7SRWY.js";
|
|
103
103
|
import {
|
|
104
104
|
CaptchaError,
|
|
105
105
|
RECAPTCHA_INSTRUCTIONS,
|
|
@@ -132,7 +132,7 @@ import {
|
|
|
132
132
|
RawMapsOverviewSchema,
|
|
133
133
|
RawMapsReviewStatsSchema
|
|
134
134
|
} from "./chunk-LFATOGDF.js";
|
|
135
|
-
import "./chunk-
|
|
135
|
+
import "./chunk-RRE7WVHQ.js";
|
|
136
136
|
|
|
137
137
|
// src/api/outbound-sanitize.ts
|
|
138
138
|
var KEY_RENAMES = {
|
|
@@ -14114,7 +14114,9 @@ function writeTable(path5, rows, delimiter) {
|
|
|
14114
14114
|
}
|
|
14115
14115
|
function exportFanout(enriched) {
|
|
14116
14116
|
const stamp = safe(enriched.capturedAt.replace(/[:.]/g, "-"));
|
|
14117
|
-
const
|
|
14117
|
+
const outputDir = outputBaseDir3();
|
|
14118
|
+
const relativeDir = join6("fanout", `${stamp}-${safe(enriched.platform)}`);
|
|
14119
|
+
const dir = join6(outputDir, relativeDir);
|
|
14118
14120
|
mkdirSync3(dir, { recursive: true });
|
|
14119
14121
|
const queryRows = enriched.queries.map((q, i) => ({ index: i + 1, query: q }));
|
|
14120
14122
|
const citationRows = enriched.aggregates.citationOrder.map((c) => {
|
|
@@ -14122,25 +14124,32 @@ function exportFanout(enriched) {
|
|
|
14122
14124
|
return { rank: c.rank, domain: c.domain, url: c.url, timesCited: c.timesCited, siteType: src?.siteType ?? "", title: src?.title ?? "" };
|
|
14123
14125
|
});
|
|
14124
14126
|
const sourceRows = enriched.browsedUrls.map((s) => ({ domain: s.domain, url: s.url, cited: s.cited, timesCited: s.timesCited, siteType: s.siteType, title: s.title, round: s.round ?? "" }));
|
|
14127
|
+
const browsedOnlyRows = enriched.browsedOnly.map((s) => ({ domain: s.domain, url: s.url, cited: s.cited, timesCited: s.timesCited, siteType: s.siteType, title: s.title, round: s.round ?? "" }));
|
|
14128
|
+
const snippetRows = enriched.snippets.map((s) => ({ domain: s.domain, url: s.url, title: s.title, text: s.text }));
|
|
14125
14129
|
const domainRows = enriched.aggregates.topSites.map((d) => ({ domain: d.domain, count: d.count, cited: d.cited, timesCited: d.timesCited, siteType: d.siteType }));
|
|
14126
|
-
const
|
|
14127
|
-
|
|
14128
|
-
|
|
14129
|
-
|
|
14130
|
-
|
|
14131
|
-
|
|
14132
|
-
|
|
14133
|
-
|
|
14134
|
-
|
|
14130
|
+
const relativePaths = {
|
|
14131
|
+
relativeTo: "MCP_SCRAPER_OUTPUT_DIR or ~/Downloads/mcp-scraper",
|
|
14132
|
+
dir: relativeDir,
|
|
14133
|
+
json: join6(relativeDir, "fanout.json"),
|
|
14134
|
+
queriesCsv: join6(relativeDir, "queries.csv"),
|
|
14135
|
+
queriesTsv: join6(relativeDir, "queries.tsv"),
|
|
14136
|
+
citationsCsv: join6(relativeDir, "citations.csv"),
|
|
14137
|
+
sourcesCsv: join6(relativeDir, "sources.csv"),
|
|
14138
|
+
browsedOnlyCsv: join6(relativeDir, "browsed-only.csv"),
|
|
14139
|
+
snippetsCsv: join6(relativeDir, "snippets.csv"),
|
|
14140
|
+
domainsCsv: join6(relativeDir, "domains.csv"),
|
|
14141
|
+
report: join6(relativeDir, "report.html")
|
|
14135
14142
|
};
|
|
14136
|
-
writeFileSync2(
|
|
14137
|
-
writeTable(
|
|
14138
|
-
writeTable(
|
|
14139
|
-
writeTable(
|
|
14140
|
-
writeTable(
|
|
14141
|
-
writeTable(
|
|
14142
|
-
|
|
14143
|
-
|
|
14143
|
+
writeFileSync2(join6(outputDir, relativePaths.json), JSON.stringify(enriched, null, 2));
|
|
14144
|
+
writeTable(join6(outputDir, relativePaths.queriesCsv), queryRows, ",");
|
|
14145
|
+
writeTable(join6(outputDir, relativePaths.queriesTsv), queryRows, " ");
|
|
14146
|
+
writeTable(join6(outputDir, relativePaths.citationsCsv), citationRows, ",");
|
|
14147
|
+
writeTable(join6(outputDir, relativePaths.sourcesCsv), sourceRows, ",");
|
|
14148
|
+
writeTable(join6(outputDir, relativePaths.browsedOnlyCsv), browsedOnlyRows, ",");
|
|
14149
|
+
writeTable(join6(outputDir, relativePaths.snippetsCsv), snippetRows, ",");
|
|
14150
|
+
writeTable(join6(outputDir, relativePaths.domainsCsv), domainRows, ",");
|
|
14151
|
+
writeFileSync2(join6(outputDir, relativePaths.report), renderReportHtml(enriched));
|
|
14152
|
+
return relativePaths;
|
|
14144
14153
|
}
|
|
14145
14154
|
function esc(s) {
|
|
14146
14155
|
return String(s).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
@@ -14255,6 +14264,7 @@ async function runFanoutCapture(page, input) {
|
|
|
14255
14264
|
const cap = new FanoutCdpCapture();
|
|
14256
14265
|
await cap.attach(page);
|
|
14257
14266
|
try {
|
|
14267
|
+
if (input.reset) cap.reset();
|
|
14258
14268
|
const baseline = cap.answerStreamCount();
|
|
14259
14269
|
if (input.prompt) await sendPrompt(page, input.prompt).catch(() => false);
|
|
14260
14270
|
const waitMs = input.wait_ms ?? (input.prompt ? 9e4 : 8e3);
|
|
@@ -14301,10 +14311,68 @@ async function ensureProfile(k, name) {
|
|
|
14301
14311
|
if (!isProfileConflict(err)) throw err;
|
|
14302
14312
|
}
|
|
14303
14313
|
}
|
|
14314
|
+
function profileConnectionMatches(connection, profileName, domain) {
|
|
14315
|
+
if (!connection || typeof connection !== "object") return false;
|
|
14316
|
+
const data = connection;
|
|
14317
|
+
return data.profile_name === profileName && data.domain === domain;
|
|
14318
|
+
}
|
|
14319
|
+
async function findProfileConnection(k, profileName, domain) {
|
|
14320
|
+
for await (const connection of k.auth.connections.list({ profile_name: profileName, domain })) {
|
|
14321
|
+
if (profileConnectionMatches(connection, profileName, domain)) return connection;
|
|
14322
|
+
}
|
|
14323
|
+
return null;
|
|
14324
|
+
}
|
|
14325
|
+
async function findOrCreateProfileConnection(k, opts) {
|
|
14326
|
+
try {
|
|
14327
|
+
return await k.auth.connections.create({
|
|
14328
|
+
domain: opts.domain,
|
|
14329
|
+
profile_name: opts.profileName,
|
|
14330
|
+
...opts.loginUrl ? { login_url: opts.loginUrl } : {}
|
|
14331
|
+
});
|
|
14332
|
+
} catch (err) {
|
|
14333
|
+
if (!isProfileConflict(err)) throw err;
|
|
14334
|
+
const existing = await findProfileConnection(k, opts.profileName, opts.domain);
|
|
14335
|
+
if (existing) return existing;
|
|
14336
|
+
throw err;
|
|
14337
|
+
}
|
|
14338
|
+
}
|
|
14339
|
+
function profileOnboardResult(connection, hostedUrl = null, liveViewUrl = null) {
|
|
14340
|
+
return {
|
|
14341
|
+
connectionId: String(connection.id),
|
|
14342
|
+
profileName: String(connection.profile_name),
|
|
14343
|
+
domain: String(connection.domain),
|
|
14344
|
+
status: String(connection.status),
|
|
14345
|
+
flowStatus: typeof connection.flow_status === "string" ? connection.flow_status : null,
|
|
14346
|
+
flowStep: typeof connection.flow_step === "string" ? connection.flow_step : null,
|
|
14347
|
+
flowExpiresAt: typeof connection.flow_expires_at === "string" ? connection.flow_expires_at : null,
|
|
14348
|
+
hostedUrl: hostedUrl ?? (typeof connection.hosted_url === "string" ? connection.hosted_url : null),
|
|
14349
|
+
liveViewUrl: liveViewUrl ?? (typeof connection.live_view_url === "string" ? connection.live_view_url : null),
|
|
14350
|
+
browserSessionId: typeof connection.browser_session_id === "string" ? connection.browser_session_id : null,
|
|
14351
|
+
postLoginUrl: typeof connection.post_login_url === "string" ? connection.post_login_url : null
|
|
14352
|
+
};
|
|
14353
|
+
}
|
|
14304
14354
|
function explicitProxyId(value) {
|
|
14305
14355
|
const trimmed = value?.trim();
|
|
14306
14356
|
return trimmed || void 0;
|
|
14307
14357
|
}
|
|
14358
|
+
async function startProfileOnboarding(opts) {
|
|
14359
|
+
const k = client();
|
|
14360
|
+
const connection = await findOrCreateProfileConnection(k, opts);
|
|
14361
|
+
const login = await k.auth.connections.login(connection.id);
|
|
14362
|
+
const state = await k.auth.connections.retrieve(connection.id);
|
|
14363
|
+
return profileOnboardResult(state, login.hosted_url ?? null, login.live_view_url ?? null);
|
|
14364
|
+
}
|
|
14365
|
+
async function getProfileOnboardingStatus(input) {
|
|
14366
|
+
const k = client();
|
|
14367
|
+
let connection = null;
|
|
14368
|
+
if (input.connectionId) {
|
|
14369
|
+
connection = await k.auth.connections.retrieve(input.connectionId);
|
|
14370
|
+
} else if (input.profileName && input.domain) {
|
|
14371
|
+
connection = await findProfileConnection(k, input.profileName, input.domain);
|
|
14372
|
+
}
|
|
14373
|
+
if (!connection) throw new Error("profile auth connection not found");
|
|
14374
|
+
return profileOnboardResult(connection);
|
|
14375
|
+
}
|
|
14308
14376
|
async function createSession(opts = {}) {
|
|
14309
14377
|
const k = client();
|
|
14310
14378
|
const resolvedProxyId = explicitProxyId(opts.proxyId);
|
|
@@ -14698,6 +14766,56 @@ function buildBrowserAgentRoutes() {
|
|
|
14698
14766
|
return next();
|
|
14699
14767
|
});
|
|
14700
14768
|
app2.use("*", auth);
|
|
14769
|
+
app2.post("/profiles/onboard", async (c) => {
|
|
14770
|
+
const body = await c.req.json().catch(() => ({}));
|
|
14771
|
+
const profileName = typeof body.profile === "string" ? body.profile.trim() : "";
|
|
14772
|
+
const domain = typeof body.domain === "string" ? body.domain.trim().replace(/^https?:\/\//, "").replace(/\/.*$/, "") : "chatgpt.com";
|
|
14773
|
+
const loginUrl = typeof body.login_url === "string" ? body.login_url.trim() : void 0;
|
|
14774
|
+
if (!profileName) return c.json({ error: "profile is required" }, 400);
|
|
14775
|
+
if (!domain) return c.json({ error: "domain is required" }, 400);
|
|
14776
|
+
try {
|
|
14777
|
+
const result = await startProfileOnboarding({ profileName, domain, loginUrl });
|
|
14778
|
+
return c.json({
|
|
14779
|
+
connection_id: result.connectionId,
|
|
14780
|
+
profile: result.profileName,
|
|
14781
|
+
domain: result.domain,
|
|
14782
|
+
status: result.status,
|
|
14783
|
+
flow_status: result.flowStatus,
|
|
14784
|
+
flow_step: result.flowStep,
|
|
14785
|
+
flow_expires_at: result.flowExpiresAt,
|
|
14786
|
+
hosted_url: result.hostedUrl,
|
|
14787
|
+
live_view_url: result.liveViewUrl,
|
|
14788
|
+
browser_session_id: result.browserSessionId,
|
|
14789
|
+
post_login_url: result.postLoginUrl
|
|
14790
|
+
});
|
|
14791
|
+
} catch (err) {
|
|
14792
|
+
return c.json(failure(err), 502);
|
|
14793
|
+
}
|
|
14794
|
+
});
|
|
14795
|
+
app2.post("/profiles/status", async (c) => {
|
|
14796
|
+
const body = await c.req.json().catch(() => ({}));
|
|
14797
|
+
const connectionId = typeof body.connection_id === "string" ? body.connection_id.trim() : void 0;
|
|
14798
|
+
const profileName = typeof body.profile === "string" ? body.profile.trim() : void 0;
|
|
14799
|
+
const domain = typeof body.domain === "string" ? body.domain.trim().replace(/^https?:\/\//, "").replace(/\/.*$/, "") : void 0;
|
|
14800
|
+
try {
|
|
14801
|
+
const result = await getProfileOnboardingStatus({ connectionId, profileName, domain });
|
|
14802
|
+
return c.json({
|
|
14803
|
+
connection_id: result.connectionId,
|
|
14804
|
+
profile: result.profileName,
|
|
14805
|
+
domain: result.domain,
|
|
14806
|
+
status: result.status,
|
|
14807
|
+
flow_status: result.flowStatus,
|
|
14808
|
+
flow_step: result.flowStep,
|
|
14809
|
+
flow_expires_at: result.flowExpiresAt,
|
|
14810
|
+
hosted_url: result.hostedUrl,
|
|
14811
|
+
live_view_url: result.liveViewUrl,
|
|
14812
|
+
browser_session_id: result.browserSessionId,
|
|
14813
|
+
post_login_url: result.postLoginUrl
|
|
14814
|
+
});
|
|
14815
|
+
} catch (err) {
|
|
14816
|
+
return c.json(failure(err), 404);
|
|
14817
|
+
}
|
|
14818
|
+
});
|
|
14701
14819
|
app2.post("/sessions", async (c) => {
|
|
14702
14820
|
const user = c.get("user");
|
|
14703
14821
|
if (Number(user.balance_mc ?? 0) < BROWSER_OPEN_MIN_BALANCE_MC) {
|
|
@@ -14801,6 +14919,7 @@ function buildBrowserAgentRoutes() {
|
|
|
14801
14919
|
prompt: typeof body.prompt === "string" ? body.prompt : void 0,
|
|
14802
14920
|
wait_ms: typeof body.wait_ms === "number" ? body.wait_ms : void 0,
|
|
14803
14921
|
first_party_domain: typeof body.first_party_domain === "string" ? body.first_party_domain : void 0,
|
|
14922
|
+
reset: body.reset === true,
|
|
14804
14923
|
export: body.export === true
|
|
14805
14924
|
};
|
|
14806
14925
|
const t0 = Date.now();
|
|
@@ -16452,4 +16571,4 @@ app.get("/blog/:slug/", (c) => {
|
|
|
16452
16571
|
export {
|
|
16453
16572
|
app
|
|
16454
16573
|
};
|
|
16455
|
-
//# sourceMappingURL=server-
|
|
16574
|
+
//# sourceMappingURL=server-3SA5Q4OF.js.map
|