smfs: a mountable filesystem for Supermemory containers
A filesystem designed for agents, with SOTA retrieval, automatic memory profiles, sync engine. Drop any file type (pdf, images, videos), and grep through them.
At a glance
- What is it?
- smfs exposes a Supermemory container as a real directory you can cat, edit and grep, and ships a TypeScript bash tool for runtimes with no filesystem at all. The semantic grep wrapper is the interesting part; the memory-path scope is the part that will surprise you.
- Who is it for?
- smfs is worth adopting if your agent already lives on a machine with a kernel and you want memory to look like files rather than an SDK call. Skip it if you need a stable API surface: the workspace version is 0.0.5, the last push was on 2026-08-18, and the README documents no rollback path for a bad mount configuration.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 43 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What smfs actually replaces
Most agent memory layers are an API you call: write a fact, query a fact. smfs takes the opposite position. It mounts a Supermemory container tag as a directory, so the agent's memory is a folder of files that any editor, script or shell command can touch. The README puts it plainly: "Read, write, and grep your memory like any local directory."
The audience is narrower than the tagline suggests. If you are building an agent that already runs on macOS, Linux, a devcontainer, a Codespace, Docker or a microVM, smfs gives you a filesystem view of memory with no new client library. If your agent runs on Cloudflare Workers, a serverless function, an edge runtime or in a browser, there is no kernel to mount onto, and the project's answer is a separate TypeScript package that fakes the filesystem in-process. Those are two different products sharing one name, and the README is explicit that the split exists.
The practical win is that you do not teach an agent a new tool. It already knows cat, ls and grep. smfs changes what those commands resolve to.
Mount backends, the sync loop and the SQLite cache
The workspace has two crates, crates/smfs-core and crates/smfs, and the Cargo.toml comments explain the backend choice. fuser is Linux-only, because on macOS it would require macFUSE, which the project says it "explicitly avoid[s]". So on macOS the mount is served by nfsserve, a pure Rust NFSv3 server. nfsserve is described as unix-wide and usable as an alternate backend on Linux. The --backend fuse|nfs flag exposes that choice, defaulting to fuse on Linux and nfs on macOS.
Reads and writes go through a local cache backed by rusqlite with the bundled feature, plus an LRU layer. Writes upload to Supermemory in the background rather than synchronously, and remote changes pull in on an interval that defaults to 30 seconds and is set with --sync-interval. That default matters: a file you wrote on another machine is not visible in the mount immediately, it shows up on the next pull.
Unmounting is not instant either. smfs unmount drains the push queue with a maximum wait controlled by --drain-timeout, default 30 seconds. If you have been writing heavily and the network is slow, that drain is where you find out.
--no-sync disables the pull side only. Local writes still push. That is a useful mode for a writer that never wants remote state overwriting its view, and a dangerous one if you forget which machine holds the truth.
Installing smfs and mounting a container
The install path is a shell script from the project's own domain, and it supports macOS on arm64 and x64 and Linux on arm64 and x64. You need a Supermemory API key from supermemory.ai before anything works.
curl -fsSL https://smfs.ai/install | bashAfter that, authenticate once. The README says smfs login stores your API key locally, so subsequent commands resolve credentials without a flag.
smfs login
smfs mount agent_memoryThe mount lands at ./agent_memory/ by default, matching the container tag. Override the location with --path. Then the filesystem behaves like any other folder.
ls agent_memory/
cat agent_memory/memory/notes.md
smfs unmount agent_memoryIf you are building from source instead, the workspace requires Rust 1.80 or newer and the README gives cargo build --release followed by ./target/release/smfs --help. The Dockerfile pins rust:1.80-slim for the builder stage and debian:bookworm-slim for the runtime, installing fuse3 in the final image. Running a FUSE mount inside a container needs --device /dev/fuse and --cap-add SYS_ADMIN, both shown in the README's docker run example.
Memory paths are the setting that decides what gets indexed
This is the part of smfs that is easiest to get wrong. Every file in a mount is durable storage. Only files under the container's memory paths go through Supermemory's memory pipeline, the stage that extracts structured facts and makes content semantically searchable. Everything outside that scope is just bytes on a disk that happens to be remote.
The server applies a built-in path scope per container by default. You can override it per mount with --memory-paths, and the README is clear about the matching rules: a trailing slash matches any file inside that folder recursively, no trailing slash means an exact file match.
smfs mount agent_memory --memory-paths "/notes/,/journal.md,/work/"
smfs mount agent_memory --memory-paths ""The empty string disables memory generation entirely and turns the mount into pure storage. Omitting the flag leaves the existing server config alone. The flag writes the configuration to the container tag, so the next mount inherits whatever you last set. That persistence is the trap: a scope you set once for an experiment becomes the container's default until you change it back. The README does not document a dry-run or a way to inspect the current scope before overwriting it, which is a real gap for a setting with this much blast radius.
Semantic grep by hijacking the grep you already type
smfs init installs a shell wrapper. After that, inside any mount, a flagless grep is routed through Supermemory's semantic index. Add any flag and it falls through to the real grep binary. That single rule is the whole interface, and it is a good one, because it means an agent that already knows grep needs no retraining.
cd agent_memory/
grep "OAuth refresh tokens"
grep "design review notes" work/
grep -F "exact string" notes.mdThe wrapper decides whether it is inside a mount by looking for a hidden .smfs marker. Outside a mount, grep is untouched. If you need semantic search from outside, smfs grep "query" --tag <container_tag> does the same thing without the wrapper.
The failure mode is silent. A user who types grep -r "something" expecting semantic results gets literal substring matching instead, because -r is a flag. The README states the rule, but nothing warns you at runtime when you have crossed the line. For an agent, that means a prompt that includes a flag quietly degrades retrieval quality with no error.
The bash/ package for runtimes with no filesystem
For Cloudflare Workers, serverless functions, edge runtimes and browser-based agents, there is nothing to mount. The @supermemory/bash TypeScript package inverts the model: the bash tool is the filesystem. You add one run_bash tool to the agent's tool-set and the agent gets the Unix commands it already knows, plus an sgrep command for semantic search across the container.
import { createBash } from "@supermemory/bash";
const { bash, toolDescription } = await createBash({
apiKey: process.env.SUPERMEMORY_API_KEY!,
containerTag: "user_42",
});
await bash.exec("echo 'hello' > /a.md && cat /a.md");
await bash.exec("sgrep 'authentication tokens'");Note that semantic search here is a distinct command, sgrep, not a grep wrapper. That is a deliberate difference from the mount path, and it means the two flows are not drop-in replacements for each other. An agent prompt written for the mount's flagless grep will not work unchanged against the bash tool. The README points to bash/README.md for the full quickstart, options and Vercel AI SDK examples, and there is also a bash-py/ directory at the repository root, though the README does not document it.
Where smfs is the wrong tool, and what it competes with
smfs assumes Supermemory is your memory backend. It is a client for one service, not a general filesystem abstraction, and the API key requirement is the first line of that dependency. If you want memory that lives entirely on your own infrastructure, this is not the layer that gets you there.
The second constraint is the mount model itself. FUSE and NFS mounts are kernel features. They do not exist in the runtimes where a lot of agents actually run, which is why the bash/ package exists at all. If your deployment target is a Worker, the mount path is irrelevant to you and you should read bash/README.md instead of the top-level quickstart.
The third is the version number. Cargo.toml sets the workspace version to 0.0.5, and the most recent tagged release is v0.0.5 from 2026-05-07. The last push to the repository was on 2026-08-18, so development has continued past the release, but there is no 1.0 and no documented compatibility promise. Treat the CLI surface as movable.
Against a direct API integration with Supermemory, the difference is where the logic sits. An API integration puts retrieval decisions in your application code: you choose when to query, what to store, how to rank. smfs pushes those decisions into the filesystem layer, and the memory-path scope plus the pull interval become your retrieval policy. That is less code and less control. For an agent that should behave like it has a home directory, the trade is good. For a pipeline where you need deterministic, auditable retrieval, calling the API yourself is the more honest design.
Licence, maintenance and what an upgrade costs
smfs is MIT licensed, stated in Cargo.toml and in the LICENSE file at the repository root. There is a licenses/ directory alongside it, which usually means bundled third-party notices; the README does not describe its contents. MIT is permissive, so embedding the binary in a product is not a licensing question in the way a copyleft dependency would be. That is a description of the licence text, not legal advice, and the Supermemory service you connect to has its own terms that this repository does not cover.
Upgrade cost is dominated by the container tag, not the binary. The --memory-paths flag persists scope to the container tag, so a configuration written by one version of the CLI stays in effect across upgrades. If a future release changes how paths are matched, the effect lands on data you already indexed, not on a config file you can diff. The CLI also stores credentials locally and keeps a SQLite cache, and --clean wipes that cache before mounting, which is the documented recovery move when local state and remote state disagree.
The repository was last pushed on 2026-08-18, which is recent enough that the project is not dormant, but the release cadence visible in the repository is three tags in four days in early May 2026 and nothing since. That pattern suggests bursts of work rather than a steady release train.
Editorial conclusion
smfs is worth adopting if your agent already lives on a machine with a kernel and you want memory to look like files rather than an SDK call. Skip it if you need a stable API surface: the workspace version is 0.0.5, the last push was on 2026-08-18, and the README documents no rollback path for a bad mount configuration. Before mounting anything you care about, run smfs mount with --memory-paths set explicitly, then check smfs status for queue depth, because the flag writes to the container tag and the next mount inherits it.
Frequently asked questions
How does smfs work with Supermemory?
smfs mounts a Supermemory container tag as a local directory, so files you read and write there are pushed to and pulled from Supermemory in the background. Only files under the container's memory paths go through the memory pipeline that extracts structured facts and makes content semantically searchable.
Can smfs or Supermemory be self-hosted?
The README does not describe a self-hosted Supermemory server. smfs itself is a client: it needs a Supermemory API key and talks to an API base URL that can be overridden with --api-url, but the README does not document running the backing service yourself.
What do I need before installing smfs?
A Supermemory API key from supermemory.ai, and a supported platform: macOS or Linux on arm64 or x64. The installer is a shell script fetched from smfs.ai, and smfs login stores the key locally so later commands do not need it passed as a flag.
How do I run a semantic search with smfs?
Run smfs init once to install the grep shell wrapper. Inside a mount, a flagless grep such as grep "OAuth refresh tokens" is semantic, while any grep that includes a flag falls through to the real grep binary. From outside a mount, smfs grep "query" --tag <container_tag> does the same thing.
Which mount backend does smfs use on macOS?
NFS, not FUSE. The Cargo.toml notes that fuser is Linux-only because it would require macFUSE on macOS, which the project avoids, so nfsserve serves the mount there. The --backend flag takes fuse or nfs, defaulting to fuse on Linux and nfs on macOS.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/supermemoryai-smfs)