{"id":50897698,"url":"https://github.com/neul-labs/stratafs","last_synced_at":"2026-07-19T13:12:51.066Z","repository":{"id":357714872,"uuid":"1036235273","full_name":"neul-labs/stratafs","owner":"neul-labs","description":"A semantic filesystem that transforms passive file storage into an intelligent, searchable knowledge base.","archived":false,"fork":false,"pushed_at":"2026-07-02T11:47:22.000Z","size":673,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-02T13:26:16.444Z","etag":null,"topics":["agents","ai-filesystem","ai-native","embedding","filesystem","golang","knowledge-base","mcp","neul-labs","rag","semantic-filesystem","vector-search"],"latest_commit_sha":null,"homepage":"https://stratafs.neullabs.com","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/neul-labs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-11T19:04:19.000Z","updated_at":"2026-07-02T11:47:25.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/neul-labs/stratafs","commit_stats":null,"previous_names":["neul-labs/stratafs"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/neul-labs/stratafs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neul-labs%2Fstratafs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neul-labs%2Fstratafs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neul-labs%2Fstratafs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neul-labs%2Fstratafs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/neul-labs","download_url":"https://codeload.github.com/neul-labs/stratafs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neul-labs%2Fstratafs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35092185,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-03T02:00:05.635Z","response_time":110,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agents","ai-filesystem","ai-native","embedding","filesystem","golang","knowledge-base","mcp","neul-labs","rag","semantic-filesystem","vector-search"],"created_at":"2026-06-16T01:31:30.075Z","updated_at":"2026-07-19T13:12:51.056Z","avatar_url":"https://github.com/neul-labs.png","language":"Go","funding_links":[],"categories":["agents"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# StrataFS\n\n**A local, offline hybrid-RAG search server — BM25 + vector + metadata retrieval over your files, local or cloud — exposed to AI agents as an MCP search server.**\n\n[![npm](https://img.shields.io/npm/v/stratafs.svg?logo=npm\u0026label=npm)](https://www.npmjs.com/package/stratafs)\n[![PyPI](https://img.shields.io/pypi/v/stratafs.svg?logo=pypi\u0026label=pypi)](https://pypi.org/project/stratafs/)\n[![Go Version](https://img.shields.io/badge/go-1.24-00ADD8?logo=go)](https://golang.org)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n[![CI](https://github.com/neul-labs/stratafs/actions/workflows/ci.yml/badge.svg)](https://github.com/neul-labs/stratafs/actions/workflows/ci.yml)\n[![Docker](https://img.shields.io/badge/docker-ghcr.io-blue?logo=docker)](https://github.com/neul-labs/stratafs/pkgs/container/stratafs)\n\n**[Website](https://stratafs.neullabs.com) · [Documentation](https://docs.neullabs.com/stratafs) · [GitHub](https://github.com/neul-labs/stratafs)**\n\n[Quickstart](documentation/docs/getting-started/quickstart.md) · [Architecture](documentation/docs/architecture/overview.md) · [MCP for agents](documentation/docs/ai-integration/mcp.md) · [Roadmap](documentation/docs/contributing/roadmap.md)\n\n\u003c/div\u003e\n\n---\n\nStrataFS is a local, offline hybrid RAG search engine. It watches your directories — local **or** cloud — parses files into chunks, generates vector embeddings, and serves everything through a hybrid retrieval engine that fuses BM25 full-text, vector similarity, and metadata ranking in a single query. It speaks the [Model Context Protocol](https://modelcontextprotocol.io), so any MCP-aware agent or assistant can search your files as a structured knowledge resource — a semantic filesystem, if you like. No SaaS. No lock-in. Read-only by design.\n\n```bash\n# 30 seconds to your first hybrid search:\nnpm install -g stratafs \u0026\u0026 stratafs config init \u0026\u0026 stratafs serve \u0026\nstratafs search \"where do we handle JWT refresh?\"\n```\n\n---\n\n## Install\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n\n**npm**\n\n```bash\nnpm install -g stratafs\n```\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n**PyPI**\n\n```bash\npip install stratafs\n```\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n**Homebrew**\n\n```bash\nbrew tap neul-labs/stratafs\nbrew install stratafs\n```\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n\n**macOS / Linux**\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/neul-labs/stratafs/main/scripts/install.sh | bash\n```\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n**Docker**\n\n```bash\ndocker run -d -p 8080:8080 -p 8081:8081 \\\n  ghcr.io/neul-labs/stratafs:latest\n```\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n**From source**\n\n```bash\ngit clone https://github.com/neul-labs/stratafs.git\ncd stratafs \u0026\u0026 make build\n```\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\nThen:\n\n```bash\nstratafs config init       # writes ~/.stratafs/config.json\nstratafs serve             # REST on :8080, MCP on :8081\nstratafs search \"any natural language query\"\n```\n\nNative installers (NSIS for Windows, signed `.pkg` for macOS, `.deb` / AppImage for Linux) are on the [releases page](https://github.com/neul-labs/stratafs/releases).\n\n---\n\n## See it work\n\n```bash\n$ stratafs search \"rate limit middleware\"\n\n  pkg/api/middleware/ratelimit.go   ★ 0.94\n  ────────────────────────────────────────\n  func RateLimit(rps int) gin.HandlerFunc {\n      bucket := tokenbucket.New(rps, rps*2)\n      return func(c *gin.Context) {\n          if !bucket.Take(1) { c.AbortWithStatus(429) ...\n\n  docs/api/rate-limiting.md         ★ 0.88\n  ────────────────────────────────────────\n  Per-IP rate limits default to 100 requests/min...\n\n  internal/gateway/policy.yaml      ★ 0.71\n  ────────────────────────────────────────\n  policies:\n    - name: api-default\n      rate: 100/m\n      burst: 200\n```\n\nThe same query over the REST API:\n\n```bash\ncurl \"http://localhost:8080/search?q=rate+limit+middleware\u0026limit=5\" | jq\n```\n\nOr from an MCP-aware agent — no glue code required:\n\n```json\n{\n  \"mcpServers\": {\n    \"stratafs\": { \"command\": \"stratafs\", \"args\": [\"serve\", \"--mcp-only\"] }\n  }\n}\n```\n\n---\n\n## Why StrataFS\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd width=\"33%\" valign=\"top\"\u003e\n\n### For developers\n\nStop `grep`-ing. Ask **natural-language questions** across your entire codebase, configs, and docs at the same time. StrataFS finds related code even when filenames don't match.\n\n- One command from install to first search\n- Works offline — no API keys, no telemetry\n- Plain HTTP API, plain SQLite on disk\n- Drops into any agent loop via MCP\n\n\u003c/td\u003e\n\u003ctd width=\"33%\" valign=\"top\"\u003e\n\n### For architects\n\nA clean, layered design built around three first-class invariants: **read-only sources**, **per-source isolation**, and **hybrid scoring in a single SQL query**.\n\n- SQLite + FTS5 + `sqlite-vec` — zero ops dependencies\n- Per-source DB → backup, drop, migrate one source at a time\n- Pluggable parsers, chunkers, storage backends, embedders\n- Streaming pipeline — constant memory regardless of file size\n\n\u003c/td\u003e\n\u003ctd width=\"33%\" valign=\"top\"\u003e\n\n### For builders\n\nEvery layer is an extension point. Add a parser, a backend, a chunker, or a ranking signal in a single Go file.\n\n- Modular package layout (`pkg/parsers`, `pkg/chunking`, `pkg/storage`, …)\n- MCP server speaks the same protocol your agent already knows\n- FUSE / WinFsp export — mount the semantic index as a real filesystem\n- Wails-based desktop UI for non-CLI users\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n---\n\n## Try it in five steps\n\n```bash\n# 1. Install\npip install stratafs\n\n# 2. Initialize\nstratafs config init\n\n# 3. Add a source (edit ~/.stratafs/config.json)\n#    {\"id\":\"docs\",\"type\":\"local\",\"path\":\"/path/to/anything\",\"enabled\":true}\n\n# 4. Start the daemon\nstratafs serve \u0026\n\n# 5. Search — CLI, REST, or MCP\nstratafs search \"the thing I half-remember writing\"\ncurl \"http://localhost:8080/search?q=onboarding+flow\"\n```\n\nThe first scan runs at 50–100 files/sec. Searches return in under 100 ms once the index is warm. Everything lives under `~/.stratafs/` — one directory, one filesystem, one source of truth.\n\n---\n\n## Architecture at a glance\n\n```\n┌──────────────┐  ┌──────────────┐  ┌──────────────┐\n│  REST API    │  │  MCP Server  │  │   CLI / UI   │\n│    :8080     │  │     :8081    │  │              │\n└──────┬───────┘  └──────┬───────┘  └──────┬───────┘\n       └─────────────────┼─────────────────┘\n                         │\n              ┌──────────▼──────────┐\n              │   Hybrid Search     │\n              │  FTS5  +  Vector    │\n              │   (single SQL CTE)  │\n              └──────────┬──────────┘\n                         │\n        ┌────────────────┼────────────────┐\n        │                │                │\n  ┌─────▼─────┐    ┌─────▼─────┐    ┌─────▼─────┐\n  │ SQLite +  │    │ FastEmbed │    │ Job Queue │\n  │ sqlite-vec│    │  + ONNX   │    │ (SQLite)  │\n  └───────────┘    └───────────┘    └─────┬─────┘\n                                          │\n                                ┌─────────▼─────────┐\n                                │  Monitor (local + │\n                                │   remote scanner) │\n                                └─────────┬─────────┘\n                                          │\n                              ┌───────────▼───────────┐\n                              │   Storage Factory     │\n                              └───────────┬───────────┘\n                                          │\n              ┌───────────────────────────┼──────────────────────────┐\n              │                           │                          │\n       ┌──────▼──────┐            ┌───────▼───────┐          ┌───────▼───────┐\n       │  Local FS   │            │ S3 / GCS /    │          │   Future      │\n       │ (fsnotify)  │            │ Azure Blob    │          │   backends    │\n       └─────────────┘            └───────────────┘          └───────────────┘\n```\n\nFour invariants do most of the work:\n\n1. **Read-only sources** — StrataFS never writes back. All state lives in `.stratafs/`.\n2. **Per-source SQLite** — no central registry, no shared bottleneck.\n3. **Compression-aware schema** — gzip above 512 bytes, transparent at query time. 40–60% disk savings.\n4. **Soft delete** — files disappear consistently, historical queries are free.\n\nLong version: [Architecture overview](documentation/docs/architecture/overview.md) · [Database internals](documentation/docs/architecture/database.md).\n\n---\n\n## Integrate it\n\n### REST\n\n```python\nimport requests\nr = requests.get(\"http://localhost:8080/search\",\n                 params={\"q\": \"feature flag rollout\"})\nfor hit in r.json()[\"results\"]:\n    print(hit[\"file_path\"], hit[\"relevance_score\"])\n```\n\n### MCP (any agent that speaks the protocol)\n\n```typescript\nconst res = await fetch(\"http://localhost:8081/mcp/tools/call\", {\n  method: \"POST\",\n  headers: { \"Content-Type\": \"application/json\" },\n  body: JSON.stringify({\n    tool: \"search\",\n    parameters: { query: \"rate limiting\", max_results: 5 }\n  }),\n});\n```\n\n### CLI\n\n```bash\nstratafs search \"deployment strategy\" --mode hybrid --limit 5 --json\n```\n\n### As a Go library\n\n```go\nimport \"github.com/neul-labs/stratafs/pkg/search\"\n\neng, _ := search.NewEngine(cfg)\nresults, _ := eng.Hybrid(ctx, \"circuit breaker pattern\", search.Opts{Limit: 10})\n```\n\n---\n\n## Performance\n\nMeasured on consumer hardware (M-series Mac, NVMe SSD, BGE Base EN v1.5).\n\n| Metric | Typical value |\n| --- | --- |\n| Indexing throughput | 50 – 100 files/sec |\n| Search latency (10 k files) | \u003c 100 ms |\n| Disk overhead | ~1.5–2× original text (with compression) |\n| Memory baseline | ~200 MB + model (~500 MB for BGE Base) |\n| Cold start | \u003c 1 s |\n\nPerformance tuning, model swaps, and benchmark methodology: [Performance guide](documentation/docs/architecture/performance.md).\n\n---\n\n## Extend it\n\nEvery moving part is a registry plus an interface. Adding things is intentionally boring.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eAdd a new file parser\u003c/strong\u003e\u003c/summary\u003e\n\n```go\n// pkg/parsers/asciidoc.go\ntype AsciidocParser struct{}\n\nfunc (p *AsciidocParser) Parse(r io.Reader) (string, error) { /* ... */ }\nfunc (p *AsciidocParser) SupportedExtensions() []string {\n    return []string{\".adoc\", \".asciidoc\"}\n}\n\nfunc init() { DefaultRegistry.Register(NewAsciidocParserFactory()) }\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eAdd a new storage backend\u003c/strong\u003e\u003c/summary\u003e\n\n```go\n// pkg/filesystem/dropbox.go\ntype DropboxFS struct{ /* ... */ }\n\nfunc (fs *DropboxFS) Open(path string) (io.ReadCloser, error) { /* ... */ }\nfunc (fs *DropboxFS) Walk(root string, fn WalkFunc) error    { /* ... */ }\n\n// pkg/storage/factory.go\ncase config.StorageTypeDropbox:\n    return f.createDropboxFS(source)\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eAdd a new chunking strategy\u003c/strong\u003e\u003c/summary\u003e\n\n```go\n// pkg/chunking/ast.go\ntype ASTChunker struct{}\nfunc (c *ASTChunker) Name() string { return \"ast\" }\nfunc (c *ASTChunker) ChunkStream(r io.Reader, o ChunkOptions) (\u003c-chan Chunk, \u003c-chan error) {\n    // Yield one chunk per top-level AST node.\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eSwap the embedding model\u003c/strong\u003e\u003c/summary\u003e\n\n```json\n{\n  \"embedding\": {\n    \"model\": \"bge-small-en-v1.5\",\n    \"dimension\": 384\n  }\n}\n```\n\nAny ONNX-compatible model works. Drop the weights in `~/.stratafs/fastembed_cache/` and point `embedding.model` at it.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eAdd a new ranking signal\u003c/strong\u003e\u003c/summary\u003e\n\nHybrid scoring is a single SQL query with weighted CTEs. Add a CTE, expose a weight, ship a PR. Full walkthrough in the [development guide](documentation/docs/contributing/development.md#adding-things).\n\n\u003c/details\u003e\n\n---\n\n## What's next on the roadmap\n\n- **Enterprise security** — RBAC for authentication and source-level permissions\n- **Streaming search results** — chunked HTTP for very large result sets\n- **Custom embeddings** — first-class support for any ONNX-compatible model on disk\n- **Cross-source ranking signals** — per-source weight, recency boost, trusted-source pinning\n- **Encrypted source databases** — SQLCipher-backed at-rest encryption\n\nAlready shipped: virtual FS export, FUSE/WinFsp mount, GNOME / Spotlight / Windows Search integration, Wails desktop UI, native installers for every desktop OS, enterprise connectors for SharePoint / Google Drive / Jira.\n\nFull list: [Roadmap](documentation/docs/contributing/roadmap.md).\n\n---\n\n## Documentation\n\nThe full docs live in [`documentation/`](documentation/) and are built with MkDocs Material.\n\n| Topic | Where |\n| --- | --- |\n| Getting started | [`documentation/docs/getting-started/`](documentation/docs/getting-started/quickstart.md) |\n| User guide (config, search, CLI, file types) | [`documentation/docs/user-guide/`](documentation/docs/user-guide/configuration.md) |\n| REST + MCP integration | [`documentation/docs/ai-integration/`](documentation/docs/ai-integration/mcp.md) |\n| Storage backends | [`documentation/docs/user-guide/storage-backends.md`](documentation/docs/user-guide/storage-backends.md) |\n| Deployment (Docker / systemd / launchd / K8s) | [`documentation/docs/deployment/`](documentation/docs/deployment/docker.md) |\n| Architecture | [`documentation/docs/architecture/`](documentation/docs/architecture/overview.md) |\n| Contributing \u0026 dev setup | [`documentation/docs/contributing/`](documentation/docs/contributing/development.md) |\n\nPreview the docs locally:\n\n```bash\ncd documentation\npip install -r requirements.txt\nmkdocs serve\n```\n\n---\n\n## Community \u0026 contributing\n\n- **Issues** — [github.com/neul-labs/stratafs/issues](https://github.com/neul-labs/stratafs/issues)\n- **Discussions** — [github.com/neul-labs/stratafs/discussions](https://github.com/neul-labs/stratafs/discussions)\n- **Contributing guide** — [documentation/docs/contributing/development.md](documentation/docs/contributing/development.md)\n\nPull requests welcome. For larger changes, open an issue first to align on the approach. Every PR runs the full test suite plus a Docker build in CI.\n\n---\n\n## Part of the Neul Labs toolchain\n\nStrataFS is part of the Neul Labs command-line \u0026 filesystem toolchain:\n\n| Project | What it does |\n|---------|--------------|\n| [stout](https://github.com/neul-labs/stout) | A drop-in replacement for the Homebrew CLI that's 10-100x faster. |\n| [recurl](https://github.com/neul-labs/recurl) | curl that just works — drop-in replacement with automatic anti-bot bypass. |\n| [rewget](https://github.com/neul-labs/rewget) | wget, but it works everywhere. |\n\nExplore the full toolchain at [neullabs.com](https://www.neullabs.com).\n\n## License\n\n[MIT](LICENSE). Do whatever you want with it. If StrataFS ends up powering something interesting, [we'd love to hear about it](https://github.com/neul-labs/stratafs/discussions).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneul-labs%2Fstratafs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fneul-labs%2Fstratafs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneul-labs%2Fstratafs/lists"}