proton-mail-bridge-client 1.11.1 → 1.14.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.
Files changed (55) hide show
  1. package/README.md +340 -254
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +155 -18
  4. package/dist/cli.js.map +1 -1
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +1306 -114
  7. package/dist/index.js.map +1 -1
  8. package/dist/is-main.d.ts +10 -0
  9. package/dist/is-main.d.ts.map +1 -0
  10. package/dist/is-main.js +32 -0
  11. package/dist/is-main.js.map +1 -0
  12. package/dist/lib.d.ts +4 -0
  13. package/dist/lib.d.ts.map +1 -0
  14. package/dist/lib.js +7 -0
  15. package/dist/lib.js.map +1 -0
  16. package/dist/scripts/bridge-smoke.js +79 -56
  17. package/dist/scripts/bridge-smoke.js.map +1 -1
  18. package/dist/services/audit-service.d.ts +3 -0
  19. package/dist/services/audit-service.d.ts.map +1 -1
  20. package/dist/services/audit-service.js +30 -11
  21. package/dist/services/audit-service.js.map +1 -1
  22. package/dist/services/background-sync-service.d.ts +1 -0
  23. package/dist/services/background-sync-service.d.ts.map +1 -1
  24. package/dist/services/background-sync-service.js +28 -2
  25. package/dist/services/background-sync-service.js.map +1 -1
  26. package/dist/services/draft-store-service.d.ts +4 -0
  27. package/dist/services/draft-store-service.d.ts.map +1 -1
  28. package/dist/services/draft-store-service.js +211 -148
  29. package/dist/services/draft-store-service.js.map +1 -1
  30. package/dist/services/local-index-service.d.ts +10 -0
  31. package/dist/services/local-index-service.d.ts.map +1 -1
  32. package/dist/services/local-index-service.js +169 -28
  33. package/dist/services/local-index-service.js.map +1 -1
  34. package/dist/services/simple-imap-service.d.ts +139 -7
  35. package/dist/services/simple-imap-service.d.ts.map +1 -1
  36. package/dist/services/simple-imap-service.js +1045 -147
  37. package/dist/services/simple-imap-service.js.map +1 -1
  38. package/dist/services/smtp-service.d.ts +2 -0
  39. package/dist/services/smtp-service.d.ts.map +1 -1
  40. package/dist/services/smtp-service.js +80 -8
  41. package/dist/services/smtp-service.js.map +1 -1
  42. package/dist/types/index.d.ts +55 -1
  43. package/dist/types/index.d.ts.map +1 -1
  44. package/dist/utils/helpers.d.ts +10 -0
  45. package/dist/utils/helpers.d.ts.map +1 -1
  46. package/dist/utils/helpers.js +110 -2
  47. package/dist/utils/helpers.js.map +1 -1
  48. package/dist/utils/logger.d.ts +5 -1
  49. package/dist/utils/logger.d.ts.map +1 -1
  50. package/dist/utils/logger.js +11 -3
  51. package/dist/utils/logger.js.map +1 -1
  52. package/dist/utils/runtime-policy.d.ts.map +1 -1
  53. package/dist/utils/runtime-policy.js +5 -0
  54. package/dist/utils/runtime-policy.js.map +1 -1
  55. package/package.json +12 -6
package/README.md CHANGED
@@ -7,104 +7,265 @@
7
7
  Bridge Client · CLI + Claude Desktop MCP for Proton Mail
8
8
  ```
9
9
 
10
- # Proton Mail Bridge Client
10
+ <div align="center">
11
11
 
12
- [![proton-mail-bridge-client MCP server](https://glama.ai/mcp/servers/googlarz/proton-mail-bridge-client/badges/card.svg)](https://glama.ai/mcp/servers/googlarz/proton-mail-bridge-client)
12
+ [![npm version](https://img.shields.io/npm/v/proton-mail-bridge-client?color=%236d4aff&label=npm)](https://www.npmjs.com/package/proton-mail-bridge-client)
13
+ [![CI](https://github.com/googlarz/proton-mail-bridge-client/actions/workflows/ci.yml/badge.svg)](https://github.com/googlarz/proton-mail-bridge-client/actions/workflows/ci.yml)
14
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
15
+ [![Node.js 18+](https://img.shields.io/badge/node-%3E%3D18-brightgreen)](https://nodejs.org)
16
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5-3178c6?logo=typescript&logoColor=white)](https://www.typescriptlang.org)
17
+ [![MCP](https://img.shields.io/badge/MCP-compatible-blueviolet)](https://modelcontextprotocol.io)
18
+ [![GitHub stars](https://img.shields.io/github/stars/googlarz/proton-mail-bridge-client?style=social)](https://github.com/googlarz/proton-mail-bridge-client)
19
+ [![Last commit](https://img.shields.io/github/last-commit/googlarz/proton-mail-bridge-client?color=brightgreen&label=last%20commit)](https://github.com/googlarz/proton-mail-bridge-client/commits/main)
20
+ [![Platforms](https://img.shields.io/badge/platform-macOS%20%7C%20Linux%20%7C%20Windows-lightgrey)](https://github.com/googlarz/proton-mail-bridge-client)
21
+ [![proton-mail-bridge-client MCP server](https://glama.ai/mcp/servers/googlarz/proton-mail-bridge-client/badges/score.svg)](https://glama.ai/mcp/servers/googlarz/proton-mail-bridge-client)
13
22
 
14
- A full-featured CLI and Claude Desktop MCP for Proton Mail, built on top of Proton Bridge.
23
+ </div>
15
24
 
16
- ## About
25
+ ---
17
26
 
18
- Proton Mail Bridge Client gives you two ways to use Proton Mail programmatically:
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. The same 40+ capabilities are also available as a full CLI for scripting, cron, and piped automation — no Claude required.
19
28
 
20
- **CLI** — a terminal client with complete parity to the MCP surface. Read, search, send, draft, archive, manage folders, triage threads, and run diagnostics — all from the command line. Body can be piped via stdin. Output is either human-readable or `--json`.
29
+ ## What you get
21
30
 
22
- **MCP server** — the same capabilities exposed as a Model Context Protocol server so Claude Desktop can read and manage your Proton Mail in any chat, on the same machine where Proton Bridge is running.
31
+ - **Claude reads and manages your Proton Mail** — triage, reply, draft, archive, search, move, batch-act on threads, pull attachments
32
+ - **Full CLI** — same 40+ commands, scriptable and pipeable, works in cron and shell scripts
33
+ - **Fast local search** — full-text search across your inbox without hitting IMAP on every query
34
+ - **Safety controls** — read-only mode, send gate, destructive-action confirmation, per-action allowlist
35
+ - **Privacy-native** — no third-party email service involved; your mail stays on your machine
23
36
 
24
- Both surfaces share the same backend: Proton Bridge IMAP and SMTP, a local SQLite index, and an audit log. No hosted relay, no remote URL, no cloud dependency beyond your own Proton account.
37
+ ---
25
38
 
26
- ## Why CLI?
39
+ ## Privacy model
27
40
 
28
- Most Proton Mail MCPs are MCP-only. This one ships a full CLI — the same 40+ commands, all in the terminal, no Claude required.
41
+ Your emails travel: **Proton Mail → Proton Bridge (local) → this server (local) → your AI client**.
29
42
 
30
- **Pipe and script:**
43
+ Nothing goes through a third-party email relay. Proton Bridge decrypts your mail locally; this server reads it over a local IMAP connection on `127.0.0.1`. The AI model (Claude Desktop, Cline, etc.) sees the email content you ask it to act on — that's the whole point — but no email leaves your machine except through your own Proton account when you send.
31
44
 
32
- ```bash
33
- # Morning digest to a file
34
- proton-mail-bridge-client digest --json > ~/morning-mail.json
45
+ If you use Claude Desktop with the default Anthropic API, conversation content (including email snippets) is sent to Anthropic per their [privacy policy](https://www.anthropic.com/privacy). If you self-host an LLM or use a local-only Claude setup, nothing leaves your machine at all.
35
46
 
36
- # Finance automation — pull every Stripe subject in seconds
37
- proton-mail-bridge-client search --from stripe.com --json | jq '.[].subject'
47
+ ---
38
48
 
39
- # Pipe a script's output directly into an email
40
- echo "Deploy complete on $(hostname) at $(date)" \
41
- | proton-mail-bridge-client send --to alerts@example.com --subject "Deploy done"
42
- ```
49
+ ## Prerequisites
50
+
51
+ **1. Proton Bridge** — must be installed, signed in, and running.
52
+ Download: [proton.me/mail/bridge](https://proton.me/mail/bridge)
43
53
 
44
- **Cron:**
54
+ > **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
+
56
+ **2. Node.js 18 or later** — `node --version` to check.
57
+
58
+ **3. Your Bridge credentials** — from the Bridge app:
59
+ - IMAP host/port (default: `127.0.0.1:1143`)
60
+ - SMTP host/port (default: `127.0.0.1:1025`)
61
+ - Username (your Proton email address)
62
+ - Bridge password (see note above)
63
+
64
+ ---
65
+
66
+ ## Install
67
+
68
+ **npm (recommended):**
45
69
 
46
70
  ```bash
47
- # Scheduled digest every weekday at 8am
48
- 0 8 * * 1-5 proton-mail-bridge-client digest >> ~/mail-log.txt
71
+ npm install -g proton-mail-bridge-client
49
72
  ```
50
73
 
51
- **One-liners:**
74
+ **Homebrew:**
52
75
 
53
76
  ```bash
54
- # Live watch: notify on any new mail from your bank
55
- proton-mail-bridge-client search --live --from bank.com
56
-
57
- # Count unread in INBOX
58
- proton-mail-bridge-client emails --folder INBOX --json | jq '[.[] | select(.isRead == false)] | length'
77
+ brew tap googlarz/tap
78
+ brew install proton-mail-bridge-client
59
79
  ```
60
80
 
61
- No other Proton Mail MCP has a CLI. If you want to automate mail outside of Claude, this is the only option.
81
+ <details>
82
+ <summary>Source install (development)</summary>
62
83
 
63
- ## Prerequisites
84
+ ```bash
85
+ git clone https://github.com/googlarz/proton-mail-bridge-client.git
86
+ cd proton-mail-bridge-client
87
+ npm install
88
+ npm run build
89
+ ```
64
90
 
65
- - Node.js 18+
66
- - [Proton Bridge](https://proton.me/mail/bridge) installed and signed in
67
- - From Bridge: IMAP host/port, SMTP host/port, username, Bridge password
91
+ The `proton-mail-bridge-client` binary is available inside the repo after build.
68
92
 
69
- Default local Bridge addresses: IMAP `127.0.0.1:1143`, SMTP `127.0.0.1:1025`
93
+ </details>
70
94
 
71
- ## Install
95
+ ---
96
+
97
+ ## Connect to Claude Desktop
72
98
 
73
- **From npm (recommended):**
99
+ Run the guided setup wizard:
74
100
 
75
101
  ```bash
76
- npm install -g proton-mail-bridge-client
102
+ proton-mail-bridge-client setup-claude-desktop
77
103
  ```
78
104
 
79
- **From Homebrew:**
105
+ The wizard:
106
+ - checks your local Bridge ports
107
+ - asks for your Bridge username and Bridge password
108
+ - writes the Claude Desktop MCP config entry
80
109
 
81
- ```bash
82
- brew tap googlarz/tap
83
- brew install proton-mail-bridge-client
84
- ```
110
+ **After setup:** restart Claude Desktop, make sure Proton Bridge is open, then check **`+` → Connectors → proton-mail-bridge**.
85
111
 
86
- **Set up Claude Desktop** (interactive wizard, works from any install):
112
+ ### Updating
87
113
 
88
114
  ```bash
115
+ npm update -g proton-mail-bridge-client
89
116
  proton-mail-bridge-client setup-claude-desktop
90
117
  ```
91
118
 
119
+ ### Manual config
120
+
121
+ The wizard handles config automatically. If you need to set it up by hand, three credential methods are supported:
122
+
92
123
  <details>
93
- <summary>Development / source install</summary>
124
+ <summary>Option 1 — Environment variables (simplest)</summary>
94
125
 
95
- > **Before running `npm run build`:** configure your credentials first — see [Environment](#environment) below.
126
+ ```json
127
+ {
128
+ "mcpServers": {
129
+ "proton-mail-bridge": {
130
+ "command": "proton-mail-bridge-mcp",
131
+ "env": {
132
+ "PROTONMAIL_USERNAME": "you@proton.me",
133
+ "PROTONMAIL_PASSWORD": "your-bridge-password",
134
+ "PROTONMAIL_IMAP_HOST": "127.0.0.1",
135
+ "PROTONMAIL_IMAP_PORT": "1143",
136
+ "PROTONMAIL_IMAP_SECURE": "false",
137
+ "PROTONMAIL_SMTP_HOST": "127.0.0.1",
138
+ "PROTONMAIL_SMTP_PORT": "1025"
139
+ }
140
+ }
141
+ }
142
+ }
143
+ ```
96
144
 
97
- ```bash
98
- git clone https://github.com/googlarz/proton-mail-bridge-client.git
99
- cd proton-mail-bridge-client
100
- npm install
101
- npm run build
145
+ </details>
146
+
147
+ <details>
148
+ <summary>Option 2 — File-based secrets (credentials in files, not config)</summary>
149
+
150
+ ```json
151
+ {
152
+ "mcpServers": {
153
+ "proton-mail-bridge": {
154
+ "command": "proton-mail-bridge-mcp",
155
+ "env": {
156
+ "PROTONMAIL_USERNAME_FILE": "/path/to/username.txt",
157
+ "PROTONMAIL_PASSWORD_FILE": "/path/to/password.txt",
158
+ "PROTONMAIL_IMAP_HOST": "127.0.0.1",
159
+ "PROTONMAIL_IMAP_PORT": "1143",
160
+ "PROTONMAIL_IMAP_SECURE": "false",
161
+ "PROTONMAIL_SMTP_HOST": "127.0.0.1",
162
+ "PROTONMAIL_SMTP_PORT": "1025"
163
+ }
164
+ }
165
+ }
166
+ }
102
167
  ```
103
168
 
104
- After install, the `proton-mail-bridge-client` (and `proton-mail-bridge`) binary is available from the repo.
169
+ </details>
170
+
171
+ <details>
172
+ <summary>Option 3 — Command-based secrets (pass, gopass, or any secret manager)</summary>
173
+
174
+ ```json
175
+ {
176
+ "mcpServers": {
177
+ "proton-mail-bridge": {
178
+ "command": "proton-mail-bridge-mcp",
179
+ "env": {
180
+ "PROTONMAIL_USERNAME_COMMAND": "pass proton/username",
181
+ "PROTONMAIL_PASSWORD_COMMAND": "pass proton/password",
182
+ "PROTONMAIL_IMAP_HOST": "127.0.0.1",
183
+ "PROTONMAIL_IMAP_PORT": "1143",
184
+ "PROTONMAIL_IMAP_SECURE": "false",
185
+ "PROTONMAIL_SMTP_HOST": "127.0.0.1",
186
+ "PROTONMAIL_SMTP_PORT": "1025"
187
+ }
188
+ }
189
+ }
190
+ }
191
+ ```
105
192
 
106
193
  </details>
107
194
 
195
+ ---
196
+
197
+ ## Connect to Cline (VS Code)
198
+
199
+ Install globally (`npm install -g proton-mail-bridge-client`), then open Cline's MCP settings:
200
+
201
+ - VS Code → Cline extension panel → MCP servers icon → **Edit MCP Settings**
202
+ - Or edit directly: `~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json` (macOS)
203
+
204
+ Add the server:
205
+
206
+ ```json
207
+ {
208
+ "mcpServers": {
209
+ "proton-mail-bridge": {
210
+ "command": "proton-mail-bridge-mcp",
211
+ "env": {
212
+ "PROTONMAIL_USERNAME": "you@proton.me",
213
+ "PROTONMAIL_PASSWORD": "your-bridge-password",
214
+ "PROTONMAIL_IMAP_HOST": "127.0.0.1",
215
+ "PROTONMAIL_IMAP_PORT": "1143",
216
+ "PROTONMAIL_IMAP_SECURE": "false",
217
+ "PROTONMAIL_SMTP_HOST": "127.0.0.1",
218
+ "PROTONMAIL_SMTP_PORT": "1025"
219
+ }
220
+ }
221
+ }
222
+ }
223
+ ```
224
+
225
+ For file-based or command-based credentials, use the same `PROTONMAIL_USERNAME_FILE` / `PROTONMAIL_PASSWORD_COMMAND` pattern from the Claude Desktop manual config above.
226
+
227
+ Reload the Cline extension after saving. Proton Mail tools will appear in Cline's tool list.
228
+
229
+ ---
230
+
231
+ ## Try it: example Claude prompts
232
+
233
+ **Morning triage**
234
+ > "Give me a digest of my inbox. Flag anything that needs a reply today and anything that looks like a bill or invoice."
235
+
236
+ **Inbox zero**
237
+ > "Go through my unread emails from the past 3 days. Archive newsletters, trash anything promotional, and tell me what's left that needs action."
238
+
239
+ **Folder filing**
240
+ > "Find all emails from stripe.com and move them to Folders/Receipts. Create the folder if it doesn't exist."
241
+
242
+ **Meeting prep**
243
+ > "I have a call with alice@example.com in an hour. Pull up our last 5 email threads and summarise the open items."
244
+
245
+ **Draft review**
246
+ > "Show me my drafts, pick the oldest one, and suggest a better subject line and closing paragraph."
247
+
248
+ > **Tip:** When creating folders, use `Folders/Name` (not just `Name`) — that's the Proton Bridge namespace for real folders vs. labels.
249
+
250
+ ---
251
+
252
+ ## Recommended System Prompt
253
+
254
+ Add this to Claude Desktop's system prompt (Settings → Claude Desktop → System Prompt) for safer defaults:
255
+
256
+ ```
257
+ You have access to my Proton Mail inbox via the proton-mail-bridge tool.
258
+
259
+ Rules:
260
+ - Always use dryRun: true before any batch operation (batch_email_action, apply_thread_action).
261
+ - Before calling send_email, reply_to_email, or forward_email, summarise what you are about to send and ask me to confirm.
262
+ - Before calling delete_email, confirm with me — deletion is permanent.
263
+ - Prefer create_draft over send_email when composing from scratch.
264
+ - Use get_inbox_digest or get_actionable_threads as your starting point for triage sessions.
265
+ ```
266
+
267
+ ---
268
+
108
269
  ## CLI
109
270
 
110
271
  ```bash
@@ -203,23 +364,18 @@ proton-mail-bridge-client sync --folder INBOX --limit 150
203
364
  Run as a background daemon — sends a system notification (macOS / Linux) whenever new mail arrives:
204
365
 
205
366
  ```bash
206
- # Foreground (Ctrl+C to stop)
207
- proton-mail-bridge-client notify
208
-
209
- # Background (macOS / Linux)
210
- proton-mail-bridge-client notify &
211
-
212
- # Custom folder and idle timeout
213
- proton-mail-bridge-client notify --folder INBOX --timeout 60
367
+ proton-mail-bridge-client notify # foreground (Ctrl+C to stop)
368
+ proton-mail-bridge-client notify & # background
369
+ proton-mail-bridge-client notify --folder INBOX --timeout 60 # custom folder and idle timeout
214
370
  ```
215
371
 
216
- Each notification event is also written as a JSON line to stdout:
372
+ Each event is also written as a JSON line to stdout:
217
373
 
218
374
  ```json
219
375
  {"event":"new_mail","folder":"INBOX","count":2,"at":"2026-05-18T14:32:01.000Z"}
220
376
  ```
221
377
 
222
- Uses IMAP IDLE — no polling, no extra network requests between events. Reconnects automatically on transient errors.
378
+ Uses IMAP IDLE — no polling between events. Reconnects automatically on transient errors.
223
379
 
224
380
  ### MCP tool passthrough
225
381
 
@@ -231,167 +387,86 @@ proton-mail-bridge-client tool get_connection_status --json
231
387
  proton-mail-bridge-client tool search_indexed_emails --args '{"query":"invoice","limit":3}'
232
388
  ```
233
389
 
234
- ## Environment
235
-
236
- The CLI and MCP server both read the same environment variables:
237
-
238
- ```bash
239
- export PROTONMAIL_USERNAME='you@proton.me'
240
- export PROTONMAIL_PASSWORD='your-bridge-password'
241
- export PROTONMAIL_IMAP_HOST='127.0.0.1'
242
- export PROTONMAIL_IMAP_PORT='1143'
243
- export PROTONMAIL_IMAP_SECURE='false'
244
- export PROTONMAIL_SMTP_HOST='127.0.0.1'
245
- export PROTONMAIL_SMTP_PORT='1025'
246
- export PROTONMAIL_DATA_DIR="$HOME/.proton-mail-bridge-client"
247
- ```
248
-
249
- Optional secrets via file or command (avoids raw credentials in shell):
390
+ ### Pipe and script
250
391
 
251
392
  ```bash
252
- export PROTONMAIL_USERNAME_FILE='/path/to/user.txt'
253
- export PROTONMAIL_PASSWORD_FILE='/path/to/pass.txt'
254
- # or
255
- export PROTONMAIL_USERNAME_COMMAND='pass proton/username'
256
- export PROTONMAIL_PASSWORD_COMMAND='pass proton/password'
257
- ```
258
-
259
- Full runtime flags:
393
+ # Morning digest to a file
394
+ proton-mail-bridge-client digest --json > ~/morning-mail.json
260
395
 
261
- ```bash
262
- export PROTONMAIL_READ_ONLY='false'
263
- export PROTONMAIL_ALLOW_SEND='true'
264
- export PROTONMAIL_ALLOW_REMOTE_DRAFT_SYNC='true'
265
- export PROTONMAIL_ALLOWED_ACTIONS='mark_read,mark_unread,star,unstar,archive,trash,restore'
266
- export PROTONMAIL_CONFIRM_DESTRUCTIVE='false'
267
- export PROTONMAIL_AUTO_SYNC='true'
268
- export PROTONMAIL_STARTUP_SYNC='true'
269
- export PROTONMAIL_SYNC_INTERVAL_MINUTES='5'
270
- export PROTONMAIL_IDLE_WATCH='true'
271
- export PROTONMAIL_IDLE_MAX_SECONDS='30'
272
- ```
396
+ # Pull every email from a domain
397
+ proton-mail-bridge-client search --from stripe.com --json | jq '.[].subject'
273
398
 
274
- ## Claude Desktop Setup
399
+ # Pipe a script's output directly into an email
400
+ echo "Deploy complete on $(hostname) at $(date)" \
401
+ | proton-mail-bridge-client send --to alerts@example.com --subject "Deploy done"
275
402
 
276
- To use Proton Mail Bridge Client with Claude Desktop, run the guided wizard:
403
+ # Scheduled digest every weekday at 8am (cron)
404
+ 0 8 * * 1-5 proton-mail-bridge-client digest >> ~/mail-log.txt
277
405
 
278
- ```bash
279
- npm run setup:claude-desktop
406
+ # Count unread in INBOX
407
+ proton-mail-bridge-client emails --folder INBOX --json | jq '[.[] | select(.isRead == false)] | length'
280
408
  ```
281
409
 
282
- This will:
283
-
284
- - check your local Bridge ports
285
- - ask for your Bridge username and password
286
- - build the project
287
- - install a stable machine-wide runtime
288
- - write the Claude Desktop MCP config entry
410
+ ---
289
411
 
290
- After setup: restart Claude Desktop, keep Proton Bridge open, then check `+` → `Connectors` → `proton-mail-bridge`.
412
+ ## Safety controls
291
413
 
292
- The runtime is installed at:
293
-
294
- - macOS: `~/Library/Application Support/Proton Mail Bridge Client`
295
- - Linux: `~/.local/share/proton-mail-bridge-client`
296
- - Windows: `%APPDATA%\Proton Mail Bridge Client`
297
-
298
- ### Updating
414
+ All flags work in both the MCP server and CLI:
299
415
 
300
416
  ```bash
301
- git pull
302
- npm run update:claude-desktop
417
+ PROTONMAIL_TOOL_TIER=core # expose 20 core tools instead of all 76 — saves context window
418
+ PROTONMAIL_READ_ONLY=true # disable all write operations
419
+ PROTONMAIL_ALLOW_SEND=false # disable SMTP sends only (other writes still work)
420
+ PROTONMAIL_CONFIRM_DESTRUCTIVE=true # require confirmed:true on send, reply, forward, delete
421
+ PROTONMAIL_ALLOWED_ACTIONS='mark_read,archive,trash' # per-action allowlist
303
422
  ```
304
423
 
305
- ### Manual Claude Desktop config
306
-
307
- Three credential methods are supported. Use whichever fits your setup:
424
+ `batch_email_action` and `apply_thread_action` both support `dryRun: true` regardless of the above flags.
308
425
 
309
- **Option 1 — Environment variables (simplest):**
426
+ ---
310
427
 
311
- ```json
312
- {
313
- "mcpServers": {
314
- "proton-mail-bridge": {
315
- "command": "node",
316
- "args": ["/path/to/runtime/dist/index.js"],
317
- "cwd": "/path/to/runtime",
318
- "env": {
319
- "PROTONMAIL_USERNAME": "you@proton.me",
320
- "PROTONMAIL_PASSWORD": "your-bridge-password",
321
- "PROTONMAIL_IMAP_HOST": "127.0.0.1",
322
- "PROTONMAIL_IMAP_PORT": "1143",
323
- "PROTONMAIL_IMAP_SECURE": "false",
324
- "PROTONMAIL_SMTP_HOST": "127.0.0.1",
325
- "PROTONMAIL_SMTP_PORT": "1025"
326
- }
327
- }
328
- }
329
- }
330
- ```
428
+ ## Environment reference
331
429
 
332
- **Option 2 — File-based secrets (credentials in files, not config):**
333
-
334
- ```json
335
- {
336
- "mcpServers": {
337
- "proton-mail-bridge": {
338
- "command": "node",
339
- "args": ["/path/to/runtime/dist/index.js"],
340
- "cwd": "/path/to/runtime",
341
- "env": {
342
- "PROTONMAIL_USERNAME_FILE": "/path/to/username.txt",
343
- "PROTONMAIL_PASSWORD_FILE": "/path/to/password.txt",
344
- "PROTONMAIL_IMAP_HOST": "127.0.0.1",
345
- "PROTONMAIL_IMAP_PORT": "1143",
346
- "PROTONMAIL_IMAP_SECURE": "false",
347
- "PROTONMAIL_SMTP_HOST": "127.0.0.1",
348
- "PROTONMAIL_SMTP_PORT": "1025"
349
- }
350
- }
351
- }
352
- }
353
- ```
354
-
355
- **Option 3 — Command-based secrets (recommended for `pass`, `gopass`, or any secret manager):**
356
-
357
- ```json
358
- {
359
- "mcpServers": {
360
- "proton-mail-bridge": {
361
- "command": "node",
362
- "args": ["/path/to/runtime/dist/index.js"],
363
- "cwd": "/path/to/runtime",
364
- "env": {
365
- "PROTONMAIL_USERNAME_COMMAND": "pass proton/username",
366
- "PROTONMAIL_PASSWORD_COMMAND": "pass proton/password",
367
- "PROTONMAIL_IMAP_HOST": "127.0.0.1",
368
- "PROTONMAIL_IMAP_PORT": "1143",
369
- "PROTONMAIL_IMAP_SECURE": "false",
370
- "PROTONMAIL_SMTP_HOST": "127.0.0.1",
371
- "PROTONMAIL_SMTP_PORT": "1025"
372
- }
373
- }
374
- }
375
- }
430
+ ```bash
431
+ # Credentials (required)
432
+ PROTONMAIL_USERNAME='you@proton.me'
433
+ PROTONMAIL_PASSWORD='your-bridge-password' # Bridge password, not Proton account password
434
+ PROTONMAIL_IMAP_HOST='127.0.0.1'
435
+ PROTONMAIL_IMAP_PORT='1143'
436
+ PROTONMAIL_IMAP_SECURE='false'
437
+ PROTONMAIL_SMTP_HOST='127.0.0.1'
438
+ PROTONMAIL_SMTP_PORT='1025'
439
+
440
+ # Secrets via file or command (avoids raw credentials in config)
441
+ PROTONMAIL_USERNAME_FILE='/path/to/user.txt'
442
+ PROTONMAIL_PASSWORD_FILE='/path/to/pass.txt'
443
+ PROTONMAIL_USERNAME_COMMAND='pass proton/username'
444
+ PROTONMAIL_PASSWORD_COMMAND='pass proton/password'
445
+
446
+ # Storage
447
+ PROTONMAIL_DATA_DIR="$HOME/.proton-mail-bridge-client"
448
+
449
+ # Tools
450
+ PROTONMAIL_TOOL_TIER='full' # 'core' exposes 20 essential tools (saves context window); 'full' exposes all 76
451
+
452
+ # Safety
453
+ PROTONMAIL_READ_ONLY='false'
454
+ PROTONMAIL_ALLOW_SEND='true'
455
+ PROTONMAIL_ALLOW_REMOTE_DRAFT_SYNC='true'
456
+ PROTONMAIL_ALLOWED_ACTIONS='mark_read,mark_unread,star,unstar,archive,trash,restore'
457
+ PROTONMAIL_CONFIRM_DESTRUCTIVE='false'
458
+
459
+ # Sync
460
+ PROTONMAIL_AUTO_SYNC='true'
461
+ PROTONMAIL_STARTUP_SYNC='true'
462
+ PROTONMAIL_SYNC_INTERVAL_MINUTES='5'
463
+ PROTONMAIL_IDLE_WATCH='true'
464
+ PROTONMAIL_IDLE_MAX_SECONDS='30'
376
465
  ```
377
466
 
378
- ### macOS note
467
+ ---
379
468
 
380
- On macOS, `better-sqlite3` must be a native binary built for the current machine. The installer handles this automatically. If you restore from another environment or see a native-module crash, run `npm run update:claude-desktop`.
381
-
382
- ## Trust & Safety
383
-
384
- - Runs entirely locally — no hosted relay, no remote URL.
385
- - Talks to Proton Mail only through Proton Bridge on your own machine.
386
- - `PROTONMAIL_READ_ONLY=true` disables all write operations.
387
- - `PROTONMAIL_ALLOW_SEND=false` disables SMTP sends without affecting other writes.
388
- - `PROTONMAIL_ALLOWED_ACTIONS` controls which mailbox mutations are permitted.
389
- - `PROTONMAIL_CONFIRM_DESTRUCTIVE=true` requires `confirmed: true` on `send_email`, `reply_to_email`, `forward_email`, `send_draft`, and `delete_email` — Claude will pause and ask before executing irreversible operations.
390
- - `batch_email_action` and `apply_thread_action` both support `dryRun: true`.
391
- - Supports `*_FILE` and `*_COMMAND` secrets so raw credentials never appear in config or shell history.
392
- - System folders (INBOX, Sent, Trash, Spam, Archive, All Mail) are guarded against accidental deletion.
393
-
394
- ## Compared With Claude's Native Gmail Connector
469
+ ## Compared with Claude's native Gmail connector
395
470
 
396
471
  | Capability | Gmail connector | Proton Mail Bridge Client |
397
472
  |---|---|---|
@@ -399,88 +474,99 @@ On macOS, `better-sqlite3` must be a native binary built for the current machine
399
474
  | Search and read | Native Claude UX | IMAP + local index |
400
475
  | Send email | No | Yes |
401
476
  | Draft workflows | Better first-party UX | Full control incl. remote draft sync |
402
- | Attachment content | Limited | Fetch and save |
477
+ | Attachment content | Limited | Fetch and save to disk |
403
478
  | Mailbox actions | Limited | Full (star, move, archive, trash, restore, delete, batch) |
404
479
  | Folder management | No | Yes (create, rename, delete) |
405
480
  | CLI access | No | Full parity with MCP |
406
- | Original message links | Better | MCP resource links only |
407
- | Native threads/labels | Gmail-native | Reconstructed from IMAP |
481
+ | Privacy | Google-hosted | Proton E2E encryption, local Bridge |
408
482
 
409
- ## Recommended System Prompt
483
+ ---
410
484
 
411
- Add this to Claude Desktop's system prompt (Settings → Claude Desktop → System Prompt) for safer default behaviour:
485
+ ## Tool surface
412
486
 
413
- ```
414
- You have access to my Proton Mail inbox via the proton-mail-bridge tool.
487
+ ### Send
488
+ `send_email` · `send_test_email` · `reply_to_email` · `reply_all_email` · `forward_email`
415
489
 
416
- Rules:
417
- - Always use dryRun: true before any batch operation (batch_email_action, apply_thread_action).
418
- - Before calling send_email, reply_to_email, or forward_email, summarise what you are about to send and ask me to confirm.
419
- - Before calling delete_email, confirm with me — deletion is permanent.
420
- - Prefer create_draft over send_email when composing from scratch.
421
- - Use get_inbox_digest or get_actionable_threads as your starting point for triage sessions.
422
- ```
490
+ ### Drafts
491
+ `create_draft` · `create_reply_draft` · `create_forward_draft` · `create_thread_reply_draft` · `list_drafts` · `list_remote_drafts` · `get_draft` · `update_draft` · `sync_draft_to_remote` · `send_draft` · `delete_draft`
492
+
493
+ ### Read
494
+ `get_emails` · `get_email_by_id` · `count_messages` · `search_emails` · `search_indexed_emails` · `list_attachments` · `get_attachment_content` · `save_attachment` · `save_attachments`
423
495
 
424
- ## Example Claude Workflows
496
+ ### Triage
497
+ `get_folders` · `sync_folders` · `get_labels` · `get_threads` · `get_thread_by_id` · `get_thread_brief` · `get_actionable_threads` · `get_inbox_digest` · `get_follow_up_candidates` · `find_document_threads` · `prepare_meeting_context` · `delete_thread` · `flag_thread` · `move_thread`
425
498
 
426
- Once connected, ask Claude anything. Some prompts that work well:
499
+ ### Actions
500
+ `mark_email_read` · `star_email` · `move_email` · `archive_email` · `trash_email` · `restore_email` · `delete_email` · `batch_email_action` · `apply_thread_action` · `empty_folder` · `bulk_delete` · `bulk_move` · `bulk_update_flags` · `bulk_update_labels` · `update_message_flags` · `update_message_labels`
427
501
 
428
- **Morning triage**
429
- > "Give me a digest of my inbox. Flag anything that needs a reply today and anything that looks like a bill or invoice."
502
+ ### Folder management
503
+ `create_folder` · `rename_folder` · `delete_folder` · `create_label`
430
504
 
431
- **Inbox zero session**
432
- > "Go through my unread emails from the past 3 days. Archive newsletters, trash anything promotional, and tell me what's left that needs action."
505
+ ### Analytics
506
+ `get_email_stats` · `get_email_analytics` · `get_contacts` · `get_volume_trends` · `folder_stats` · `top_senders`
433
507
 
434
- **Folder filing**
435
- > "Find all emails from stripe.com and move them to Folders/Receipts. Create the folder if it doesn't exist."
508
+ ### Diagnostics
509
+ `get_connection_status` · `get_runtime_status` · `run_doctor` · `get_audit_logs` · `run_background_sync` · `wait_for_mailbox_changes` · `sync_emails` · `get_index_status` · `clear_cache` · `clear_index` · `get_logs`
436
510
 
437
- **Meeting prep**
438
- > "I have a call with alice@example.com in an hour. Pull up our last 5 email threads and summarise the open items."
511
+ ---
439
512
 
440
- **Draft review**
441
- > "Show me my drafts, pick the oldest one, and suggest a better subject line and closing paragraph."
513
+ ## Using it as a library
442
514
 
443
- > **Tip:** If Claude needs to create a folder before moving emails, remind it to use `Folders/Name` (not just `Name`) — that's the Proton Bridge namespace for real folders vs. labels.
515
+ Beyond the CLI and MCP server, the underlying service classes are importable directly:
444
516
 
445
- ## Tool Surface
517
+ ```ts
518
+ import { SimpleIMAPService, SMTPService } from "proton-mail-bridge-client/services";
446
519
 
447
- ### Send
448
- `send_email` · `send_test_email` · `reply_to_email` · `forward_email`
520
+ const imapService = new SimpleIMAPService(config, logger);
521
+ const smtpService = new SMTPService(config);
522
+ ```
449
523
 
450
- ### Drafts
451
- `create_draft` · `create_reply_draft` · `create_forward_draft` · `create_thread_reply_draft` · `list_drafts` · `list_remote_drafts` · `get_draft` · `update_draft` · `sync_draft_to_remote` · `send_draft` · `delete_draft`
524
+ `proton-mail-bridge-client/services` has no side effects on import — unlike the package's
525
+ main entry point, which also self-starts the MCP server when run directly. Also exported:
526
+ all shared types (`ProtonMailConfig`, `EmailSummary`, `EmailDetail`, …), `planFolderSync`,
527
+ `isLikelyAuthenticationError`, and `sanitizeHeader`.
452
528
 
453
- ### Read
454
- `get_emails` · `get_email_by_id` · `search_emails` · `list_attachments` · `get_attachment_content` · `save_attachments` · `save_attachment`
529
+ ---
455
530
 
456
- ### Triage
457
- `get_folders` · `sync_folders` · `get_labels` · `get_threads` · `get_thread_by_id` · `get_thread_brief` · `get_actionable_threads` · `get_inbox_digest` · `get_follow_up_candidates` · `find_document_threads` · `prepare_meeting_context`
531
+ ## Operational notes
458
532
 
459
- ### Actions
460
- `mark_email_read` · `star_email` · `move_email` · `archive_email` · `trash_email` · `restore_email` · `delete_email` · `batch_email_action` · `apply_thread_action`
533
+ - `get_emails` and `search_emails` return a composite `emailId` — use it for all subsequent reads and actions.
534
+ - `search_indexed_emails` supports `from:`, `to:`, `subject:`, `label:`, `domain:` shortcuts.
535
+ - The local index lives at `PROTONMAIL_DATA_DIR/mail-index.sqlite`. Background sync and IMAP IDLE keep it warm.
536
+ - Audit logs live at `PROTONMAIL_DATA_DIR/audit.log`.
537
+ - Draft sync is best-effort — the local draft is always preserved even if remote sync fails.
538
+ - System folders (INBOX, Sent, Trash, Spam, Archive, All Mail) are guarded against accidental deletion.
461
539
 
462
- ### Folder management
463
- `create_folder` · `rename_folder` · `delete_folder`
540
+ ---
464
541
 
465
- ### Analytics
466
- `get_email_stats` · `get_email_analytics` · `get_contacts` · `get_volume_trends`
542
+ ## Troubleshooting
467
543
 
468
- ### Diagnostics
469
- `get_connection_status` · `get_runtime_status` · `run_doctor` · `get_audit_logs` · `run_background_sync` · `wait_for_mailbox_changes` · `sync_emails` · `get_index_status` · `search_indexed_emails` · `clear_cache` · `clear_index` · `get_logs`
544
+ **"Wrong password" or connection refused**
545
+ Make sure you're using the **Bridge password**, not your Proton account password. Find it in the Bridge app under Account → Copy password. Bridge must be running before the MCP server or CLI can connect.
470
546
 
471
- ## Operational Notes
547
+ **macOS native module crash after update**
548
+ `better-sqlite3` is a native binary built for your machine. After a major Node.js upgrade or environment change, rebuild it:
549
+ ```bash
550
+ proton-mail-bridge-client setup-claude-desktop
551
+ ```
552
+ This reinstalls the runtime and rebuilds native modules in place.
472
553
 
473
- - `get_emails` and `search_emails` return a composite `emailId` — use it for reads and actions.
474
- - The local index lives at `PROTONMAIL_DATA_DIR/mail-index.sqlite`.
475
- - Audit logs live at `PROTONMAIL_DATA_DIR/audit.log`.
476
- - Background sync and IMAP IDLE keep the index warm but depend on Bridge staying up.
477
- - `search_indexed_emails` supports `from:`, `to:`, `subject:`, `label:`, `domain:` shortcuts.
478
- - Draft sync is best-effort — local draft is always preserved even if remote sync fails.
554
+ **Claude can't see the connector**
555
+ After changing the MCP config, restart Claude Desktop fully (not just reload). Then check **`+` → Connectors → proton-mail-bridge**. If it's not there, run `proton-mail-bridge-client doctor` to validate the connection.
556
+
557
+ **Folder not found when moving email**
558
+ Use `Folders/Name` for real folders (e.g., `Folders/Receipts`), not just `Name`. Labels and folders share the same namespace in Proton Bridge but are structurally different.
559
+
560
+ ---
479
561
 
480
562
  ## Changelog
481
563
 
482
564
  See [CHANGELOG.md](CHANGELOG.md) for release history.
483
565
 
566
+ ## Contributing
567
+
568
+ Bug reports and pull requests welcome: [github.com/googlarz/proton-mail-bridge-client/issues](https://github.com/googlarz/proton-mail-bridge-client/issues)
569
+
484
570
  ## License
485
571
 
486
572
  MIT