{"id":47303232,"url":"https://github.com/nano-step/nano-brain","last_synced_at":"2026-06-14T08:01:20.026Z","repository":{"id":340188020,"uuid":"1164874191","full_name":"nano-step/nano-brain","owner":"nano-step","description":"Persistent memory \u0026 code intelligence server for AI coding agents. Deploy on VPS for shared memory across machines. Hybrid search (BM25 + pgvector), knowledge graph, impact analysis. 14 MCP tools. Works with Claude Code, OpenCode, Cursor, and any MCP client.","archived":false,"fork":false,"pushed_at":"2026-06-13T07:22:24.000Z","size":7961,"stargazers_count":6,"open_issues_count":13,"forks_count":1,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-06-13T09:16:37.568Z","etag":null,"topics":["ai-agents","ai-memory","claude-code","golang","hybrid-search","knowledge-graph","mcp","opencode","pgvector","rag"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nano-step.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"docs/ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-02-23T15:24:46.000Z","updated_at":"2026-06-13T05:59:25.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/nano-step/nano-brain","commit_stats":null,"previous_names":["kokorolx/nano-brain","nano-step/nano-brain"],"tags_count":166,"template":false,"template_full_name":null,"purl":"pkg:github/nano-step/nano-brain","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nano-step%2Fnano-brain","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nano-step%2Fnano-brain/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nano-step%2Fnano-brain/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nano-step%2Fnano-brain/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nano-step","download_url":"https://codeload.github.com/nano-step/nano-brain/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nano-step%2Fnano-brain/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34313515,"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-06-14T02:00:07.365Z","response_time":62,"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":["ai-agents","ai-memory","claude-code","golang","hybrid-search","knowledge-graph","mcp","opencode","pgvector","rag"],"created_at":"2026-03-17T06:13:49.833Z","updated_at":"2026-06-14T08:01:20.013Z","avatar_url":"https://github.com/nano-step.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# nano-brain\n\n**Persistent memory and code intelligence for AI coding agents.**\n\n[![Go 1.23](https://img.shields.io/badge/Go-1.23-00ADD8?logo=go)](https://go.dev/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n[![GitHub](https://img.shields.io/badge/GitHub-nano--step%2Fnano--brain-181717?logo=github)](https://github.com/nano-step/nano-brain)\n\n## Table of Contents\n\n- [What It Does](#what-it-does)\n- [Use Cases](#use-cases)\n- [Key Features](#key-features)\n- [Prerequisites](#prerequisites)\n- [Recommended Models \u0026 Free Providers](#recommended-models--free-providers)\n- [Quick Start](#quick-start)\n- [Verifying Downloads](#verifying-downloads)\n- [Configuration](#configuration)\n- [REST API](#rest-api)\n- [CLI Commands](#cli-commands)\n- [MCP Tools](#mcp-tools)\n- [Search Pipeline](#search-pipeline)\n- [Architecture](#architecture)\n- [Migration from V1](#migration-from-v1)\n- [Tech Stack](#tech-stack)\n- [License](#license)\n\n---\n\n## What It Does\n\nnano-brain is a persistent memory server for AI coding agents that solves session amnesia. It automatically ingests AI sessions, notes, and codebase files, indexes everything with hybrid search (BM25 + pgvector), and serves memories via MCP tools and REST API. Built in Go with PostgreSQL — single static binary, zero CGO dependencies.\n\n## Use Cases\n\n### Multi-machine developer (primary use case)\nYou work on your office PC, home machine, and personal laptop — each with a different Claude Code or OpenCode session. Without shared memory, your AI agent forgets everything between machines.\n\nDeploy nano-brain on a VPS (or any always-on server) with a PostgreSQL instance. Every session you run on any machine gets harvested and indexed there. When you switch machines, your agent picks up exactly where you left off — decisions, context, code knowledge, all there.\n\n```\nOffice PC ──┐\n             ├──► nano-brain on VPS ──► shared PostgreSQL\nHome Mac ───┘\n```\n\n### Persistent AI agent memory\nAI agents forget everything when the session ends. nano-brain gives them durable, searchable memory across sessions — decisions made, patterns discovered, code written — so they don't repeat work or ask the same questions twice.\n\n### Code intelligence for large codebases\nnano-brain builds a symbol graph of your codebase: functions, types, dependencies, call chains. Agents can ask \"what breaks if I change this function?\" (`memory_impact`) or \"trace the call chain from this entry point\" (`memory_trace`) — across files, across sessions.\n\n### Notes and documentation search\nWrite structured notes, ADRs, or decision records into nano-brain. Hybrid search (BM25 + semantic) retrieves them by keyword or concept. Agents can surface the right context without you having to remember where you put it.\n\n### Team knowledge base (no per-member setup)\nDeploy one nano-brain server for the whole team. Every developer's AI agent connects to the same PostgreSQL instance — decisions, architecture notes, code intelligence, and session learnings are instantly shared across the team. New team members get full project context from day one without any setup on their machine.\n\n```\nDev A (office)   ──┐\nDev B (remote)   ──┼──► nano-brain on team server ──► shared PostgreSQL\nDev C (new hire) ──┘\n```\n\nRole-based access: admins get full read/write, developers get read/write scoped to their workspace, stakeholders or reviewers get read-only access.\n\n### Knowledge preservation when an engineer leaves\nA senior engineer resigns. Without nano-brain, their institutional knowledge — why certain decisions were made, which parts of the codebase are fragile, what was tried and failed — walks out the door with them.\n\nWith nano-brain, their sessions are already harvested and indexed. The team can still ask \"why did we pick this approach?\" or \"what did Alice know about the payment service?\" and get answers from her past sessions.\n\n### Freelancer / consultant context switching\nYou work on 3 client projects in parallel. Each is a separate workspace. When you switch clients, run `nano-brain wake-up` to get an instant briefing — recent work, active collections, key context — and your AI agent picks up exactly where you left off without re-reading the codebase.\n\n### Legacy codebase archaeology\nYou inherit a 5-year-old codebase with minimal documentation and no original authors to ask. Index it into nano-brain. Your AI agent can now answer \"what does this function do?\", \"why does this class exist?\", and \"if I change this file, what else breaks?\" — navigating cross-file relationships without reading 200k lines manually.\n\nGo, TypeScript, Python, JavaScript supported today. Rust, Java, and others planned.\n\n### Pre-commit / pre-PR impact check\nBefore pushing, run `memory_impact` on your changed files to discover what else in the codebase depends on them — across files, across repos in the same workspace. Catch breaking changes before they hit CI. *(Multi-file diff-aware mode in roadmap.)*\n\n## Key Features\n\n- **Hybrid search** — BM25 full-text + pgvector HNSW cosine similarity + RRF fusion + recency decay\n- **9 MCP tools** — query, search, vsearch, get, write, tags, status, update, wake_up\n- **Session harvesting** — auto-ingest OpenCode and Claude Code sessions\n- **File watcher** — fsnotify-based directory monitoring with debounce\n- **Content-addressed storage** — SHA-256 deduplication\n- **Heading-aware markdown chunking**\n- **Multi-workspace isolation** with per-workspace data\n- **Config hot-reload** — `POST /api/reload-config`\n- **V1 migration** — import from SQLite (pure Go, no CGO)\n- **Benchmarking suite** — generate, run, compare, stress\n- **Search telemetry** — local-only, 90-day retention, non-blocking\n\n## Prerequisites\n\n- **Go 1.23+** (building from source) OR pre-built binary\n- **PostgreSQL 17** with **pgvector 0.8.2** extension\n- **Embedding provider:** Ollama (default, local) or Voyage AI\n\n## Recommended Models \u0026 Free Providers\n\nnano-brain needs two types of AI models: **embedding** (for vector search) and **chat/completion** (for code summarization, session summarization). Both use standard APIs — any OpenAI-compatible provider works.\n\n### Embedding Models (via Ollama — free, local)\n\n| Model | Dims | Context | Size | Quality | Best For |\n|-------|------|---------|------|---------|----------|\n| **nomic-embed-text** | 768 | 8K tokens | 274 MB | ★★★ | Default choice — handles full functions, CPU-friendly |\n| **mxbai-embed-large** | 1024 | 512 tokens | 670 MB | ★★★★ | Best precision for short code chunks (\u003c500 tokens) |\n| **qwen3-embedding:8b** | 4096 | 8K tokens | 4.9 GB | ★★★★★ | Maximum quality — needs GPU (5 GB+ VRAM) |\n| **bge-m3** | 1024 | 8K tokens | 1.2 GB | ★★★★ | Multilingual codebases, hybrid retrieval |\n| **all-minilm** | 384 | 256 tokens | 46 MB | ★★ | Extreme resource constraints only |\n\n```bash\n# Install your chosen model\nollama pull nomic-embed-text    # recommended default\nollama pull mxbai-embed-large   # upgrade for precision\nollama pull qwen3-embedding:8b  # premium (GPU required)\n```\n\n\u003e **Tip:** Start with `nomic-embed-text`. It handles long functions without truncation and runs on CPU. Upgrade only if retrieval quality matters for your use case.\n\n### Chat/Completion Models (for code \u0026 session summarization)\n\nThese providers offer **free tiers** with OpenAI-compatible `/chat/completions` endpoints — plug directly into nano-brain's `code_summarization` and `summarization` config.\n\n| Provider | Free Tier | Rate Limits | Best Model | Speed |\n|----------|-----------|-------------|------------|-------|\n| **[Cerebras](https://cerebras.ai)** | 1M tokens/day | 30 req/min | `llama3.1-8b` | ~2,000 tok/s |\n| **[Groq](https://groq.com)** | Ongoing (no expiry) | 30 req/min, 14.4K req/day | `llama-3.3-70b-versatile` | ~400 tok/s |\n| **[Together AI](https://together.ai)** | $25 free credits | 60 req/min | `meta-llama/Llama-3.3-70B-Instruct-Turbo` | ~200 tok/s |\n| **[Google AI Studio](https://ai.google.dev)** | 1,500 req/day | 15 req/min | `gemini-2.0-flash` | ~300 tok/s |\n| **Ollama (local)** | Unlimited | Hardware-bound | `qwen3:8b`, `llama3.1:8b` | Depends on GPU |\n\n\u003e **Note:** Google Gemini is NOT OpenAI-compatible natively — use it via a proxy like [9router](https://github.com/nano-step/9router) or [LiteLLM](https://github.com/BerriAI/litellm) to get a `/chat/completions` endpoint.\n\n### Configuration Examples\n\n**Cerebras (recommended — fastest free inference):**\n\n```yaml\ncode_summarization:\n  enabled: true\n  provider_url: \"https://api.cerebras.ai/v1\"\n  api_key: \"your-cerebras-key\"   # free signup, no credit card\n  model: \"llama3.1-8b\"\n\nsummarization:\n  enabled: true\n  provider_url: \"https://api.cerebras.ai/v1\"\n  api_key: \"your-cerebras-key\"\n  model: \"llama3.1-8b\"\n```\n\n**Groq (generous free tier, great for throughput):**\n\n```yaml\ncode_summarization:\n  enabled: true\n  provider_url: \"https://api.groq.com/openai/v1\"\n  api_key: \"your-groq-key\"      # free signup\n  model: \"llama-3.3-70b-versatile\"\n```\n\n**Together AI (200+ models, $25 free credits):**\n\n```yaml\ncode_summarization:\n  enabled: true\n  provider_url: \"https://api.together.ai/v1\"\n  api_key: \"your-together-key\"  # $25 free, no card required\n  model: \"meta-llama/Llama-3.3-70B-Instruct-Turbo\"\n```\n\n**Ollama (fully local, no API key needed):**\n\n```yaml\ncode_summarization:\n  enabled: true\n  provider_url: \"http://localhost:11434/v1\"\n  api_key: \"\"\n  model: \"qwen3:8b\"\n```\n\n**Via 9router (proxy multiple providers):**\n\n```yaml\ncode_summarization:\n  enabled: true\n  provider_url: \"http://localhost:9090/v1\"  # 9router endpoint\n  api_key: \"\"\n  model: \"nano-brain\"                       # routed by 9router config\n```\n\n### Provider Selection Guide\n\n| You want... | Use |\n|-------------|-----|\n| Zero cost, no API keys, full privacy | Ollama (local) |\n| Free cloud, fastest inference | Cerebras |\n| Free cloud, best model quality | Groq (`llama-3.3-70b`) |\n| Many model options, startup-friendly | Together AI |\n| Route through multiple providers | 9router / LiteLLM proxy |\n\n## Quick Start\n\n\u003e **Let your AI agent set this up for you.** See [SETUP_AGENT.md](docs/SETUP_AGENT.md) — a step-by-step guide your agent can follow to install, configure, and verify nano-brain, checking for missing dependencies and asking before installing anything.\n\n---\n\n### Path 1 — Local machine (Ollama + Docker, ~5 min)\n\nThe fastest way to get started on a single machine.\n\n**Prerequisites:** [Docker](https://docs.docker.com/get-docker/), [Ollama](https://ollama.com/download), Node.js 18+\n\n```bash\n# 1. Install nano-brain\nnpm install -g @nano-step/nano-brain\n\n# 2. Start PostgreSQL + pgvector\ndocker run -d --name nanobrain-pg -p 5432:5432 \\\n  -e POSTGRES_USER=nanobrain -e POSTGRES_PASSWORD=nanobrain -e POSTGRES_DB=nanobrain_dev \\\n  pgvector/pgvector:pg17\n\n# 3. Pull embedding model\nollama pull nomic-embed-text\n\n# 4. Verify everything is in order\nnano-brain doctor\n\n# 5. Start the server (background)\nnano-brain serve -d\n\n# 6. Register your project\nnano-brain init --root=/path/to/your/project\n```\n\n**Add to your MCP client** (Claude Code, OpenCode, Cursor, etc.):\n```json\n{\n  \"mcp\": {\n    \"nano-brain\": {\n      \"type\": \"http\",\n      \"url\": \"http://localhost:3100/mcp\"\n    }\n  }\n}\n```\n\nYour AI agent now has persistent memory. It will automatically index your project files and harvest sessions as you work.\n\n---\n\n### Path 2 — VPS / team server (shared memory across machines)\n\nDeploy once, connect from any machine. The whole team shares the same knowledge base.\n\n**On the server:**\n```bash\n# 1. Start PostgreSQL + pgvector\ndocker run -d --name nanobrain-pg -p 5432:5432 \\\n  -e POSTGRES_USER=nanobrain -e POSTGRES_PASSWORD=nanobrain -e POSTGRES_DB=nanobrain_dev \\\n  pgvector/pgvector:pg17\n\n# 2. Install and start nano-brain (with auth + public binding)\nnpm install -g @nano-step/nano-brain\nnano-brain serve -d --host=0.0.0.0\n\n# 3. Generate a bearer token for your team\nnano-brain auth token\n# → nbt_xxxxxxxxxxxxxxxx\n```\n\n**On each developer machine** — add to MCP client config:\n```json\n{\n  \"mcp\": {\n    \"nano-brain\": {\n      \"type\": \"http\",\n      \"url\": \"http://YOUR_VPS_IP:3100/mcp\",\n      \"headers\": {\n        \"Authorization\": \"Bearer nbt_xxxxxxxxxxxxxxxx\"\n      }\n    }\n  }\n}\n```\n\n```bash\n# Register your local project against the remote server\nNANO_BRAIN_SERVER=http://YOUR_VPS_IP:3100 nano-brain init --root=/path/to/project\n```\n\nSee [Authentication](#authentication-vps--remote-deployment) for role-based tokens (admin / developer / read-only).\n\n---\n\n### Path 3 — Build from source\n\n```bash\n# Build\nCGO_ENABLED=0 go build -o nano-brain ./cmd/nano-brain\n\n# Start PostgreSQL + pgvector\ndocker run -d --name nanobrain-pg -p 5432:5432 \\\n  -e POSTGRES_USER=nanobrain -e POSTGRES_PASSWORD=nanobrain -e POSTGRES_DB=nanobrain_dev \\\n  pgvector/pgvector:pg17\n\n# Start server\nDATABASE_URL=\"postgres://nanobrain:nanobrain@localhost:5432/nanobrain_dev\" ./nano-brain\n\n# Register workspace and check status\n./nano-brain init --root=/path/to/project\n./nano-brain status\n```\n\n---\n\n### Via npx (no global install)\n\n```bash\nnpx @nano-step/nano-brain@latest doctor\nnpx @nano-step/nano-brain@latest serve -d\n```\n\n\u003e Also available as `npx nano-brain@latest`. Do NOT run from the nano-brain source directory — npm will resolve the local package instead of the registry.\n\n## Verifying Downloads\n\nEvery release ships a `SHA256SUMS` asset alongside the four platform binaries.\nYou can verify a downloaded binary against the published checksums using\nstandard tooling:\n\n```bash\nTAG=v2026.6.2.1   # any release tag\ncurl -fLO https://github.com/nano-step/nano-brain/releases/download/$TAG/SHA256SUMS\ncurl -fLO https://github.com/nano-step/nano-brain/releases/download/$TAG/nano-brain-linux-amd64\nsha256sum -c SHA256SUMS --ignore-missing\n# nano-brain-linux-amd64: OK\n```\n\n`npm install @nano-step/nano-brain` (and the unscoped `nano-brain` alias)\nperforms this verification **automatically** during postinstall — a SHA-256\nmismatch aborts the install with exit code 1 and removes the partial binary.\n\nFor air-gapped installs or environments where a corporate proxy modifies the\ndownload stream, set `NANO_BRAIN_SKIP_SHA_VERIFY=1` before running `npm install`\nto bypass the check (a warning is printed so the bypass is visible in CI logs).\n\nReleases tagged before this feature shipped do not have a `SHA256SUMS` asset;\ninstalls of those versions succeed with a single WARN line and no verification.\nSee issue [#320](https://github.com/nano-step/nano-brain/issues/320) for the\nthreat model and rationale.\n\n## Configuration\n\nConfig file: `~/.nano-brain/config.yml`\n\n```yaml\nserver:\n  host: localhost\n  port: 3100\n\ndatabase:\n  url: postgres://nanobrain:nanobrain@localhost:5432/nanobrain_dev\n\nembedding:\n  provider: ollama              # ollama or voyage\n  url: http://localhost:11434\n  model: nomic-embed-text\n  dimension: 0                  # auto-detect from provider\n  concurrency: 3\n\nsearch:\n  rrf_k: 60\n  recency_weight: 0.3\n  recency_half_life_days: 180\n  limit: 20\n\nharvester:\n  opencode:\n    db_root: \"\"                 # e.g., ~/.ai-sandbox/opencode-dbs (multi-DB, highest priority)\n    db_path: \"\"                 # e.g., ~/.local/share/opencode/opencode.db (single DB)\n    session_dir: \"\"             # e.g., ~/.local/share/opencode/storage (legacy JSON)\n  claudecode:\n    enabled: false\n    session_dir: \"\"\n\nwatcher:\n  debounce_ms: 2000\n  reindex_interval: 300\n  # Per-collection exclude_patterns and allowed_extensions are also supported\n  # via the workspaces map. See \"Ignore patterns\" section below for the\n  # global and workspace-local .nano-brainignore files.\n\nstorage:\n  max_file_size: 314572800      # 300MB\n  max_size: 10737418240         # 10GB\n\ntelemetry:\n  retention_days: 90\n\nlogging:\n  level: info\n  file: \"\"                      # empty = stdout only\n\nsummarization:\n  enabled: false                # set to true to generate LLM summaries of harvested sessions\n  provider_url: \"\"              # OpenAI-compatible endpoint, e.g. https://ai-proxy.example.com/v1\n  api_key: \"\"                   # or set NANO_BRAIN_SUMMARIZE_API_KEY env var\n  model: \"nano-brain\"           # model name passed to the provider\n  max_tokens: 8000              # max tokens per LLM completion\n  concurrency: 3                # parallel map-phase LLM calls\n```\n\n### Authentication (VPS / remote deployment)\n\nWhen binding to a non-loopback address, enable auth to protect your memory:\n\n```yaml\nserver:\n  host: 0.0.0.0\n  port: 3100\n  auth:\n    enabled: true\n    realm: nano-brain\n    users:\n      - username: admin\n        password_hash: \"$2a$10$...\"   # from: nano-brain auth hash \u003cpassword\u003e\n    tokens:\n      - \"nbt_...\"                     # from: nano-brain auth token\n    bypass_paths:\n      - /health\n```\n\nGenerate credentials:\n\n```bash\n# Generate bcrypt hash for Basic Auth\nnano-brain auth hash mypassword\n\n# Generate bearer token\nnano-brain auth token\n```\n\nUsage examples:\n\n```bash\n# Basic Auth\ncurl -u admin:mypassword http://host:3100/api/v1/query -d '{\"query\":\"test\"}'\n\n# Bearer token\ncurl -H \"Authorization: Bearer nbt_...\" http://host:3100/api/v1/query -d '{\"query\":\"test\"}'\n\n# MCP client with URL-embedded credentials\n# url: http://admin:mypassword@host:3100/mcp\n```\n\n### Ignore patterns\n\nTwo layers of `.nano-brainignore` files control what the watcher indexes,\nboth using standard `.gitignore` syntax (one pattern per line, supports `**`,\n`!negation`, blank lines, `#` comments).\n\n#### Global — `~/.nano-brain/.nano-brainignore`\n\nLoaded once at server startup. Patterns apply to **every** registered\ncollection across **every** workspace. Use this for rules that are personal\nto your machine and span all your projects (e.g. always skip `*.png`).\n\n```\n# Skip generated files everywhere\n*.png\n*.jpg\n*.pdf\nbuild/\ndist/\nnode_modules/\n\n# But keep this one icon\n!icons/important.png\n```\n\n#### Workspace-local — `\u003cworkspace_root\u003e/.nano-brainignore`\n\nLoaded once per collection when the watcher starts watching it (server\nstartup, `POST /api/v1/init`, or `POST /api/v1/collections`). Patterns\napply **only** to that one workspace. Use this for project-specific rules\nyou want to **share with your team via version control** — e.g. skip\ngenerated code that you commit to git but don't want indexed.\n\n```\n# nano-brain-specific rules for this repo (commit me)\n*.generated.go\nfixtures/large/\n*.snap\n```\n\nWorkspace-local rules layer **additively** on top of global rules and\nper-collection `.gitignore`. There is no cross-file negation: a `!pattern`\nin workspace-local cannot un-exclude a path matched by global.\n\nThe file at the workspace root is loaded for the `code` collection. The\nsibling `memory` and `sessions` collections are rooted under `~/.nano-brain/`\nand do not normally need their own ignore files.\n\n#### Order of evaluation (most aggressive first)\n\n1. Hardcoded default exclude dirs (`node_modules`, `.git`, `dist`, `build`, `target`, etc.)\n2. Global `~/.nano-brain/.nano-brainignore`\n3. Workspace-local `\u003cworkspace_root\u003e/.nano-brainignore`\n4. Per-collection `.gitignore` (in collection root)\n5. Per-collection `exclude_patterns` (config-level)\n6. Per-collection `allowed_extensions` (whitelist)\n\n#### Reloading\n\nBoth global and workspace-local files are loaded at collection registration\ntime. To pick up edits:\n\n- **Global**: restart the server.\n- **Workspace-local**: restart the server, OR re-register the workspace\n  with `POST /api/v1/init` (this rebuilds the collection's filter and\n  re-reads the file).\n\n`POST /api/reload-config` does **not** re-read ignore files — only search\nconfig and log level are reloaded by that endpoint.\n\nIssues: #263 (global), #317 (workspace-local).\n\n### Session Summarization\n\nWhen `summarization.enabled: true`, nano-brain automatically generates structured markdown summaries of each harvested session using an OpenAI-compatible LLM provider. Summaries are:\n\n- Stored in PostgreSQL under collection `session-summary` for semantic search via the standard query/vsearch API (PG is the source of truth)\n- Optionally written to disk as Markdown files for Obsidian-compatible access (see [Disk persistence](#disk-persistence-obsidian-compatible) below)\n- Idempotent — unchanged sessions are skipped; re-harvested sessions overwrite old summaries\n\n#### Disk persistence (Obsidian-compatible)\n\nBy default, summaries are written to disk as Markdown files at the path configured in\n`summarization.output_dir` (default: `~/.nano-brain/summaries`). The file layout is:\n\n```\n\u003coutput_dir\u003e/\u003cworkspace_name\u003e/\u003csource\u003e_\u003cslugified-title\u003e_\u003cYYYY-MM-DD\u003e.md\n```\n\nFiles are byte-identical to the `documents.content` field in PostgreSQL — disk is a\nderivative view, DB is source of truth. Disk write failures (permission denied, disk\nfull) log a WARN but do not roll back the DB transaction.\n\nTo opt out (DB-only persistence):\n\n```yaml\nsummarization:\n  write_to_disk: false\n```\n\nTo backfill historical summaries already in the DB:\n\n```\nnano-brain backfill-summaries\n```\n\n**Quick setup with ai-proxy:**\n\n```yaml\nsummarization:\n  enabled: true\n  provider_url: \"https://ai-proxy.example.com/v1\"\n  api_key: \"\"           # set NANO_BRAIN_SUMMARIZE_API_KEY instead\n  model: \"claude-sonnet-4-5\"\n  max_tokens: 8000\n  concurrency: 3\n```\n\nOr via environment variable:\n\n```bash\nexport NANO_BRAIN_SUMMARIZE_API_KEY=\"sk-...\"\n```\n\nLarge sessions (100K+ tokens) are handled via map-reduce chunking — no session is too large.\n\n### Query Preprocessing (Search Quality)\n\nWhen `search.query_preprocessing.enabled: true`, nano-brain uses an LLM to preprocess search queries before execution — translating non-English queries to English, expanding with related terms, and detecting temporal intent. This improves retrieval quality for natural language queries.\n\n```yaml\nsearch:\n  bm25_language: \"english\"          # \"english\" (default) or \"simple\" (language-agnostic)\n  query_preprocessing:\n    enabled: false                   # set to true to activate\n    provider_url: \"\"                 # OpenAI-compatible endpoint (reuse summarization provider)\n    api_key: \"\"                      # or set NANO_BRAIN_SEARCH_PREPROCESS_API_KEY\n    model: \"\"                        # model for query preprocessing\n    max_latency_ms: 500              # timeout — falls back to raw query on timeout\n\nwatcher:\n  chunk_overlap: 600                 # bytes of overlap between adjacent chunks (default: 600)\n```\n\n**How it works:** The preprocessor makes a single LLM call that returns: translated query (if non-English), 2-3 expansion terms, intent classification (keyword/conceptual/temporal), and optional time filter extraction. On timeout or error, the original query passes through unchanged.\n\n**Multilingual note:** If you primarily query in English, `nomic-embed-text` is sufficient. For multilingual workspaces, consider switching to `bge-m3` (1024d) — this requires re-embedding all chunks (`POST /api/v1/update`).\n\n### Environment Variables\n\n| Variable | Description |\n|----------|-------------|\n| `NANO_BRAIN_CONFIG` | Path to YAML config file (12-factor; useful in Docker/k8s). Precedence: `--config` flag \u003e `NANO_BRAIN_CONFIG` \u003e `~/.nano-brain/config.yml`. Leading/trailing whitespace is stripped. If the env-pointed file does not exist, a `WARNING:` is printed to stderr and defaults are used (operator can spot typos). |\n| `DATABASE_URL` | PostgreSQL connection string |\n| `VOYAGE_API_KEY` | Voyage AI API key |\n| `OPENCODE_DB_ROOT` | OpenCode per-project DB root directory (multi-DB mode) |\n| `OPENCODE_DB_PATH` | OpenCode single SQLite database path |\n| `OPENCODE_STORAGE_DIR` | OpenCode session directory (legacy) |\n| `NANO_BRAIN_SUMMARIZE_API_KEY` | API key for the summarization LLM provider |\n| `NANO_BRAIN_AUTH_ENABLED` | Enable Basic Auth + Bearer Token (`true`/`false`) |\n| `NANO_BRAIN_AUTH_TOKENS` | Comma-separated bearer tokens |\n| `NANO_BRAIN_*` | Override any config field (e.g., `NANO_BRAIN_SERVER_PORT=3100`) |\n\n**Docker example** — run the server in a container against a host PostgreSQL:\n\n```bash\n# /path/to/container-config.yml uses host.docker.internal for DB/Ollama\ndocker run -d \\\n  -e NANO_BRAIN_CONFIG=/etc/nano-brain/config.yml \\\n  -v /path/to/container-config.yml:/etc/nano-brain/config.yml:ro \\\n  -p 3100:3100 \\\n  nano-brain:latest\n```\n\n## REST API\n\n### Public Endpoints\n\n| Method | Path | Description |\n|--------|------|-------------|\n| GET | `/health` | Health check |\n| GET | `/api/status` | Server status with version, uptime, workspace stats |\n| POST | `/api/v1/init` | Register workspace |\n| GET | `/api/v1/workspaces` | List all workspaces (with doc counts) |\n| POST | `/api/v1/workspaces/resolve` | Resolve path → workspace hash + `registered` status (read-only) |\n| DELETE | `/api/v1/workspaces/:hash` | Permanently delete a workspace + cascade docs/chunks/embeddings |\n| GET | `/api/v1/wake-up` | Workspace briefing |\n| POST | `/api/harvest` | Trigger session harvesting |\n| POST | `/api/reload-config` | Hot-reload configuration |\n\n### Workspace-Scoped Endpoints\n\nWorkspace is passed in the JSON body for POST, query param for GET.\n\n| Method | Path | Description |\n|--------|------|-------------|\n| POST | `/api/v1/write` | Write/update document |\n| POST | `/api/v1/embed` | Trigger embedding |\n| POST | `/api/v1/search` | BM25 keyword search |\n| POST | `/api/v1/vsearch` | Vector similarity search |\n| POST | `/api/v1/query` | Hybrid search (BM25 + vector + RRF + recency) |\n| POST | `/api/v1/collections` | Add collection |\n| GET | `/api/v1/collections` | List collections |\n| PUT | `/api/v1/collections/:name` | Rename collection |\n| DELETE | `/api/v1/collections/:name` | Remove collection |\n| GET | `/api/v1/tags` | List tags with counts |\n| POST | `/api/v1/get` | Get single document by source_path or id |\n| POST | `/api/v1/multi-get` | Batch fetch documents by paths or ids |\n| POST | `/api/v1/reindex` | Queue reindex (202) |\n| POST | `/api/v1/update` | Queue update (202) |\n| POST | `/api/v1/summarize` | Trigger LLM summarization of harvested sessions |\n| POST | `/api/v1/wake-up` | Workspace briefing with session_dir |\n\n### MCP Endpoints\n\n| Method | Path | Description |\n|--------|------|-------------|\n| GET/POST | `/mcp` | Streamable HTTP (MCP 2025-03-26) |\n| GET/POST | `/sse` | SSE transport (legacy) |\n\n## CLI Commands\n\n| Command | Description |\n|---------|-------------|\n| `nano-brain` (no args) | Start HTTP server (default: port 3100) |\n| `nano-brain init --root=\u003cpath\u003e` | Register workspace |\n| `nano-brain workspaces list` | List registered workspaces with doc counts |\n| `nano-brain workspaces current [--path=\u003cp\u003e] [--export\\|--json\\|--check]` | Resolve current/path workspace hash. `--export` prints `export NANO_BRAIN_WORKSPACE=\u003chash\u003e` for `eval`; `--check` exits 2 if not registered |\n| `nano-brain workspaces remove --workspace=\u003chash\u003e [--dry-run\\|--force]` | Permanently delete a workspace + all its documents/chunks/embeddings |\n| `nano-brain write` | Write document via CLI |\n| `nano-brain query [--scope=all] [--tags=t1,t2]` | Hybrid search (BM25 + vector + RRF + recency) |\n| `nano-brain search [--scope=all] [--tags=t1,t2]` | BM25 keyword search |\n| `nano-brain vsearch [--scope=all] [--tags=t1,t2]` | Vector similarity search |\n| `nano-brain wake-up --workspace=\u003chash\u003e` | Workspace briefing (collections, stats, recent memories) |\n| `nano-brain get \u003csource_path\\|uuid\u003e --workspace=\u003chash\u003e` | Fetch a single document by source_path or UUID |\n| `nano-brain tags --workspace=\u003chash\u003e` | List all tags with document counts |\n| `nano-brain multi-get --workspace=\u003chash\u003e --paths=p1,p2` | Fetch multiple documents in one round-trip |\n| `nano-brain collection add\\|remove\\|list` | Manage collections |\n| `nano-brain harvest` | Trigger session harvesting |\n| `nano-brain backfill-summaries [--dry-run] [--workspace=] [--since=]` | Export existing DB summaries to disk (.md files for Obsidian etc.) |\n| `nano-brain cleanup-stale-raw [--dry-run]` | Delete pre-#192 raw OpenCode session docs superseded by summaries |\n| `nano-brain cleanup-orphan-workspaces [--dry-run]` | Delete documents/chunks under workspace_hash values not registered in `workspaces`. Run BEFORE migration 00011 (issue #238). |\n| `nano-brain bench generate\\|run\\|compare\\|stress` | Benchmarking suite |\n| `nano-brain db:migrate` | Run pending goose migrations |\n| `nano-brain db:migrate --from-v1 \u003cpath\u003e` | Import V1 SQLite data |\n| `nano-brain logs [-n 50] [-f]` | Tail log file |\n| `nano-brain docker start\\|stop\\|status` | Docker compose management |\n| `nano-brain status [--json]` | Server status |\n| `nano-brain auth hash \u003cpassword\u003e` | Generate bcrypt password hash for config |\n| `nano-brain auth token` | Generate random bearer token (`nbt_`-prefixed) |\n| `nano-brain doctor [--json]` | Check prerequisites (config, PostgreSQL, pgvector, Ollama, model) |\n\n## MCP Tools\n\nnano-brain exposes 14 tools via MCP (Model Context Protocol):\n\n| Tool | Description |\n|------|-------------|\n| `memory_query` | Hybrid search (BM25 + vector + RRF + recency); supports time-range filters (`created_after`, `created_before`, `updated_after`, `updated_before`) |\n| `memory_search` | BM25 keyword search; supports time-range filters (`created_after`, `created_before`, `updated_after`, `updated_before`) |\n| `memory_vsearch` | Vector similarity search; supports time-range filters (`created_after`, `created_before`, `updated_after`, `updated_before`) |\n| `memory_get` | Get document by path |\n| `memory_write` | Write/update document |\n| `memory_tags` | List tags with counts |\n| `memory_status` | Server and embedding status |\n| `memory_update` | Trigger re-embedding |\n| `memory_wake_up` | Workspace briefing |\n| `memory_graph` | Knowledge graph view (module → function → dep) |\n| `memory_trace` | Call chain trace from entry point |\n| `memory_impact` | Cross-file change impact analysis |\n| `memory_symbols` | Symbol search (functions, types, constants) |\n| `memory_workspaces_resolve` | Resolve filesystem path → workspace hash + registered status (read-only) |\n\n### MCP Configuration\n\n```json\n{\n  \"mcp\": {\n    \"nano-brain\": {\n      \"type\": \"remote\",\n      \"url\": \"http://localhost:3100/mcp\"\n    }\n  }\n}\n```\n\n## Search Pipeline\n\n```\nQuery --\u003e BM25 (ts_rank_cd) ---+\n                               +--\u003e RRF Fusion (k=60) --\u003e Recency Decay --\u003e Results\nQuery --\u003e Vector (HNSW cos) ---+\n```\n\n- **BM25:** `websearch_to_tsquery` + `ts_rank_cd` on PostgreSQL tsvector\n- **Vector:** pgvector HNSW index with cosine distance\n- **RRF:** Reciprocal Rank Fusion (k=60), scores normalized to [0,1]\n- **Recency:** exponential half-life decay (default 180 days, weight 0.3)\n\n## Architecture\n\n- 15 internal packages: config, server, handlers, storage, sqlc, embed, search, watcher, harvest, mcp, migrate, telemetry, health, bench\n- 7 goose SQL migrations (embedded)\n- Constructor injection (no DI framework)\n- errgroup + context for goroutine lifecycle\n- Echo v4 middleware: workspace extraction, content-type enforcement, version header\n\n## Migration from V1\n\n```bash\n# Import V1 SQLite data to PostgreSQL\nnano-brain db:migrate --from-v1 /path/to/old/index.db\n\n# Idempotent — safe to run multiple times\n# Uses content-addressed SHA-256 hashing\n# Pure Go SQLite reader (modernc.org/sqlite, no CGO)\n```\n\n## Tech Stack\n\n- **Go 1.23** — compiled to single static binary (`CGO_ENABLED=0`)\n- **PostgreSQL 17** — relational storage + full-text search (tsvector/tsquery)\n- **pgvector 0.8.2** — HNSW vector indexing\n- **Echo v4** — HTTP framework\n- **sqlc** — type-safe SQL code generation\n- **goose v3** — database migrations\n- **zerolog** — structured JSON logging\n- **koanf** — YAML + env configuration\n- **fsnotify** — file system watching\n- **modernc.org/sqlite** — V1 migration reader (pure Go)\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnano-step%2Fnano-brain","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnano-step%2Fnano-brain","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnano-step%2Fnano-brain/lists"}