Self-hosted service
supermemoryai/smfs avatar
supermemoryai/smfs

smfs: a FUSE and NFS mount that turns a Supermemory container into a directory you can grep

A filesystem designed for agents, with SOTA retrieval, automatic memory profiles, sync engine. Drop any file type (pdf, images, videos), and grep through them.

478 stars36 forksRustMIT

At a glance

What is it?
smfs exposes a Supermemory container as a local folder on macOS and Linux, with a semantic grep wrapper and a separate TypeScript bash tool for runtimes that have no filesystem. It is early software at version 0.0.5, and the memory pipeline only processes files inside configured memory paths.
Who is it for?
Adopt smfs if your agents already write into Supermemory and you want that content reachable through ordinary file tools on macOS or Linux, or if you run agents on Cloudflare Workers and other runtimes with no filesystem, where the @supermemory/bash package is the only usable path.
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 28 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 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem smfs targets: agent memory that no ordinary tool can read

Agent memory usually lives behind an API. To inspect it you write a client, call an endpoint, and print JSON. That works until you want to do something mundane, like open a note in your editor, pipe a file through a script, or search for a phrase you half remember. smfs removes that step by mounting a Supermemory container as a real directory. The README describes the intent plainly: read, write, and grep your memory like any local directory. The audience is narrow and identifiable. It is developers who already store agent context in Supermemory and want filesystem semantics on top, plus agent authors running in environments where no filesystem exists at all. If you do not use Supermemory, smfs has nothing to mount, because every operation goes through a Supermemory API key and a container tag. That dependency is the whole product boundary, and the README never pretends otherwise.

Two access flows because one runtime does not fit all agents

The repository splits access along a runtime boundary rather than a feature boundary. On macOS, Linux, devcontainers, Codespaces, Docker and microVMs, smfs mounts a container as a local folder, and the README states this works wherever a kernel and filesystem exist. On Cloudflare Workers, serverless functions, edge runtimes and browser-based agents, there is no filesystem to mount onto, so the project ships a TypeScript package, @supermemory/bash, that implements the filesystem itself. The README puts it directly: the bash tool is the filesystem. The agent gets a single run_bash tool and uses the Unix commands it already knows, plus an sgrep command for semantic search across the container. This is a reasonable split, and it is also a maintenance split. The Rust daemon and the TypeScript package are separate codebases with separate release cadences, so a fix in one does not imply a fix in the other. Nothing in the supplied material describes how the two stay in sync on behaviour.

How the mount works: a daemon, a queue, and a 30 second pull

Mounting a tag starts a background daemon. `smfs mount <container_tag>` places the folder at ./<tag>/ by default, overridable with --path. Inside the mount, writes upload to Supermemory in the background, and remote changes pull in every 30 seconds. The pull interval is configurable with --sync-interval, and --no-sync disables the pull side entirely while local writes continue to push. The backend differs by platform: the flag listing gives fuse on Linux and nfs on macOS as defaults, selectable with --backend. Unmounting is not instant. `smfs unmount <tag>` drains pending pushes, and --drain-timeout caps that wait at 30 seconds by default. For operators, `smfs status <tag>` reports daemon health and queue depth, `smfs logs <tag>` tails the daemon log, and `smfs sync <tag>` forces a cycle. The queue is therefore the thing to watch. A mount that looks healthy in your file browser can still be holding unsent writes, and the drain timeout means an unmount can give up waiting.

Memory paths decide whether a file is searchable or just stored

This is the part most likely to surprise someone. Files in a mount are durable everywhere, but according to the README only files under the container's memory paths get processed by Supermemory's memory pipeline, the part that extracts structured facts and makes them semantically searchable. Everything else is plain durable storage. By default the server applies its built-in path scope per container, and you can override it per mount with --memory-paths, a comma separated list. Trailing slash means match any file inside that folder recursively, no trailing slash means exact file match. Passing an empty string disables memory generation 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 the same scope until you change it. That persistence is convenient and also a trap: a scope you set once for an experiment stays in effect for every later mount of that tag, including mounts started from a different machine or a different developer's shell.

Semantic grep hides behind the system grep command

`smfs init` installs a shell wrapper. After that, inside any mount, a flagless `grep "query"` routes through Supermemory's semantic index, and `grep "query" work/` scopes that search to a directory. Any flag falls through to the real grep, so `grep -F "exact string" notes.md` and `grep -rF "literal" .` behave normally. The wrapper detects that your shell is inside a mount via a hidden .smfs marker. Outside a mount, grep is unchanged. The README calls this split the whole UX, and it is a genuinely clever choice: agents already know grep, so no new tool has to be taught. The cost is ambiguity. A person who types grep without a flag and gets semantic results may not register that they changed tools. There is an escape hatch for scripts that cannot rely on the wrapper: `smfs grep "query" --tag <container_tag>` performs the same semantic search from outside a mount.

Getting it running: install, login, mount, and the container cases

The installer is a shell script: `curl -fsSL https://smfs.ai/install | bash`, supporting macOS and Linux on arm64 and x64. You need a Supermemory API key. Then `smfs login` stores it, `smfs mount agent_memory` mounts the tag, and `ls agent_memory/` or `cat agent_memory/memory/notes.md` confirms it. Building from source is `cargo build --release` followed by `./target/release/smfs --help`, and the README states Rust 1.80 or newer is required. In containers, the Docker example is explicit about the privileges FUSE needs: `--device /dev/fuse` and `--cap-add SYS_ADMIN`. The release Dockerfile reuses the same installer as the shell quickstart. The TypeScript side is a package import rather than a binary: `createBash({ apiKey, containerTag })` returns a bash object and a tool description, and the README shows `await bash.exec("echo 'hello' > /a.md && cat /a.md")` plus `await bash.exec("sgrep 'authentication tokens'")`. Note that the README's Docker section appears truncated mid-command, so treat the container instructions as incomplete in the published text.

Limits, failure modes, and where smfs is the wrong tool

The version number is the first thing to weigh. The most recent release in the supplied material is v0.0.5 from May 2026, preceded by v0.0.4 and v0.0.3 within the same week. Three patch releases in four days is the shape of software still finding its footing, and the README's own Docker section is cut off mid-instruction, which suggests documentation is tracking code rather than leading it. Beyond maturity, there is a design limit worth stating plainly: the memory pipeline is opt-in per path. If you mount a container, drop two hundred files into it, and search semantically without setting --memory-paths, you may be searching a much smaller set than you think, because the default scope is whatever the server already had configured. The --ephemeral flag is another sharp edge. It keeps an in-memory cache and persists nothing after unmount, which is fine for scratch work and wrong for anything you expect to find later. Finally, the mount is not a general filesystem. It is a view onto one Supermemory container identified by one tag, and the semantic layer is Supermemory's index, not something smfs builds locally. If you want a local-first vector store you control, this is the wrong shape of tool.

Alternatives and the actual difference in approach

The closest comparison is an agent memory library such as mem0, which gives you a Python or TypeScript API for adding and searching memories and expects your code to call it. The difference is where the interface lives. With a library, your application is the client and every read or write is an explicit function call you wrote. With smfs, the interface is the filesystem, so existing tools become clients: your editor, a shell script, a test runner, and an agent that already knows `cat` and `grep`. That matters most when the consumer is an LLM agent, because filesystem commands are heavily represented in training data and need no tool schema. The trade is that a library can be embedded in a process with no daemon, no mount, and no kernel privileges, while smfs on Linux needs FUSE and, in Docker, /dev/fuse plus SYS_ADMIN. A second alternative is simply the Supermemory API itself, which smfs wraps. Using the API directly avoids the daemon and the queue, at the cost of writing the client code that smfs exists to eliminate.

Maintenance cost, licence, and what to check before you depend on it

The licence is MIT, which permits commercial and private use with the usual requirement to preserve the copyright notice and permission text. That is a permissive choice with no copyleft obligation, though nothing here should be read as legal advice; read the LICENSE file in the repository for the operative terms. Operationally, the recurring costs are a long-running daemon per mount, a pull loop every 30 seconds by default, and a push queue that must drain at unmount. `smfs list` shows running mounts and `smfs status <tag>` shows queue depth, so the two commands worth putting in front of anyone who mounts tags on a shared machine are those. Upgrades are a single binary replaced by the installer or by cargo, but the TypeScript package versions independently, so a Rust fix does not reach a Workers deployment until @supermemory/bash ships. Because the memory path scope is written to the container tag, changing it is a shared-state operation: coordinate before you run `smfs mount agent_memory --memory-paths "/notes/,/journal.md,/work/"` on a tag other people use.

Editorial conclusion

Adopt smfs if your agents already write into Supermemory and you want that content reachable through ordinary file tools on macOS or Linux, or if you run agents on Cloudflare Workers and other runtimes with no filesystem, where the @supermemory/bash package is the only usable path. Do not adopt it as a general-purpose searchable filesystem, because memory generation only applies to paths you declare with --memory-paths, and everything else is plain durable storage that semantic search will not surface. Before committing, verify three things on your own container: that the default mount backend for your platform (fuse on Linux, nfs on macOS) works in your environment, that your chosen memory path scope actually produces searchable memories, and that the 30 second default sync interval and 30 second drain timeout fit your write patterns.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. supermemoryai/smfs on GitHub
Community notes

Community notes