Home/Install

Quickstart

Build it, index a repo, ask a question.

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.

In plain terms This is the hands-on setup page, written for developers. In plain terms, you will do three things: build the program, point it at a folder of code so it can read and understand it (that step is called indexing), and then ask questions in plain language or connect it to your AI coding assistant. The default build runs fully offline; turning on real meaning-based search is one extra flag.

Get it running on your platform

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
On macOS: the CLI, the MCP server, the HTTP / gRPC surfaces, and the 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.

What runs where

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.

Native Linux-only
SurfaceLinuxmacOS
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)
macOS caveats. The FUSE mount is Linux-only: 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.

Build from source

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).

coderank
Local CodeRankEmbed semantic embedder (pure-Rust candle, CPU). This is the real-embeddings quality path.
tls
rustls (ring backend) TLS and client-certificate verification (mTLS) for syna serve.
io_uring
Batched device reads — uring::read_batch reaps many reads in a single submit/complete cycle (pure-Rust io-uring, no liburing).
watch
inotify auto-reindex — re-indexes on any external write. No extra privileges; this is the default watch backend.
fanotify
Whole-mount VFS watch via fanotify (FAN_MARK_MOUNT). Needs root (CAP_SYS_ADMIN).
Pure-Rust. FUSE/CUSE implement the wire protocol directly (no libfuse), the web stack is synchronous 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.

CLI tour

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

Semantic search (real embeddings)

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"

Wire it into Claude Code, Codex & Gemini

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.

Claude Code

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"]
    }
  }
}

Codex

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?"

Gemini CLI

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.

Tune for the performance win

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
Steer the agent to actually use it. Claude Code routes navigation through 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.

Ports

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.

5200
syna serve — HTTP API (REST + /events + /ws WebSocket) and gRPC-Web.
5201
syna grpc — native HTTP/2 (h2c) gRPC, same dispatch as REST.
Off-loopback. Binding to a non-loopback address rejects unauthenticated requests. Turn on mTLS with syna serve --tls-cert server.pem --tls-key server.key --client-ca clients-ca.pem (build --features tls).