The smuggler's ship for your data — one cockpit for every system, a transfer engine you can walk away from, and a manifest that survives the jump.
kessel is a fast, native desktop file manager for remote filesystems, built in Rust on GPUI and Apache OpenDAL. It is a Cyberduck/FileZilla-class client that unifies object storage and classic transfer protocols behind one interface: S3, SFTP, FTP, WebDAV, Google Cloud Storage, Azure Blob, Google Drive, Dropbox, OneDrive, and the local filesystem today — and because the storage layer is OpenDAL, adding a backend mostly means turning a feature flag on.
- One or two panes per tab (horizontal / vertical split) with drag & drop between panes, to directory rows, and from Finder/Explorer
- Virtualized file list built for huge directory listings, with per-backend columns (size, modified, unix permissions, S3 storage class, bucket region)
- Finder-grade selection: click, cmd-click, shift-click ranges, rubber-band, full keyboard navigation
- Per-pane folder tree, quick look, in-app search, hidden-file toggle
- Account-root S3 browsing: save a site without a bucket and the root lists every bucket in the account
- Persistent queue — every job and per-file task lives in SQLite with its state and byte offset, so the queue survives a crash or quit and resumes mid-transfer on relaunch
- Upload, download and site-to-site copy are the same code path: a layered source Operator streamed into a layered destination Operator
- Conflict handling per file: ask, overwrite, skip, resume (append the missing tail), or rename
- Priorities, pause/resume (per job and global), retries, post-transfer verification, timestamp preservation, transfer history
- Global and per-site bandwidth throttling and concurrency caps
- Directory sync between any two sites: a diff pass (size + modified time) produces a reviewable plan — copy new, update changed, and in mirror mode delete extraneous — then hands the copies to the persistent queue
- Google Drive, Dropbox and OneDrive connect through a built-in OAuth flow (browser sign-in with PKCE and a loopback redirect); only the long-lived refresh token is kept, in the OS keychain, and access tokens renew automatically
- S3 sites authenticate with access keys (with optional STS session
token), or straight from
~/.awsprofiles — including SSO and assume-role profiles, resolved to short-lived credentials and refreshed before they expire
- Arc-style sidebar: bookmarks act as pinned tabs, ephemeral tabs below, spaces switch whole tab sets — the session persists across restarts
- Bookmark folders, tags, icons and accent colors
- Secrets never touch SQLite: passwords, keys and passphrases go to the OS keychain, referenced by handle only
The historically hardest parts of a transfer client — broad protocol support and a resilient transfer core — are OpenDAL's, not ours. Every connection is wrapped in a composable, per-site layer stack:
| Layer | What it buys you |
|---|---|
RetryLayer |
exponential backoff; dropped FTP/S3 connections self-heal |
TimeoutLayer |
bounded operations; no hung transfers on a dead socket |
ThrottleLayer |
bandwidth control, per-site and global |
ConcurrentLimitLayer |
caps in-flight operations per backend |
LoggingLayer + TracingLayer |
structured logs feeding the in-app console |
- Command bar (
cmd-k): fuzzy palette over every command, bookmark and space, with keystroke hints - Settings editor (
cmd-,): searchable, Zed-style — categories, inline descriptions — writing through to the same hand-editable config file; comments survive, values hot-reload - Hand-editable JSON5 config (comments, trailing commas) with live reload — every value applies while the app is running
- Configurable keybindings, same JSON5 dialect
- Zed theme & icon-theme browser: search the Zed extension gallery,
install with one click, hot-applied — plus anything you drop into
<data_dir>/themes/or<data_dir>/extensions/yourself - Native menu bar with the standard app/File/Edit/View/Go/Help menus
- Built-in MCP server (off by default): point Claude Code or any MCP
client at
http://127.0.0.1:39100/mcpand browse sites, inspect the queue and transfer history, or — explicitly opt-in — enqueue and control transfers. Configure undermcpinconfig.json5(claude mcp add --transport http kessel http://127.0.0.1:39100/mcp)
- Fully keyboard-operable: every command is reachable via configurable shortcuts, the command bar, or the native menu bar
- Localized UI (English and German built in); add a locale by dropping a
<locale>.json5string table into<data_dir>/i18n/— see CONTRIBUTING.md
| Concern | Choice |
|---|---|
| Language | Rust (stable) |
| GUI | GPUI + gpui-component |
| Storage layer | Apache OpenDAL — unified Operator + layer stack |
| Async runtime | tokio (app-owned runtime; gpui keeps its own executor) |
| Local state | SQLite via sqlx (bookmarks, queue, history, session) |
| Secrets | OS keychain via keyring |
| Config | JSON5 via the config crate, live-reloaded |
| Observability | tracing ecosystem |
- Rust stable (latest; GPUI tracks latest stable)
- macOS 12+ (primary target; the codebase is written to be portable)
git clone https://github.com/coderscantina/kessel.git
cd kessel
cargo runscripts/bundle.sh # release build → target/bundle/release/Kessel.app
scripts/bundle.sh dev # debug build with the dev icon and bundle id
scripts/package.sh # sign + notarize + staple → target/dist/Kessel-<version>.dmgpackage.sh reads KESSEL_SIGN_IDENTITY (a Developer ID Application
identity) and notarizes via KESSEL_NOTARY_PROFILE or
APPLE_ID/APPLE_TEAM_ID/APPLE_APP_PASSWORD; without an identity it falls
back to an ad-hoc-signed, non-notarized DMG for local use.
- CalVer: releases are tagged
vYY.M.D(e.g.v26.7.10) — the version tells you exactly how old your build is. At most one release per day. - Gitmoji: commits follow the Gitmoji convention
(
✨feature,🐛fix,♻️refactor,🔖release, …); the CHANGELOG is generated from commit subjects, so they're written to be read. scripts/release.shcuts a release: bumpsCargo.toml, creates the🔖 Releasecommit, folds the generated changelog entry into it, tags and pushes — and the tag triggers the GitHub workflow that builds a universal binary, signs, notarizes, packages the DMG and publishes the release with an update manifest.- Auto-update: kessel checks the latest release on startup (daily
thereafter,
update.check = falseto opt out) and offers a one-click, checksum-verified install-and-relaunch.
App defaults ship compiled in; your overrides live in
<data_dir>/kessel/config.json5 (macOS:
~/Library/Application Support/kessel/config.json5) — same shape, comments
welcome, hot-reloaded on save. Keybindings follow the same pattern in
keybindings.json5. See assets/config/ for the annotated
defaults.
Contributions are welcome — see CONTRIBUTING.md for the workflow, commit conventions, and how to get a development build running.
If you discover a security vulnerability, please email security@coderscantina.com instead of opening a public issue.
kessel is open-source software licensed under the MIT license.
- Apache OpenDAL — the storage layer that makes broad protocol support tractable
- GPUI and gpui-component — the GPU-accelerated UI stack
- Lucide — icons