npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

nano-brain

v2026.5.3105

Published

Persistent memory and code intelligence for AI coding agents

Downloads

16,835

Readme

nano-brain

Persistent memory and code intelligence for AI coding agents.

Go 1.23 License: MIT GitHub

What It Does

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

Key Features

  • Hybrid search — BM25 full-text + pgvector HNSW cosine similarity + RRF fusion + recency decay
  • 9 MCP tools — query, search, vsearch, get, write, tags, status, update, wake_up
  • Session harvesting — auto-ingest OpenCode and Claude Code sessions
  • File watcher — fsnotify-based directory monitoring with debounce
  • Content-addressed storage — SHA-256 deduplication
  • Heading-aware markdown chunking
  • Multi-workspace isolation with per-workspace data
  • Config hot-reloadPOST /api/reload-config
  • V1 migration — import from SQLite (pure Go, no CGO)
  • Benchmarking suite — generate, run, compare, stress
  • Search telemetry — local-only, 90-day retention, non-blocking

Prerequisites

  • Go 1.23+ (building from source) OR pre-built binary
  • PostgreSQL 17 with pgvector 0.8.2 extension
  • Embedding provider: Ollama (default, local) or Voyage AI

Quick Start

Option A: Via npx (no Go required)

# Start PostgreSQL + pgvector
docker run -d --name nanobrain-pg -p 5432:5432 \
  -e POSTGRES_USER=nanobrain -e POSTGRES_PASSWORD=nanobrain -e POSTGRES_DB=nanobrain_dev \
  pgvector/pgvector:pg17

# Start Ollama + pull embedding model
ollama pull nomic-embed-text

# Check prerequisites
npx @nano-step/nano-brain@beta doctor

# Start server
npx @nano-step/nano-brain@beta

Also available as: npx nano-brain@beta (unscoped alias)

Note: Do NOT run npx nano-brain from the nano-brain source directory — npm will resolve the local package instead of the registry. Run from any other directory.

Option B: Build from source

# Build
CGO_ENABLED=0 go build -o nano-brain ./cmd/nano-brain

# Start PostgreSQL + pgvector (example with Docker)
docker run -d --name nanobrain-pg -p 5432:5432 \
  -e POSTGRES_USER=nanobrain -e POSTGRES_PASSWORD=nanobrain -e POSTGRES_DB=nanobrain_dev \
  pgvector/pgvector:pg17

# Start server
DATABASE_URL="postgres://nanobrain:nanobrain@localhost:5432/nanobrain_dev" ./nano-brain

# Register workspace
curl -X POST http://localhost:3100/api/v1/init \
  -H "Content-Type: application/json" \
  -d '{"root_path":"/path/to/project","name":"my-project"}'

# Write a document
curl -X POST http://localhost:3100/api/v1/write \
  -H "Content-Type: application/json" \
  -d '{"workspace":"<hash>","source_path":"notes/decision.md","content":"# Decision\nUse PostgreSQL.","tags":["decision"]}'

# Search
curl -X POST http://localhost:3100/api/v1/query \
  -H "Content-Type: application/json" \
  -d '{"workspace":"<hash>","query":"database decision"}'

Configuration

Config file: ~/.nano-brain/config.yml

server:
  host: localhost
  port: 3100

database:
  url: postgres://nanobrain:nanobrain@localhost:5432/nanobrain_dev

embedding:
  provider: ollama              # ollama or voyage
  url: http://localhost:11434
  model: nomic-embed-text
  dimension: 0                  # auto-detect from provider
  concurrency: 3

search:
  rrf_k: 60
  recency_weight: 0.3
  recency_half_life_days: 180
  limit: 20

harvester:
  opencode:
    db_root: ""                 # e.g., ~/.ai-sandbox/opencode-dbs (multi-DB, highest priority)
    db_path: ""                 # e.g., ~/.local/share/opencode/opencode.db (single DB)
    session_dir: ""             # e.g., ~/.local/share/opencode/storage (legacy JSON)
  claudecode:
    enabled: false
    session_dir: ""

watcher:
  debounce_ms: 2000
  reindex_interval: 300
  # Per-collection exclude_patterns and allowed_extensions are also supported
  # via the workspaces map. See "Global ignore patterns" section below for
  # the cross-collection .nano-brainignore file.

storage:
  max_file_size: 314572800      # 300MB
  max_size: 10737418240         # 10GB

telemetry:
  retention_days: 90

logging:
  level: info
  file: ""                      # empty = stdout only

summarization:
  enabled: false                # set to true to generate LLM summaries of harvested sessions
  provider_url: ""              # OpenAI-compatible endpoint, e.g. https://ai-proxy.example.com/v1
  api_key: ""                   # or set NANO_BRAIN_SUMMARIZE_API_KEY env var
  model: "nano-brain"           # model name passed to the provider
  max_tokens: 8000              # max tokens per LLM completion
  concurrency: 3                # parallel map-phase LLM calls

Authentication (VPS / remote deployment)

When binding to a non-loopback address, enable auth to protect your memory:

server:
  host: 0.0.0.0
  port: 3100
  auth:
    enabled: true
    realm: nano-brain
    users:
      - username: admin
        password_hash: "$2a$10$..."   # from: nano-brain auth hash <password>
    tokens:
      - "nbt_..."                     # from: nano-brain auth token
    bypass_paths:
      - /health

Generate credentials:

# Generate bcrypt hash for Basic Auth
nano-brain auth hash mypassword

# Generate bearer token
nano-brain auth token

Usage examples:

# Basic Auth
curl -u admin:mypassword http://host:3100/api/v1/query -d '{"query":"test"}'

# Bearer token
curl -H "Authorization: Bearer nbt_..." http://host:3100/api/v1/query -d '{"query":"test"}'

# MCP client with URL-embedded credentials
# url: http://admin:mypassword@host:3100/mcp

Global ignore patterns (~/.nano-brain/.nano-brainignore)

The watcher loads a global gitignore-style file at ~/.nano-brain/.nano-brainignore on startup. Patterns in this file apply to all registered collections, removing the need to repeat the same exclusions in each watcher.workspaces block.

Format: standard .gitignore syntax (one pattern per line, supports **, !negation, blank lines, # comments).

Example ~/.nano-brain/.nano-brainignore:

# Skip generated files everywhere
*.png
*.jpg
*.pdf
build/
dist/
node_modules/

# But keep this one icon
!icons/important.png

Order of evaluation (most aggressive first):

  1. Hardcoded default exclude dirs (node_modules, .git, dist, build, target, etc.)
  2. Global .nano-brainignore (this feature)
  3. Per-collection .gitignore (in collection root)
  4. Per-collection exclude_patterns (config-level)
  5. Per-collection allowed_extensions (whitelist)

Restart required: changes to .nano-brainignore take effect on next server start (hot-reload deferred to a follow-up). Issue #263.

Session Summarization

When summarization.enabled: true, nano-brain automatically generates structured markdown summaries of each harvested session using an OpenAI-compatible LLM provider. Summaries are:

  • Stored in PostgreSQL under collection session-summary for semantic search via the standard query/vsearch API (PG is the source of truth)
  • Optionally written to disk as Markdown files for Obsidian-compatible access (see Disk persistence below)
  • Idempotent — unchanged sessions are skipped; re-harvested sessions overwrite old summaries

Disk persistence (Obsidian-compatible)

By default, summaries are written to disk as Markdown files at the path configured in summarization.output_dir (default: ~/.nano-brain/summaries). The file layout is:

<output_dir>/<workspace_name>/<source>_<slugified-title>_<YYYY-MM-DD>.md

Files are byte-identical to the documents.content field in PostgreSQL — disk is a derivative view, DB is source of truth. Disk write failures (permission denied, disk full) log a WARN but do not roll back the DB transaction.

To opt out (DB-only persistence):

summarization:
  write_to_disk: false

To backfill historical summaries already in the DB:

nano-brain backfill-summaries

Quick setup with ai-proxy:

summarization:
  enabled: true
  provider_url: "https://ai-proxy.example.com/v1"
  api_key: ""           # set NANO_BRAIN_SUMMARIZE_API_KEY instead
  model: "claude-sonnet-4-5"
  max_tokens: 8000
  concurrency: 3

Or via environment variable:

export NANO_BRAIN_SUMMARIZE_API_KEY="sk-..."

Large sessions (100K+ tokens) are handled via map-reduce chunking — no session is too large.

Environment Variables

| Variable | Description | |----------|-------------| | NANO_BRAIN_CONFIG | Path to YAML config file (12-factor; useful in Docker/k8s). Precedence: --config flag > NANO_BRAIN_CONFIG > ~/.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). | | DATABASE_URL | PostgreSQL connection string | | VOYAGE_API_KEY | Voyage AI API key | | OPENCODE_DB_ROOT | OpenCode per-project DB root directory (multi-DB mode) | | OPENCODE_DB_PATH | OpenCode single SQLite database path | | OPENCODE_STORAGE_DIR | OpenCode session directory (legacy) | | NANO_BRAIN_SUMMARIZE_API_KEY | API key for the summarization LLM provider | | NANO_BRAIN_AUTH_ENABLED | Enable Basic Auth + Bearer Token (true/false) | | NANO_BRAIN_AUTH_TOKENS | Comma-separated bearer tokens | | NANO_BRAIN_* | Override any config field (e.g., NANO_BRAIN_SERVER_PORT=3100) |

Docker example — run the server in a container against a host PostgreSQL:

# /path/to/container-config.yml uses host.docker.internal for DB/Ollama
docker run -d \
  -e NANO_BRAIN_CONFIG=/etc/nano-brain/config.yml \
  -v /path/to/container-config.yml:/etc/nano-brain/config.yml:ro \
  -p 3100:3100 \
  nano-brain:latest

REST API

Public Endpoints

| Method | Path | Description | |--------|------|-------------| | GET | /health | Health check | | GET | /api/status | Server status with version, uptime, workspace stats | | POST | /api/v1/init | Register workspace | | GET | /api/v1/workspaces | List all workspaces (with doc counts) | | DELETE | /api/v1/workspaces/:hash | Permanently delete a workspace + cascade docs/chunks/embeddings | | GET | /api/v1/wake-up | Workspace briefing | | POST | /api/harvest | Trigger session harvesting | | POST | /api/reload-config | Hot-reload configuration |

Workspace-Scoped Endpoints

Workspace is passed in the JSON body for POST, query param for GET.

| Method | Path | Description | |--------|------|-------------| | POST | /api/v1/write | Write/update document | | POST | /api/v1/embed | Trigger embedding | | POST | /api/v1/search | BM25 keyword search | | POST | /api/v1/vsearch | Vector similarity search | | POST | /api/v1/query | Hybrid search (BM25 + vector + RRF + recency) | | POST | /api/v1/collections | Add collection | | GET | /api/v1/collections | List collections | | PUT | /api/v1/collections/:name | Rename collection | | DELETE | /api/v1/collections/:name | Remove collection | | GET | /api/v1/tags | List tags with counts | | POST | /api/v1/get | Get single document by source_path or id | | POST | /api/v1/multi-get | Batch fetch documents by paths or ids | | POST | /api/v1/reindex | Queue reindex (202) | | POST | /api/v1/update | Queue update (202) | | POST | /api/v1/summarize | Trigger LLM summarization of harvested sessions | | POST | /api/v1/wake-up | Workspace briefing with session_dir |

MCP Endpoints

| Method | Path | Description | |--------|------|-------------| | GET/POST | /mcp | Streamable HTTP (MCP 2025-03-26) | | GET/POST | /sse | SSE transport (legacy) |

CLI Commands

| Command | Description | |---------|-------------| | nano-brain (no args) | Start HTTP server (default: port 3100) | | nano-brain init --root=<path> | Register workspace | | nano-brain workspaces list | List registered workspaces with doc counts | | nano-brain workspaces remove --workspace=<hash> [--dry-run\|--force] | Permanently delete a workspace + all its documents/chunks/embeddings | | nano-brain write | Write document via CLI | | nano-brain query [--scope=all] [--tags=t1,t2] | Hybrid search (BM25 + vector + RRF + recency) | | nano-brain search [--scope=all] [--tags=t1,t2] | BM25 keyword search | | nano-brain vsearch [--scope=all] [--tags=t1,t2] | Vector similarity search | | nano-brain wake-up --workspace=<hash> | Workspace briefing (collections, stats, recent memories) | | nano-brain get <source_path\|uuid> --workspace=<hash> | Fetch a single document by source_path or UUID | | nano-brain tags --workspace=<hash> | List all tags with document counts | | nano-brain multi-get --workspace=<hash> --paths=p1,p2 | Fetch multiple documents in one round-trip | | nano-brain collection add\|remove\|list | Manage collections | | nano-brain harvest | Trigger session harvesting | | nano-brain backfill-summaries [--dry-run] [--workspace=] [--since=] | Export existing DB summaries to disk (.md files for Obsidian etc.) | | nano-brain cleanup-stale-raw [--dry-run] | Delete pre-#192 raw OpenCode session docs superseded by summaries | | nano-brain cleanup-orphan-workspaces [--dry-run] | Delete documents/chunks under workspace_hash values not registered in workspaces. Run BEFORE migration 00011 (issue #238). | | nano-brain bench generate\|run\|compare\|stress | Benchmarking suite | | nano-brain db:migrate | Run pending goose migrations | | nano-brain db:migrate --from-v1 <path> | Import V1 SQLite data | | nano-brain logs [-n 50] [-f] | Tail log file | | nano-brain docker start\|stop\|status | Docker compose management | | nano-brain status [--json] | Server status | | nano-brain auth hash <password> | Generate bcrypt password hash for config | | nano-brain auth token | Generate random bearer token (nbt_-prefixed) | | nano-brain doctor [--json] | Check prerequisites (config, PostgreSQL, pgvector, Ollama, model) |

MCP Tools

nano-brain exposes 13 tools via MCP (Model Context Protocol):

| Tool | Description | |------|-------------| | memory_query | Hybrid search (BM25 + vector + RRF + recency) | | memory_search | BM25 keyword search | | memory_vsearch | Vector similarity search | | memory_get | Get document by path | | memory_write | Write/update document | | memory_tags | List tags with counts | | memory_status | Server and embedding status | | memory_update | Trigger re-embedding | | memory_wake_up | Workspace briefing | | memory_graph | Knowledge graph view (module → function → dep) | | memory_trace | Call chain trace from entry point | | memory_impact | Cross-file change impact analysis | | memory_symbols | Symbol search (functions, types, constants) |

MCP Configuration

{
  "mcp": {
    "nano-brain": {
      "type": "remote",
      "url": "http://localhost:3100/mcp"
    }
  }
}

Search Pipeline

Query --> BM25 (ts_rank_cd) ---+
                               +--> RRF Fusion (k=60) --> Recency Decay --> Results
Query --> Vector (HNSW cos) ---+
  • BM25: websearch_to_tsquery + ts_rank_cd on PostgreSQL tsvector
  • Vector: pgvector HNSW index with cosine distance
  • RRF: Reciprocal Rank Fusion (k=60), scores normalized to [0,1]
  • Recency: exponential half-life decay (default 180 days, weight 0.3)

Architecture

  • 15 internal packages: config, server, handlers, storage, sqlc, embed, search, watcher, harvest, mcp, migrate, telemetry, health, bench
  • 7 goose SQL migrations (embedded)
  • Constructor injection (no DI framework)
  • errgroup + context for goroutine lifecycle
  • Echo v4 middleware: workspace extraction, content-type enforcement, version header

Migration from V1

# Import V1 SQLite data to PostgreSQL
nano-brain db:migrate --from-v1 /path/to/old/index.db

# Idempotent — safe to run multiple times
# Uses content-addressed SHA-256 hashing
# Pure Go SQLite reader (modernc.org/sqlite, no CGO)

Tech Stack

  • Go 1.23 — compiled to single static binary (CGO_ENABLED=0)
  • PostgreSQL 17 — relational storage + full-text search (tsvector/tsquery)
  • pgvector 0.8.2 — HNSW vector indexing
  • Echo v4 — HTTP framework
  • sqlc — type-safe SQL code generation
  • goose v3 — database migrations
  • zerolog — structured JSON logging
  • koanf — YAML + env configuration
  • fsnotify — file system watching
  • modernc.org/sqlite — V1 migration reader (pure Go)

License

MIT