proton-drive-mcp 1.5.1 → 1.5.2
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 +8 -0
- package/README.md +1 -1
- package/dist/cli.js +3 -3
- package/dist/index.js +2 -1
- package/dist/services/drive.js +2 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.5.2 — 2026-10-05
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- `drive_upload` (and `proton-drive-cli upload --skip-thumbnails`) can skip thumbnail generation, the CLI's `--skip-thumbnails` option.
|
|
7
|
+
|
|
8
|
+
### Changed
|
|
9
|
+
- README: the coverage statement now says exactly what is covered: all 32 scriptable commands of CLI 0.8.0 (everything except the interactive `auth login`), but not every optional flag. Deliberately not exposed: `sharing invite --include-node-name` (it would send the file name in the invitation email in clear text) and the `inherited` invite role (its meaning is unverified and status output would mislabel it).
|
|
10
|
+
|
|
3
11
|
## 1.5.1 — 2026-10-02
|
|
4
12
|
|
|
5
13
|
### Changed
|
package/README.md
CHANGED
|
@@ -59,7 +59,7 @@ What to expect: search matches names, sizes and dates, not the text of every fil
|
|
|
59
59
|
- **Claude manages your Proton Drive** — list, upload, download, move, share, trash, restore
|
|
60
60
|
- **Proton Photos album management** — list albums, create/delete albums, add and remove photos
|
|
61
61
|
- **Companion CLI** — 45 of the 47 operations, scriptable and pipeable, works in cron and shell scripts (the two sync-folder tools, `drive_read_file` and `drive_write_file`, are MCP-only)
|
|
62
|
-
- **Full Proton Drive CLI coverage** —
|
|
62
|
+
- **Full Proton Drive CLI command coverage** — all 32 scriptable commands of CLI 0.8.0 have a matching tool (checked against the CLI's own help; `auth login` is the one command excluded, since it's an interactive browser flow). Not every optional flag is exposed: `sharing invite --include-node-name` is deliberately off (it would put the file name in the invitation email in clear text) and the `inherited` invite role is not offered; commands that accept several paths run one path per call except bulk move and bulk trash
|
|
63
63
|
- **Zero credential exposure** — auth is handled entirely by the official Proton Drive CLI; this MCP never touches your password or session token
|
|
64
64
|
- **Shell injection safe** — all CLI calls use `execFile` with discrete argument arrays, never string interpolation
|
|
65
65
|
- **Privacy-native** — end-to-end encryption is handled by Proton's own CLI; this server is just a thin MCP wrapper
|
package/dist/cli.js
CHANGED
|
@@ -40,7 +40,7 @@ Commands:
|
|
|
40
40
|
[--limit N] [--offset N] [--refresh]
|
|
41
41
|
Find files/folders under path (default /my-files) in one walk
|
|
42
42
|
mkdir <path> Create a new folder
|
|
43
|
-
upload <local> <remote> [--file-conflict X] [--folder-conflict X] [--confirm]
|
|
43
|
+
upload <local> <remote> [--file-conflict X] [--folder-conflict X] [--skip-thumbnails] [--confirm]
|
|
44
44
|
Upload file/folder (files: skip/create-new-revision/rename/replace; folders: skip/merge/rename/replace;
|
|
45
45
|
'replace' trashes the existing remote item and needs --confirm)
|
|
46
46
|
download <remote> <local> [--file-conflict X] [--folder-conflict X] [--confirm]
|
|
@@ -271,7 +271,7 @@ async function run() {
|
|
|
271
271
|
case "upload": {
|
|
272
272
|
const rawLocal = sub;
|
|
273
273
|
if (!rawLocal) {
|
|
274
|
-
console.error("Usage: upload <local> <remote> [--file-conflict X] [--folder-conflict X]");
|
|
274
|
+
console.error("Usage: upload <local> <remote> [--file-conflict X] [--folder-conflict X] [--skip-thumbnails]");
|
|
275
275
|
process.exit(1);
|
|
276
276
|
}
|
|
277
277
|
let local;
|
|
@@ -298,7 +298,7 @@ async function run() {
|
|
|
298
298
|
console.error("Strategy 'replace' trashes the existing remote item.\nPass --confirm to proceed.");
|
|
299
299
|
process.exit(1);
|
|
300
300
|
}
|
|
301
|
-
print(await drive.upload(local, remote, fileConflictRaw, folderConflictRaw));
|
|
301
|
+
print(await drive.upload(local, remote, fileConflictRaw, folderConflictRaw, args.includes("--skip-thumbnails")));
|
|
302
302
|
break;
|
|
303
303
|
}
|
|
304
304
|
case "download": {
|
package/dist/index.js
CHANGED
|
@@ -249,6 +249,7 @@ const TOOLS = [
|
|
|
249
249
|
enum: ["skip", "merge", "rename", "replace"],
|
|
250
250
|
description: "'skip' keeps the existing remote folder (default). 'merge' merges contents into it. 'rename' uploads under a unique name. 'replace' trashes the remote folder first — confirm with user.",
|
|
251
251
|
},
|
|
252
|
+
skipThumbnails: { type: "boolean", description: "Skip thumbnails." },
|
|
252
253
|
},
|
|
253
254
|
required: ["localPath", "remotePath"],
|
|
254
255
|
additionalProperties: false,
|
|
@@ -1210,7 +1211,7 @@ export async function main() {
|
|
|
1210
1211
|
if ((fcs === "replace" || dcs2 === "replace") && a.confirmed !== true) {
|
|
1211
1212
|
throw new NeedsConfirmationError("drive_upload with strategy 'replace' trashes the existing remote item. Describe this to the user, get their explicit OK, then call again with confirmed=true.");
|
|
1212
1213
|
}
|
|
1213
|
-
const uploadResult = await drive.upload(validateLocalPath(a.localPath, { scan: true }), validateRemotePath(a.remotePath), fcs, dcs2);
|
|
1214
|
+
const uploadResult = await drive.upload(validateLocalPath(a.localPath, { scan: true }), validateRemotePath(a.remotePath), fcs, dcs2, a.skipThumbnails === true);
|
|
1214
1215
|
if (uploadResult.failed > 0) {
|
|
1215
1216
|
return fail(`Upload completed with ${uploadResult.failed} failed file(s). uploaded=${uploadResult.uploaded} skipped=${uploadResult.skipped}`);
|
|
1216
1217
|
}
|
package/dist/services/drive.js
CHANGED
|
@@ -254,7 +254,7 @@ export class DriveService {
|
|
|
254
254
|
}
|
|
255
255
|
return file;
|
|
256
256
|
}
|
|
257
|
-
async upload(localPath, remotePath, fileConflictStrategy = "skip", folderConflictStrategy = "skip") {
|
|
257
|
+
async upload(localPath, remotePath, fileConflictStrategy = "skip", folderConflictStrategy = "skip", skipThumbnails = false) {
|
|
258
258
|
// finally: a partly completed upload that then fails also changes the tree.
|
|
259
259
|
let result;
|
|
260
260
|
try {
|
|
@@ -267,6 +267,7 @@ export class DriveService {
|
|
|
267
267
|
fileConflictStrategy,
|
|
268
268
|
"--folder-conflict-strategy",
|
|
269
269
|
folderConflictStrategy,
|
|
270
|
+
...(skipThumbnails ? ["--skip-thumbnails"] : []),
|
|
270
271
|
]);
|
|
271
272
|
}
|
|
272
273
|
finally {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "proton-drive-mcp",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.2",
|
|
4
4
|
"description": "MCP server and CLI that gives Claude full access to Proton Drive — upload, download, share, and manage your end-to-end encrypted files without leaving the conversation.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|