中文 | Download | License | Third-Party Notices
MFuse is a macOS app that exposes remote storage in Finder through File Provider, with a modular backend layer for multiple protocols.
|
|
|
|
- SFTP
- S3
- WebDAV
- SMB
- FTP
- NFS
- Google Drive (sign-in may be unavailable until Google approves the app)
- Dropbox (temporarily unavailable)
- Microsoft OneDrive (temporarily unavailable)
Dropbox and OneDrive are hidden in the app for now: release builds do not include their OAuth client IDs yet, so signing in cannot work. Existing connections of these types are kept but cannot connect.
Google Drive sign-in uses MFuse's OAuth app, which is still in Google's verification. Until it is approved, signing in may be refused or show an "unverified app" warning.
- SFTP directory enumeration has a compatibility fallback: when the normal SFTP listing path times out or hits certain connection-level failures, MFuse may execute a small
python3snippet on the remote host over the existing SSH session to enumerate the directory. This fallback is not used for normal successful listings, permission-denied errors, or missing-path errors. Remote hosts that hit this fallback must havepython3available, otherwise enumeration fails. - FTP uses passive mode only (
EPSV, falling back toPASV); active mode cannot work behind NAT. With TLS on, port 990 uses implicit FTPS and any other port uses explicit FTPS (AUTH TLS); data connections are always encrypted (PROT P). Servers that require TLS session reuse on data connections (vsftpd'srequire_ssl_reuse=YES, FileZilla Server's default) are not supported yet: the TLS library MFuse uses cannot resume a session. - NFS is NFSv3 over TCP, through nfs.swift; NFSv4-only servers are not supported. Remote Path is the exported directory, which is mounted through the portmapper (port 111) and the MOUNT service. Requests carry
AUTH_SYSwith the UID and GID set on the connection, or the Mac user's own by default, and come from a port above 1024, which the File Provider extension cannot go below: a Linux export needs theinsecureoption (for example/srv/nfs *(rw,insecure,no_subtree_check)), or the server refuses the mount. NFSv3 has no server-side copy, so copies pass through the Mac. File names that are not UTF-8 keep their bytes; Finder shows those bytes as placeholder characters.
.
├── MFuse/ # macOS app
├── MFuseProvider/ # File Provider extension
├── Packages/
│ ├── MFuseCore/ # shared models, storage, mount abstractions
│ ├── MFuseSFTP/
│ ├── MFuseS3/
│ ├── MFuseWebDAV/
│ ├── MFuseSMB/
│ ├── MFuseFTP/
│ ├── MFuseNFS/
│ ├── MFuseGoogleDrive/
│ ├── MFuseDropbox/
│ └── MFuseOneDrive/
├── project.yml # XcodeGen project definition
└── Makefile
- macOS 14+
- Xcode 15+
- Swift 5.9+
- XcodeGen
swiftlintfor linting
make generateGoogle Drive, Dropbox and OneDrive use bundled PKCE OAuth app settings loaded from build settings (Dropbox and OneDrive are currently disabled in the app; see above).
Set them in project.local.yml before running the app:
settings:
base:
MFGOOGLE_CLIENT_ID: YOUR_GOOGLE_CLIENT_ID.apps.googleusercontent.com
MFDROPBOX_CLIENT_ID: YOUR_DROPBOX_APP_KEY
MFONEDRIVE_CLIENT_ID: YOUR_MICROSOFT_APP_IDThe Google client must be an iOS-type OAuth client with bundle ID
com.lollipopkit.mfuse, with the Google Drive API enabled and the
https://www.googleapis.com/auth/drive scope on its consent screen.
Default redirect URIs are already wired in the app bundle:
- Google Drive:
com.googleusercontent.apps.<client-id-prefix>:/oauth2redirect, derived from the client ID - Dropbox:
com.lollipopkit.mfuse.dropbox:/oauth - OneDrive:
com.lollipopkit.mfuse.onedrive:/oauth
Current scope:
- Dropbox: standard user file space
- OneDrive: the signed-in user's default personal/work
drive
Out of scope for this first pass:
- SharePoint document libraries and other non-default Microsoft Graph drives
- Dropbox Team Space / admin impersonation flows
make testmake test currently maps to test-stable and runs the stable local package subset.
Use make test-all when you want the full package test matrix.
make lintmake buildmake releasemake release loads signing and notarization credentials from .env, computes the
current git rev-list --count HEAD, and releases with:
MARKETING_VERSION=<MFUSE_BASE_VERSION>.<commit count>CURRENT_PROJECT_VERSION=<commit count>
Example: when the commit count is 2 and MFUSE_BASE_VERSION=1.0, the release
version becomes 1.0.2 and the build number becomes 2.
The release flow now expects:
- a
Developer ID Applicationcertificate already installed in your macOS keychain - notarization credentials already stored via
xcrun notarytool store-credentials - app and extension provisioning profiles already installed under
~/Library/MobileDevice/Provisioning Profiles ghalready authenticated for the target repository with upload permission
After notarization succeeds, make release automatically creates or updates the
GitHub Release tagged v<MARKETING_VERSION>, sets its title to the same value,
and uploads the generated DMG asset.
Current test coverage is centered on Swift packages, especially:
MFuseCorecore models and connection managementMFuseFTPparser behaviorMFuseWebDAVXML parsing
Some backend tests are placeholders or integration-oriented, so protocol coverage is not uniform yet.
Packages/MFuseE2E runs the same file operations — create, overwrite, range and streamed reads, unicode names, move, copy, recursive delete — against real SFTP (password and key), FTP, FTPS (explicit and implicit), WebDAV, SMB, NFSv3 and S3 servers. It does not exercise the File Provider extension itself.
- Provision a Debian 13 host with
scripts/e2e/setup-vm.sh, which installs OpenSSH, vsftpd, Samba, Apache WebDAV, the Linux NFS server and SeaweedFS (S3). Credentials are passed on stdin and never stored in the repository. - Put the matching
MFUSE_E2E_*settings in~/.config/mfuse/e2e.env(see the variablessetup-vm.shreads). Copy the host's test CA certificate,/etc/mfuse-e2e/ca.pem, and pointMFUSE_E2E_CAat it; the FTPS tests trust it only inside the test process. SetMFUSE_E2E_NFS_UIDandMFUSE_E2E_NFS_GIDto the test user's ids on the host (id -u,id -g). - Run
make test-e2e. WithoutMFUSE_E2E_HOSTthe tests are skipped.
HTTPS WebDAV is not covered yet.
MFuse is licensed under the GNU Affero General Public License v3.0. See LICENSE.
Third-party dependencies remain under their own licenses. See THIRD_PARTY_NOTICES.md for the current dependency notice summary.


