Home/Install
A pure-Rust workspace — the core cargo build needs no C/C++ toolchain: no libfuse, no async runtime, no protoc. Native engines slot in behind traits and TLS / io_uring stay opt-in features.
There are no prebuilt binaries or package-manager channels yet — every platform builds the same pure-Rust workspace from source, which needs nothing but a Rust toolchain (no C/C++ compiler, no libfuse, no protoc). Pick your OS for the fastest path; feature flags and the full CLI tour are in the sections below.
# 1 · install the Rust toolchain (skip if you already have cargo) brew install rustup-init && rustup-init -y # or: curl https://sh.rustup.rs -sSf | sh # 2 · clone & build — pure Rust, no Xcode / C toolchain, no libfuse, no protoc git clone https://github.com/021flow/synafs && cd synafs cargo build --release # Apple Silicon & Intel # 3 · index a repo and ask — runs natively on macOS ./target/release/syna init ./target/release/syna index . ./target/release/syna query "reciprocal rank fusion" --top 3 # real semantic embeddings work on macOS — Metal is 3.8× faster than CPU cargo build --release --features coderank-metal SYNA_DEVICE=metal SYNA_EMBEDDER=coderank ./target/release/syna index . # note: syna mount (FUSE) is Linux-only — every other surface runs here
coderank semantic embedder all run natively on Apple Silicon and Intel — the whole workspace builds on macOS. The FUSE mount, auto-reindex watch, fanotify, io_uring, and the /dev/synafs CUSE device are Linux-only — see the table below.SynaFS is pure Rust, so the core compiles and runs the same on both platforms. The kernel-level surfaces depend on Linux syscalls (fanotify, io_uring, CUSE) or on FUSE, which is gated to Linux, so those differ by OS.
| Surface | Linux | macOS |
|---|---|---|
| Core CLIinit · index · query · edit · commit · log · diff · gc | ✓ | ✓ |
| MCP serversyna-mcp — JSON-RPC over stdio | ✓ | ✓ |
| Web + gRPCsyna serve · syna grpc | ✓ | ✓ |
| Semantic embedder--features coderank (CPU) · coderank-metal (GPU) | ✓ | ✓ |
| FUSE mountsyna mount | ✓ | — |
| Auto-reindex watchsyna watch (inotify) | ✓ | — |
| Whole-mount watchsyna watch --fanotify | ✓ | — |
| io_uring batched reads--features io_uring | ✓ | — |
| CUSE device/dev/synafs (CUSE) | ✓ | — |
syna-fuse is excluded from the macOS build (so the workspace compiles without libfuse) and syna mount exits with a clear message there. watch auto-reindex is wired to inotify with no kqueue fallback yet, and fanotify, io_uring, and the /dev/synafs CUSE device call Linux-only syscalls. Everything an AI agent touches — search, read, edit, the MCP tools — is native on both.Clone and build the release binaries. The default build is fully offline (the hash-dev embedder is deterministic and needs no model). Run the test suite to confirm the workspace compiles and passes end-to-end.
git clone https://github.com/021flow/synafs && cd synafs cargo build --release cargo test # 300 tests: RRF/BM25 + consistency/recovery + symbols + as-of/GC/diff + FUSE + web/gRPC + C ABI/CUSE
Feature flags are off by default; turn on only what you need. Tests for the gated paths run with cargo test --features "syna-sys/io_uring syna-web/tls syna-engine/watch syna-engine/fanotify" (311 tests).
candle, CPU). This is the real-embeddings quality path.syna serve.uring::read_batch reaps many reads in a single submit/complete cycle (pure-Rust io-uring, no liburing).FAN_MARK_MOUNT). Needs root (CAP_SYS_ADMIN).tiny_http (no protoc, no async runtime), and gRPC's HTTP/2 + HPACK is hand-written. The whole core builds without a C/C++ toolchain.One binary, syna, fronts the whole engine. Each command below is real — index a tree, search it by meaning, edit through the write path, seal and travel the version DAG, then bring up the FUSE mount and the network surfaces.
# index a repo, then query by meaning syna init syna index . syna query "reciprocal rank fusion" --top 3 --lang rust syna query --batch "where is auth checked?" "how are configs loaded?" # N questions, one call syna query "validate token" --rerank symbolgraph:callers # call-graph rerank syna query "login" --as-of HEAD~1 # search code as it was then # write path → reindex → consistency token; seal & inspect history syna edit src/auth.rs --content "$(cat new.rs)" syna commit -m "checkpoint" # seal the working tree into a version syna log syna diff --symbol validate # symbol-level diff across versions syna symbols validate --relation callers # who calls it syna gc # reclaim chunks from unreachable versions # surfaces syna mount /mnt/repo # FUSE: ls /mnt/repo/.syna/query/... SYNA_TOKEN=secret syna serve --addr 127.0.0.1:5200 # HTTP API + gRPC-Web syna grpc --addr 127.0.0.1:5201 # native HTTP/2 gRPC syna watch # inotify auto-reindex (build --features watch) sudo syna watch --fanotify # whole-mount VFS watch (build --features fanotify, root) sudo syna dev # /dev/synafs CUSE device (CAP_SYS_ADMIN) syna bench # throughput · p50/p99 latency · recall@k/MRR syna usage # MCP adoption health from .syna/mcp-usage.jsonl
The default hash-dev embedder is offline and deterministic, so its vectors are non-semantic and BM25 carries ranking. For true semantic retrieval, build with --features coderank and set SYNA_EMBEDDER=coderank at index time. The model auto-downloads to ~/.cache/synafs on first use; serving reads the snapshot's embedder_id and configures the matching embedder automatically. To cut the indexing wall, build --features coderank-metal and set SYNA_DEVICE=metal — measured 3.8× faster than CPU on an M5 Max with identical chunk counts and top-1 results. A CUDA path exists (coderank-cuda) but is unverified: there is no NVIDIA device in CI.
# build with the local semantic embedder (pure-Rust candle) cargo build --release --features coderank # index and query with real embeddings (model auto-downloads to ~/.cache/synafs) SYNA_EMBEDDER=coderank syna index <repo> syna query "authenticate a user token"
The syna-mcp binary is a first-class MCP surface — line-delimited JSON-RPC 2.0 over stdio. It speaks the same Model Context Protocol every major coding agent already supports, so wiring it in is one config block. Build it and syna index the repo first, then point each agent at the binary and pass the repo (the directory holding the index) as an argument.
Register the server with the claude CLI (use absolute paths):
cargo build --release # register with Claude Code (use absolute paths) claude mcp add synafs -- /ABS/PATH/SynaFS/target/release/syna-mcp /ABS/PATH/your-repo
Or wire it through a project .mcp.json:
{
"mcpServers": {
"synafs": {
"command": "/ABS/PATH/SynaFS/target/release/syna-mcp",
"args": ["/ABS/PATH/your-repo"]
}
}
}Add an [mcp_servers.synafs] block to ~/.codex/config.toml:
# ~/.codex/config.toml (or per-project .codex/config.toml) [mcp_servers.synafs] command = "/ABS/PATH/SynaFS/target/release/syna-mcp" args = ["/ABS/PATH/your-repo"] # for semantic results from a coderank-built binary: env = { SYNA_EMBEDDER = "coderank" }
# or wire it inline for a single run (no config file) codex exec \ -c 'mcp_servers.synafs.command="/ABS/PATH/SynaFS/target/release/syna-mcp"' \ -c 'mcp_servers.synafs.args=["/ABS/PATH/your-repo"]' \ "where is reciprocal rank fusion implemented?"
Add a mcpServers entry to ~/.gemini/settings.json (or a project-local .gemini/settings.json):
// ~/.gemini/settings.json (or per-project .gemini/settings.json)
{
"mcpServers": {
"synafs": {
"command": "/ABS/PATH/SynaFS/target/release/syna-mcp",
"args": ["/ABS/PATH/your-repo"],
"env": { "SYNA_EMBEDDER": "coderank" }
}
}
}Tools exposed to every agent: search, read_span, neighbors, symbol_lookup, impact, path, diff_impact, context_pack, file_info, apply_edit, subscribe, and diff_symbol. For semantic results, index with SYNA_EMBEDDER=coderank using a coderank-built binary; the server then auto-configures the matching embedder from the snapshot.
Wiring the MCP in is step one. The measured gains — fewer files opened, less context to reach the answer, lower input-token cost — come from semantic retrieval replacing the agent's blind grep loop. Four things make that real:
# 1 · build the local semantic embedder once cargo build --release --features coderank # 2 · index with REAL embeddings — this is the retrieval-quality path agents ride on SYNA_EMBEDDER=coderank syna index /ABS/PATH/your-repo # 3 · keep the index fresh as the agent edits (inotify auto-reindex) syna watch # build --features watch # 4 · ask several independent questions in ONE call, not one turn each syna query --batch "where is auth checked?" "how are configs loaded?" # then audit what your agent sessions actually did syna usage # adoption health from .syna/mcp-usage.jsonl
hash-dev embedder is non-semantic; build --features coderank and index with SYNA_EMBEDDER=coderank so search ranks by meaning, not keyword overlap.SYNA_FRESH=0 opts out, SYNA_FRESH_MAX caps the sweep, default 64). Run syna watch as well if you want edits folded in eagerly rather than at query time.search inlines the top hit's source, so the agent answers without a follow-up read — measured search+read operations 14 → 7 at equal accuracy. Independent questions should travel together: MCP search takes texts: [...] and the CLI takes syna query --batch "q1" "q2", turning a six-question session into one turn.search and reaps the savings; Codex tends to grep anyway and treats the tool as an optional extra (median 2–3 calls). If an agent under-adopts it, prompt it to prefer semantic search before shell commands, or restrict its shell. Run syna usage to see what your sessions actually did — it summarises the recorded MCP telemetry and flags drift (redundant re-reads, unbatched multi-query sessions) with a one-line fix each. Details in the Agents writeup.The network surfaces bind to loopback by default. Off-loopback access requires a Bearer token (SYNA_TOKEN); TLS / mTLS is opt-in via the tls feature.
syna serve — HTTP API (REST + /events + /ws WebSocket) and gRPC-Web.syna grpc — native HTTP/2 (h2c) gRPC, same dispatch as REST.syna serve --tls-cert server.pem --tls-key server.key --client-ca clients-ca.pem (build --features tls).