FileNest for macOS is the first native client for FileNest Server, an open-source, self-hosted file storage system. It exposes files held by a FileNest Server in Finder using Apple's replicated File Provider architecture. Files begin as remote placeholders and are downloaded only when macOS asks to materialize them.
Experimental: This is an initial, read-only proof of concept. Keep independent backups. It is intended for development against a trusted local network and is not ready for secure Internet deployment.
This version can:
- store a server URL in the shared app-group preferences and a bearer token in a shared Keychain access group;
- test
/api/v1/healthand authenticated/api/v1/serverresponses; - register one stable File Provider domain with macOS;
- enumerate root and nested folders from
/api/v1/items?parent_id=...; - expose file names, types, sizes, dates, and revisions to Finder;
- download a remote file from
/api/v1/items/{id}/contentinto the File Provider temporary volume when Finder opens it; and - reject create, modify, move, rename, and delete requests as unsupported.
It implements FileNest protocol v0, whose numeric protocol_version is 1. The authoritative contract is FileNest Server's protocol-v0.md. No upload, delete, rename, sharing, account, or change-feed endpoints exist in that protocol.
Finder
│
File Provider (NSFileProviderReplicatedExtension)
│
FileNest macOS client
│ HTTPS/HTTP during development
FileNest Server
│
SSD/HDD
The implementation has four layers:
FileNestAppis the small SwiftUI setup and diagnostics app.FileNestCoreowns typed protocol models, configuration, Keychain access, andURLSessionnetworking.FileNestProvidercontains testable identifier, metadata, enumeration, and File Provider error mapping logic.FileNestFileProvideris the thin replicated extension entry point that handles metadata requests, hydration, and read-only mutation failures.
macOS owns and manages materialized local copies. The extension never mounts a custom filesystem and does not use FUSE, a kernel extension, or Finder configuration hacks.
- macOS 14 Sonoma or newer for development with Xcode 16 (the app itself has a macOS 13 deployment target)
- Xcode 16 or newer with the macOS SDK and Swift Testing installed
- an Apple development team capable of signing a macOS app, File Provider extension, App Group, and shared Keychain group
- a running FileNest Server built with Go 1.24 or newer
There are no third-party package dependencies. Package.swift exists so the shared production modules and unit tests can also be built independently of the app project.
From the filenest/server repository, choose a data directory and generate a token of at least 32 random bytes:
export FILENEST_DATA_DIR="$HOME/FileNestData"
export FILENEST_LISTEN_ADDR="127.0.0.1:8080"
export FILENEST_TOKEN="$(openssl rand -hex 32)"
go run ./cmd/filenestFor a different Mac on the trusted LAN to connect, bind the server to a reachable LAN interface, for example 0.0.0.0:8080, and allow the port through the host firewall. This exposes the plain HTTP token and content to anyone able to observe that network. Do not expose this prototype directly to the Internet.
Verify the server locally:
curl http://127.0.0.1:8080/api/v1/health
curl -H "Authorization: Bearer $FILENEST_TOKEN" \
http://127.0.0.1:8080/api/v1/serverThe checked-in identifiers are development defaults:
| Target/resource | Identifier |
|---|---|
| App bundle | uk.filenest.macos |
| Extension bundle | uk.filenest.macos.FileProvider |
| File Provider domain | uk.filenest.primary |
| App Group | group.uk.filenest.shared |
| Shared Keychain group suffix | uk.filenest.shared |
Before running:
- Open
FileNest.xcodeproj. - Select your development team for the
FileNestandFileNestFileProvidertargets and leave automatic signing enabled. - If the checked-in bundle IDs are unavailable to your team, replace both bundle identifiers with unique values.
- Register an App Group for your team. If you replace
group.uk.filenest.shared, change it consistently in:FileNestApp/FileNestApp.entitlementsFileNestFileProvider/FileNestFileProvider.entitlementsFileNestFileProvider/Info.plistConfigurationStore.appGroupIdentifier
- Enable App Groups for both signable targets with the same group.
- Enable Keychain Sharing for both signable targets with the same
uk.filenest.sharedsuffix. Xcode expands$(AppIdentifierPrefix)to the signing team prefix. - Keep App Sandbox and outgoing network connections enabled for both targets.
The committed entitlements declare these capabilities, but the matching identifiers and provisioning profiles must exist in the selected Apple developer team. A free Personal Team may not provision every required capability. The app does not claim that domain registration succeeded when signing or entitlements are missing.
- Select the shared
FileNestscheme and the My Mac destination. - Build and run the app.
- Enter the server origin, such as
http://127.0.0.1:8080orhttp://192.168.1.10:8080. A reverse-proxy base path is also preserved if supplied. - Enter the value of
FILENEST_TOKEN. - Choose Test Connection. The app checks health, authentication, protocol version, and the required read capability.
- Choose Enable FileNest in Finder. The app tests the connection again before registering the stable domain.
- Open Finder and select FileNest under Locations. Browse a folder, then open a file to trigger its download and local materialization.
The token is stored as a generic password in Keychain and is never written to UserDefaults or application logs. The URL is stored in the shared App Group preferences so the host app and extension use the same configuration.
In Xcode, select Product → Test or run:
xcodebuild test \
-project FileNest.xcodeproj \
-scheme FileNest \
-destination 'platform=macOS'With a complete command-line Swift/Swift Testing installation, the shared suite can also run with:
swift testTests use a custom URLProtocol; they do not require a Raspberry Pi or a live FileNest Server. Coverage includes JSON decoding, RFC 3339 dates, URL and opaque-ID encoding, authentication headers, streamed download placement, structured API errors, configuration separation, Apple root identifier mapping, File Provider metadata, read-only capabilities, and File Provider error translation.
The initial server supports plain HTTP for local development, so the app allows user-configured HTTP origins. Plain HTTP provides no confidentiality for bearer tokens or file contents. Use it only on a trusted network. TLS certificates continue to receive normal system validation; the client does not install a permissive trust delegate or bypass certificate checks.
Secure remote Internet access, device pairing, scoped credentials, and certificate management are not provided by this prototype.
- Protocol v0 and this client are read-only. Finder mutations are denied and never reported as successful.
- The server advertises
changes: false; there is no change feed, background polling, or push notification. The working set is intentionally empty and exposes a stable no-change anchor. Finder refreshes directory listings when it enumerates them, but remote changes may not appear immediately in already cached views. - A server-side move or rename changes the item's ID in protocol v0.
- Downloads fetch the whole file. The server's Range support is not yet used for partial File Provider materialization.
- There is one fixed domain, one server, and one bearer token.
- Offline metadata caching, uploads, conflicts, thumbnails, sharing, version history, installers, and auto-update are out of scope.
- Finder integration cannot be exercised without a correctly signed extension and registered App Group.
- HTTP is permitted for development; secure production deployment is not supported.
“Authentication failed”
Confirm the token exactly matches FILENEST_TOKEN. Tokens never belong in the server URL. If the app and extension behave differently, verify that both targets have the identical Keychain Sharing group and signing team.
“Server unreachable”
Open /api/v1/health from the same Mac. For LAN use, ensure the server is not bound only to 127.0.0.1, check the firewall, and use the server's reachable IP address.
“Protocol unsupported”
This client accepts only numeric protocol version 1 and requires capabilities.read == true. Update either component instead of adding undocumented endpoints or compatibility guesses.
The Enable button fails or FileNest is absent from Finder
Check signing for both app and extension, confirm the extension is embedded in FileNest.app/Contents/PlugIns, and verify that the App Group exists for the selected team. You can inspect registered extensions without changing system state:
pluginkit -m -A -D | grep uk.filenest.macosAfter changing bundle IDs or entitlements, clean the Xcode build folder, delete the old development app, rebuild, and register the domain again. macOS may retain a domain associated with the old extension identity until that development app is removed.
A remote change is not visible
Navigate away and reopen the folder. Protocol v0 has no server change feed, so immediate invalidation of cached Finder metadata is not possible without extending the shared server protocol first.
.
├── FileNest.xcodeproj/ # app, extension, libraries, tests, shared scheme
├── FileNestApp/ # SwiftUI configuration application
├── FileNestCore/ # protocol models, API client, Keychain/configuration
├── FileNestFileProvider/ # replicated extension and provider support
├── FileNestTests/ # mocked-network and mapping unit tests
├── Package.swift # standalone shared-module/test build
├── README.md
└── LICENSE
- Add a server change-feed contract before implementing File Provider change enumeration and cache invalidation.
- Add partial-content hydration using the protocol's Range support.
- Design authenticated create/modify/delete server APIs, then implement bidirectional sync and conflict handling.
- Add a domain removal/reconfiguration flow and richer diagnostics.
- Add app and Finder sidebar artwork.
FileNest for macOS is licensed under the GNU General Public License v3.0. See LICENSE.