mcp-scraper 0.72.3 → 0.72.5

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/CHANGELOG.md CHANGED
@@ -4,6 +4,18 @@ All notable changes to MCP Scraper are documented here. The format is based on [
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.72.5] - 2026-08-27
8
+
9
+ ### Fixed
10
+
11
+ - Gmail Memory imports now provide deterministic descriptions for newly encountered import tags, allowing complete messages, manifests, and attachments to enter the selected vault instead of stopping at the first note write.
12
+
13
+ ## [0.72.4] - 2026-08-27
14
+
15
+ ### Fixed
16
+
17
+ - `gmail_send_message` now uses the same owner-checked, action-gated Gmail REST transport as complete reads and bulk actions, with a durable idempotency receipt, instead of depending on the unavailable generic provider MCP send transport.
18
+
7
19
  ## [0.72.3] - 2026-08-27
8
20
 
9
21
  ### Fixed
@@ -1260,7 +1272,9 @@ All notable changes to MCP Scraper are documented here. The format is based on [
1260
1272
  - Write actions remain unavailable until the account owner explicitly enables them.
1261
1273
  - Provider-specific connection data is normalized into one agent-facing contract.
1262
1274
 
1263
- [Unreleased]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.72.3...HEAD
1275
+ [Unreleased]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.72.5...HEAD
1276
+ [0.72.5]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.72.4...v0.72.5
1277
+ [0.72.4]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.72.3...v0.72.4
1264
1278
  [0.72.3]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.72.2...v0.72.3
1265
1279
  [0.72.2]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.72.1...v0.72.2
1266
1280
  [0.72.1]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.72.0...v0.72.1
package/README.md CHANGED
@@ -159,7 +159,7 @@ Build the branded one-click bundle:
159
159
  npm run build:mcpb
160
160
  ```
161
161
 
162
- 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.72.3`, SHA-256 `2d0a2d317cdd870c43a34163565614ce7edc0c24597c88d1a329d6c4914c94a3`). Install it by opening or dragging it into Claude Desktop. Claude displays the `MCP Scraper` install card, icon, API-key configuration field, and manually curated current-release message from the bundle manifest.
162
+ 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.72.5`, SHA-256 `fa1470cbf16f4586a6009e32f0278078e7a99065676bf8ad1975db70736ad5fb`). Install it by opening or dragging it into Claude Desktop. Claude displays the `MCP Scraper` install card, icon, API-key configuration field, and manually curated current-release message from the bundle manifest.
163
163
 
164
164
  The MCPB install exposes every tool — web-intelligence plus all `browser_*` tools — through the one `mcp-scraper` server.
165
165
 
@@ -44074,6 +44074,7 @@ var init_main_nango_transport = __esm({
44074
44074
  { method: "GET", pattern: /^\/gmail\/v1\/users\/me\/labels$/ },
44075
44075
  { method: "POST", pattern: /^\/gmail\/v1\/users\/me\/messages\/batchModify$/ },
44076
44076
  { method: "POST", pattern: /^\/gmail\/v1\/users\/me\/messages\/batchDelete$/ },
44077
+ { method: "POST", pattern: /^\/gmail\/v1\/users\/me\/messages\/send$/ },
44077
44078
  { method: "POST", pattern: /^\/gmail\/v1\/users\/me\/messages\/[A-Za-z0-9_-]+\/(?:trash|untrash)$/ }
44078
44079
  ];
44079
44080
  GMAIL_QUERY_KEYS = /* @__PURE__ */ new Set(["q", "maxResults", "pageToken", "format", "metadataHeaders", "fields"]);
@@ -44379,6 +44380,21 @@ function base64urlDecode(value) {
44379
44380
  const normalized = value.replace(/-/g, "+").replace(/_/g, "/");
44380
44381
  return Buffer.from(normalized.padEnd(Math.ceil(normalized.length / 4) * 4, "="), "base64");
44381
44382
  }
44383
+ function encodeHeaderValue(value) {
44384
+ return /^[\x20-\x7e]*$/.test(value) ? value : `=?UTF-8?B?${Buffer.from(value, "utf8").toString("base64")}?=`;
44385
+ }
44386
+ function buildRawTextMessage(to, subject, body) {
44387
+ const encodedBody = Buffer.from(body, "utf8").toString("base64").match(/.{1,76}/g)?.join("\r\n") ?? "";
44388
+ return [
44389
+ `To: ${to}`,
44390
+ `Subject: ${encodeHeaderValue(subject)}`,
44391
+ "MIME-Version: 1.0",
44392
+ "Content-Type: text/plain; charset=UTF-8",
44393
+ "Content-Transfer-Encoding: base64",
44394
+ "",
44395
+ encodedBody
44396
+ ].join("\r\n");
44397
+ }
44382
44398
  function decodeQuotedPrintable(buffer) {
44383
44399
  const source = buffer.toString("latin1").replace(/=\r?\n/g, "");
44384
44400
  const bytes = [];
@@ -44637,6 +44653,39 @@ var init_gmail_service = __esm({
44637
44653
  this.createArtifact = dependencies.createArtifact ?? createConnectedDataBinaryArtifact;
44638
44654
  this.createJsonlArtifact = dependencies.createJsonlArtifact ?? createConnectedDataArtifact;
44639
44655
  }
44656
+ async sendMessage(args) {
44657
+ const to = args.to.trim().toLowerCase();
44658
+ const subject = args.subject.trim();
44659
+ if (!/^[^\s@<>]+@[^\s@<>]+\.[^\s@<>]+$/.test(to) || /[\r\n]/.test(args.to)) throw new GmailServiceError("invalid_request", "A valid recipient email address is required.");
44660
+ if (!subject || subject.length > 500 || /[\r\n]/.test(subject)) throw new GmailServiceError("invalid_request", "A subject of at most 500 characters without line breaks is required.");
44661
+ if (!args.body || args.body.length > 5e4) throw new GmailServiceError("invalid_request", "A plain-text body of at most 50,000 characters is required.");
44662
+ if (args.idempotencyKey.length < 8 || args.idempotencyKey.length > 200) throw new GmailServiceError("idempotency_key_invalid", "Idempotency key must contain 8-200 characters.");
44663
+ const fingerprint3 = gmailFingerprint({ connectionId: args.connectionId, to, subject, bodySha256: (0, import_node_crypto25.createHash)("sha256").update(args.body).digest("hex") });
44664
+ const begun = await beginGmailAction({ ownerId: args.ownerId, idempotencyKey: args.idempotencyKey, fingerprint: fingerprint3 });
44665
+ if (begun.replay && begun.execution.result) return { ...begun.execution.result, replay: true };
44666
+ if (begun.replay) return { actionId: begun.execution.actionId, status: "outcome_unknown", replay: true, retryable: false };
44667
+ const claim = await claimGmailActionChunk(begun.execution.actionId, "send:0");
44668
+ if (!claim.claimed) return { ...claim.receipt.result ?? {}, actionId: begun.execution.actionId, status: claim.receipt.status, replay: true };
44669
+ try {
44670
+ const payload = record(await this.providerCall({
44671
+ identity: args.providerIdentity ?? args.ownerId,
44672
+ connectionId: args.connectionId,
44673
+ method: "POST",
44674
+ path: "/gmail/v1/users/me/messages/send",
44675
+ body: { raw: Buffer.from(buildRawTextMessage(to, subject, args.body), "utf8").toString("base64url") },
44676
+ requestId: args.idempotencyKey
44677
+ }));
44678
+ const result2 = { actionId: begun.execution.actionId, status: "complete", messageId: stringValue(payload?.id), threadId: stringValue(payload?.threadId), replay: false };
44679
+ await finishGmailActionChunk(begun.execution.actionId, "send:0", "complete", result2);
44680
+ await finishGmailAction(begun.execution.actionId, "complete", result2);
44681
+ return result2;
44682
+ } catch (error) {
44683
+ const result2 = { actionId: begun.execution.actionId, status: "outcome_unknown", code: serviceErrorCode(error), retryable: false };
44684
+ await finishGmailActionChunk(begun.execution.actionId, "send:0", "failed", result2);
44685
+ await finishGmailAction(begun.execution.actionId, "partial", result2);
44686
+ throw error;
44687
+ }
44688
+ }
44640
44689
  async searchMessages(args) {
44641
44690
  const query = args.query.trim();
44642
44691
  if (!query || query.length > 2e3) throw new GmailServiceError("invalid_request", "A Gmail query of at most 2,000 characters is required.");
@@ -45475,6 +45524,21 @@ function gmailFileAssetSaveArguments(args) {
45475
45524
  idempotencyKey: args.idempotencyKey
45476
45525
  };
45477
45526
  }
45527
+ function gmailMemoryNoteArguments(args) {
45528
+ const descriptions = {
45529
+ gmail: "Content preserved from an owner-authorized Gmail connection.",
45530
+ "email-import": "A complete email source captured through the Gmail import workflow.",
45531
+ "import-manifest": "A durable manifest recording a completed or partial source import."
45532
+ };
45533
+ return {
45534
+ vault: args.vault,
45535
+ path: args.path,
45536
+ title: args.title,
45537
+ content: args.content,
45538
+ props: { sourceKey: args.sourceKey, capturedAt: args.capturedAt, tags: args.tags, references: args.references ?? [] },
45539
+ tagDescriptions: Object.fromEntries(args.tags.map((tag) => [tag, descriptions[tag] ?? `Gmail import tag: ${tag}.`]))
45540
+ };
45541
+ }
45478
45542
  function gmailMemoryAssetToolsForMime(mimeType) {
45479
45543
  return mimeType.startsWith("image/") ? { saveTool: "image_asset_save", getTool: "image_asset_get" } : { saveTool: "file_asset_save", getTool: "file_asset_get" };
45480
45544
  }
@@ -45513,7 +45577,7 @@ async function memoryPort(c) {
45513
45577
  },
45514
45578
  async saveNote(args) {
45515
45579
  const path6 = `gmail/${(0, import_node_crypto29.createHash)("sha256").update(args.sourceKey).digest("hex")}.md`;
45516
- const result2 = await memoryCall("putTool", { vault: args.vault, path: path6, title: args.title, content: args.content, props: { sourceKey: args.sourceKey, capturedAt: args.capturedAt, tags: args.tags, references: args.references ?? [] } }, key2);
45580
+ const result2 = await memoryCall("putTool", gmailMemoryNoteArguments({ ...args, path: path6 }), key2);
45517
45581
  if (!result2.ok) throw new GmailMemoryIngestError("memory_note_failed", String(result2.error ?? "Memory note write failed."), 503, true);
45518
45582
  return { ...result2, path: path6 };
45519
45583
  },
@@ -54132,7 +54196,7 @@ var PACKAGE_VERSION;
54132
54196
  var init_version = __esm({
54133
54197
  "src/version.ts"() {
54134
54198
  "use strict";
54135
- PACKAGE_VERSION = "0.72.3";
54199
+ PACKAGE_VERSION = "0.72.5";
54136
54200
  }
54137
54201
  });
54138
54202
 
@@ -105068,7 +105132,7 @@ function settleWithinTickBudget(label, unfinished, work, onDeadlineOrError) {
105068
105132
  );
105069
105133
  });
105070
105134
  }
105071
- var import_resend3, import_node_crypto98, import_hono39, import_hono40, import_factory8, import_cookie2, import_stripe2, secureCookies2, isProduction2, sessionCookieOptions2, requireAllowedOrigin, auth5, sessionAuth, requireIntegrationsTier, requirePaidSchedulingTier, app, deploymentProfile, STRIPE_API_VERSION, SYNC_HARVEST_TIMEOUT_OVERRIDE_MS, CRON_TICK_BUDGET_MS, CRON_TICK_DRAIN_BUDGET_MS;
105135
+ var import_resend3, import_node_crypto98, import_hono39, import_hono40, import_factory8, import_cookie2, import_stripe2, secureCookies2, isProduction2, sessionCookieOptions2, requireAllowedOrigin, auth5, sessionAuth, requireIntegrationsTier, requirePaidSchedulingTier, app, deploymentProfile, STRIPE_API_VERSION, directGmailService, SYNC_HARVEST_TIMEOUT_OVERRIDE_MS, CRON_TICK_BUDGET_MS, CRON_TICK_DRAIN_BUDGET_MS;
105072
105136
  var init_server = __esm({
105073
105137
  "src/api/server.ts"() {
105074
105138
  "use strict";
@@ -105113,6 +105177,7 @@ var init_server = __esm({
105113
105177
  init_instagram_routes();
105114
105178
  init_reddit_routes();
105115
105179
  init_gmail_routes();
105180
+ init_gmail_service();
105116
105181
  init_video_routes();
105117
105182
  init_maps_routes();
105118
105183
  init_trustpilot_routes();
@@ -105990,6 +106055,7 @@ var init_server = __esm({
105990
106055
  return scheduleConnectionError(c, err, "Unable to send the Slack message.");
105991
106056
  }
105992
106057
  });
106058
+ directGmailService = new GmailService();
105993
106059
  app.post("/schedule-connections/actions/gmail/send-message", auth5, requireIntegrationsTier, async (c) => {
105994
106060
  const user = c.get("user");
105995
106061
  const body = await c.req.json().catch(() => ({}));
@@ -105998,13 +106064,15 @@ var init_server = __esm({
105998
106064
  return c.json({ ok: false, error: "connectionId, to, subject, and body are required." }, 400);
105999
106065
  }
106000
106066
  try {
106001
- const result2 = await callScheduleConnectionAction(
106002
- user.email,
106067
+ const result2 = await directGmailService.sendMessage({
106068
+ ownerId: (0, import_node_crypto98.createHash)("sha256").update(user.api_key).digest("hex").slice(0, 24),
106069
+ providerIdentity: user.email,
106003
106070
  connectionId,
106004
- { to: body.to, subject: body.subject, body: body.body },
106005
- "send-message",
106006
- connectedActionIdempotencyKey(c)
106007
- );
106071
+ to: body.to,
106072
+ subject: body.subject,
106073
+ body: body.body,
106074
+ idempotencyKey: connectedActionIdempotencyKey(c)
106075
+ });
106008
106076
  return c.json({ ok: true, result: result2 });
106009
106077
  } catch (err) {
106010
106078
  return scheduleConnectionError(c, err, "Unable to send the email.");
@@ -17,7 +17,7 @@ loadDotEnv();
17
17
  async function main() {
18
18
  const [{ serve }, { app }, { startWorker }, { migrate }] = await Promise.all([
19
19
  import("@hono/node-server"),
20
- import("../server-MCB6LV5G.js"),
20
+ import("../server-IABKDP7V.js"),
21
21
  import("../worker-JQORPCFQ.js"),
22
22
  import("../db-566MOHHD.js")
23
23
  ]);
@@ -30,7 +30,7 @@ var import_promises5 = require("fs/promises");
30
30
  var import_node_path3 = require("path");
31
31
 
32
32
  // src/version.ts
33
- var PACKAGE_VERSION = "0.72.3";
33
+ var PACKAGE_VERSION = "0.72.5";
34
34
 
35
35
  // src/cli/agent-config.ts
36
36
  function apiKeyValue(options) {
@@ -13,7 +13,7 @@ import "../chunk-VXLU74YZ.js";
13
13
  import "../chunk-GGZEC22A.js";
14
14
  import {
15
15
  PACKAGE_VERSION
16
- } from "../chunk-V2YM7V4E.js";
16
+ } from "../chunk-WHXNA6GK.js";
17
17
 
18
18
  // src/cli/human-cli.ts
19
19
  import { Command } from "commander";
@@ -112,7 +112,7 @@ function renderInstallTerminal(options) {
112
112
  }
113
113
 
114
114
  // src/version.ts
115
- var PACKAGE_VERSION = "0.72.3";
115
+ var PACKAGE_VERSION = "0.72.5";
116
116
 
117
117
  // bin/mcp-scraper-install.ts
118
118
  var noColor = process.argv.includes("--no-color") || process.env.NO_COLOR !== void 0 || process.env.FORCE_COLOR === "0" || !process.stdout.isTTY;
@@ -4,7 +4,7 @@ import {
4
4
  } from "../chunk-RAFQEPJ4.js";
5
5
  import {
6
6
  PACKAGE_VERSION
7
- } from "../chunk-V2YM7V4E.js";
7
+ } from "../chunk-WHXNA6GK.js";
8
8
 
9
9
  // bin/mcp-scraper-install.ts
10
10
  var noColor = process.argv.includes("--no-color") || process.env.NO_COLOR !== void 0 || process.env.FORCE_COLOR === "0" || !process.stdout.isTTY;
@@ -6950,7 +6950,7 @@ render();
6950
6950
  }
6951
6951
 
6952
6952
  // src/version.ts
6953
- var PACKAGE_VERSION = "0.72.3";
6953
+ var PACKAGE_VERSION = "0.72.5";
6954
6954
 
6955
6955
  // src/mcp/input-field-descriptions.ts
6956
6956
  var import_zod2 = require("zod");
@@ -13,7 +13,7 @@ import {
13
13
  registerScheduledResultsMcpTools,
14
14
  registerSerpIntelligenceCaptureTools,
15
15
  resolveDeploymentProfile
16
- } from "../chunk-QRXSCUU2.js";
16
+ } from "../chunk-3SECYTNB.js";
17
17
  import "../chunk-PGJQDMC2.js";
18
18
  import "../chunk-T3MZISOF.js";
19
19
  import "../chunk-7RQULQF3.js";
@@ -26,7 +26,7 @@ import "../chunk-VXLU74YZ.js";
26
26
  import "../chunk-GGZEC22A.js";
27
27
  import {
28
28
  PACKAGE_VERSION
29
- } from "../chunk-V2YM7V4E.js";
29
+ } from "../chunk-WHXNA6GK.js";
30
30
  import "../chunk-DNM65UCK.js";
31
31
  import "../chunk-FVL4GUTP.js";
32
32
  import "../chunk-WEFPBAAG.js";
@@ -32,7 +32,7 @@ import {
32
32
  } from "./chunk-VXLU74YZ.js";
33
33
  import {
34
34
  PACKAGE_VERSION
35
- } from "./chunk-V2YM7V4E.js";
35
+ } from "./chunk-WHXNA6GK.js";
36
36
  import {
37
37
  createPrivateArtifact,
38
38
  privateArtifactOwnerId,
@@ -755,6 +755,7 @@ var GMAIL_PROXY_PATHS = [
755
755
  { method: "GET", pattern: /^\/gmail\/v1\/users\/me\/labels$/ },
756
756
  { method: "POST", pattern: /^\/gmail\/v1\/users\/me\/messages\/batchModify$/ },
757
757
  { method: "POST", pattern: /^\/gmail\/v1\/users\/me\/messages\/batchDelete$/ },
758
+ { method: "POST", pattern: /^\/gmail\/v1\/users\/me\/messages\/send$/ },
758
759
  { method: "POST", pattern: /^\/gmail\/v1\/users\/me\/messages\/[A-Za-z0-9_-]+\/(?:trash|untrash)$/ }
759
760
  ];
760
761
  var GMAIL_QUERY_KEYS = /* @__PURE__ */ new Set(["q", "maxResults", "pageToken", "format", "metadataHeaders", "fields"]);
@@ -1496,6 +1497,21 @@ function base64urlDecode(value) {
1496
1497
  const normalized = value.replace(/-/g, "+").replace(/_/g, "/");
1497
1498
  return Buffer.from(normalized.padEnd(Math.ceil(normalized.length / 4) * 4, "="), "base64");
1498
1499
  }
1500
+ function encodeHeaderValue(value) {
1501
+ return /^[\x20-\x7e]*$/.test(value) ? value : `=?UTF-8?B?${Buffer.from(value, "utf8").toString("base64")}?=`;
1502
+ }
1503
+ function buildRawTextMessage(to, subject, body) {
1504
+ const encodedBody = Buffer.from(body, "utf8").toString("base64").match(/.{1,76}/g)?.join("\r\n") ?? "";
1505
+ return [
1506
+ `To: ${to}`,
1507
+ `Subject: ${encodeHeaderValue(subject)}`,
1508
+ "MIME-Version: 1.0",
1509
+ "Content-Type: text/plain; charset=UTF-8",
1510
+ "Content-Transfer-Encoding: base64",
1511
+ "",
1512
+ encodedBody
1513
+ ].join("\r\n");
1514
+ }
1499
1515
  function decodeQuotedPrintable(buffer) {
1500
1516
  const source = buffer.toString("latin1").replace(/=\r?\n/g, "");
1501
1517
  const bytes = [];
@@ -1666,6 +1682,39 @@ var GmailService = class {
1666
1682
  this.createArtifact = dependencies.createArtifact ?? createConnectedDataBinaryArtifact;
1667
1683
  this.createJsonlArtifact = dependencies.createJsonlArtifact ?? createConnectedDataArtifact;
1668
1684
  }
1685
+ async sendMessage(args) {
1686
+ const to = args.to.trim().toLowerCase();
1687
+ const subject = args.subject.trim();
1688
+ if (!/^[^\s@<>]+@[^\s@<>]+\.[^\s@<>]+$/.test(to) || /[\r\n]/.test(args.to)) throw new GmailServiceError("invalid_request", "A valid recipient email address is required.");
1689
+ if (!subject || subject.length > 500 || /[\r\n]/.test(subject)) throw new GmailServiceError("invalid_request", "A subject of at most 500 characters without line breaks is required.");
1690
+ if (!args.body || args.body.length > 5e4) throw new GmailServiceError("invalid_request", "A plain-text body of at most 50,000 characters is required.");
1691
+ if (args.idempotencyKey.length < 8 || args.idempotencyKey.length > 200) throw new GmailServiceError("idempotency_key_invalid", "Idempotency key must contain 8-200 characters.");
1692
+ const fingerprint = gmailFingerprint({ connectionId: args.connectionId, to, subject, bodySha256: createHash4("sha256").update(args.body).digest("hex") });
1693
+ const begun = await beginGmailAction({ ownerId: args.ownerId, idempotencyKey: args.idempotencyKey, fingerprint });
1694
+ if (begun.replay && begun.execution.result) return { ...begun.execution.result, replay: true };
1695
+ if (begun.replay) return { actionId: begun.execution.actionId, status: "outcome_unknown", replay: true, retryable: false };
1696
+ const claim = await claimGmailActionChunk(begun.execution.actionId, "send:0");
1697
+ if (!claim.claimed) return { ...claim.receipt.result ?? {}, actionId: begun.execution.actionId, status: claim.receipt.status, replay: true };
1698
+ try {
1699
+ const payload = record(await this.providerCall({
1700
+ identity: args.providerIdentity ?? args.ownerId,
1701
+ connectionId: args.connectionId,
1702
+ method: "POST",
1703
+ path: "/gmail/v1/users/me/messages/send",
1704
+ body: { raw: Buffer.from(buildRawTextMessage(to, subject, args.body), "utf8").toString("base64url") },
1705
+ requestId: args.idempotencyKey
1706
+ }));
1707
+ const result = { actionId: begun.execution.actionId, status: "complete", messageId: stringValue(payload?.id), threadId: stringValue(payload?.threadId), replay: false };
1708
+ await finishGmailActionChunk(begun.execution.actionId, "send:0", "complete", result);
1709
+ await finishGmailAction(begun.execution.actionId, "complete", result);
1710
+ return result;
1711
+ } catch (error) {
1712
+ const result = { actionId: begun.execution.actionId, status: "outcome_unknown", code: serviceErrorCode(error), retryable: false };
1713
+ await finishGmailActionChunk(begun.execution.actionId, "send:0", "failed", result);
1714
+ await finishGmailAction(begun.execution.actionId, "partial", result);
1715
+ throw error;
1716
+ }
1717
+ }
1669
1718
  async searchMessages(args) {
1670
1719
  const query = args.query.trim();
1671
1720
  if (!query || query.length > 2e3) throw new GmailServiceError("invalid_request", "A Gmail query of at most 2,000 characters is required.");
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var PACKAGE_VERSION = "0.72.3";
2
+ var PACKAGE_VERSION = "0.72.5";
3
3
 
4
4
  export {
5
5
  PACKAGE_VERSION
@@ -7,7 +7,7 @@ import {
7
7
  GmailServiceError,
8
8
  normalizeGmailMessage,
9
9
  parseGmailAddresses
10
- } from "./chunk-MB72PA6S.js";
10
+ } from "./chunk-K2SXQGKM.js";
11
11
  import "./chunk-PJEEKOUM.js";
12
12
  import "./chunk-T3MZISOF.js";
13
13
  import "./chunk-CXY5WV45.js";
@@ -70,7 +70,7 @@ import {
70
70
  probeNangoConnectionDirect,
71
71
  recordNangoConnectionCost,
72
72
  settleConnectedUsage
73
- } from "./chunk-MB72PA6S.js";
73
+ } from "./chunk-K2SXQGKM.js";
74
74
  import {
75
75
  ANALYTICS_CONTENT_SORTS,
76
76
  AnalyticsProviderRegistryError,
@@ -271,7 +271,7 @@ import {
271
271
  resolveDeploymentProfile,
272
272
  resolveLocalSourcebookSchemaType,
273
273
  transcribeMediaUrl
274
- } from "./chunk-QRXSCUU2.js";
274
+ } from "./chunk-3SECYTNB.js";
275
275
  import {
276
276
  auditImageUrls,
277
277
  auditImages,
@@ -336,7 +336,7 @@ import {
336
336
  } from "./chunk-GGZEC22A.js";
337
337
  import {
338
338
  PACKAGE_VERSION
339
- } from "./chunk-V2YM7V4E.js";
339
+ } from "./chunk-WHXNA6GK.js";
340
340
  import {
341
341
  SITE_EXTRACT_ARTIFACT_PREFIX,
342
342
  abandonExtractSettlement,
@@ -3845,7 +3845,7 @@ async function generateOgImage(post) {
3845
3845
 
3846
3846
  // src/api/server.ts
3847
3847
  import { Resend as Resend3 } from "resend";
3848
- import { randomUUID as randomUUID39 } from "crypto";
3848
+ import { createHash as createHash48, randomUUID as randomUUID39 } from "crypto";
3849
3849
 
3850
3850
  // src/api/kpo-extractor.ts
3851
3851
  import TurndownService from "turndown";
@@ -21938,6 +21938,21 @@ function gmailFileAssetSaveArguments(args) {
21938
21938
  idempotencyKey: args.idempotencyKey
21939
21939
  };
21940
21940
  }
21941
+ function gmailMemoryNoteArguments(args) {
21942
+ const descriptions = {
21943
+ gmail: "Content preserved from an owner-authorized Gmail connection.",
21944
+ "email-import": "A complete email source captured through the Gmail import workflow.",
21945
+ "import-manifest": "A durable manifest recording a completed or partial source import."
21946
+ };
21947
+ return {
21948
+ vault: args.vault,
21949
+ path: args.path,
21950
+ title: args.title,
21951
+ content: args.content,
21952
+ props: { sourceKey: args.sourceKey, capturedAt: args.capturedAt, tags: args.tags, references: args.references ?? [] },
21953
+ tagDescriptions: Object.fromEntries(args.tags.map((tag) => [tag, descriptions[tag] ?? `Gmail import tag: ${tag}.`]))
21954
+ };
21955
+ }
21941
21956
  function gmailMemoryAssetToolsForMime(mimeType) {
21942
21957
  return mimeType.startsWith("image/") ? { saveTool: "image_asset_save", getTool: "image_asset_get" } : { saveTool: "file_asset_save", getTool: "file_asset_get" };
21943
21958
  }
@@ -21976,7 +21991,7 @@ async function memoryPort(c) {
21976
21991
  },
21977
21992
  async saveNote(args) {
21978
21993
  const path5 = `gmail/${createHash6("sha256").update(args.sourceKey).digest("hex")}.md`;
21979
- const result2 = await memoryCall("putTool", { vault: args.vault, path: path5, title: args.title, content: args.content, props: { sourceKey: args.sourceKey, capturedAt: args.capturedAt, tags: args.tags, references: args.references ?? [] } }, key2);
21994
+ const result2 = await memoryCall("putTool", gmailMemoryNoteArguments({ ...args, path: path5 }), key2);
21980
21995
  if (!result2.ok) throw new GmailMemoryIngestError("memory_note_failed", String(result2.error ?? "Memory note write failed."), 503, true);
21981
21996
  return { ...result2, path: path5 };
21982
21997
  },
@@ -45764,7 +45779,7 @@ async function callMainOwnedExportPage(identity, input) {
45764
45779
  });
45765
45780
  }
45766
45781
  if (connection.providerConfigKey === "google-mail" && input.dataset === "emails") {
45767
- const { GmailService: GmailService2 } = await import("./gmail-service-E276SBJU.js");
45782
+ const { GmailService: GmailService2 } = await import("./gmail-service-QXDGNWUJ.js");
45768
45783
  const service = new GmailService2();
45769
45784
  const ownerId3 = createHash27("sha256").update(identity.toLowerCase()).digest("hex").slice(0, 24);
45770
45785
  const after = Math.floor(Date.parse(input.from) / 1e3);
@@ -56776,6 +56791,7 @@ app.post("/schedule-connections/actions/slack/send-message", auth5, requireInteg
56776
56791
  return scheduleConnectionError(c, err, "Unable to send the Slack message.");
56777
56792
  }
56778
56793
  });
56794
+ var directGmailService = new GmailService();
56779
56795
  app.post("/schedule-connections/actions/gmail/send-message", auth5, requireIntegrationsTier, async (c) => {
56780
56796
  const user = c.get("user");
56781
56797
  const body = await c.req.json().catch(() => ({}));
@@ -56784,13 +56800,15 @@ app.post("/schedule-connections/actions/gmail/send-message", auth5, requireInteg
56784
56800
  return c.json({ ok: false, error: "connectionId, to, subject, and body are required." }, 400);
56785
56801
  }
56786
56802
  try {
56787
- const result2 = await callScheduleConnectionAction(
56788
- user.email,
56803
+ const result2 = await directGmailService.sendMessage({
56804
+ ownerId: createHash48("sha256").update(user.api_key).digest("hex").slice(0, 24),
56805
+ providerIdentity: user.email,
56789
56806
  connectionId,
56790
- { to: body.to, subject: body.subject, body: body.body },
56791
- "send-message",
56792
- connectedActionIdempotencyKey(c)
56793
- );
56807
+ to: body.to,
56808
+ subject: body.subject,
56809
+ body: body.body,
56810
+ idempotencyKey: connectedActionIdempotencyKey(c)
56811
+ });
56794
56812
  return c.json({ ok: true, result: result2 });
56795
56813
  } catch (err) {
56796
56814
  return scheduleConnectionError(c, err, "Unable to send the email.");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-scraper",
3
- "version": "0.72.3",
3
+ "version": "0.72.5",
4
4
  "description": "MCP server for MCP Scraper web intelligence tools",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",