proton-mail-bridge-client 1.19.5 → 2.0.1
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 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +49 -2
- package/dist/index.js.map +1 -1
- package/dist/services/delivery-queue-service.d.ts +1 -0
- package/dist/services/delivery-queue-service.d.ts.map +1 -1
- package/dist/services/delivery-queue-service.js +61 -15
- package/dist/services/delivery-queue-service.js.map +1 -1
- package/dist/services/local-index-service.d.ts +1 -0
- package/dist/services/local-index-service.d.ts.map +1 -1
- package/dist/services/local-index-service.js +105 -21
- package/dist/services/local-index-service.js.map +1 -1
- package/dist/services/simple-imap-service.d.ts +3 -0
- package/dist/services/simple-imap-service.d.ts.map +1 -1
- package/dist/services/simple-imap-service.js +135 -12
- package/dist/services/simple-imap-service.js.map +1 -1
- package/dist/services/snooze-service.d.ts +2 -0
- package/dist/services/snooze-service.d.ts.map +1 -1
- package/dist/services/snooze-service.js +95 -7
- package/dist/services/snooze-service.js.map +1 -1
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/file-lock.d.ts +1 -0
- package/dist/utils/file-lock.d.ts.map +1 -1
- package/dist/utils/file-lock.js +9 -1
- package/dist/utils/file-lock.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
[](https://www.npmjs.com/package/proton-mail-bridge-client)
|
|
13
13
|
[](https://github.com/googlarz/proton-mail-bridge-client/actions/workflows/ci.yml)
|
|
14
14
|
[](LICENSE)
|
|
15
|
-
[](https://nodejs.org)
|
|
16
16
|
[](https://www.typescriptlang.org)
|
|
17
17
|
[](https://modelcontextprotocol.io)
|
|
18
18
|
[](https://github.com/googlarz/proton-mail-bridge-client)
|
|
@@ -26,6 +26,8 @@
|
|
|
26
26
|
|
|
27
27
|
Give Claude Desktop (or Cline, or any MCP client) full access to your Proton Mail inbox: read, search, send, draft, triage threads, manage folders, save attachments, and more — 95 MCP tools in total. Most of the same capabilities are also available as a full CLI for scripting, cron, and piped automation — no Claude required.
|
|
28
28
|
|
|
29
|
+
> **Battle-tested at scale (v2.0.0):** full mailbox backfill validated end-to-end against a real account with 57,000+ indexed messages across 62 folders/labels — including a 22,800-message Archive folder backfilled from scratch, UID-window by UID-window, with zero data loss across restarts, transient IMAP disconnects, and connection timeouts.
|
|
30
|
+
|
|
29
31
|
## What you get
|
|
30
32
|
|
|
31
33
|
- **Claude reads and manages your Proton Mail** — triage, reply, draft, archive, search, move, batch-act on threads, pull attachments
|
|
@@ -53,7 +55,7 @@ Download: [proton.me/mail/bridge](https://proton.me/mail/bridge)
|
|
|
53
55
|
|
|
54
56
|
> **Bridge password vs Proton password:** Proton Bridge generates a separate local password that is *not* your Proton account password. Find it inside the Bridge app under **Account → Copy password** (or similar — exact label varies by Bridge version). You'll need this for setup.
|
|
55
57
|
|
|
56
|
-
**2. Node.js
|
|
58
|
+
**2. Node.js 20 or later** — `node --version` to check.
|
|
57
59
|
|
|
58
60
|
**3. Your Bridge credentials** — from the Bridge app:
|
|
59
61
|
- IMAP host/port (default: `127.0.0.1:1143`)
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AASA,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,EAA2H,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAC/L,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;AA0qD1B,eAAO,MAAM,eAAe,aAyB1B,CAAC;AAgGH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,YAAY,EAAE,YAAY,EAC1B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAC1B,OAAO,CAAC,CAAC,CAAC,CAwBZ;AAmED,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;AA4KD,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,WAAW,EACnB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,OAAO,GAChB;IAAE,EAAE,EAAE,MAAM,EAAE,CAAC;IAAC,EAAE,EAAE,MAAM,EAAE,CAAA;CAAE,CAyBhC;AA4wBD,wBAAgB,kBAAkB,IAAI,gBAAgB,CAkGrD;AAED,wBAAgB,YAAY,CAC1B,MAAM,EAAE,gBAAgB,EACxB,OAAO,GAAE;IACP,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AASA,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,EAA2H,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAC/L,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;AA0qD1B,eAAO,MAAM,eAAe,aAyB1B,CAAC;AAgGH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,YAAY,EAAE,YAAY,EAC1B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAC1B,OAAO,CAAC,CAAC,CAAC,CAwBZ;AAmED,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;AA4KD,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,WAAW,EACnB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,OAAO,GAChB;IAAE,EAAE,EAAE,MAAM,EAAE,CAAC;IAAC,EAAE,EAAE,MAAM,EAAE,CAAA;CAAE,CAyBhC;AA4wBD,wBAAgB,kBAAkB,IAAI,gBAAgB,CAkGrD;AAED,wBAAgB,YAAY,CAC1B,MAAM,EAAE,gBAAgB,EACxB,OAAO,GAAE;IACP,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAk5FP;AAED,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAmE1C"}
|
package/dist/index.js
CHANGED
|
@@ -4002,7 +4002,7 @@ export function createServer(config, options = {}) {
|
|
|
4002
4002
|
return createTextResult(result);
|
|
4003
4003
|
}
|
|
4004
4004
|
case "bulk_move": {
|
|
4005
|
-
|
|
4005
|
+
ensureEmailActionAllowed(config.runtime, "move");
|
|
4006
4006
|
const emailIds = Array.isArray(args.emailIds)
|
|
4007
4007
|
? args.emailIds.map(String) : undefined;
|
|
4008
4008
|
const match = args.match && typeof args.match === "object"
|
|
@@ -4230,7 +4230,7 @@ export function createServer(config, options = {}) {
|
|
|
4230
4230
|
return createTextResult(await withAudit(auditService, name, args, async () => imapService.starEmail(requireString(args, "emailId"), normalizeBoolean(args.isStarred, true))));
|
|
4231
4231
|
case "move_email":
|
|
4232
4232
|
{
|
|
4233
|
-
|
|
4233
|
+
ensureEmailActionAllowed(config.runtime, "move");
|
|
4234
4234
|
const emailId = requireString(args, "emailId");
|
|
4235
4235
|
const targetFolder = requireString(args, "targetFolder");
|
|
4236
4236
|
const result = await withAudit(auditService, name, args, async () => {
|
|
@@ -4379,6 +4379,9 @@ export function createServer(config, options = {}) {
|
|
|
4379
4379
|
}
|
|
4380
4380
|
const action = requireEmailAction(args);
|
|
4381
4381
|
ensureEmailActionAllowed(config.runtime, action);
|
|
4382
|
+
if (action === "delete") {
|
|
4383
|
+
ensureDestructiveConfirmed(config.runtime, normalizeBoolean(args.confirmed, false), `Permanently delete ${emailIds.length} email(s) (cannot be recovered)`);
|
|
4384
|
+
}
|
|
4382
4385
|
const result = await withAudit(auditService, name, args, async () => applyBatchEmailAction(imapService, [], {
|
|
4383
4386
|
emailIds,
|
|
4384
4387
|
action,
|
|
@@ -4625,6 +4628,47 @@ export function createServer(config, options = {}) {
|
|
|
4625
4628
|
}));
|
|
4626
4629
|
case "sync_emails":
|
|
4627
4630
|
{
|
|
4631
|
+
const folder = optionalString(args, "folder");
|
|
4632
|
+
const full = typeof args.full === "boolean" ? args.full : undefined;
|
|
4633
|
+
const limitPerFolder = typeof args.limitPerFolder === "number" ? args.limitPerFolder : undefined;
|
|
4634
|
+
const includeAttachmentText = typeof args.includeAttachmentText === "boolean" ? args.includeAttachmentText : undefined;
|
|
4635
|
+
// backgroundSyncService.runNow() always runs the *fixed* background-
|
|
4636
|
+
// sync config (autoSyncFolder/autoSyncFull/autoSyncLimitPerFolder —
|
|
4637
|
+
// typically just "INBOX,Sent", incremental, 100/folder) and ignores
|
|
4638
|
+
// any argument entirely. This tool's own schema advertises folder/
|
|
4639
|
+
// full/limitPerFolder/includeAttachmentText as per-call overrides,
|
|
4640
|
+
// but every one of them was silently discarded — a caller asking to
|
|
4641
|
+
// sync "Archive" with full:true got back a status snapshot of the
|
|
4642
|
+
// last INBOX/Sent background run, with Archive never touched at
|
|
4643
|
+
// all. Found live: sync_emails({folder:"Archive", full:true}) did
|
|
4644
|
+
// not add an Archive entry to get_index_status's syncCheckpoints.
|
|
4645
|
+
// When the caller supplies any of these, run a one-off sync with
|
|
4646
|
+
// their actual parameters instead.
|
|
4647
|
+
if (folder !== undefined || full !== undefined || limitPerFolder !== undefined || includeAttachmentText !== undefined) {
|
|
4648
|
+
const snapshot = await imapService.collectEmailsForIndex({
|
|
4649
|
+
folder,
|
|
4650
|
+
full,
|
|
4651
|
+
limitPerFolder,
|
|
4652
|
+
includeAttachmentText,
|
|
4653
|
+
checkpoints: await localIndexService.getSyncCheckpointMap(),
|
|
4654
|
+
});
|
|
4655
|
+
const indexStatus = await localIndexService.recordSnapshot({
|
|
4656
|
+
folders: snapshot.folders,
|
|
4657
|
+
emails: snapshot.emails,
|
|
4658
|
+
syncedAt: snapshot.syncedAt,
|
|
4659
|
+
folderStats: snapshot.folderStats,
|
|
4660
|
+
});
|
|
4661
|
+
return createTextResult({
|
|
4662
|
+
checkedAt: new Date().toISOString(),
|
|
4663
|
+
synced: { folder: folder ?? "all", full: Boolean(full), folderStats: snapshot.folderStats },
|
|
4664
|
+
index: {
|
|
4665
|
+
updatedAt: indexStatus.updatedAt,
|
|
4666
|
+
storedMessageCount: indexStatus.storedMessageCount,
|
|
4667
|
+
dedupedMessageCount: indexStatus.dedupedMessageCount,
|
|
4668
|
+
path: indexStatus.path,
|
|
4669
|
+
},
|
|
4670
|
+
});
|
|
4671
|
+
}
|
|
4628
4672
|
const syncStatus = await backgroundSyncService.runNow("sync_emails");
|
|
4629
4673
|
const indexStatus = await localIndexService.getStatus();
|
|
4630
4674
|
return createTextResult({
|
|
@@ -4915,6 +4959,9 @@ export function createServer(config, options = {}) {
|
|
|
4915
4959
|
const emailIds = [...new Set(thread.messages
|
|
4916
4960
|
.filter((message) => !unreadOnly || !message.isRead)
|
|
4917
4961
|
.map((message) => message.primaryEmailId))];
|
|
4962
|
+
if (action === "delete") {
|
|
4963
|
+
ensureDestructiveConfirmed(config.runtime, normalizeBoolean(args.confirmed, false), `Permanently delete ${emailIds.length} email(s) in thread (cannot be recovered)`);
|
|
4964
|
+
}
|
|
4918
4965
|
const result = await withAudit(auditService, name, args, async () => applyBatchEmailAction(imapService, [], {
|
|
4919
4966
|
emailIds,
|
|
4920
4967
|
action,
|