proton-mail-bridge-client 1.17.1 → 1.18.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 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +33 -19
- package/dist/index.js.map +1 -1
- package/dist/services/simple-imap-service.d.ts.map +1 -1
- package/dist/services/simple-imap-service.js +4 -1
- package/dist/services/simple-imap-service.js.map +1 -1
- package/dist/services/snooze-service.d.ts.map +1 -1
- package/dist/services/snooze-service.js +4 -1
- package/dist/services/snooze-service.js.map +1 -1
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -346,6 +346,7 @@ PROTONMAIL_IMAP_PORT='1143'
|
|
|
346
346
|
PROTONMAIL_IMAP_SECURE='false'
|
|
347
347
|
PROTONMAIL_SMTP_HOST='127.0.0.1'
|
|
348
348
|
PROTONMAIL_SMTP_PORT='1025'
|
|
349
|
+
PROTONMAIL_SMTP_SECURE='true' # Bridge's local SMTP port requires implicit TLS from the first byte; set false only for a non-Bridge SMTP relay
|
|
349
350
|
|
|
350
351
|
# Secrets via file or command (avoids raw credentials in config)
|
|
351
352
|
PROTONMAIL_USERNAME_FILE='/path/to/user.txt'
|
package/dist/index.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { SimpleIMAPService } from "./services/simple-imap-service.js";
|
|
|
9
9
|
import { SMTPService } from "./services/smtp-service.js";
|
|
10
10
|
import { SnoozeService } from "./services/snooze-service.js";
|
|
11
11
|
import type { EmailDetail, ProtonMailConfig } from "./types/index.js";
|
|
12
|
+
export declare const CORE_TOOL_NAMES: Set<string>;
|
|
12
13
|
export declare function headerString(headers: Record<string, unknown> | undefined, name: string): string | undefined;
|
|
13
14
|
export declare function parseAuthenticationResults(value?: string): {
|
|
14
15
|
dkim?: string;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAOA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAYnE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAwD,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAC5H,OAAO,EAAkB,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE7D,OAAO,KAAK,EAUV,WAAW,EAEX,gBAAgB,EAEjB,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAOA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAYnE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAwD,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAC5H,OAAO,EAAkB,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE7D,OAAO,KAAK,EAUV,WAAW,EAEX,gBAAgB,EAEjB,MAAM,kBAAkB,CAAC;AAkqD1B,eAAO,MAAM,eAAe,aAyB1B,CAAC;AAuLH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAK3G;AAKD,wBAAgB,0BAA0B,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAI1G;AASD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAa9E;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,WAAW,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAS7F;AAk5BD,wBAAgB,kBAAkB,IAAI,gBAAgB,CAgGrD;AAED,wBAAgB,YAAY,CAC1B,MAAM,EAAE,gBAAgB,EACxB,OAAO,GAAE;IACP,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6pFP;AAED,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAqD1C"}
|
package/dist/index.js
CHANGED
|
@@ -718,7 +718,7 @@ const TOOLS = [
|
|
|
718
718
|
},
|
|
719
719
|
{
|
|
720
720
|
name: "snooze_email",
|
|
721
|
-
description: "Move an email out of sight into Folders/Snoozed and bring it back to its original folder at wakeAt. IMPORTANT: like scheduled sends, wake only fires while this MCP server process stays running — if the app is closed before wakeAt, the email wakes on next server startup instead of at the requested time, not reliably at wakeAt itself. Cancelable via cancel_snooze, which wakes it immediately.",
|
|
721
|
+
description: "Move an email out of sight into Folders/MCP-Snoozed and bring it back to its original folder at wakeAt. IMPORTANT: like scheduled sends, wake only fires while this MCP server process stays running — if the app is closed before wakeAt, the email wakes on next server startup instead of at the requested time, not reliably at wakeAt itself. Cancelable via cancel_snooze, which wakes it immediately.",
|
|
722
722
|
annotations: { destructiveHint: false },
|
|
723
723
|
inputSchema: {
|
|
724
724
|
type: "object",
|
|
@@ -1668,10 +1668,14 @@ const TOOLS = [
|
|
|
1668
1668
|
// Core tier: the 20 tools that cover ~80% of daily email use.
|
|
1669
1669
|
// Set PROTONMAIL_TOOL_TIER=core to expose only these — reduces context-window burn
|
|
1670
1670
|
// significantly on every session. Default is "full" (all tools).
|
|
1671
|
-
const CORE_TOOL_NAMES = new Set([
|
|
1671
|
+
export const CORE_TOOL_NAMES = new Set([
|
|
1672
1672
|
"get_emails",
|
|
1673
1673
|
"get_email_by_id",
|
|
1674
|
-
|
|
1674
|
+
// search_emails (live IMAP) is deliberately excluded from core — it
|
|
1675
|
+
// overlaps with search_indexed_emails (faster, offline-capable, and
|
|
1676
|
+
// already the "prefer" default per its own description) and the core
|
|
1677
|
+
// tier exists specifically to reduce tool-selection overlap. Still
|
|
1678
|
+
// available under PROTONMAIL_TOOL_TIER=full for stale-index/live-only cases.
|
|
1675
1679
|
"search_indexed_emails",
|
|
1676
1680
|
"send_email",
|
|
1677
1681
|
"reply_to_email",
|
|
@@ -2427,20 +2431,17 @@ async function previewEmailAction(imapService, emailId, action, targetFolder) {
|
|
|
2427
2431
|
isStarred: detail.isStarred,
|
|
2428
2432
|
};
|
|
2429
2433
|
}
|
|
2434
|
+
// Best-effort: confirms the sent copy landed in the Sent folder, purely for
|
|
2435
|
+
// the sentCopy:"[sent-copy:verified]" hint in the response. sentCopyVerify
|
|
2436
|
+
// already does its own robust folder resolution internally (by specialUse,
|
|
2437
|
+
// then by name) on every call — retrying it with different guessed folder
|
|
2438
|
+
// names here was redundant and, worse, sequential (up to 3 x 30s = 90s),
|
|
2439
|
+
// which blocked the send_email response long enough to trip the MCP
|
|
2440
|
+
// client's own request timeout on an email that had already sent
|
|
2441
|
+
// successfully. One bounded call; failing to verify quickly just means the
|
|
2442
|
+
// hint stays "unverified", never a false failure.
|
|
2430
2443
|
async function verifySentCopy(imapService, messageId) {
|
|
2431
|
-
|
|
2432
|
-
const resolved = await resolver?.();
|
|
2433
|
-
if (resolved) {
|
|
2434
|
-
return imapService.sentCopyVerify(messageId, resolved, 30_000);
|
|
2435
|
-
}
|
|
2436
|
-
let lastResult = { found: false };
|
|
2437
|
-
for (const sentFolderName of ["Sent", "Sent Mail", "Sent Messages"]) {
|
|
2438
|
-
lastResult = await imapService.sentCopyVerify(messageId, sentFolderName, 30_000);
|
|
2439
|
-
if (lastResult.found) {
|
|
2440
|
-
return lastResult;
|
|
2441
|
-
}
|
|
2442
|
-
}
|
|
2443
|
-
return lastResult;
|
|
2444
|
+
return imapService.sentCopyVerify(messageId, "Sent", 8_000);
|
|
2444
2445
|
}
|
|
2445
2446
|
function getBulkMaxBatchSize(args) {
|
|
2446
2447
|
return typeof args.maxBatchSize === "number" ? Math.min(args.maxBatchSize, 2000) : 500;
|
|
@@ -2609,7 +2610,11 @@ export function buildConfigFromEnv() {
|
|
|
2609
2610
|
if (!username || !password) {
|
|
2610
2611
|
throw new Error("Missing required environment variables or secret sources: PROTONMAIL_USERNAME and PROTONMAIL_PASSWORD.");
|
|
2611
2612
|
}
|
|
2612
|
-
const smtpPort = parseIntegerEnv("PROTONMAIL_SMTP_PORT",
|
|
2613
|
+
const smtpPort = parseIntegerEnv("PROTONMAIL_SMTP_PORT", 1025, 1, 65_535);
|
|
2614
|
+
// Bridge's local SMTP port requires implicit TLS from the first byte (no
|
|
2615
|
+
// plaintext greeting, no STARTTLS) — confirmed against a live Bridge
|
|
2616
|
+
// instance. Overridable for non-Bridge SMTP setups.
|
|
2617
|
+
const smtpSecure = parseBooleanEnv("PROTONMAIL_SMTP_SECURE", true);
|
|
2613
2618
|
const imapPort = parseIntegerEnv("PROTONMAIL_IMAP_PORT", 1143, 1, 65_535);
|
|
2614
2619
|
const debug = parseBooleanEnv("DEBUG", false);
|
|
2615
2620
|
const readOnly = parseBooleanEnv("PROTONMAIL_READ_ONLY", false);
|
|
@@ -2645,7 +2650,7 @@ export function buildConfigFromEnv() {
|
|
|
2645
2650
|
smtp: {
|
|
2646
2651
|
host: smtpHost,
|
|
2647
2652
|
port: smtpPort,
|
|
2648
|
-
secure:
|
|
2653
|
+
secure: smtpSecure,
|
|
2649
2654
|
username,
|
|
2650
2655
|
password,
|
|
2651
2656
|
},
|
|
@@ -4883,7 +4888,16 @@ export function createServer(config, options = {}) {
|
|
|
4883
4888
|
if (isLikelyConnectionError(error)) {
|
|
4884
4889
|
throw new McpError(ErrorCode.InternalError, "Could not connect to Proton Bridge. Make sure the Bridge app is running, and that PROTONMAIL_IMAP_HOST/PORT and PROTONMAIL_SMTP_HOST/PORT match the ports shown in Bridge's settings. Run run_doctor for a full connectivity check.");
|
|
4885
4890
|
}
|
|
4886
|
-
throw new
|
|
4891
|
+
// Every throw new Error(...) across src/services and src/utils is a
|
|
4892
|
+
// deliberately-worded, actionable message (not-found, validation,
|
|
4893
|
+
// policy-disabled, etc.) with no secrets or stack traces in it —
|
|
4894
|
+
// surface it directly instead of discarding it into a generic
|
|
4895
|
+
// "check get_logs" message that sends the caller on a diagnostic
|
|
4896
|
+
// wild goose chase for something that was already fully explained.
|
|
4897
|
+
const message = error instanceof Error && error.message
|
|
4898
|
+
? error.message
|
|
4899
|
+
: "An internal error occurred. Check get_logs for details, or run run_doctor for a full connectivity check.";
|
|
4900
|
+
throw new McpError(ErrorCode.InternalError, message);
|
|
4887
4901
|
}
|
|
4888
4902
|
});
|
|
4889
4903
|
return {
|