mcp-scraper 0.11.0 → 0.12.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 +1 -1
- package/dist/bin/api-server.cjs +85 -11
- 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 +6 -3
- package/dist/bin/mcp-stdio-server.cjs.map +1 -1
- package/dist/bin/mcp-stdio-server.js +2 -2
- package/dist/{chunk-QJBWER2Q.js → chunk-HXNE5GLG.js} +7 -4
- package/dist/{chunk-QJBWER2Q.js.map → chunk-HXNE5GLG.js.map} +1 -1
- package/dist/chunk-YA364G53.js +7 -0
- package/dist/chunk-YA364G53.js.map +1 -0
- package/dist/{server-LRWHUBUN.js → server-TFWBW24U.js} +81 -10
- package/dist/{server-LRWHUBUN.js.map → server-TFWBW24U.js.map} +1 -1
- package/docs/mcp-tool-manifest.generated.json +29 -4
- package/package.json +2 -2
- package/dist/chunk-P2WZLJKQ.js +0 -7
- package/dist/chunk-P2WZLJKQ.js.map +0 -1
package/README.md
CHANGED
|
@@ -88,7 +88,7 @@ Build the branded one-click bundle:
|
|
|
88
88
|
npm run build:mcpb
|
|
89
89
|
```
|
|
90
90
|
|
|
91
|
-
The generated bundle is written to `build/mcpb/mcp-scraper-<version>.mcpb` and copied to `public/downloads/` for the hosted download. The current public bundle is `https://mcpscraper.dev/downloads/mcp-scraper.mcpb` (`0.
|
|
91
|
+
The generated bundle is written to `build/mcpb/mcp-scraper-<version>.mcpb` and copied to `public/downloads/` for the hosted download. The current public bundle is `https://mcpscraper.dev/downloads/mcp-scraper.mcpb` (`0.12.0`, SHA-256 `2a0dfdc53e93d48588ef672c6daf0ec0e6194b3f938add02b106bf5e86c20ef3`). Install it by opening or dragging it into Claude Desktop. Claude displays the `MCP Scraper` install card, icon, and API-key configuration field from the bundle manifest.
|
|
92
92
|
|
|
93
93
|
The MCPB install exposes every tool — web-intelligence plus all `browser_*` tools — through the one `mcp-scraper` server.
|
|
94
94
|
|
package/dist/bin/api-server.cjs
CHANGED
|
@@ -27452,7 +27452,7 @@ var PACKAGE_VERSION;
|
|
|
27452
27452
|
var init_version = __esm({
|
|
27453
27453
|
"src/version.ts"() {
|
|
27454
27454
|
"use strict";
|
|
27455
|
-
PACKAGE_VERSION = "0.
|
|
27455
|
+
PACKAGE_VERSION = "0.12.0";
|
|
27456
27456
|
}
|
|
27457
27457
|
});
|
|
27458
27458
|
|
|
@@ -32869,11 +32869,12 @@ var init_memory_tool_schemas = __esm({
|
|
|
32869
32869
|
CreateScheduledActionSchema = {
|
|
32870
32870
|
id: "create-scheduled-action",
|
|
32871
32871
|
upstreamName: "createScheduledActionTool",
|
|
32872
|
-
description: "Create a scheduled action
|
|
32872
|
+
description: "Create a scheduled action in agent mode (default) or connection_sync mode. Agent mode asks an agent to follow the description and write a result into the target vault. connection_sync deterministically runs the approved read-only tools on bound service connections and ingests their data; it requires at least one connection to be bound before execution. Cadence 'once' runs a single time then completes permanently. Requires an active scheduling subscription and write access to the target vault.",
|
|
32873
32873
|
input: {
|
|
32874
32874
|
description: import_zod35.z.string().min(1).describe("Free-text description of what this action should do each time it runs."),
|
|
32875
32875
|
vault: import_zod35.z.string().min(1).describe("The vault this action writes its results into. You must already have write access to it."),
|
|
32876
32876
|
cadence: import_zod35.z.enum(["once", "daily", "weekly", "monthly"]).describe('How often this action runs. "once" fires a single time and then completes.'),
|
|
32877
|
+
executionMode: import_zod35.z.enum(["agent", "connection_sync"]).default("agent").describe(`How to execute each run. "agent" (default) lets an agent follow the description. "connection_sync" deterministically ingests data from the schedule's bound connections using only their approved read-only tools; bind at least one connection before it runs.`),
|
|
32877
32878
|
timeOfDay: import_zod35.z.string().regex(/^([01]\d|2[0-3]):([0-5]\d)$/).optional().describe("24-hour HH:MM clock time to run at, in the given timezone. Optional \u2014 omit to run at any time during the period (matches prior default behavior)."),
|
|
32878
32879
|
timezone: import_zod35.z.string().optional().describe('IANA timezone name, e.g. "America/Denver". Only meaningful together with timeOfDay. Defaults to UTC.'),
|
|
32879
32880
|
deployDate: import_zod35.z.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional().describe('Calendar date (YYYY-MM-DD, in the given timezone) this action should first become eligible to run \u2014 its deployment/start date. For recurring cadences, the first occurrence lands on or after this date; every later occurrence still follows the normal cadence. For cadence "once", this (combined with timeOfDay if given) is exactly what day it fires. Omit to start immediately.')
|
|
@@ -32882,6 +32883,7 @@ var init_memory_tool_schemas = __esm({
|
|
|
32882
32883
|
ok: import_zod35.z.boolean().describe("True when the scheduled action was created."),
|
|
32883
32884
|
id: import_zod35.z.string().optional().describe("The new scheduled action id."),
|
|
32884
32885
|
nextRunAt: import_zod35.z.string().optional().describe("When it will first run."),
|
|
32886
|
+
executionMode: import_zod35.z.enum(["agent", "connection_sync"]).optional().describe("The stored execution mode. Defaults to agent when omitted from the request."),
|
|
32885
32887
|
error: import_zod35.z.string().optional().describe("Human-readable failure reason when ok is false."),
|
|
32886
32888
|
code: import_zod35.z.string().optional().describe("Machine-readable denial code: not_enabled when no scheduling subscription is active.")
|
|
32887
32889
|
},
|
|
@@ -32956,7 +32958,7 @@ var init_memory_tool_schemas = __esm({
|
|
|
32956
32958
|
ListScheduledActionsSchema = {
|
|
32957
32959
|
id: "list-scheduled-actions",
|
|
32958
32960
|
upstreamName: "listScheduledActionsTool",
|
|
32959
|
-
description: "List every scheduled action you own \u2014 active, paused, and completed one-time actions \u2014 with cadence, next run time, and last run status.",
|
|
32961
|
+
description: "List every scheduled action you own \u2014 active, paused, and completed one-time actions \u2014 with execution mode, cadence, next run time, and last run status. connection_sync means deterministic read-only ingestion from bound service connections.",
|
|
32960
32962
|
input: {},
|
|
32961
32963
|
output: {
|
|
32962
32964
|
ok: import_zod35.z.boolean(),
|
|
@@ -32965,6 +32967,7 @@ var init_memory_tool_schemas = __esm({
|
|
|
32965
32967
|
description: import_zod35.z.string(),
|
|
32966
32968
|
vault: import_zod35.z.string(),
|
|
32967
32969
|
cadence: import_zod35.z.enum(["once", "daily", "weekly", "monthly"]),
|
|
32970
|
+
executionMode: import_zod35.z.enum(["agent", "connection_sync"]),
|
|
32968
32971
|
timeOfDay: import_zod35.z.string().nullable(),
|
|
32969
32972
|
timezone: import_zod35.z.string(),
|
|
32970
32973
|
status: import_zod35.z.enum(["active", "paused", "completed"]),
|
|
@@ -38884,6 +38887,43 @@ var init_memory_db = __esm({
|
|
|
38884
38887
|
});
|
|
38885
38888
|
|
|
38886
38889
|
// src/api/nango-control.ts
|
|
38890
|
+
function connectionSyncPolicyIssues(selections) {
|
|
38891
|
+
const issues = [];
|
|
38892
|
+
for (const selection of selections) {
|
|
38893
|
+
const required = CONNECTION_SYNC_REQUIRED_TOOLS[selection.providerConfigKey];
|
|
38894
|
+
if (!required) {
|
|
38895
|
+
issues.push({ providerConfigKey: selection.providerConfigKey, code: "unsupported_provider" });
|
|
38896
|
+
continue;
|
|
38897
|
+
}
|
|
38898
|
+
const allowed = new Set(selection.allowedTools);
|
|
38899
|
+
const missingTools = required.filter((tool) => !allowed.has(tool));
|
|
38900
|
+
if (missingTools.length > 0) {
|
|
38901
|
+
issues.push({ providerConfigKey: selection.providerConfigKey, code: "missing_required_tools", missingTools });
|
|
38902
|
+
}
|
|
38903
|
+
const requiredSet = new Set(required);
|
|
38904
|
+
const unexpectedTools = [...allowed].filter((tool) => !requiredSet.has(tool));
|
|
38905
|
+
if (unexpectedTools.length > 0) {
|
|
38906
|
+
issues.push({ providerConfigKey: selection.providerConfigKey, code: "unexpected_tools", unexpectedTools });
|
|
38907
|
+
}
|
|
38908
|
+
}
|
|
38909
|
+
return issues;
|
|
38910
|
+
}
|
|
38911
|
+
function connectionSyncSelectionError(connections) {
|
|
38912
|
+
if (connections.length === 0) {
|
|
38913
|
+
return "Data sync requires at least one bound service connection with approved read-only tools.";
|
|
38914
|
+
}
|
|
38915
|
+
const issues = connectionSyncPolicyIssues(connections);
|
|
38916
|
+
const unsupported = [...new Set(issues.filter((issue) => issue.code === "unsupported_provider").map((issue) => issue.providerConfigKey))];
|
|
38917
|
+
if (unsupported.length > 0) {
|
|
38918
|
+
return `Data sync currently supports only ${Object.keys(CONNECTION_SYNC_REQUIRED_TOOLS).join(", ")}. Unsupported providerConfigKey: ${unsupported.join(", ")}.`;
|
|
38919
|
+
}
|
|
38920
|
+
const missing = issues.filter((issue) => issue.code === "missing_required_tools").map((issue) => `${issue.providerConfigKey}: ${(issue.missingTools ?? []).join(", ")}`);
|
|
38921
|
+
if (missing.length > 0) {
|
|
38922
|
+
return `Data sync is missing required approved read tools (${missing.join("; ")}).`;
|
|
38923
|
+
}
|
|
38924
|
+
const unexpected = issues.filter((issue) => issue.code === "unexpected_tools").map((issue) => `${issue.providerConfigKey}: ${(issue.unexpectedTools ?? []).join(", ")}`);
|
|
38925
|
+
return unexpected.length > 0 ? `Data sync permits only its exact read-only tool set; remove unexpected tools (${unexpected.join("; ")}).` : null;
|
|
38926
|
+
}
|
|
38887
38927
|
function controlBaseUrl() {
|
|
38888
38928
|
return (process.env.NANGO_CONTROL_URL?.trim() || DEFAULT_NANGO_CONTROL_URL).replace(/\/$/, "");
|
|
38889
38929
|
}
|
|
@@ -39013,6 +39053,7 @@ async function getNangoCatalog() {
|
|
|
39013
39053
|
], 100);
|
|
39014
39054
|
const appReviewStatus = row.appReviewLimited === true || row.app_review_limited === true ? "limited" : firstString(row, ["appReviewStatus", "app_review_status", "reviewStatus", "review_status"], 100);
|
|
39015
39055
|
const appReviewNote = firstString(row, ["appReviewNote", "app_review_note", "reviewNote", "review_note"], 500);
|
|
39056
|
+
const connectionSyncRequiredTools = [...CONNECTION_SYNC_REQUIRED_TOOLS[providerConfigKey] ?? []];
|
|
39016
39057
|
result.push({
|
|
39017
39058
|
providerConfigKey,
|
|
39018
39059
|
provider,
|
|
@@ -39023,6 +39064,8 @@ async function getNangoCatalog() {
|
|
|
39023
39064
|
authMode,
|
|
39024
39065
|
categories,
|
|
39025
39066
|
safeDefaultAllowedTools,
|
|
39067
|
+
connectionSyncSupported: connectionSyncRequiredTools.length > 0,
|
|
39068
|
+
connectionSyncRequiredTools,
|
|
39026
39069
|
platformSetupStatus,
|
|
39027
39070
|
appReviewStatus,
|
|
39028
39071
|
appReviewNote
|
|
@@ -39186,7 +39229,7 @@ async function callScheduleConnectionRead(identity, connectionId, tool, args) {
|
|
|
39186
39229
|
const data = unwrapData(body);
|
|
39187
39230
|
return isRecord(data) ? data.result ?? data : data;
|
|
39188
39231
|
}
|
|
39189
|
-
var DEFAULT_NANGO_CONTROL_URL, DISABLED_NANGO_TOOLS, NangoControlError, ScheduleConnectionValidationError;
|
|
39232
|
+
var DEFAULT_NANGO_CONTROL_URL, DISABLED_NANGO_TOOLS, CONNECTION_SYNC_REQUIRED_TOOLS, NangoControlError, ScheduleConnectionValidationError;
|
|
39190
39233
|
var init_nango_control = __esm({
|
|
39191
39234
|
"src/api/nango-control.ts"() {
|
|
39192
39235
|
"use strict";
|
|
@@ -39195,6 +39238,17 @@ var init_nango_control = __esm({
|
|
|
39195
39238
|
"google-mail": /* @__PURE__ */ new Set(["list-filters"]),
|
|
39196
39239
|
slack: /* @__PURE__ */ new Set(["search-files", "search-messages"])
|
|
39197
39240
|
};
|
|
39241
|
+
CONNECTION_SYNC_REQUIRED_TOOLS = {
|
|
39242
|
+
"google-mail": ["list-messages", "get-message"],
|
|
39243
|
+
"google-calendar": ["list-events", "get-event"],
|
|
39244
|
+
zoom: [
|
|
39245
|
+
"list-meetings",
|
|
39246
|
+
"get-meeting",
|
|
39247
|
+
"list-recordings",
|
|
39248
|
+
"get-recording",
|
|
39249
|
+
"get-meeting-transcript"
|
|
39250
|
+
]
|
|
39251
|
+
};
|
|
39198
39252
|
NangoControlError = class extends Error {
|
|
39199
39253
|
status;
|
|
39200
39254
|
constructor(message, status = 502) {
|
|
@@ -40266,9 +40320,10 @@ var init_server = __esm({
|
|
|
40266
40320
|
try {
|
|
40267
40321
|
const actions = await Promise.all(r.actions.map(async (action) => {
|
|
40268
40322
|
const id = typeof action.id === "string" ? action.id : "";
|
|
40269
|
-
|
|
40323
|
+
const executionMode = action.executionMode === "connection_sync" ? "connection_sync" : "agent";
|
|
40324
|
+
if (!id) return { ...action, executionMode, connections: [] };
|
|
40270
40325
|
const bindings = await getScheduleConnectionBindings(user.email, id);
|
|
40271
|
-
return { ...action, connections: bindingsForSchedule(bindings, id) };
|
|
40326
|
+
return { ...action, executionMode, connections: bindingsForSchedule(bindings, id) };
|
|
40272
40327
|
}));
|
|
40273
40328
|
return c.json({
|
|
40274
40329
|
...r,
|
|
@@ -40278,7 +40333,7 @@ var init_server = __esm({
|
|
|
40278
40333
|
console.warn("[schedule-actions] connection bindings unavailable:", err instanceof Error ? err.message : String(err));
|
|
40279
40334
|
return c.json({
|
|
40280
40335
|
...r,
|
|
40281
|
-
actions: r.actions.map((action) => ({ ...action, connections: [] })),
|
|
40336
|
+
actions: r.actions.map((action) => ({ ...action, executionMode: action.executionMode === "connection_sync" ? "connection_sync" : "agent", connections: [] })),
|
|
40282
40337
|
connectionBindingsUnavailable: true
|
|
40283
40338
|
});
|
|
40284
40339
|
}
|
|
@@ -40288,6 +40343,10 @@ var init_server = __esm({
|
|
|
40288
40343
|
const { key, error } = await getOrCreateUserMemoryKey(user);
|
|
40289
40344
|
if (!key) return c.json({ ok: false, error: error ?? "memory unavailable" }, 503);
|
|
40290
40345
|
const body = await c.req.json().catch(() => ({}));
|
|
40346
|
+
const executionMode = body.executionMode ?? "agent";
|
|
40347
|
+
if (executionMode !== "agent" && executionMode !== "connection_sync") {
|
|
40348
|
+
return c.json({ ok: false, error: 'executionMode must be "agent" or "connection_sync".' }, 400);
|
|
40349
|
+
}
|
|
40291
40350
|
const hasConnections = Object.prototype.hasOwnProperty.call(body, "connections");
|
|
40292
40351
|
let connections;
|
|
40293
40352
|
try {
|
|
@@ -40295,18 +40354,23 @@ var init_server = __esm({
|
|
|
40295
40354
|
} catch (err) {
|
|
40296
40355
|
return scheduleConnectionError(c, err, "Invalid service connections.");
|
|
40297
40356
|
}
|
|
40298
|
-
|
|
40357
|
+
if (executionMode === "connection_sync") {
|
|
40358
|
+
const policyError = connectionSyncSelectionError(connections);
|
|
40359
|
+
if (policyError) return c.json({ ok: false, error: policyError }, 400);
|
|
40360
|
+
}
|
|
40361
|
+
const actionBody = { ...body, executionMode };
|
|
40299
40362
|
delete actionBody.connections;
|
|
40300
40363
|
const r = await memoryCall("createScheduledActionTool", actionBody, key);
|
|
40301
|
-
|
|
40302
|
-
if (
|
|
40364
|
+
const createResponse = { ...r, executionMode };
|
|
40365
|
+
if (!r.ok || !hasConnections) return c.json(createResponse);
|
|
40366
|
+
if (connections.length === 0) return c.json({ ...createResponse, connections: [] });
|
|
40303
40367
|
if (!r.id) {
|
|
40304
40368
|
console.error("[schedule-actions] create returned no id while service connections were requested");
|
|
40305
40369
|
return c.json({ ok: false, error: "The scheduled action was created without a usable id; service connections were not attached." }, 502);
|
|
40306
40370
|
}
|
|
40307
40371
|
try {
|
|
40308
40372
|
const bound = await putScheduleConnectionBindings(user.email, r.id, connections);
|
|
40309
|
-
return c.json({ ...
|
|
40373
|
+
return c.json({ ...createResponse, connections: bound });
|
|
40310
40374
|
} catch (err) {
|
|
40311
40375
|
const rollback = await memoryCall("deleteScheduledActionTool", { id: r.id }, key).catch(() => ({ ok: false }));
|
|
40312
40376
|
if (!rollback.ok) console.error("[schedule-actions] failed to compensate action after connection binding failure", r.id);
|
|
@@ -40344,6 +40408,16 @@ var init_server = __esm({
|
|
|
40344
40408
|
}
|
|
40345
40409
|
try {
|
|
40346
40410
|
const scheduleActionId = c.req.param("id");
|
|
40411
|
+
const { key, error } = await getOrCreateUserMemoryKey(user);
|
|
40412
|
+
if (!key) return c.json({ ok: false, error: error ?? "memory unavailable" }, 503);
|
|
40413
|
+
const schedules = await memoryCall("listScheduledActionsTool", {}, key);
|
|
40414
|
+
if (!schedules.ok || !Array.isArray(schedules.actions)) return c.json(schedules, 502);
|
|
40415
|
+
const schedule = schedules.actions.find((action) => action.id === scheduleActionId);
|
|
40416
|
+
if (!schedule) return c.json({ ok: false, error: "scheduled action not found" }, 404);
|
|
40417
|
+
if (schedule.executionMode === "connection_sync") {
|
|
40418
|
+
const policyError = connectionSyncSelectionError(connections);
|
|
40419
|
+
if (policyError) return c.json({ ok: false, error: policyError }, 400);
|
|
40420
|
+
}
|
|
40347
40421
|
const bindings = await putScheduleConnectionBindings(user.email, scheduleActionId, connections);
|
|
40348
40422
|
return c.json({ ok: true, connections: bindings });
|
|
40349
40423
|
} catch (err) {
|