Single-binary local RAG · Pure Go

A RAG database that lives in one binary.

Ingest, index, and query your PDFs, Word docs, Markdown, and images — on your own filesystem. A bundled pure-Go embedding model means it works fully offline from the first run; point it at a local Ollama when you want higher-quality embeddings or reranking. No Docker, no API keys, no cloud.

Alpha · v0.3.3 Offline by default BM25 Vector
~/projects
$ go-rag init created ./.go-rag/ · embedder: bundled (offline) $ go-rag add ./my-docs/ 142 files · 3,981 chunks $ go-rag query "how does auth work?" 3 results · 41ms $ _
Why

As frictionless as git init.

A local RAG database shouldn't need infrastructure. Install the binary, run go-rag init, and you have a working system.

01

No cloud, no keys

Everything runs on your machine. A bundled pure-Go embedding model handles ingest and query out of the box; point it at a local Ollama instance later for alternative models and reranking — never required.

02

No Docker required

A single static binary, built with CGO_ENABLED=0. Copy it, run it, done. Or pull the multi-arch container image if that's your preference.

03

Loopback by default

Every transport binds to 127.0.0.1. Reaching the network is an explicit, logged opt-in (--bind-external).

Features

Built for retrieval quality, not just retrieval.

Every piece exists to answer one question honestly: is this result actually relevant, and can you trust it?

Hybrid retrieval (RRF)

Fuses BM25 keyword and vector semantic ranked lists with Reciprocal Rank Fusion — one tunable constant, honoured identically across CLI, REST, gRPC, and MCP.

Bundled embedding model

A pure-Go embedding model ships in the binary — ingest and query work fully offline from the first run, with no external service to install first. Bring your own model via Ollama when you want.

Isolated vaults

Each vault gets its own config and indexes — isolated by key-space prefixes within a single Pebble store. No cross-vault contamination, without a database per vault.

Poisoning detection

Instruction-injection chunks are flagged and quarantined out of default results, with per-signal verdicts and an audit trail — so a poisoned document can't silently steer retrieval.

MCP daemon

A background daemon serves 30 MCP tools over HTTP — wire it into Claude Desktop and query, ingest, inspect, triage, and manage your vault directly from the model.

Optional Ollama enrichment

Point go-rag at a local Ollama for alternative embedding models and cross-encoder reranking — an upgrade you opt into, never a prerequisite to get started.

How retrieval works

Two lists become one.

Hybrid mode fuses the BM25 and vector ranked lists with a single symmetric constant. Hover a row (when JavaScript is on) to see how each list contributes to the final ranking.

score(d) = Σ 1/(k + rank)  ·  k = 60 by default

Lexical BM25 rank

  • 1 · auth-middleware.go
  • 2 · session-store.go
  • 3 · token-refresh.md
  • 4 · rbac-policy.go

Semantic vector rank

  • 1 · token-refresh.md
  • 2 · auth-middleware.go
  • 3 · oauth-flow.md
  • 4 · session-store.go

Fused result

  1. 1 · auth-middleware.go0.0317
  2. 2 · token-refresh.md0.0308
  3. 3 · session-store.go0.0290
  4. 4 · oauth-flow.md0.0159

The same k applies to both lists, so the fusion stays reviewable and matches the standard RRF formula. Tune it per corpus with go-rag config set rrf_k 120, or override it for a single query with go-rag query "…" --rrf-k 30.

Architecture

Layered, and each layer does one job.

A single binary, but not a single blob — the CLI, ingest pipeline, retrieval, and storage layers are cleanly separated internally.

CLIinit · add · query · vault · auth · upgrade · mcp · …
Ingest pipelineasync-after-ACK · <10ms writes
Readers · Embedder · Change detectiontext/markdown/docx/pdf/image · bundled pure-Go embedder (Ollama optional) · fsnotify + polling
Retrieval BM25 FTS + vector + RRF fusion, optional cross-encoder rerank, injection-poisoning filter
BM25Vector
Embedded Pebble KVkey-space prefixes · per-vault isolation
Install

One line to a working binary.

macOS and Linux, amd64 and arm64. The script resolves the latest release, verifies the download against the published SHA-256 checksums, and puts go-rag on your PATH.

# verify the download against the published SHA-256 checksums, then install
curl -fsSL https://madeinoz67.github.io/go-rag/install.sh | sh

Prefer to read it first? curl -fsSL https://madeinoz67.github.io/go-rag/install.sh -o install.sh, open it, then sh install.sh.

brew install madeinoz67/tap/go-rag

Published from the release pipeline alongside the binaries. Requires the tap to be live for the current release.

# requires Go 1.22+
go install github.com/madeinoz67/go-rag/cmd/go-rag@latest

Windows has no curl | sh path. Download the build from the latest release and extract the go-rag.exe from the zip:

Latest release

Or, with Go installed: go install github.com/madeinoz67/go-rag/cmd/go-rag@latest (produces go-rag.exe).

Also available
  • Docker
    Multi-arch image (linux/amd64 + linux/arm64), built on every release:
    docker pull ghcr.io/madeinoz67/go-rag
  • Self-upgrade
    Already installed? go-rag upgrade fetches the latest release, verifies the checksum, and atomically replaces the running binary.
Then

Three commands to a query.

01

Initialize

Create a vault with default config and the bundled offline embedder.

go-rag init
02

Ingest

Point it at a folder. Idempotent, with a progress bar. PDF, Word, Markdown, images, text.

go-rag add ./my-docs/
03

Query

Hybrid search with source-cited results, reranked by default. Tune mode, k, threshold, filters.

go-rag query "how does X work?"
CLI reference

Every command, grouped by what you're doing.

A small subset shown here — run go-rag --help for the full list.

Ingest & query

go-rag initInitialize a new RAG database
go-rag add <path>Add files or directories (idempotent; progress bar)
go-rag scan [--watch]Scan for changes (fsnotify + polling)
go-rag query "<q>"Hybrid semantic + keyword search
go-rag reprocess <path>Force re-ingest, bypassing dedup
go-rag delete <doc-id>Remove a document + its chunks (index-only)

Daemon & MCP

go-rag startStart the daemon (MCP + REST + gRPC + console)
go-rag stopStop the running daemon
go-rag mcpstdio→HTTP proxy, bridges Claude Desktop to the daemon
go-rag statusDaemon + database statistics and health
go-rag healthProbe the running daemon's health endpoint
go-rag upgradeUpgrade the binary to the latest release

Inspect

go-rag filesList ingested file paths
go-rag dirsPer-directory file + chunk counts
go-rag documentsList documents (cursor + status + pagination)
go-rag chunk <id>Fetch a single chunk by content-addressed ID
go-rag auditRead the structured audit log

Vaults, quality & auth

go-rag vault …create / list / delete / clear / clone / export / import
go-rag evalMeasure recall@k, MRR, NDCG@k on a golden dataset
go-rag poison …list / release / reset injection-flagged chunks
go-rag migrateRe-embed documents to the current model
go-rag auth …Manage API keys, sessions, the admin user
go-rag config [get|set]View or change configuration
MCP daemon

Query your vault from Claude Desktop.

The daemon owns the database and serves 30 MCP tools over HTTP. They cover the full surface — query and status, ingest and maintenance, document/chunk inspection, injection-poisoning triage, vaults, retrieval-quality eval, and admin auth — so an agent can run the whole system without shelling out.

Query & statusgo_rag_query · go_rag_status · go_rag_guide
Ingest & maintainadd · init · scan · reprocess · migrate · migrate_plan · delete_document · model_install
Inspectfiles · dirs · list_documents · list_chunks · get_chunk · get_chunk_context · batch_get_chunks
Poisoning triagepoison_list · poison_release · poison_reset · poison_rescan
Vaults · config · eval · auth (admin)vault_list · config · eval · auth_list/create/revoke · session_list/revoke
{
  "mcpServers": {
    "go-rag": {
      "command": "/abs/path/to/go-rag",
      "args": ["mcp", "--vault", "cyber-notes"]
    }
  }
}

go-rag mcp is a stdio→HTTP proxy that bridges a stdio MCP client (Claude Desktop) to your running daemon. Start the daemon with go-rag start first.

Retrieval quality

Measured, not assumed.

go-rag ships a built-in retrieval evaluator so you can score recall@k, precision@k, MRR, and NDCG@k over your own golden dataset — offline, reproducible, no Ollama required.

Run it on the bundled golden corpus, or point it at your own:

go-rag eval --benchmark scifact # recall@k, MRR, NDCG@k go-rag eval-gen # emit candidate query→chunk pairs for triage

The eval harness is the same one used to regression-test retrieval changes in CI — what you measure is what shipped.

Advanced

When you need more than the basics.

A management console, container deployment, isolated vaults, alternative embeddings and enrichment, and a MuninnDB memory bridge — all opt-in, all local-first. For the full references, see the docs.

Management console

A single-operator web UI — the fourth loopback transport at 127.0.0.1:7881, Bearer-guarded. Browse and inspect documents, run queries with the full retrieval controls, triage injection-poisoned chunks, manage vaults, and read live observability — all from the browser. It starts with the daemon.

go-rag start   # console at http://127.0.0.1:7881

Docker

A multi-arch distroless image (linux/amd64 + linux/arm64), built on every release. The container runs the foreground daemon against a named volume; map the port to host loopback to keep the loopback-only posture.

docker pull ghcr.io/madeinoz67/go-rag
docker run -d --name go-rag \
  -p 127.0.0.1:7878:7878 \
  -v go-rag-data:/data \
  ghcr.io/madeinoz67/go-rag

Isolated vaults

Multiple vaults in one Pebble store — each with its own config, embeddings, and indexes, isolated by key-space prefixes. One daemon serves them all; --vault targets a specific one per command. Clone, export, and import for backup or migration.

go-rag vault create work
go-rag --vault work add ./work-docs/
go-rag --vault work query "release process"

Embeddings & enrichment

A bundled pure-Go embedder works offline from the first run; point go-rag at a local Ollama when you want a different model. An embedding-drift monitor pins the profile a corpus was built under and fails loudly if it changes. Opt-in background enrichment (local model) writes auto-tags and per-document summaries to a sidecar — and the tags flow straight into the --tags filter.

go-rag model install   # fetch + verify the bundled model
go-rag enrich          # back-fill tags + summaries (opt-in)

MuninnDB bridge

Promote chunks into long-term memory — go-rag chunks become content-addressed engrams in a local MuninnDB vault, auto-backfilled when you enable it. It's opt-in, loopback-only, and never blocks a core operation; if MuninnDB is down, go-rag carries on unaffected.

export GORAG_BRIDGE_TOKEN=…
go-rag bridge muninn init
go-rag bridge muninn status
Security

Loopback-only, by default.

go-rag never silently exposes your document vault to the network. Every transport binds to 127.0.0.1 — reaching further requires an explicit, logged opt-in. Single-operator auth (API keys, admin user, sessions) is there when you need it.

MCP127.0.0.1:7878
REST127.0.0.1:7879
gRPC127.0.0.1:7880
Console127.0.0.1:7881
External bindrequires --bind-external