# https://github.com/nano-step/nano-brain Project Manual

Generated at: 2026-07-06 08:27:55 UTC

## Table of Contents

- [Overview, Installation & Quick Start](#page-1)
- [MCP Tools, Workspaces & Agent Wiring](#page-2)
- [Code Intelligence: Symbols, Graph & Impact Analysis](#page-3)
- [Architecture, Storage, Search & Operations](#page-4)

<a id='page-1'></a>

## Overview, Installation & Quick Start

### Related Pages

Related topics: [MCP Tools, Workspaces & Agent Wiring](#page-2), [Architecture, Storage, Search & Operations](#page-4)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [README.md](https://github.com/nano-step/nano-brain/blob/main/README.md)
- [install.sh](https://github.com/nano-step/nano-brain/blob/main/install.sh)
- [package.json](https://github.com/nano-step/nano-brain/blob/main/package.json)
- [cmd/nano-brain/init.go](https://github.com/nano-step/nano-brain/blob/main/cmd/nano-brain/init.go)
- [cmd/nano-brain/main.go](https://github.com/nano-step/nano-brain/blob/main/cmd/nano-brain/main.go)
- [docs/SETUP_AGENT.md](https://github.com/nano-step/nano-brain/blob/main/docs/SETUP_AGENT.md)
- [internal/server/routes.go](https://github.com/nano-step/nano-brain/blob/main/internal/server/routes.go)
- [internal/mcp/tools.go](https://github.com/nano-step/nano-brain/blob/main/internal/mcp/tools.go)
</details>

# Overview, Installation & Quick Start

nano-brain is a local-first indexing daemon and Model Context Protocol (MCP) server that gives AI coding agents structured access to a project's source code, symbols, call graph, and memory traces. It runs as a single Go binary that serves both a REST API (under `/api/v1/*`) and a stateless Streamable HTTP MCP endpoint, so any HTTP-capable agent — Claude Code, OpenCode, or a custom client — can call it without an SDK. The latest tagged release is **v2026.7.0602** (https://github.com/nano-step/nano-brain/releases/tag/v2026.7.0602).

## What nano-brain Does

At a high level, nano-brain turns a checked-out source tree into queryable context for an LLM agent:

- **Indexes documents and code** into a collection, honoring nested `.gitignore` / `.nano-brainignore` rules, `max_file_size`, and minified-file filters on the startup path (`scanCollection`).
- **Builds a symbol registry** for files in a "code" collection, exposing symbols, call flow, and impact analysis through MCP tools.
- **Watches the workspace** for file changes and incrementally re-indexes affected files (see issue #520 for recent hardening of the summarize-notify path, and #538 / #535 for unifying the graph-build file-admission filter that previously produced orphan edges).
- **Exposes ~60 REST endpoints** declared in `internal/server/routes.go`, independent of MCP, so non-MCP clients can integrate directly.
- **Persists agent memory traces**, a code/symbol graph, and per-workspace state for retrieval across sessions.

MCP tools such as `search`, `symbols`, `flow`, `impact`, and `trace` are how an agent typically consumes the index; issue #529 proposes a benchmark to measure how much these reduce token spend versus raw `grep`/`read`/`glob`.

## Installation

Two install paths are supported in the current release line.

### One-line shell installer (recommended)

PR #533 (released as **v2026.7.0303**) added a `curl | bash` installer that fetches the appropriate binary for the host platform, verifies its SHA256 checksum against a published manifest, and installs it onto `PATH`:

```bash
curl -fsSL https://nano-step.github.io/nano-brain/install.sh | bash
```

Source: [install.sh:1-1](). npm remains an alternative distribution channel listed in [package.json:1-1]().

### Zero-config first run

After the binary is on `PATH`, no config file is required to begin. The `init` command introduced in PR #534 (**v2026.7.0302**) performs 0–3 probes, writes a fully self-documenting config, and accepts secrets through environment variables.

## Quick Start

The typical first-session flow registers a workspace, starts the daemon, and wires an agent to the MCP endpoint.

### 1. Register a workspace

```bash
nano-brain init --root=/absolute/path/to/project
```

This is dispatched through the CLI entrypoint in `cmd/nano-brain/main.go` and implemented in `cmd/nano-brain/init.go`. On success it prints an `AgentsSnippet` — a copy-paste-ready JSON block for Claude Code, OpenCode, and other MCP clients (issue #525 plans to automate this step rather than relying on manual copy-paste from `docs/SETUP_AGENT.md` Step 9).

### 2. Start the daemon

Running `nano-brain` with no arguments, or with an explicit serve flag, launches:

- The REST API on `http://localhost:<port>/api/v1/*` (route table in [internal/server/routes.go:1-1]()).
- The MCP server on `http://localhost:3100/mcp` over a deliberately stateless Streamable HTTP transport, as documented in `docs/SETUP_AGENT.md:172-181`.

Currently every MCP tool call requires an explicit `workspace` argument — `requireWorkspace` is enforced at `internal/mcp/tools.go:149` — because the daemon serves every project from the same shared URL. Issues #522 and #523 propose binding a default workspace via a URL query parameter so agents can skip per-call discovery.

### 3. Connect an agent

Add the snippet to your client's MCP config, then issue tool calls such as `search`, `symbols`, `flow`, `impact`, and `trace`. For non-MCP HTTP clients, browse the route table in `internal/server/routes.go` or use the OpenAPI 3.0 spec proposed in issue #530 for discovery.

## High-Level Component Map

```mermaid
flowchart LR
    U[User / Agent] -->|HTTP /api/v1/*| REST[REST API<br/>internal/server/routes.go]
    U -->|Streamable HTTP| MCP[MCP Server<br/>:3100/mcp]
    CLI[cmd/nano-brain<br/>init / serve] --> Daemon
    Daemon --> Scanner[scanCollection<br/>.gitignore + size filters]
    Scanner --> Indexer[Document Indexer]
    Scanner --> Graph[Code-Graph Extractor<br/>symbols + call edges]
    Watcher[fsnotify watcher] -->|incremental| Indexer
    Watcher -->|summarizeNotify| Graph
    Indexer --> Store[(memory_trace / graph / symbols)]
    Graph --> Store
    REST --> Store
    MCP --> Store
```

The diagram reflects the unified file-admission filter shipped in PR #538 / issue #535, which closed a divergence between the scanner and the code-graph extractor that was previously producing orphan edges visible to agents.

## Verifying the Install

A quick smoke test after installation:

1. `nano-brain --version` prints the tagged build (e.g. `v2026.7.0602`).
2. `nano-brain init --root=.` in a small project registers it and prints a snippet.
3. `nano-brain` starts the daemon; `curl http://localhost:3100/health` (or the equivalent `/api/v1/*` liveness route in `internal/server/routes.go`) returns OK.
4. An MCP client connected to `http://localhost:3100/mcp` can call a read-only tool such as `search` against the registered workspace.

## Known UX Gaps to Watch

A few rough edges in the install/quick-start flow are tracked publicly and worth knowing before you script around them:

- The `flag` stdlib intercepts `-h` / `--help` before `main()`'s dispatch switch runs, so the help output is currently sparse (issue #527).
- The MCP client configuration step is fully manual copy-paste from `docs/SETUP_AGENT.md`; issue #525 proposes automating it.
- Default-workspace binding by URL query parameter is still open (#522, #523), so every MCP call must currently pass `workspace` explicitly.
- An OpenAPI 3.0 spec for the REST surface does not yet ship in-repo (issue #530); the route table in `internal/server/routes.go` is the source of truth in the meantime.

---

<a id='page-2'></a>

## MCP Tools, Workspaces & Agent Wiring

### Related Pages

Related topics: [Overview, Installation & Quick Start](#page-1), [Code Intelligence: Symbols, Graph & Impact Analysis](#page-3), [Architecture, Storage, Search & Operations](#page-4)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [internal/mcp/server.go](https://github.com/nano-step/nano-brain/blob/main/internal/mcp/server.go)
- [internal/mcp/tools.go](https://github.com/nano-step/nano-brain/blob/main/internal/mcp/tools.go)
- [internal/mcp/streamable.go](https://github.com/nano-step/nano-brain/blob/main/internal/mcp/streamable.go)
- [internal/mcp/sse.go](https://github.com/nano-step/nano-brain/blob/main/internal/mcp/sse.go)
- [cmd/nano-brain/mcp_client_config.go](https://github.com/nano-step/nano-brain/blob/main/cmd/nano-brain/mcp_client_config.go)
- [cmd/nano-brain/claudecode_init.go](https://github.com/nano-step/nano-brain/claudecode_init.go)
- [internal/server/routes.go](https://github.com/nano-step/nano-brain/blob/main/internal/server/routes.go)
- [docs/SETUP_AGENT.md](https://github.com/nano-step/nano-brain/blob/main/docs/SETUP_AGENT.md)
</details>

# MCP Tools, Workspaces & Agent Wiring

## Purpose and Scope

nano-brain exposes a single MCP (Model Context Protocol) endpoint to AI coding agents. The MCP layer is the primary integration surface for tools such as Claude Code and OpenCode, sitting alongside — but logically independent of — the REST API defined in `internal/server/routes.go` (the REST surface is itself the subject of a separate OpenAPI proposal, see issue #530). The MCP server is intentionally implemented as a stateless Streamable HTTP transport so a single daemon process can serve many agents and many workspaces from the same URL (`http://localhost:3100/mcp`, documented in `docs/SETUP_AGENT.md`).

Within the codebase, three concerns fall under "MCP Tools, Workspaces & Agent Wiring":

1. The MCP server and its two transport implementations (`streamable.go`, `sse.go`).
2. The tool registry and the per-call workspace gate (`tools.go`).
3. The agent-side wiring helpers (`mcp_client_config.go`, `claudecode_init.go`) that produce the JSON snippets agents paste into their MCP config.

Source: [internal/mcp/server.go]()

## Server and Transport

`internal/mcp/server.go` owns request routing, JSON-RPC framing, and the lifecycle of the Streamable HTTP handler. It registers the tool list, resource list, and the request handlers that fan out into `internal/mcp/tools.go`. The server runs on the same daemon port as the REST API; MCP is mounted at `/mcp` (port 3100 by default).

Two transport implementations live alongside the core:

- `internal/mcp/streamable.go` — the default Streamable HTTP transport. It is deliberately stateless: no session affinity, no per-connection state on the daemon, and no implicit workspace binding. This is what allows one daemon to serve multiple projects.
- `internal/mcp/sse.go` — a Server-Sent Events transport kept for clients that have not yet adopted Streamable HTTP.

The stateless design has direct consequences: because the server carries no per-agent state, **the agent must identify the workspace on every request** (see next section). The trade-off is documented in `docs/SETUP_AGENT.md` and is the motivation behind open issues #522 and #523, which propose a `?workspace=...` URL query parameter to bind a default at connection time and skip per-call discovery.

## Tools and the Workspace Gate

`internal/mcp/tools.go` is where the agent-facing capability surface is defined. Each tool (e.g. `search`, `symbols`, `flow`, `impact`, `trace`) is registered with a JSON schema, a handler closure, and — for the workspace-aware tools — a call into `requireWorkspace`.

```go
// internal/mcp/tools.go:149
func requireWorkspace(args map[string]any) (string, error) { ... }
```

`requireWorkspace` is the single chokepoint enforcing the policy that "every MCP tool call must carry an explicit workspace argument." It extracts the `workspace` field from the JSON-RPC params, validates it against the daemon's registered workspace set, and returns a stable workspace key that downstream code can use to resolve a root path. If the field is missing or unknown, the call is rejected before any indexing or graph query runs. This is what makes the stateless Streamable transport usable: the per-call `workspace` parameter replaces what would otherwise be session state.

The tool handlers themselves then call into the indexing, symbol, flow, and trace subsystems to fulfill the request. A recent fix in v2026.7.0602 (PR #538, issue #535) unified the file-admission filters used by the watcher's graph-build path with the document-indexer path, so `search` and `symbols` no longer return orphan edges from files that bypass `.gitignore` / `max_file_size` checks.

## Agent Wiring and Client Configuration

The agent-side of "MCP Tools, Workspaces & Agent Wiring" lives in `cmd/nano-brain/`. Two files drive the client config story:

- `cmd/nano-brain/mcp_client_config.go` — generic JSON-snippet emitter. After `nano-brain init --root=<path>` it prints an `AgentsSnippet` containing the MCP server entry (URL, transport, env-vars). Each agent (Claude Code, OpenCode, others) has its own consumer of this snippet.
- `cmd/nano-brain/claudecode_init.go` — Claude Code-specific path. It writes the snippet into the Claude Code config file, handling the `claude_desktop_config.json` / `~/.claude.json` layout and the env-var secrets that v2026.7.0302 introduced (issue/PR #534, "minimal zero-config init").

The current flow is fully manual: `docs/SETUP_AGENT.md` Step 9 walks the user through copy-pasting JSON into each client's config. Issue #525 tracks a proposal to make this automatic after `nano-brain init` — i.e. detect the running client, write the snippet, and confirm.

## Workspace Resolution Workflow

| Stage | Where it lives | What happens |
|---|---|---|
| 1. Init | `cmd/nano-brain/claudecode_init.go`, `mcp_client_config.go` | User runs `nano-brain init --root=<path>`; daemon registers workspace and prints the `AgentsSnippet`. |
| 2. Agent connection | `internal/mcp/streamable.go` | Agent opens a stateless Streamable HTTP session to `/mcp`; no workspace yet. |
| 3. Tool call | `internal/mcp/tools.go:149` (`requireWorkspace`) | Agent passes `workspace` arg; daemon validates and resolves root. |
| 4. Query | downstream indexing / graph / trace | Tool handler executes against the resolved workspace. |
| 5. (Proposed) Default binding | open: #522, #523 | `?workspace=<id>` on `/mcp` would set the default and skip step 3. |

Source: [internal/mcp/tools.go:149](), [internal/mcp/streamable.go](), [cmd/nano-brain/claudecode_init.go](), [cmd/nano-brain/mcp_client_config.go](), [docs/SETUP_AGENT.md:172-181]()

## Known Gaps and Open Work

- **No default workspace binding** (#522, #523): every call must include `workspace`; agents without per-project config have to discover it client-side.
- **No auto-wiring** (#525): `init` does not modify any client config; the user must copy-paste.
- **No OpenAPI for the REST side** (#530): non-MCP HTTP clients have no machine-readable schema, even though `internal/server/routes.go` exposes ~60 endpoints.
- **Watcher / graph filter parity** (fixed in v2026.7.0602, #535 / PR #538): the code-graph extractor was bypassing the document-indexer file filters; agents querying `flow` / `impact` could see orphan edges. The fix unifies admission so `search`, `symbols`, and the graph tools all see the same file set.
- **CLI help** (#527): `-h` / `--help` is intercepted by Go's stdlib `flag` package before the dispatch switch in `main()` runs, so the help text shown to users wiring up agents is unhelpfully thin. This affects the very first impression of the agent-setup flow.

---

<a id='page-3'></a>

## Code Intelligence: Symbols, Graph & Impact Analysis

### Related Pages

Related topics: [MCP Tools, Workspaces & Agent Wiring](#page-2), [Architecture, Storage, Search & Operations](#page-4)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [internal/graph/registry.go](https://github.com/nano-step/nano-brain/blob/main/internal/graph/registry.go)
- [internal/graph/edge.go](https://github.com/nano-step/nano-brain/blob/main/internal/graph/edge.go)
- [internal/graph/go_extractor.go](https://github.com/nano-step/nano-brain/blob/main/internal/graph/go_extractor.go)
- [internal/graph/typescript_extractor.go](https://github.com/nano-step/nano-brain/blob/main/internal/graph/typescript_extractor.go)
- [internal/graph/python_extractor.go](https://github.com/nano-step/nano-brain/blob/main/internal/graph/python_extractor.go)
- [internal/graph/ruby_extractor.go](https://github.com/nano-step/nano-brain/blob/main/internal/graph/ruby_extractor.go)
- [internal/server/routes.go](https://github.com/nano-step/nano-brain/blob/main/internal/server/routes.go)
- [internal/mcp/tools.go](https://github.com/nano-step/nano-brain/blob/main/internal/mcp/tools.go)
</details>

# Code Intelligence: Symbols, Graph & Impact Analysis

Nano-brain's code-intelligence layer turns a workspace of source files into a queryable graph of symbols and the edges between them. It is exposed to AI agents through MCP tools (`symbols`, `flow`, `impact`, `trace`) and to any HTTP client through the REST routes registered in `internal/server/routes.go`. The system is language-aware: each supported language has its own extractor that produces normalized symbols, while a shared registry deduplicates them and a shared edge-builder derives relationships.

## Purpose and Scope

The goal of the code-intelligence subsystem is to answer three classes of agent question cheaply:

- **Where is this symbol defined?** (lookup)
- **What depends on this symbol?** (forward flow)
- **What does this symbol depend on, and what would break if it changed?** (reverse flow / impact)

To do this, the system maintains two coupled structures: a symbol registry (the nodes) and a directed edge set (the relationships). Both are written when a collection is scanned, and both are updated incrementally by the file watcher. The MCP tools are thin readers over these structures — they do not re-parse source code on each call.

The subsystem is scoped to source code. Documents, notes, and other non-code artifacts are handled by a separate document indexer and do not contribute symbols or edges.

## Architecture

The code-intelligence pipeline has three stages: **extract → register → query**.

| Stage | Component | Responsibility |
|-------|-----------|----------------|
| Extract | `go_extractor.go`, `typescript_extractor.go`, `python_extractor.go`, `ruby_extractor.go` | Parse a file and emit a flat list of symbol candidates with kind, name, file, line, and signature. |
| Register | `registry.go` | Deduplicate by stable ID, persist symbols per-collection, and own the symbol→file index. |
| Build edges | `edge.go` | Resolve references between symbols (calls, imports, type uses) into directed edges stored alongside the registry. |
| Serve | `routes.go`, `mcp/tools.go` | Expose the read-side over REST and MCP. |

```mermaid
flowchart LR
  F[Source file] --> EXT[Language extractor]
  EXT --> S[Symbol candidates]
  S --> REG[Symbol registry]
  REG --> E[Edge builder]
  E --> ED[Edge store]
  REG --> Q[MCP / REST queries]
  ED --> Q
```

The registry is per-collection, not global. A "code"-typed collection gets a symbol registry enabled; a "notes" or "docs" collection does not. This gating is what allows the watcher to decide which files to re-extract on change.

## Symbol Registry and Extractors

`internal/graph/registry.go` owns symbol storage. Each symbol has a stable identity (typically a content-derived hash of `{file, qualified-name, kind}`) so that re-extracting an unchanged file does not produce duplicate entries. The registry is the single source of truth for "does this symbol exist?" lookups used by every downstream tool.

Each language extractor normalizes its AST into the same shape so the registry and edge builder do not need to know the source language. For example:

- `go_extractor.go` emits packages, functions, methods, types, and constants from the Go AST.
- `typescript_extractor.go` covers `function`, `class`, `interface`, `type`, and exported `const`/`let`.
- `python_extractor.go` covers modules, classes, functions, and decorated callables.
- `ruby_extractor.go` covers modules, classes, methods, and constants.

The exact emitted kinds differ by language, but every record carries the same envelope: `{id, kind, name, qualified_name, file, line, signature?}`. `Source: [internal/graph/registry.go:1-120]()`

## Edges, Flow, and Impact

`internal/graph/edge.go` defines the edge model. Edges are typed (call, import, type-use, inheritance) and directed. They are derived from a second pass over each file's parse output: the extractor emits "references" alongside symbols, and the edge resolver matches references against the registry to produce edges.

Two MCP tools read this structure:

- **flow** returns forward edges from a symbol — what calls it, what imports it, what uses its type.
- **impact** returns reverse edges from a symbol — what it calls, what it imports, what types it depends on. The same structure powers "blast radius" reasoning: if the agent is about to change a function, `impact` enumerates the symbols that would need to be examined.

Both tools accept a `workspace` parameter to disambiguate which collection's registry to read. `Source: [internal/mcp/tools.go:149](internal/mcp/tools.go)` (the `requireWorkspace` guard). Trace tools combine the two: walk forward from a definition, then reverse from each call site, to produce a call chain.

## File Admission and Known Gaps

A common class of bug in this subsystem comes from **admission-filter drift**: a file is admitted into the graph pipeline even though the document indexer would have rejected it (matched by `.gitignore` / `.nano-brainignore`, exceeding `max_file_size`, or minified). When that happens, the extractor may produce zero symbols, but the edge builder can still emit "import" edges pointing into nothing — orphan edges. Agents that read `memory_trace` or `graph/symbols` then see references to files that do not exist in the symbol set, which silently poisons downstream context.

Issue #535 documented exactly this divergence between the two graph-build code paths: the startup/rescan path (`scanCollection`) correctly honored the nested ignore files, but the watcher's incremental path did not. The fix landed in v2026.7.0602 (PR #538) and unified admission so both paths use the same filter. `Source: [internal/graph/registry.go:120-200]()`

A related concern, issue #520, was that the watcher's `summarizeNotify` callback fired for every file indexed into a code collection, even when the extractor produced no symbols (e.g., JSON state caches matched by a broad glob). The gate is now keyed on "did the file yield at least one registered symbol?" rather than "was the file admitted?".

When invoking the code-intelligence tools from MCP, agents should still be defensive: an edge whose target symbol is missing is a soft signal, not a hard error. The registry is the authority on what exists.

---

<a id='page-4'></a>

## Architecture, Storage, Search & Operations

### Related Pages

Related topics: [Overview, Installation & Quick Start](#page-1), [MCP Tools, Workspaces & Agent Wiring](#page-2), [Code Intelligence: Symbols, Graph & Impact Analysis](#page-3)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [internal/storage/storage.go](https://github.com/nano-step/nano-brain/blob/main/internal/storage/storage.go)
- [internal/storage/pool.go](https://github.com/nano-step/nano-brain/blob/main/internal/storage/pool.go)
- [internal/storage/migrate.go](https://github.com/nano-step/nano-brain/blob/main/internal/storage/migrate.go)
- [internal/storage/sqlc/db.go](https://github.com/nano-step/nano-brain/blob/main/internal/storage/sqlc/db.go)
- [internal/storage/queries/search.sql](https://github.com/nano-step/nano-brain/blob/main/internal/storage/queries/search.sql)
- [internal/storage/queries/graph.sql](https://github.com/nano-step/nano-brain/blob/main/internal/storage/queries/graph.sql)
- [internal/mcp/tools.go](https://github.com/nano-step/nano-brain/blob/main/internal/mcp/tools.go)
- [internal/server/routes.go](https://github.com/nano-step/nano-brain/blob/main/internal/server/routes.go)
- [internal/watcher/watcher.go](https://github.com/nano-step/nano-brain/blob/main/internal/watcher/watcher.go)
</details>

# Architecture, Storage, Search & Operations

nano-brain is a Go-based indexing daemon that turns a local workspace into a queryable corpus for AI coding agents. It exposes the same data over two transports — a stateless MCP endpoint at `http://localhost:3100/mcp` and a JSON REST API — while persisting everything in PostgreSQL. This page covers the four moving parts: the process model, the storage layer, the search/graph pipeline, and the operations surface (file watcher, MCP, REST, CLI).

## Process & Module Model

At boot the daemon loads a workspace config (produced by `nano-brain init --root=<path>`), opens a Postgres pool, and starts two background goroutines: a file watcher and a periodic re-scanner. Tool calls from MCP clients and REST clients both funnel into the same `internal/storage` package, so the two transports never diverge in behavior. As reported in the community, every MCP tool currently requires an explicit `workspace` argument through `requireWorkspace`, because the Streamable HTTP transport is deliberately stateless and the daemon serves every project from the same shared URL. Source: [internal/mcp/tools.go:149]()

| Layer | Package | Role |
| --- | --- | --- |
| Transport | `internal/server`, `internal/mcp` | HTTP routing, MCP Streamable HTTP, REST JSON |
| Domain | `internal/indexer`, `internal/graph` | Parse, summarize, link |
| Storage | `internal/storage` | Pool, migrations, sqlc-generated queries |
| Operations | `internal/watcher`, `cmd/nano-brain` | fsnotify, CLI subcommands |

## Storage & Persistence

PostgreSQL is the single source of truth. Connection management lives in `internal/storage/pool.go`, which builds a `*sql.DB` and configures pool limits for concurrent MCP traffic. Schema versioning is handled by `internal/storage/migrate.go`, which runs idempotent `CREATE TABLE IF NOT EXISTS` migrations at startup. Source: [internal/storage/pool.go](), [internal/storage/migrate.go]()

The generated `internal/storage/sqlc/db.go` exposes typed query methods that wrap the hand-written SQL in `internal/storage/queries/*.sql`. Two files are central to the data model:

- `documents` rows hold chunked text with `(workspace, path, content, tsvector)`.
- `symbols` rows hold parsed symbols with `(workspace, file, kind, name, range)`.
- `graph_edges` rows hold directed links `(from_symbol, to_symbol, kind)`.

The repository explicitly stores the corpus, the symbol registry, and the call/import graph in the same database, which is why a single query layer (search.sql, graph.sql) can serve all three MCP tools. Source: [internal/storage/queries/search.sql](), [internal/storage/queries/graph.sql]()

## Search & Graph Layer

`search.sql` implements the `search` MCP tool: it combines PostgreSQL full-text search (`tsvector @@ websearch_to_tsquery`) with workspace scoping and a recency-weighted rank. `graph.sql` implements `flow`, `impact`, and `trace` by traversing `graph_edges` recursively with `WITH RECURSIVE` CTEs bounded by depth and visited-set to avoid cycles. Source: [internal/storage/queries/search.sql](), [internal/storage/queries/graph.sql]()

Indexing is driven by two code paths that must apply the same file-admission filters (nested `.gitignore` / `.nano-brainignore`, `max_file_size`, minified-file detection):

1. The startup/rescan path, `scanCollection`, walks the workspace and feeds documents to the text indexer.
2. The watcher path, `summarizeNotify`, re-indexes changed files in real time and also feeds the code-graph extractor.

Issue #535 documented that these two paths had drifted: the graph extractor was bypassing `.gitignore` and `max_file_size`, which produced orphan edges in `memory_trace` / `graph` / `symbols` and poisoned agent queries. The fix in v2026.7.0602 unified admission so both paths route through the same filter. Source: [internal/watcher/watcher.go](), Issue #535, PR #538

## Operations Surface

**File watcher.** `internal/watcher/watcher.go` registers an fsnotify watch per registered workspace, debounces events, and forwards the surviving set to `summarizeNotify`. After #520, the notify callback only fires summarization for files that the symbol-registry actually parses — JSON / state-cache files that match a broad glob no longer trigger wasted work. Source: [internal/watcher/watcher.go](), Issue #520

**MCP transport.** `internal/mcp/tools.go` registers the tool surface (`search`, `symbols`, `flow`, `impact`, `trace`) over Streamable HTTP. Each handler calls `requireWorkspace` to bind the request to a registered workspace, then delegates to the storage package. Community issues #522/#523 propose relaxing this to read a default workspace from a URL query parameter, which would let agents skip the per-call `workspace` argument. Source: [internal/mcp/tools.go:149](), Issue #522

**REST API.** `internal/server/routes.go` mounts ~60 routes under `/api/v1/*` plus a few top-level routes. The REST surface is independent of MCP, so any HTTP client can call it directly. Issue #530 tracks the missing OpenAPI 3.0 spec that would let non-MCP clients discover the endpoints without reading the source. Source: [internal/server/routes.go](), Issue #530

**CLI.** `cmd/nano-brain` dispatches subcommands: `init`, `start`, `scan`, `watch`, `serve`. Issue #527 reports that the stdlib `flag` package intercepts `-h` / `--help` before the dispatch switch runs, so the user sees only the six global flags and the help list is stale. A fix would route help through the same switch. Source: [cmd/nano-brain/main.go](), Issue #527

**Installer & release.** v2026.7.0303 added a `curl|bash` one-line installer with SHA256 verification, keeping npm as an alternative; v2026.7.0302 introduced a zero-config `init` that runs 0–3 probes and writes a self-documenting config with env-var secrets. Source: Release v2026.7.0303, Release v2026.7.0302

---

<!-- evidence_pipeline_checked: true -->
<!-- evidence_injected: true -->

---

## Pitfall Log

Project: nano-step/nano-brain

Summary: Found 30 structured pitfall item(s), including 0 high/blocking item(s). Top priority: Installation risk - Installation risk requires verification.

## 1. Installation risk - Installation risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this installation risk before relying on the project: Interactive MCP client auto-configuration after workspace registration
- User impact: Developers may fail before the first successful local run: Interactive MCP client auto-configuration after workspace registration
- Evidence: failure_mode_cluster:github_issue | https://github.com/nano-step/nano-brain/issues/525

## 2. Installation risk - Installation risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this installation risk before relying on the project: v2026.7.0303
- User impact: Upgrade or migration may change expected behavior: v2026.7.0303
- Evidence: failure_mode_cluster:github_release | https://github.com/nano-step/nano-brain/releases/tag/v2026.7.0303

## 3. Installation risk - Installation risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/nano-step/nano-brain/issues/535

## 4. Installation risk - Installation risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/nano-step/nano-brain/issues/525

## 5. Installation risk - Installation risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/nano-step/nano-brain/issues/523

## 6. Installation risk - Installation risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/nano-step/nano-brain/issues/520

## 7. Configuration risk - Configuration risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a configuration risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: capability.host_targets | https://github.com/nano-step/nano-brain

## 8. Configuration risk - Configuration risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this configuration risk before relying on the project: Add OpenAPI 3.0 spec for the REST API, so non-MCP clients can discover all endpoints
- User impact: Developers may misconfigure credentials, environment, or host setup: Add OpenAPI 3.0 spec for the REST API, so non-MCP clients can discover all endpoints
- Evidence: failure_mode_cluster:github_issue | https://github.com/nano-step/nano-brain/issues/530

## 9. Configuration risk - Configuration risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this configuration risk before relying on the project: CLI --help is misleading: -h/--help shows nothing useful, no-args starts a real server, help list is stale
- User impact: Developers may misconfigure credentials, environment, or host setup: CLI --help is misleading: -h/--help shows nothing useful, no-args starts a real server, help list is stale
- Evidence: failure_mode_cluster:github_issue | https://github.com/nano-step/nano-brain/issues/527

## 10. Configuration risk - Configuration risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this configuration risk before relying on the project: MCP: bind default workspace via URL query param, skip agent-side discovery
- User impact: Developers may misconfigure credentials, environment, or host setup: MCP: bind default workspace via URL query param, skip agent-side discovery
- Evidence: failure_mode_cluster:github_issue | https://github.com/nano-step/nano-brain/issues/523, failure_mode_cluster:github_issue | https://github.com/nano-step/nano-brain/issues/522

## 11. Configuration risk - Configuration risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this configuration risk before relying on the project: v2026.7.0103
- User impact: Upgrade or migration may change expected behavior: v2026.7.0103
- Evidence: failure_mode_cluster:github_release | https://github.com/nano-step/nano-brain/releases/tag/v2026.7.0103

## 12. Configuration risk - Configuration risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this configuration risk before relying on the project: v2026.7.0302
- User impact: Upgrade or migration may change expected behavior: v2026.7.0302
- Evidence: failure_mode_cluster:github_release | https://github.com/nano-step/nano-brain/releases/tag/v2026.7.0302

## 13. Capability evidence risk - Capability evidence risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: README/documentation is current enough for a first validation pass.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: capability.assumptions | https://github.com/nano-step/nano-brain

## 14. Runtime risk - Runtime risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this runtime risk before relying on the project: Benchmark: token cost of context-gathering with nano-brain vs. manual grep/read
- User impact: Developers may hit a documented source-backed failure mode: Benchmark: token cost of context-gathering with nano-brain vs. manual grep/read
- Evidence: failure_mode_cluster:github_issue | https://github.com/nano-step/nano-brain/issues/529

## 15. Maintenance risk - Maintenance risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/nano-step/nano-brain

## 16. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: downstream_validation.risk_items | https://github.com/nano-step/nano-brain

## 17. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: risks.scoring_risks | https://github.com/nano-step/nano-brain

## 18. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a security or permission risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/nano-step/nano-brain/issues/530

## 19. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a security or permission risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/nano-step/nano-brain/issues/529

## 20. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a security or permission risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/nano-step/nano-brain/issues/527

## 21. Capability evidence risk - Capability evidence risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: Developers should check this capability risk before relying on the project: watcher: gate code-summarize notify on files that actually yield symbols
- User impact: Developers may hit a documented source-backed failure mode: watcher: gate code-summarize notify on files that actually yield symbols
- Evidence: failure_mode_cluster:github_issue | https://github.com/nano-step/nano-brain/issues/520

## 22. Capability evidence risk - Capability evidence risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: Developers should check this conceptual risk before relying on the project: Harness recalibration: differential gates R90-R92, retire state file, Claude Code enforcement hook
- User impact: Developers may hit a documented source-backed failure mode: Harness recalibration: differential gates R90-R92, retire state file, Claude Code enforcement hook
- Evidence: failure_mode_cluster:github_issue | https://github.com/nano-step/nano-brain/issues/536

## 23. Runtime risk - Runtime risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: Developers should check this performance risk before relying on the project: Code-graph extractor bypasses document-indexer file filters (.gitignore, max_file_size, minified) → orphan edges poison memory_trace/graph/symbols for agents
- User impact: Developers may hit a documented source-backed failure mode: Code-graph extractor bypasses document-indexer file filters (.gitignore, max_file_size, minified) → orphan edges poison memory_trace/graph/symbols for agents
- Evidence: failure_mode_cluster:github_issue | https://github.com/nano-step/nano-brain/issues/535

## 24. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: issue_or_pr_quality=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/nano-step/nano-brain

## 25. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: release_recency=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/nano-step/nano-brain

## 26. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: Developers should check this maintenance risk before relying on the project: v2026.7.0102
- User impact: Upgrade or migration may change expected behavior: v2026.7.0102
- Evidence: failure_mode_cluster:github_release | https://github.com/nano-step/nano-brain/releases/tag/v2026.7.0102

## 27. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: Developers should check this maintenance risk before relying on the project: v2026.7.0104
- User impact: Upgrade or migration may change expected behavior: v2026.7.0104
- Evidence: failure_mode_cluster:github_release | https://github.com/nano-step/nano-brain/releases/tag/v2026.7.0104

## 28. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: Developers should check this maintenance risk before relying on the project: v2026.7.0201
- User impact: Upgrade or migration may change expected behavior: v2026.7.0201
- Evidence: failure_mode_cluster:github_release | https://github.com/nano-step/nano-brain/releases/tag/v2026.7.0201

## 29. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: Developers should check this maintenance risk before relying on the project: v2026.7.0301
- User impact: Upgrade or migration may change expected behavior: v2026.7.0301
- Evidence: failure_mode_cluster:github_release | https://github.com/nano-step/nano-brain/releases/tag/v2026.7.0301

## 30. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: Developers should check this maintenance risk before relying on the project: v2026.7.0601
- User impact: Upgrade or migration may change expected behavior: v2026.7.0601
- Evidence: failure_mode_cluster:github_release | https://github.com/nano-step/nano-brain/releases/tag/v2026.7.0601

<!-- canonical_name: nano-step/nano-brain; human_manual_source: deepwiki_human_wiki -->
