proton-drive-mcp 1.0.12

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 ADDED
@@ -0,0 +1,140 @@
1
+ # Changelog
2
+
3
+ ## 1.0.12 — 2026-06-10
4
+
5
+ ### Fixed
6
+ - **`role` type guard** — `drive_share_invite` MCP handler now uses `typeof a.role === "string"` instead of `as string` cast, consistent with `conflictStrategy` fix in v1.0.11
7
+ - **`requireEmail` TypeScript** — added explicit unreachable return annotation to satisfy strict TypeScript configurations
8
+ - **`CONTROL_RE` source encoding** — regex now uses `
`/`
` escape sequences in the `RegExp` constructor string instead of literal Unicode characters, preventing silent stripping by editors or formatters
9
+
10
+ ## 1.0.11 — 2026-06-10
11
+
12
+ ### Fixed
13
+ - **`validateMessage` control characters and length** — `validateMessage` now rejects control characters (`\x00-\x1f`, `\x7f`, U+2028, U+2029) and messages exceeding 2000 characters; previously only leading dashes were checked
14
+ - **`validatePath` and `validateEmail` DEL and Unicode separators** — control character check now covers `\x7f` (DEL), U+2028 (LINE SEPARATOR), and U+2029 (PARAGRAPH SEPARATOR) in addition to `\x00-\x1f`
15
+ - **`conflictStrategy` type check** — changed `as string` cast to `typeof ... === "string"` check, consistent with other argument guards
16
+ - **CLI `--message` flag validated** — `share invite` now passes `--message` through `validateMessage` before `DriveService` (was missing; MCP handler already did this)
17
+
18
+ ### Added
19
+ - Tests: `validatePath` DEL char, `validateMessage` control chars + length cap — 57 tests total
20
+
21
+ ## 1.0.10 — 2026-06-10
22
+
23
+ ### Fixed
24
+ - **Path traversal guard** — `validatePath` now rejects paths containing `..` segments (e.g. `/my-files/../../etc/passwd`); previously only leading dashes and control characters were blocked
25
+ - **CLI path validation** — all path arguments in the CLI companion are now validated through `validatePath` (flag-injection check, control-char check, traversal check) before reaching `DriveService`; previously CLI args were passed raw
26
+ - **CLI email validation** — `share invite` and `share revoke` now run `validateEmail` (full format + leading-dash check) on the email argument; previously only a leading-dash check was applied
27
+ - **CLI `--message` validation** — `share invite` now validates the `--message` flag value through `validateMessage` before passing to `DriveService`; consistent with MCP handler
28
+ - **`validateEmail` control characters** — email validation now rejects values containing `\x00–\x1f`, consistent with `validatePath`
29
+ - **`DriveParseError` no longer leaks raw CLI output** — the error message shown to MCP clients is now the generic `"Failed to parse CLI output as JSON"`; the raw bytes are written to stderr for diagnostics
30
+ - **Subprocess auth check ordering** — stderr is now only checked for "not authenticated" when stdout is empty; previously a CLI warning on stderr could cause a valid JSON response to be discarded
31
+ - **`maxBuffer`** — `execFileAsync` now sets `maxBuffer: 50MB`; previously the 1MB default caused an unhandled `ERR_CHILD_PROCESS_STDIO_MAXBUFFER` error on large directory listings
32
+ - **`killSignal: "SIGKILL"`** — subprocess timeouts now send `SIGKILL` instead of the default `SIGTERM`, which a process can ignore
33
+
34
+ ### Added
35
+ - `src/utils/validation.ts` — shared validation module; `validatePath`, `validateEmail`, `validateMessage` are now in one place, used by both the MCP server and the CLI companion
36
+ - Tests: `validatePath` (10 cases), `validateEmail` (7 cases — including control chars), `validateMessage` (4 cases), `DriveCliNotFoundError` propagation — 53 tests total
37
+
38
+ ## 1.0.9 — 2026-06-10
39
+
40
+ ### Fixed
41
+ - `drive_trash` and `drive_restore` success messages now include the path (e.g. `"Moved to trash: /my-files/old.pdf"`)
42
+ - `validateEmail` now rejects values starting with `-` — consistent with `validatePath` and `validateMessage`
43
+ - `drive_share_revoke` success message now uses the validated email string instead of the raw `a.email` input
44
+ - CLI `share invite` now rejects email values starting with `-` before calling the service
45
+ - Publish workflow now runs `npm run ci` (lint + test) instead of only `npm test`, ensuring type errors don't block a publish
46
+
47
+ ## 1.0.8 — 2026-06-10
48
+
49
+ ### Fixed
50
+ - **`--message` flag injection** — `validateMessage` now rejects values starting with `-`; an LLM could otherwise pass `--role admin` as a message and inject flags into the `proton-drive sharing invite` call
51
+ - **Timeout detection** — also catches `e.code === "ETIMEDOUT"` and `e.signal != null` in addition to `e.killed === true`; Node may set any of these depending on platform and process behavior
52
+ - **`list()` and `listTrash()` non-array results** — previously silently returned `[]` when the CLI returned an unexpected object shape; now throws `DriveParseError` with a diagnostic snippet
53
+ - **`authStatus()` null result** — when CLI returns empty output now returns `{ authenticated: false }` explicitly rather than relying on optional-chaining fallbacks through a null cast
54
+ - **`shareInvite` splice replaced** — replaced fragile `args.splice(2, 0, "--message", message)` with a declarative spread `[...(message ? ["--message", message] : []), ...]`; equivalent behavior, immune to future arg-order changes
55
+ - **`drive_move` and `drive_delete` success messages** now include the paths operated on (e.g. `"Deleted: /my-files/old.pdf"`, `"Moved: /src → /dst"`)
56
+ - **`validatePath` control characters** — now rejects paths containing `\x00–\x1f`; null bytes are silently truncated by the OS at the syscall boundary
57
+ - **`getFlag` missing value** — `--conflict` or `--message` with no following value (or another flag immediately after) now emits a clear error instead of returning `undefined`
58
+ - **CHANGELOG v1.0.6** — fixed copy-paste error that listed unpacked size as "~50 kB to ~50 kB"
59
+ - **README** — removed overclaim that "Claude will always use `drive_list_trash` first"; this is not enforced by code
60
+
61
+ ### Added
62
+ - `PROTON_DRIVE_BIN` environment variable — overrides the `proton-drive` binary name/path for non-standard installations; documented in README troubleshooting
63
+ - Tests: `authStatus` null result, `authStatus` loggedIn alias now also asserts email forwarding, `list` non-array throws `DriveParseError`, `listTrash` non-array throws `DriveParseError`, upload asserts `--skip-thumbnails` is present in args (31 tests total)
64
+
65
+ ## 1.0.7 — 2026-06-10
66
+
67
+ ### Fixed
68
+ - `validatePath` now rejects values starting with `-`, preventing a flag-injection scenario where an LLM could pass a value like `--skip-thumbnails` as a path and alter CLI behavior
69
+ - `drive_mkdir` success message now uses the validated path string instead of the raw `a.path` input
70
+
71
+ ## 1.0.6 — 2026-06-10
72
+
73
+ ### Fixed
74
+ - `drive_share_invite` MCP handler now validates `role` at runtime (viewer/editor/admin), consistent with the CLI companion and the `conflictStrategy` guard added in v1.0.4
75
+ - Removed `.d.ts`, `.d.ts.map`, and `.js.map` files from the published package — this is a CLI tool, not a library; declaration files and source maps have no value for consumers (~22 kB → ~14 kB packed)
76
+
77
+ ### Changed
78
+ - CI workflow: removed redundant `Build` step — `npm test` already calls `npm run build` internally, so the explicit step was building twice
79
+ - Publish workflow: added version-tag match check — fails the publish job if `package.json` version doesn't match the pushed git tag, preventing accidental version drift
80
+
81
+ ## 1.0.5 — 2026-06-10
82
+
83
+ ### Fixed
84
+ - **Logger MCP mode detection** — `isMcp` was evaluated at module import time (before `main()` set the env var), causing `logger.info` to write to stdout in MCP mode and corrupt JSON-RPC framing. Now evaluated lazily on each call.
85
+ - `drive_upload` MCP handler now validates `conflictStrategy` at runtime (schema restriction alone is insufficient for misbehaving clients)
86
+ - `shareInvite` test now uses `deepEqual` to assert exact argument order, catching any future splice regression
87
+ - `checkCliAvailable` now passes `--json` to `proton-drive version` for consistency with all other subprocess calls; added a comment explaining the ENOENT-only semantics
88
+
89
+ ## 1.0.4 — 2026-06-10
90
+
91
+ ### Fixed
92
+ - Timeout errors now surface as "CLI process timed out after Xs" instead of the generic "Command failed" message
93
+ - `--conflict` flag in CLI `upload` command now validates the value (skip/overwrite/rename) before calling the service
94
+ - `role` argument in CLI `share invite` command now validates the value (viewer/editor/admin) before calling the service
95
+
96
+ ### Added
97
+ - Tests for `drive_version` covering both standard `{ cli, sdk }` response and the `{ version }` fallback shape (28 tests total)
98
+
99
+ ## 1.0.3 — 2026-06-10
100
+
101
+ ### Fixed
102
+ - CLI error handler now surfaces `DriveParseError` as "Parse error: ..." (was "Error: Error: ...")
103
+ - CLI catch-all for plain `Error` instances now prints `err.message` directly (was `String(err)` → "Error: Error: message")
104
+ - Removed unused `CliResult<T>` type from `src/types/index.ts`
105
+ - Removed stray double blank line in `src/cli.ts`
106
+
107
+ ## 1.0.2 — 2026-06-10
108
+
109
+ ### Fixed
110
+ - `DriveParseError` now surfaces as "Parse error: ..." instead of "Unexpected error: Error: ..."
111
+ - Validation errors (empty path, invalid email) now show the message directly without the misleading "Unexpected error:" prefix
112
+
113
+ ## 1.0.1 — 2026-06-10
114
+
115
+ ### Added
116
+ - `drive_mkdir` — create empty folders on Proton Drive
117
+ - `drive_list_trash` — list trash contents before emptying or restoring
118
+ - `drive_delete` and `drive_empty_trash` now require `confirmed: true` to prevent accidental data loss
119
+ - CLI `--json` flag for pipe-friendly single-line output
120
+ - CLI `trash list` subcommand
121
+ - CLI `mkdir` command
122
+ - `smithery.yaml` for MCP registry submission
123
+ - Path validation: empty strings are rejected before reaching the CLI
124
+ - Email validation on `drive_share_invite`
125
+ - Friendly CLI error when `proton-drive` binary is not in PATH
126
+ - Upload/download timeout extended to 30 minutes (was 60 seconds)
127
+ - `DriveCliError.stderr` shown in CLI error output
128
+
129
+ ## 1.0.0 — 2026-06-10
130
+
131
+ Initial release.
132
+
133
+ ### MCP Tools
134
+ - `drive_auth_status`, `drive_auth_logout`, `drive_version`
135
+ - `drive_list`, `drive_upload`, `drive_download`, `drive_move`, `drive_delete`
136
+ - `drive_share_status`, `drive_share_invite`, `drive_share_revoke`
137
+ - `drive_trash`, `drive_restore`, `drive_empty_trash`
138
+
139
+ ### CLI
140
+ - `proton-drive-cli` companion CLI exposing all 14 tools
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 googlarz
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,341 @@
1
+ ```
2
+ ____ ____ ___ _____ ___ _ _ ____ ____ _____ _______
3
+ | _ \| _ \ / _ \_ _/ _ \| \ | | | _ \| _ \|_ _\ \ / / ____|
4
+ | |_) | |_) | | | || || | | | \| | | | | | |_) || | \ \ / /| _|
5
+ | __/| _ <| |_| || || |_| | |\ | | |_| | _ < | | \ V / | |___
6
+ |_| |_| \_\\___/ |_| \___/|_| \_| |____/|_| \_\___| \_/ |_____|
7
+ MCP · CLI + Claude Desktop MCP for Proton Drive
8
+ ```
9
+
10
+ <div align="center">
11
+
12
+ [![npm version](https://img.shields.io/npm/v/proton-drive-mcp?color=%236d4aff&label=npm)](https://www.npmjs.com/package/proton-drive-mcp)
13
+ [![CI](https://github.com/googlarz/proton-drive-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/googlarz/proton-drive-mcp/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-drive-mcp?style=social)](https://github.com/googlarz/proton-drive-mcp)
19
+ [![Last commit](https://img.shields.io/github/last-commit/googlarz/proton-drive-mcp?color=brightgreen&label=last%20commit)](https://github.com/googlarz/proton-drive-mcp/commits/main)
20
+ [![Platforms](https://img.shields.io/badge/platform-macOS%20%7C%20Linux%20%7C%20Windows-lightgrey)](https://github.com/googlarz/proton-drive-mcp)
21
+
22
+ </div>
23
+
24
+ ---
25
+
26
+ Give Claude Desktop (or any MCP client) full access to your Proton Drive: list folders, upload and download files, invite collaborators, manage sharing, and handle trash — all with end-to-end encryption intact. The same capabilities are available as a full CLI for scripting, backups, and cron.
27
+
28
+ ## What you get
29
+
30
+ - **Claude manages your Proton Drive** — list, upload, download, move, share, trash, restore
31
+ - **Full CLI** — same 14 operations, scriptable and pipeable, works in cron and shell scripts
32
+ - **Zero credential exposure** — auth is handled entirely by the official Proton Drive CLI; this MCP never touches your password or session token
33
+ - **Shell injection safe** — all CLI calls use `execFile` with discrete argument arrays, never string interpolation
34
+ - **Privacy-native** — end-to-end encryption is handled by Proton's own CLI; this server is just a thin MCP wrapper
35
+
36
+ ---
37
+
38
+ ## Privacy model
39
+
40
+ Your files travel: **Proton Drive (cloud, E2E encrypted) → Proton Drive CLI (local, decrypts) → this MCP server (local) → your AI client**.
41
+
42
+ The Proton Drive CLI handles all cryptography locally. This MCP server calls the CLI as a subprocess and forwards results — it never receives your password, never stores credentials, and never touches the raw encrypted data. Authentication state lives in your OS keychain (macOS Keychain, Windows Credential Manager, Linux libsecret), managed exclusively by the official Proton CLI.
43
+
44
+ If you use Claude Desktop with the default Anthropic API, file content you ask Claude to act on is sent to Anthropic per their [privacy policy](https://www.anthropic.com/privacy).
45
+
46
+ ---
47
+
48
+ ## Prerequisites
49
+
50
+ **1. Proton Drive CLI** — download from [proton.me/download/drive/cli](https://proton.me/download/drive/cli/index.html) and add to your `PATH`.
51
+
52
+ **2. Authenticate the CLI** — run once in your terminal:
53
+
54
+ ```bash
55
+ proton-drive auth login
56
+ ```
57
+
58
+ This opens a browser for Proton's standard sign-in flow. Credentials are stored in your OS keychain — not on disk, not in config files.
59
+
60
+ **3. Node.js 18 or later** — `node --version` to check.
61
+
62
+ ---
63
+
64
+ ## Install
65
+
66
+ **Via npx (no install needed):**
67
+
68
+ ```bash
69
+ # Used directly in Claude Desktop config — no global install required
70
+ npx -y proton-drive-mcp
71
+ ```
72
+
73
+ **Global install:**
74
+
75
+ ```bash
76
+ npm install -g proton-drive-mcp
77
+ ```
78
+
79
+ ---
80
+
81
+ ## Connect to Claude Desktop
82
+
83
+ Add to your `claude_desktop_config.json`:
84
+
85
+ **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
86
+ **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
87
+
88
+ ```json
89
+ {
90
+ "mcpServers": {
91
+ "proton-drive": {
92
+ "command": "npx",
93
+ "args": ["-y", "proton-drive-mcp"]
94
+ }
95
+ }
96
+ }
97
+ ```
98
+
99
+ Restart Claude Desktop. Check **`+` → Connectors → proton-drive** to confirm the server is connected.
100
+
101
+ > **Tip:** Make sure `proton-drive auth login` has been run at least once before starting Claude Desktop.
102
+
103
+ ### If installed globally
104
+
105
+ ```json
106
+ {
107
+ "mcpServers": {
108
+ "proton-drive": {
109
+ "command": "proton-drive-mcp"
110
+ }
111
+ }
112
+ }
113
+ ```
114
+
115
+ ---
116
+
117
+ ## Try it: example Claude prompts
118
+
119
+ **Backup a build artifact**
120
+ > "Upload ./dist/app-v2.zip to /my-files/Releases and tell me if it succeeded."
121
+
122
+ **Morning file triage**
123
+ > "List everything in /my-files. Tell me what's larger than 10MB and what was modified most recently."
124
+
125
+ **Share a folder with a colleague**
126
+ > "Share /my-files/Q2-Reports with alice@proton.me as editor. Add a message: 'Please review before Friday.'"
127
+
128
+ **Offboarding**
129
+ > "Revoke bob@company.com's access from /my-files/Projects and /shared/Design. Confirm when done."
130
+
131
+ **Automated download**
132
+ > "Download /my-files/contracts/nda-2026.pdf to ~/Documents/Legal/."
133
+
134
+ **Trash cleanup**
135
+ > "List what's in the trash and empty it once I confirm."
136
+
137
+ ---
138
+
139
+ ## CLI
140
+
141
+ ```bash
142
+ proton-drive-cli <command> [args]
143
+ ```
144
+
145
+ ### Auth & info
146
+
147
+ ```bash
148
+ proton-drive-cli auth status # check if authenticated
149
+ proton-drive-cli auth logout # log out (clears OS keychain session)
150
+ proton-drive-cli version # CLI and SDK version
151
+ ```
152
+
153
+ ### Files & folders
154
+
155
+ ```bash
156
+ proton-drive-cli list /my-files
157
+ proton-drive-cli list /my-files/Reports
158
+
159
+ proton-drive-cli mkdir /my-files/NewFolder
160
+
161
+ proton-drive-cli upload ./report.pdf /my-files/Reports
162
+ proton-drive-cli upload ./dist /my-files/Releases --conflict overwrite
163
+
164
+ proton-drive-cli download /my-files/report.pdf ./local/report.pdf
165
+ proton-drive-cli download /my-files/Reports ./local/Reports
166
+
167
+ proton-drive-cli move /my-files/old-name.pdf /my-files/new-name.pdf
168
+ proton-drive-cli delete /my-files/obsolete-draft.pdf
169
+
170
+ # Machine-readable output (pipe-friendly)
171
+ proton-drive-cli list /my-files --json | jq '.[].name'
172
+ ```
173
+
174
+ ### Sharing
175
+
176
+ ```bash
177
+ proton-drive-cli share status /my-files/Reports
178
+ proton-drive-cli share invite /my-files/Reports alice@pm.me editor
179
+ proton-drive-cli share invite /my-files/Reports bob@pm.me viewer --message "FYI"
180
+ proton-drive-cli share revoke /my-files/Reports alice@pm.me
181
+ ```
182
+
183
+ ### Trash
184
+
185
+ ```bash
186
+ proton-drive-cli trash /my-files/old-draft.pdf # move to trash
187
+ proton-drive-cli trash list # see what's in trash
188
+ proton-drive-cli restore /my-files/old-draft.pdf # restore from trash
189
+ proton-drive-cli trash empty # permanently delete all trashed items
190
+ ```
191
+
192
+ ### Pipe and script
193
+
194
+ ```bash
195
+ # Backup build output after CI
196
+ proton-drive-cli upload ./dist /my-files/Releases/$(date +%Y-%m-%d) --conflict rename
197
+
198
+ # Download all contracts for audit
199
+ proton-drive-cli download /my-files/Contracts ./audit/contracts
200
+
201
+ # Nightly backup via cron
202
+ 0 2 * * * proton-drive-cli upload ~/Documents /my-files/Backups/$(date +%Y-%m-%d) --conflict skip
203
+
204
+ # Check who has access before a team change
205
+ proton-drive-cli share status /my-files/Projects
206
+ ```
207
+
208
+ ---
209
+
210
+ ## Tool surface
211
+
212
+ ### Auth
213
+ `drive_auth_status` · `drive_auth_logout` · `drive_version`
214
+
215
+ ### Filesystem
216
+ `drive_list` · `drive_mkdir` · `drive_upload` · `drive_download` · `drive_move` · `drive_delete`
217
+
218
+ ### Sharing
219
+ `drive_share_status` · `drive_share_invite` · `drive_share_revoke`
220
+
221
+ ### Trash
222
+ `drive_list_trash` · `drive_trash` · `drive_restore` · `drive_empty_trash`
223
+
224
+ ---
225
+
226
+ ## Tool reference
227
+
228
+ | Tool | Description | Key parameters |
229
+ |------|-------------|----------------|
230
+ | `drive_auth_status` | Check if CLI is authenticated | — |
231
+ | `drive_auth_logout` | Log out (clear session) | — |
232
+ | `drive_version` | CLI and SDK version info | — |
233
+ | `drive_list` | List files and folders at a path | `path` |
234
+ | `drive_mkdir` | Create a new empty folder | `path` |
235
+ | `drive_upload` | Upload local file or folder | `localPath`, `remotePath`, `conflictStrategy` (skip/overwrite/rename) |
236
+ | `drive_download` | Download to local path | `remotePath`, `localPath` |
237
+ | `drive_move` | Move or rename | `sourcePath`, `destinationPath` |
238
+ | `drive_delete` | Permanently delete ⚠️ | `path`, `confirmed: true` |
239
+ | `drive_list_trash` | List items currently in trash | — |
240
+ | `drive_share_status` | Get sharing members and URL | `path` |
241
+ | `drive_share_invite` | Invite a user | `path`, `email`, `role` (viewer/editor/admin), `message?` |
242
+ | `drive_share_revoke` | Revoke access | `path`, `email` |
243
+ | `drive_trash` | Move to trash | `path` |
244
+ | `drive_restore` | Restore from trash | `path` |
245
+ | `drive_empty_trash` | Permanently delete all trash ⚠️ | `confirmed: true` |
246
+
247
+ > ⚠️ **Destructive tools** require `confirmed: true`. Use `drive_list_trash` first so you know what will be deleted, then pass `confirmed: true` to proceed.
248
+
249
+ ---
250
+
251
+ ## Compared with other Drive MCPs
252
+
253
+ | Capability | Generic S3/GDrive MCPs | proton-drive-mcp |
254
+ |---|---|---|
255
+ | End-to-end encryption | No | Yes (via Proton CLI) |
256
+ | Credential exposure | API keys in config | Zero — OS keychain only |
257
+ | Sharing & invitations | Rarely | Full (invite, revoke, status) |
258
+ | Trash & restore | Rarely | Full |
259
+ | CLI parity | No | Full CLI mirrors all MCP tools |
260
+ | Shell injection safe | Varies | Yes — `execFile` only |
261
+
262
+ ---
263
+
264
+ ## Operational notes
265
+
266
+ - `drive_upload` passes `--skip-thumbnails` by default. Remove it from the subprocess args if you want WebP preview generation (requires Bun 1.3.14+ installed).
267
+ - `drive_move` and `drive_delete` are best-effort — the Proton Drive CLI documentation does not guarantee these commands exist in v1. If a command returns a CLI error, the MCP tool surfaces it cleanly.
268
+ - Paths are always Drive-absolute: `/my-files/folder/file.pdf`. Relative paths are not supported.
269
+ - All calls include `--json` automatically — you never need to pass it manually via the CLI wrapper.
270
+
271
+ ---
272
+
273
+ ## Troubleshooting
274
+
275
+ **"proton-drive CLI not found"**
276
+ Download from [proton.me/download/drive/cli](https://proton.me/download/drive/cli/index.html) and ensure the binary is in your `PATH`. Verify with `which proton-drive`.
277
+
278
+ **"Not authenticated"**
279
+ Run `proton-drive auth login` in your terminal. Auth state is stored in your OS keychain and persists across sessions.
280
+
281
+ **Claude can't see the connector**
282
+ Restart Claude Desktop fully after changing the MCP config. Check **`+` → Connectors → proton-drive**. The Proton Drive CLI must be in the `PATH` that Claude Desktop inherits (on macOS this may differ from your shell PATH — use the full binary path in config if needed).
283
+
284
+ **Upload fails on image files**
285
+ The CLI generates WebP thumbnails by default using Bun's image API. If Bun isn't installed or doesn't support thumbnails on your platform, the MCP passes `--skip-thumbnails` to bypass this. No action needed.
286
+
287
+ **Custom binary path**
288
+ If the `proton-drive` binary is installed under a non-standard name or location, set `PROTON_DRIVE_BIN` in your environment:
289
+ ```bash
290
+ PROTON_DRIVE_BIN=/usr/local/bin/proton-drive npx proton-drive-mcp
291
+ ```
292
+ Or in Claude Desktop config:
293
+ ```json
294
+ {
295
+ "mcpServers": {
296
+ "proton-drive": {
297
+ "command": "npx",
298
+ "args": ["-y", "proton-drive-mcp"],
299
+ "env": { "PROTON_DRIVE_BIN": "/usr/local/bin/proton-drive" }
300
+ }
301
+ }
302
+ }
303
+ ```
304
+
305
+ **Windows PATH issues**
306
+ Use the full path to the `proton-drive.exe` binary in your Claude Desktop config if `npx` can't find it:
307
+ ```json
308
+ {
309
+ "mcpServers": {
310
+ "proton-drive": {
311
+ "command": "C:\\path\\to\\proton-drive-mcp.cmd"
312
+ }
313
+ }
314
+ }
315
+ ```
316
+
317
+ ---
318
+
319
+ ## Development
320
+
321
+ ```bash
322
+ git clone https://github.com/googlarz/proton-drive-mcp.git
323
+ cd proton-drive-mcp
324
+ npm install
325
+ npm run build
326
+ npm test
327
+ ```
328
+
329
+ ---
330
+
331
+ ## Changelog
332
+
333
+ See [CHANGELOG.md](CHANGELOG.md) for release history.
334
+
335
+ ## Contributing
336
+
337
+ Bug reports and pull requests welcome: [github.com/googlarz/proton-drive-mcp/issues](https://github.com/googlarz/proton-drive-mcp/issues)
338
+
339
+ ## License
340
+
341
+ MIT