mcp-scraper 0.21.5 → 0.23.0
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 +4 -3
- package/dist/bin/api-server.cjs +267 -26
- 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 +83 -15
- package/dist/bin/mcp-stdio-server.cjs.map +1 -1
- package/dist/bin/mcp-stdio-server.js +2 -2
- package/dist/chunk-64DNEO5R.js +7 -0
- package/dist/chunk-64DNEO5R.js.map +1 -0
- package/dist/{chunk-QO7HX67W.js → chunk-CGFJD7C6.js} +84 -16
- package/dist/chunk-CGFJD7C6.js.map +1 -0
- package/dist/{server-POMKHEXJ.js → server-XO2J5KFL.js} +176 -10
- package/dist/server-XO2J5KFL.js.map +1 -0
- package/docs/mcp-tool-manifest.generated.json +277 -18
- package/package.json +1 -1
- package/dist/chunk-QO7HX67W.js.map +0 -1
- package/dist/chunk-YLX3SKJN.js +0 -7
- package/dist/chunk-YLX3SKJN.js.map +0 -1
- package/dist/server-POMKHEXJ.js.map +0 -1
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
sanitizeAttempts,
|
|
36
36
|
sanitizeHarvestResult,
|
|
37
37
|
transcribeMediaUrl
|
|
38
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-CGFJD7C6.js";
|
|
39
39
|
import {
|
|
40
40
|
auditImages,
|
|
41
41
|
buildLinkReport,
|
|
@@ -76,7 +76,7 @@ import {
|
|
|
76
76
|
RawMapsOverviewSchema,
|
|
77
77
|
RawMapsReviewStatsSchema
|
|
78
78
|
} from "./chunk-XGIPATLV.js";
|
|
79
|
-
import "./chunk-
|
|
79
|
+
import "./chunk-64DNEO5R.js";
|
|
80
80
|
import {
|
|
81
81
|
completeExtractJob,
|
|
82
82
|
countSuccessfulPages,
|
|
@@ -21463,6 +21463,130 @@ ${lines.length ? `${lines.join("\n")}
|
|
|
21463
21463
|
};
|
|
21464
21464
|
}
|
|
21465
21465
|
|
|
21466
|
+
// src/api/search-console-table-export.ts
|
|
21467
|
+
import { randomUUID as randomUUID8 } from "crypto";
|
|
21468
|
+
var SEARCH_CONSOLE_TABLE_EXPORT_MAX_ROWS = 5e4;
|
|
21469
|
+
var SEARCH_CONSOLE_TABLE_EXPORT_PAGE_SIZE = 2e3;
|
|
21470
|
+
var SEARCH_CONSOLE_TABLE_EXPORT_MAX_BYTES = 50 * 1024 * 1024;
|
|
21471
|
+
var SEARCH_CONSOLE_TABLE_COLUMNS = [
|
|
21472
|
+
"id",
|
|
21473
|
+
"provider_record_id",
|
|
21474
|
+
"connection_id",
|
|
21475
|
+
"site_url",
|
|
21476
|
+
"permission_level",
|
|
21477
|
+
"date",
|
|
21478
|
+
"query",
|
|
21479
|
+
"page",
|
|
21480
|
+
"country",
|
|
21481
|
+
"device",
|
|
21482
|
+
"clicks",
|
|
21483
|
+
"impressions",
|
|
21484
|
+
"ctr",
|
|
21485
|
+
"position",
|
|
21486
|
+
"captured_at",
|
|
21487
|
+
"content_hash",
|
|
21488
|
+
"created_at",
|
|
21489
|
+
"updated_at"
|
|
21490
|
+
];
|
|
21491
|
+
var SearchConsoleTableExportValidationError = class extends Error {
|
|
21492
|
+
};
|
|
21493
|
+
function validateSearchConsoleTableExportRequest(args) {
|
|
21494
|
+
const tableName = typeof args.tableName === "string" ? args.tableName.trim() : "";
|
|
21495
|
+
if (!/^gsc_performance_[a-f0-9]{12}$/.test(tableName)) {
|
|
21496
|
+
throw new SearchConsoleTableExportValidationError("tableName must be a Search Console performance table returned by list_service_connections.");
|
|
21497
|
+
}
|
|
21498
|
+
const allowedColumns = new Set(SEARCH_CONSOLE_TABLE_COLUMNS);
|
|
21499
|
+
const allowedOps = /* @__PURE__ */ new Set(["eq", "neq", "gt", "gte", "lt", "lte", "like", "in"]);
|
|
21500
|
+
const rawFilters = args.filters === void 0 ? [] : args.filters;
|
|
21501
|
+
if (!Array.isArray(rawFilters) || rawFilters.length > 20) {
|
|
21502
|
+
throw new SearchConsoleTableExportValidationError("filters must be an array with at most 20 entries.");
|
|
21503
|
+
}
|
|
21504
|
+
const filters = rawFilters.map((value) => {
|
|
21505
|
+
const filter = value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
21506
|
+
if (!filter || typeof filter.column !== "string" || !allowedColumns.has(filter.column) || typeof filter.op !== "string" || !allowedOps.has(filter.op)) {
|
|
21507
|
+
throw new SearchConsoleTableExportValidationError("Each filter must use a documented Search Console table column and supported operator.");
|
|
21508
|
+
}
|
|
21509
|
+
if (filter.op === "in" && !Array.isArray(filter.value)) {
|
|
21510
|
+
throw new SearchConsoleTableExportValidationError("The in filter operator requires an array value.");
|
|
21511
|
+
}
|
|
21512
|
+
return {
|
|
21513
|
+
column: filter.column,
|
|
21514
|
+
op: filter.op,
|
|
21515
|
+
value: filter.value
|
|
21516
|
+
};
|
|
21517
|
+
});
|
|
21518
|
+
let sort;
|
|
21519
|
+
if (args.sort !== void 0) {
|
|
21520
|
+
const raw = args.sort && typeof args.sort === "object" && !Array.isArray(args.sort) ? args.sort : null;
|
|
21521
|
+
if (!raw || typeof raw.column !== "string" || !allowedColumns.has(raw.column) || raw.direction !== void 0 && raw.direction !== "asc" && raw.direction !== "desc") {
|
|
21522
|
+
throw new SearchConsoleTableExportValidationError("sort must use a documented Search Console table column and asc or desc direction.");
|
|
21523
|
+
}
|
|
21524
|
+
sort = {
|
|
21525
|
+
column: raw.column,
|
|
21526
|
+
...raw.direction ? { direction: raw.direction } : {}
|
|
21527
|
+
};
|
|
21528
|
+
}
|
|
21529
|
+
const maxRows = args.maxRows === void 0 ? 1e4 : Number(args.maxRows);
|
|
21530
|
+
if (!Number.isInteger(maxRows) || maxRows < 1 || maxRows > SEARCH_CONSOLE_TABLE_EXPORT_MAX_ROWS) {
|
|
21531
|
+
throw new SearchConsoleTableExportValidationError(`maxRows must be an integer from 1 to ${SEARCH_CONSOLE_TABLE_EXPORT_MAX_ROWS}.`);
|
|
21532
|
+
}
|
|
21533
|
+
return { tableName, filters, ...sort ? { sort } : {}, maxRows };
|
|
21534
|
+
}
|
|
21535
|
+
async function exportSearchConsoleTableData(args) {
|
|
21536
|
+
const lines = [];
|
|
21537
|
+
let bytes = 0;
|
|
21538
|
+
let offset = 0;
|
|
21539
|
+
let matchedRows = 0;
|
|
21540
|
+
let stoppedForBytes = false;
|
|
21541
|
+
while (offset < args.maxRows) {
|
|
21542
|
+
const limit = Math.min(SEARCH_CONSOLE_TABLE_EXPORT_PAGE_SIZE, args.maxRows - offset);
|
|
21543
|
+
const page = await args.queryPage({
|
|
21544
|
+
tableName: args.tableName,
|
|
21545
|
+
filters: args.filters,
|
|
21546
|
+
...args.sort ? { sort: args.sort } : {},
|
|
21547
|
+
limit,
|
|
21548
|
+
offset
|
|
21549
|
+
});
|
|
21550
|
+
if (!page.ok) throw new Error(page.error || "Search Console table query failed.");
|
|
21551
|
+
const rows = Array.isArray(page.rows) ? page.rows : [];
|
|
21552
|
+
matchedRows = Number.isSafeInteger(page.count) && Number(page.count) >= 0 ? Number(page.count) : rows.length;
|
|
21553
|
+
for (const row of rows) {
|
|
21554
|
+
const line = `${JSON.stringify(row)}
|
|
21555
|
+
`;
|
|
21556
|
+
const lineBytes = Buffer.byteLength(line);
|
|
21557
|
+
if (bytes + lineBytes > SEARCH_CONSOLE_TABLE_EXPORT_MAX_BYTES) {
|
|
21558
|
+
stoppedForBytes = true;
|
|
21559
|
+
break;
|
|
21560
|
+
}
|
|
21561
|
+
lines.push(line);
|
|
21562
|
+
bytes += lineBytes;
|
|
21563
|
+
}
|
|
21564
|
+
offset += rows.length;
|
|
21565
|
+
if (stoppedForBytes || rows.length < limit || offset >= matchedRows) break;
|
|
21566
|
+
}
|
|
21567
|
+
const exportId = randomUUID8();
|
|
21568
|
+
const artifact = await args.writeArtifact({
|
|
21569
|
+
ownerId: args.ownerId,
|
|
21570
|
+
exportId,
|
|
21571
|
+
filename: `search-console-filtered-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}.jsonl`,
|
|
21572
|
+
content: lines.join("")
|
|
21573
|
+
});
|
|
21574
|
+
const complete = lines.length >= matchedRows;
|
|
21575
|
+
const warnings = [];
|
|
21576
|
+
if (!complete && lines.length >= args.maxRows) warnings.push("max_rows_reached");
|
|
21577
|
+
if (stoppedForBytes) warnings.push("artifact_size_limit_reached");
|
|
21578
|
+
warnings.push("search_console_source_returns_top_rows_not_guaranteed_exhaustive");
|
|
21579
|
+
return {
|
|
21580
|
+
ok: true,
|
|
21581
|
+
tableName: args.tableName,
|
|
21582
|
+
rowsExported: lines.length,
|
|
21583
|
+
matchedRows,
|
|
21584
|
+
complete,
|
|
21585
|
+
artifact,
|
|
21586
|
+
warnings
|
|
21587
|
+
};
|
|
21588
|
+
}
|
|
21589
|
+
|
|
21466
21590
|
// src/api/credit-operations.ts
|
|
21467
21591
|
async function applyMonthlyFreeRefresh(user) {
|
|
21468
21592
|
return user;
|
|
@@ -23359,6 +23483,21 @@ function providerConfigKeyFrom(value) {
|
|
|
23359
23483
|
const key = value.trim();
|
|
23360
23484
|
return key && key.length <= 200 ? key : null;
|
|
23361
23485
|
}
|
|
23486
|
+
function calendarAttendeesFrom(value) {
|
|
23487
|
+
if (!Array.isArray(value) || value.length > 100) return null;
|
|
23488
|
+
const attendees = [];
|
|
23489
|
+
for (const item of value) {
|
|
23490
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) return null;
|
|
23491
|
+
const attendee = item;
|
|
23492
|
+
if (typeof attendee.email !== "string" || !attendee.email.trim()) return null;
|
|
23493
|
+
if (attendee.displayName !== void 0 && typeof attendee.displayName !== "string") return null;
|
|
23494
|
+
attendees.push({
|
|
23495
|
+
email: attendee.email.trim(),
|
|
23496
|
+
...typeof attendee.displayName === "string" && attendee.displayName.trim() ? { displayName: attendee.displayName.trim() } : {}
|
|
23497
|
+
});
|
|
23498
|
+
}
|
|
23499
|
+
return attendees;
|
|
23500
|
+
}
|
|
23362
23501
|
function bindingsForSchedule(bindings, scheduleActionId) {
|
|
23363
23502
|
return bindings.filter((binding) => binding.scheduleActionId === scheduleActionId);
|
|
23364
23503
|
}
|
|
@@ -23575,18 +23714,20 @@ app.post("/schedule-connections/actions/google-calendar/create-event", auth2, re
|
|
|
23575
23714
|
const user = c.get("user");
|
|
23576
23715
|
const body = await c.req.json().catch(() => ({}));
|
|
23577
23716
|
const connectionId = providerConfigKeyFrom(body.connectionId);
|
|
23578
|
-
|
|
23579
|
-
|
|
23717
|
+
const attendees = calendarAttendeesFrom(body.attendees);
|
|
23718
|
+
if (!connectionId || typeof body.summary !== "string" || typeof body.description !== "string" || typeof body.startDateTime !== "string" || typeof body.endDateTime !== "string" || !attendees) {
|
|
23719
|
+
return c.json({ ok: false, error: "connectionId, summary, description, startDateTime, endDateTime, and attendees are required." }, 400);
|
|
23580
23720
|
}
|
|
23581
23721
|
const timeZone = typeof body.timeZone === "string" ? body.timeZone : void 0;
|
|
23582
23722
|
try {
|
|
23583
23723
|
const result = await callScheduleConnectionAction(user.email, connectionId, {
|
|
23584
23724
|
calendarId: typeof body.calendarId === "string" ? body.calendarId : "primary",
|
|
23585
23725
|
summary: body.summary,
|
|
23586
|
-
description:
|
|
23726
|
+
description: body.description,
|
|
23587
23727
|
location: typeof body.location === "string" ? body.location : void 0,
|
|
23588
23728
|
start: { dateTime: body.startDateTime, timeZone },
|
|
23589
|
-
end: { dateTime: body.endDateTime, timeZone }
|
|
23729
|
+
end: { dateTime: body.endDateTime, timeZone },
|
|
23730
|
+
attendees
|
|
23590
23731
|
});
|
|
23591
23732
|
return c.json({ ok: true, result });
|
|
23592
23733
|
} catch (err) {
|
|
@@ -23597,8 +23738,8 @@ app.post("/schedule-connections/actions/zoom/create-meeting", auth2, requireInte
|
|
|
23597
23738
|
const user = c.get("user");
|
|
23598
23739
|
const body = await c.req.json().catch(() => ({}));
|
|
23599
23740
|
const connectionId = providerConfigKeyFrom(body.connectionId);
|
|
23600
|
-
if (!connectionId || typeof body.topic !== "string" || typeof body.startDateTime !== "string") {
|
|
23601
|
-
return c.json({ ok: false, error: "connectionId, topic, and
|
|
23741
|
+
if (!connectionId || typeof body.topic !== "string" || typeof body.startDateTime !== "string" || typeof body.agenda !== "string") {
|
|
23742
|
+
return c.json({ ok: false, error: "connectionId, topic, startDateTime, and agenda are required." }, 400);
|
|
23602
23743
|
}
|
|
23603
23744
|
try {
|
|
23604
23745
|
const result = await callScheduleConnectionAction(user.email, connectionId, {
|
|
@@ -23606,7 +23747,7 @@ app.post("/schedule-connections/actions/zoom/create-meeting", auth2, requireInte
|
|
|
23606
23747
|
startDateTime: body.startDateTime,
|
|
23607
23748
|
durationMinutes: typeof body.durationMinutes === "number" ? body.durationMinutes : 30,
|
|
23608
23749
|
timezone: typeof body.timezone === "string" ? body.timezone : void 0,
|
|
23609
|
-
agenda:
|
|
23750
|
+
agenda: body.agenda
|
|
23610
23751
|
});
|
|
23611
23752
|
return c.json({ ok: true, result });
|
|
23612
23753
|
} catch (err) {
|
|
@@ -23764,6 +23905,31 @@ app.post("/schedule-connections/actions/export", auth2, requireIntegrationsTier,
|
|
|
23764
23905
|
return scheduleConnectionError(c, err, "Unable to export this connected service.");
|
|
23765
23906
|
}
|
|
23766
23907
|
});
|
|
23908
|
+
app.post("/schedule-connections/actions/export-search-console-table", auth2, requireIntegrationsTier, async (c) => {
|
|
23909
|
+
const user = c.get("user");
|
|
23910
|
+
const body = await c.req.json().catch(() => ({}));
|
|
23911
|
+
try {
|
|
23912
|
+
const request = validateSearchConsoleTableExportRequest(body);
|
|
23913
|
+
const { key, error } = await getOrCreateUserMemoryKey(user);
|
|
23914
|
+
if (!key) return c.json({ ok: false, error: error ?? "Memory table access is unavailable." }, 503);
|
|
23915
|
+
const result = await exportSearchConsoleTableData({
|
|
23916
|
+
ownerId: sha256Hex(user.api_key).slice(0, 24),
|
|
23917
|
+
...request,
|
|
23918
|
+
queryPage: (input) => memoryCall("queryTableTool", input, key),
|
|
23919
|
+
writeArtifact: createConnectedDataArtifact
|
|
23920
|
+
});
|
|
23921
|
+
return c.json(result);
|
|
23922
|
+
} catch (err) {
|
|
23923
|
+
if (err instanceof SearchConsoleTableExportValidationError) {
|
|
23924
|
+
return c.json({ ok: false, error: err.message }, 400);
|
|
23925
|
+
}
|
|
23926
|
+
if (err instanceof Error && err.message === "connected_data_private_blob_not_configured") {
|
|
23927
|
+
return c.json({ ok: false, error: "Private connected-data artifact storage is not configured." }, 503);
|
|
23928
|
+
}
|
|
23929
|
+
console.error("[search-console-table-export]", err instanceof Error ? err.name : "unknown_error");
|
|
23930
|
+
return c.json({ ok: false, error: "Unable to export the persisted Search Console table." }, 502);
|
|
23931
|
+
}
|
|
23932
|
+
});
|
|
23767
23933
|
app.post("/schedule-connections/actions/export-download", auth2, requireIntegrationsTier, async (c) => {
|
|
23768
23934
|
const user = c.get("user");
|
|
23769
23935
|
const body = await c.req.json().catch(() => ({}));
|
|
@@ -25025,4 +25191,4 @@ app.get("/blog/:slug/", (c) => {
|
|
|
25025
25191
|
export {
|
|
25026
25192
|
app
|
|
25027
25193
|
};
|
|
25028
|
-
//# sourceMappingURL=server-
|
|
25194
|
+
//# sourceMappingURL=server-XO2J5KFL.js.map
|