CLI
kutup is a Rust CLI for the same E2EE primitives as the web — register, login, account recovery, ls, upload (resumable), download, sync, trash, share, versions, devices, 2fa, public-link consumption, file/folder rename. All operations are end-to-end encrypted in your shell; the server only ever sees ciphertext.
Scripting-friendly: every command honors a global --json flag (stdout is exactly one JSON document; prompts/progress/status go to stderr, and with --json even errors are emitted as JSON on stderr), and exit codes are differentiated — 0 ok, 1 generic, 2 usage, 3 auth/session, 4 not found, 5 network/server. Destructive commands prompt [y/N] and take --yes for non-interactive use.
Build from source (Rust ≥ 1.91.1):
git clone https://github.com/kutupbt/kutup.gitcd kutupcargo build --release -p kutup-cli # → target/release/kutupinstall -m755 target/release/kutup ~/.local/bin/kutupTagged release binaries are built for Linux x86-64/ARM64, macOS Intel/Apple Silicon, and Windows x86-64 and published on GitHub Releases (see release workflow).
Common workflows
Section titled “Common workflows”# Create an account (client-side crypto; prints a 24-word recovery phrase once).kutup register --server https://your.kutup.host --email you@example.com --username you
# Login (interactive password prompt; password can also come from KUTUP_PASSWORD).kutup login --server https://your.kutup.host --email you@example.com
# List your folders + files at the Drive root.kutup lskutup ls <folder-id> # contents of a sub-folder
# Forgot the password? Reset it with the 24-word recovery phrase# (KUTUP_RECOVERY_PHRASE + KUTUP_PASSWORD for non-interactive use).kutup recover --server https://your.kutup.host --email you@example.com
# Upload a file. The CLI's chunked stream encryption (5 MB blocks via# crypto_secretstream) has NO browser-imposed size limit — multi-GB# files (ISOs, raw video, datasets) work where the web upload chokes# around ~2 GB and crashes the tab. File size is bounded by disk,# not RAM. Interrupted uploads RESUME from the last 5 MB chunk when# you rerun the same command (--no-resume restarts from zero).kutup upload ./big-dataset.tar.gz <folder-id>kutup upload ./local-dir <folder-id> --recursive
# Download a file. For collab-edited files (notes / office /# whiteboards) returns the latest snapshot — same content the web# shows, not the cold-start initial. Whiteboard image assets are# re-inlined so the .excalidraw is self-contained.kutup download <file-id>kutup download <file-id> ./local/path/
# Bidirectional sync: recursive (sub-folders ↔ sub-collections), with# real change detection — local edits re-upload, remote changes# re-download, and concurrent edits produce a name.sync-conflict-<ts># copy instead of silently overwriting. Deletions propagate only with# --delete; --dry-run previews without touching anything.kutup sync ./local-folder <folder-id>kutup sync ./local-folder <folder-id> --watch # live fsnotify synckutup sync ./local-folder <folder-id> --watch --poll 60 # + poll remote every 60skutup sync ./local-folder <folder-id> --delete --dry-run
# Trash: deleted items are recoverable until the retention window ends.kutup trash lskutup trash restore <id>kutup trash empty --yes
# Rename a file or a folder (names are E2EE metadata; content untouched).kutup mv <file-id> "new name.txt"kutup mv <folder-id> "New folder name" --folder
# List versions. Restore is currently safe for CLI/sync-created files;# live-collaboration snapshots need the web client's derived content-key path.kutup versions list <file-id>kutup versions restore <file-id> <version-id>
# Public-link consumption — no kutup login required for the URL itself.kutup pub get https://your.kutup.host/s/<token>#key=<base64>kutup pub download <url> <file-id>
# Discover the rest.kutup --helpkutup versionThe >2 GB path is the standout. Browser File API + Web Crypto streaming work in theory but practically wedge the tab at multi-GB sizes; the CLI streams crypto_secretstream (XChaCha20-Poly1305, 5 MB chunks) over a Rust reader, so it handles arbitrarily large files at constant ~5 MB memory.