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

@andespindola/brainlink

v1.0.5

Published

Local-first knowledge memory for agents with Markdown, backlinks, indexing and context retrieval.

Readme

Brainlink

Local-first memory and knowledge graph for AI agents.

Brainlink turns a folder of Markdown files into a searchable, link-aware memory layer that agents can use before answering, planning, coding, documenting or handing work to another agent.

It is inspired by Obsidian-style knowledge bases: plain Markdown, [[wiki links]], backlinks, tags and graph navigation. The difference is that Brainlink is built for automation first: CLI, JSON output, local HTTP API and a graph frontend.

Purpose

This repository exists to give agents a durable project memory that lives outside the model context window.

Without Brainlink, an agent usually depends on:

  • the current prompt
  • the current chat history
  • files it happens to inspect in this run
  • short-lived assumptions made during a task

With Brainlink, an agent can persist and retrieve:

  • architecture decisions
  • coding conventions
  • user preferences
  • operational runbooks
  • previous investigation summaries
  • domain concepts
  • unresolved questions
  • handoff notes for other agents

The goal is not to replace the model's context window. The goal is to make the model's context window smarter by filling it with the most relevant memory before the agent acts.

How Brainlink Improves Agents

Brainlink improves agent behavior by giving them a repeatable memory workflow:

  • Less repeated discovery: agents can retrieve previous decisions instead of rediscovering the same context.
  • Better continuity: long-running projects keep memory across sessions and across different agents.
  • Grounded answers: context packages include source paths, titles, tags and relevant excerpts.
  • Safer collaboration: agent namespaces prevent private context from different agents being mixed accidentally.
  • Inspectable memory: humans can open the vault as plain Markdown or in Obsidian-like tools.
  • Automation-ready output: CLI commands support --json, so agents and external tool servers can consume stable machine-readable responses.

Why

LLMs do not have infinite context. Brainlink gives agents an external memory layer:

  1. Durable knowledge is written as Markdown.
  2. Notes are connected with [[wiki links]].
  3. Concepts are classified with #tags.
  4. Brainlink builds a local JSON index (.brainlink/index.json) and private encrypted search packs.
  5. Agents query the index before responding.
  6. Brainlink returns compact, source-backed context.

Markdown is the source of truth. .brainlink/index.json is a rebuildable index artifact. After each index run, Brainlink also writes private encrypted search packs at .brainlink/search-packs/*.blpk to preserve fast retrieval and portable recovery. Online retrieval always uses a single compression stage per pack; optional second-stage compression is reserved for offline backup artifacts only. Pack decryption uses a Brainlink key from $BRAINLINK_HOME/keys or from BRAINLINK_SEARCH_PACK_KEY when explicitly configured. Legacy .jsonl.gz packs are upgraded to .blpk automatically on first search/context access.

Features

  • Local-first Markdown vault.
  • Obsidian-compatible [[wiki links]] and #tags.
  • Weighted graph edges so agents can rank relationship importance and priority.
  • Backlinks, broken-link reports, orphan detection and validation.
  • Full-text, semantic and hybrid retrieval on a local file index.
  • Middle-out context assembly around the strongest chunk per document.
  • In-process index and context caching with automatic invalidation on index updates.
  • Optional CAG context packs at .brainlink/context-packs/*.json, derived from the current index signature and reusable across repeated context calls.
  • HTTP graph server caches generated frontend assets and graph-layout JSON payloads by signature, and skips layout serialization when ETag returns 304.
  • Compressed-space prefiltering for .blpk packs before decryption and scan.
  • Incremental indexing that reprocesses only changed markdown files and reuses existing chunks/embeddings for unchanged notes.
  • Adaptive compressed-pack rebuild policy to keep indexing fast during small edit batches.
  • Agent namespaces under agents/<agent-id>/.
  • S3-compatible bucket vaults through s3://bucket/prefix URIs.
  • CLI with machine-readable --json output.
  • Short CLI alias: blink.
  • Built-in MCP stdio server for agent tool integration.
  • Local HTTP API.
  • Realtime graph UI with agent selector and colored knowledge groups.
  • Graph renderer uses a cauliflower-style hub layout: the primary hub stays centered, segment hubs anchor surrounding lobes, and visual edges are simplified to root hub -> segment hubs -> local context nodes.
  • Real weighted [[wiki link]] edges stay preserved in the indexed graph APIs for backlinks, ranking and context traversal; the browser layout uses a separate visual edge layer for readability.
  • Graph exploration uses stable chunk streaming (/api/graph-stream) with explicit node/edge budgets, returning the full mode-level scene while it fits the budget.
  • Render pipeline uses WebGL in a dedicated worker through OffscreenCanvas, keeping the main thread focused on UI controls and details panels.
  • Large graph layout API automatically uses compact payload encoding with link-coverage-aware edge selection to reduce initial client load without hiding major relationships.
  • Large-segment layout spacing now grows logarithmically to keep initial visual density consistent between medium and very large vaults (for example, ~1k vs ~50k notes).
  • Graph coordinates are visually compacted across graph sizes so reset starts from a stable fitted scene and zoom-in progressively reveals local detail.
  • Zoomed-out graph summarizes the scene as segment hub clusters, then progressively reveals individual nodes as the user zooms in.
  • Graph reset fits the full graph scene instead of starting in a separate macro overview mode.
  • Graph filtering runs in a dedicated browser worker to keep the UI thread responsive during heavy datasets.
  • Node titles are shown as the user zooms closer, while labels remain bounded to visible on-screen nodes in very large graphs.

Install

Requirements:

  • Node.js >=22.5.0
  • npm
npm install -g @andespindola/brainlink@latest

The package installs two equivalent commands:

brainlink --help
blink --help

Use brainlink when clarity matters. Use blink for faster daily terminal usage.

The npm package page may show npm i @andespindola/brainlink. That installs Brainlink as a project dependency. Use -g when you want the terminal commands available globally, or run it without a global install:

npx @andespindola/brainlink@latest --help

Agent Autonomous Setup

This section is written for agents. If you are an AI agent operating in a user workspace, use this workflow to install and use Brainlink without requiring the user to run commands manually.

For a condensed setup path, see docs/QUICKSTART.md.

1. Check Whether Brainlink Is Installed

command -v blink || command -v brainlink

If neither command exists, install it:

npm install -g @andespindola/brainlink@latest

Then verify:

blink --help

2. Use The Default Vault Or Choose A Custom Vault

By default, Brainlink stores memory in:

$HOME/.brainlink/vault

Use the default vault when memory should span many projects:

blink init

Choose a project-local vault only when memory belongs to one repository:

BLINK_VAULT=".brainlink-vault"
blink init "$BLINK_VAULT"

You can also set BRAINLINK_HOME to move Brainlink's default home directory:

export BRAINLINK_HOME="/path/to/brainlink-home"

3. Choose An Agent Namespace

Use a stable namespace for yourself:

BLINK_AGENT="coding-agent"

Use shared only for knowledge that should be visible to every workflow.

4. Read Memory Before Acting

Before answering or changing code, retrieve context:

blink context "What should I know before working on this task?" \
  --agent "$BLINK_AGENT" \
  --json

If the context is weak, inspect raw search results:

blink search "architecture conventions tests release" \
  --agent "$BLINK_AGENT" \
  --mode hybrid \
  --limit 10 \
  --json

5. Write Durable Memory After Learning Something Useful

Only store knowledge that is likely to matter later:

blink add "Testing Policy" \
  --agent "$BLINK_AGENT" \
  --content $'Run npm run check before final delivery. #testing #process\n\n## Context Links\n\n- [[Release Checklist]]'

Brainlink does not infer durable graph relationships from generated context. A context result is only a read package for the model. To create a real graph link, write a concise ## Context Links section and put the canonical [[Note Title]] links there.

Writes with blink add reindex the vault automatically by default. This can be disabled with --no-auto-index and controlled globally with autoIndexOnWrite in brainlink.config.json.

When adding memory, follow this contract:

  • Link the new note to existing notes through ## Context Links when there is a related concept.
  • Use the exact target note title inside [[...]].
  • Add retrieval tags such as #architecture, #decision, #runbook or #preference.
  • General wiki-link mentions outside ## Context Links remain searchable Markdown content, but they do not become graph edges.

If you disable auto-index, run blink index after batched writes.

6. Validate Memory Health

blink validate --agent "$BLINK_AGENT" --json
blink broken-links --agent "$BLINK_AGENT" --json
blink orphans --agent "$BLINK_AGENT" --json

Agent Operating Loop

Use this loop during real work:

  1. Identify the task and choose BLINK_AGENT.
  2. Run blink context "<task>" --agent "$BLINK_AGENT" --json.
  3. Use returned sources as project memory.
  4. Perform the task.
  5. Save only durable learnings with blink add, including [[wiki links]] to related notes.
  6. Run blink index only when auto-index was disabled during a batch.
  7. Validate with blink validate, blink broken-links and blink orphans when graph links matter.

Do not store secrets, credentials, private keys, access tokens or transient chat noise.

Quick Start

blink init ./vault

blink add "Architecture" \
  --vault ./vault \
  --content "Brainlink keeps Markdown as source of truth. #architecture"

blink add "Auth Decision" \
  --vault ./vault \
  --content "We chose JWT for API clients. [[Architecture]] #auth #jwt"

blink search "jwt auth" --vault ./vault

blink context "how does auth work?" --vault ./vault

blink server --vault ./vault

Open the graph UI:

http://127.0.0.1:4321

When --vault is omitted, commands use the default vault at $HOME/.brainlink/vault. Pass --vault or configure vault in brainlink.config.json when you want a custom project-local vault.

Bucket Vaults

Brainlink can use an S3-compatible bucket as the Markdown source of truth:

export AWS_REGION="us-east-1"
export AWS_ACCESS_KEY_ID="..."
export AWS_SECRET_ACCESS_KEY="..."

blink add "Architecture" \
  --vault "s3://my-memory-bucket/brainlink" \
  --content "Bucket Markdown is the source of truth. #architecture"

blink index --vault "s3://my-memory-bucket/brainlink"
blink context "architecture" --vault "s3://my-memory-bucket/brainlink"

For Cloudflare R2, MinIO or another S3-compatible endpoint:

export BRAINLINK_S3_ENDPOINT="https://<account-id>.r2.cloudflarestorage.com"
export BRAINLINK_S3_FORCE_PATH_STYLE=1

Bucket vaults mirror Markdown into a local cache under $BRAINLINK_HOME/bucket-cache. The bucket remains canonical; the local .brainlink/index.json stays a disposable index artifact. Run index after remote bucket changes before relying on search, context, graph or validation commands. Watch mode is only supported for local filesystem vaults.

Core Model

vault/
  agents/
    shared/
      architecture.md
    coding-agent/
      implementation-policy.md
    research-agent/
      source-review-policy.md
  .brainlink/
    index.json

Permanent data:

  • Markdown notes
  • optional Git history around the vault

Rebuildable data:

  • .brainlink/index.json
  • full-text records
  • local embedding vectors
  • local embedding buckets
  • chunks
  • resolved links
  • backlinks

Agent Namespaces

Brainlink separates memory by agent so multiple agents can use the same CLI without mixing private context.

Use shared for project-wide memory:

blink add "Project Rules" \
  --vault ./vault \
  --agent shared \
  --content "All agents should run tests before final answers. #process"

Use a dedicated namespace for private agent memory:

blink add "TypeScript Policy" \
  --vault ./vault \
  --agent coding-agent \
  --content "Prefer explicit types and functional core boundaries. [[Project Rules]] #typescript"

List indexed namespaces:

blink agents --vault ./vault
blink agents --vault ./vault --json

Query a single namespace:

blink search "typescript" --vault ./vault --agent coding-agent --json
blink search "authentication token policy" --vault ./vault --agent coding-agent --mode semantic --json
blink context "how should I change this module?" --vault ./vault --agent coding-agent
blink graph --vault ./vault --agent coding-agent --json

Link resolution is scoped:

  1. same agent namespace
  2. shared
  3. unresolved link

This allows coding-agent and research-agent to both have a note named Architecture without contaminating each other's private memory.

MCP Server Integration

Brainlink ships a stdio MCP server with the npm package:

brainlink-mcp

Example MCP client configuration:

{
  "mcpServers": {
    "brainlink": {
      "command": "brainlink-mcp"
    }
  }
}

One-Command Agent Setup

If your agent runtime is Codex-compatible, run:

blink agent install --self-test
blink agent upgrade

This configures ~/.codex/config.toml with Brainlink MCP (brainlink-mcp) so Brainlink is available by default in agent sessions. agent install and agent upgrade also apply the MCP fully-auto bootstrap policy by default (enforceBootstrap, enforceContextFirst, autoBootstrapOnRead, autoBootstrapOnStartup all enabled).

If you are inside this repository and want plugin gallery setup too:

blink agent install --plugin-path ./plugins/brainlink

To verify:

blink agent status

For fully automated first run (vault index + health + bootstrap readiness + agent integration):

blink quickstart --query "what should I know before this task?" --json

For a locked-down setup, allowlist the vaults that MCP clients may access:

{
  "mcpServers": {
    "brainlink": {
      "command": "brainlink-mcp",
      "env": {
        "BRAINLINK_ALLOWED_VAULTS": "/absolute/path/to/project-vault,/absolute/path/to/team-vault"
      }
    }
  }
}

Install In MCP Client Stores

Brainlink can be exposed to MCP-compatible client stores in two ways:

  1. Register the stdio server directly when the client accepts mcpServers configuration.
  2. Register the local plugin from this repository when the client supports a plugin gallery or local marketplace.

Direct MCP server setup:

npm install -g @andespindola/brainlink@latest
command -v brainlink-mcp

Use this server configuration in any MCP-compatible client that reads a JSON MCP manifest:

{
  "mcpServers": {
    "brainlink": {
      "command": "brainlink-mcp"
    }
  }
}

Local plugin gallery setup:

npm install -g @andespindola/brainlink@latest
git clone https://github.com/andersonflima/brainlink.git "$HOME/brainlink"
mkdir -p "$HOME/plugins"
ln -s "$HOME/brainlink/plugins/brainlink" "$HOME/plugins/brainlink"

Then register the plugin in the local marketplace file used by compatible clients:

node <<'NODE'
const fs = require('node:fs')
const os = require('node:os')
const path = require('node:path')

const marketplacePath = path.join(os.homedir(), '.agents', 'plugins', 'marketplace.json')
const pluginEntry = {
  name: 'brainlink',
  source: {
    source: 'local',
    path: './plugins/brainlink'
  },
  policy: {
    installation: 'AVAILABLE',
    authentication: 'ON_INSTALL'
  },
  category: 'Productivity'
}

fs.mkdirSync(path.dirname(marketplacePath), { recursive: true })

const marketplace = fs.existsSync(marketplacePath)
  ? JSON.parse(fs.readFileSync(marketplacePath, 'utf8'))
  : {
      name: 'local',
      interface: {
        displayName: 'Local'
      },
      plugins: []
    }

const plugins = Array.isArray(marketplace.plugins) ? marketplace.plugins : []
marketplace.plugins = [...plugins.filter((plugin) => plugin?.name !== 'brainlink'), pluginEntry]

fs.writeFileSync(marketplacePath, `${JSON.stringify(marketplace, null, 2)}\n`)
NODE

Restart the client after changing marketplace or MCP configuration so it reloads the Brainlink entry. The plugin starts brainlink-mcp and exposes the same tool set listed below.

Available tools:

  • brainlink_bootstrap: plug-and-play entrypoint that runs index + health checks and can return context in one call.
  • brainlink_policy: read or update bootstrap/context-first policy, including presets (preset: "fully-auto" | "strict").
  • brainlink_recommendations: return an automatic action plan so agents can run Brainlink in the recommended order, including RAG/CAG context strategy guidance.
  • brainlink_context: read indexed context for a task or question; pass strategy: "rag" for fresh retrieval assembly, strategy: "cag" for persisted context packs or strategy: "auto" for CAG hits with RAG fallback.
  • brainlink_context_packs: list or clear persisted CAG context packs.
  • brainlink_search: search indexed notes.
  • brainlink_explain: explain why indexed notes matched a query.
  • brainlink_dedupe: detect duplicate candidates using exact hash + semantic similarity scores.
  • brainlink_resolve_duplicate: resolve duplicate pairs (merge, link, ignore) with connectivity-safe fallback edges.
  • brainlink_add_note: write durable Markdown memory and reindex.
  • brainlink_remember: capture durable memory with inferred title, tags and Context Links; supports dry-run.
  • brainlink_inbox_add: capture a quick untriaged memory item.
  • brainlink_inbox_list: list untriaged inbox memory items.
  • brainlink_inbox_process: suggest titles, tags and links for inbox items.
  • brainlink_delete_note: delete a durable Markdown note by title or path after explicit confirmation and reindex.
  • brainlink_add_file: ingest a local file as a note and reindex.
  • brainlink_canonicalize_context_links: ensure existing notes link to inferred context hubs.
  • brainlink_volatile_add: write temporary agent-decided memory with TTL; volatile sections are included in context and never create durable graph edges.
  • brainlink_volatile_clear: clear temporary memory for the current vault/agent namespace.
  • brainlink_index: rebuild the vault index. Pass full=true for a complete source reindex.
  • brainlink_stats: read indexed vault statistics.
  • brainlink_doctor_actions: return vault checks plus prioritized executable next actions.
  • brainlink_validate: validate broken links and orphan notes.
  • brainlink_sync: run index, stats, validation, broken-link and orphan checks in one call.
  • brainlink_graph: read indexed graph nodes and weighted links.
  • brainlink_graph_contexts: list the visual graph contexts used by the local server.
  • brainlink_broken_links: list unresolved wiki links.
  • brainlink_suggest_links: suggest Context Links for content or fixes for unresolved wiki links.
  • brainlink_repair_links: repair unresolved wiki links by retargeting safe matches or creating placeholder target notes.
  • brainlink_orphans: list disconnected notes.
  • brainlink_session_close: write or preview a session handoff note.
  • brainlink_project_init: seed project memory from local project docs.

For the most automatic workflow, start MCP sessions with brainlink_bootstrap (optionally with query) and then continue with brainlink_context/brainlink_add_note. MCP is kept in parity with practical Brainlink CLI workflows when a feature is safe and meaningful for tool clients. By default, Brainlink enforces context-first for MCP reads (enforceContextFirst=true): non-context read tools return preflight until brainlink_context is called for the vault/agent session. By default, MCP startup already runs bootstrap on the configured default vault/agent (autoBootstrapOnStartup=true), so sessions begin warm. By default, Brainlink enforces bootstrap and auto-runs it for read tools when session state is missing or stale (autoBootstrapOnRead=true). If you disable autoBootstrapOnRead through brainlink_policy, read tools return a preflight instruction with suggested brainlink_bootstrap arguments. brainlink_bootstrap, brainlink_policy and preflight responses include structured nextActions so MCP clients can continue automatically without custom parsing. For one-call planning, use brainlink_recommendations to get the recommended tool sequence for the current vault/agent/query. The MCP context tools are plug-and-play by default: omit strategy to use the configured token-efficient default (auto unless changed), pass strategy: "cag" for repeated/stable task context, or pass strategy: "rag" when fresh retrieval is required. brainlink_recommendations, preflight responses and policy next actions include executable context arguments so clients can continue without custom parsing.

The same linking rule applies through MCP: brainlink_context is read-only, and real graph links require Markdown notes with explicit ## Context Links sections. brainlink_add_note and brainlink_add_file reindex by default and include index + writeConnectivity metadata. Brainlink does not auto-link new notes to fallback hubs.

Agents can raise the importance of a relationship by putting priority markers on the same line as a wiki link:

- [ ] Review [[Architecture]] priority: high
Related: [[Incident Runbook]] #critical

Indexed edges expose weight and priority (low, normal, high, critical) through CLI JSON, HTTP graph APIs and brainlink_graph. Brainlink indexes every non-self [[wiki link]] inside ## Context Links as a graph edge. Old indexes are rebuilt automatically when their graph link model version is missing or stale.

To migrate older vaults without deleting existing Markdown, generate concise context-link sections from current wiki-link mentions:

blink migrate-context-links --vault ./vault --limit 5
blink index --vault ./vault --full

Graph UI

Start the local frontend:

blink server --host 127.0.0.1 --port 4321

By default, the server uses $HOME/.brainlink/vault. Pass --vault ./vault only when you want to inspect a custom vault. By default, the server watches Markdown files in local filesystem vaults and reindexes after note changes. Use --no-watch to disable realtime reindexing. By default, blink server tries to open the graph in a native desktop GUI window:

  • macOS: Swift + WebKit
  • Windows: PowerShell WinForms WebBrowser
  • Linux: optional Python GTK + WebKit2 (requires python3 + gi + WebKit2)

On Linux, native GUI is disabled by default for better startup performance. Enable it with BRAINLINK_LINUX_NATIVE_GUI=1. If native GUI launch is unavailable on your system, it falls back to dedicated app-window mode and then to the default browser. For Chromium-family browsers on Linux (chromium, chromium-browser, google-chrome, microsoft-edge, brave-browser), Brainlink now auto-applies compatibility flags during launch (--ozone-platform=x11, --ozone-platform-hint=x11, --disable-gpu, --disable-vulkan, --use-gl=swiftshader, --disable-features=Vulkan,VaapiVideoDecoder, --disable-background-networking) to avoid common Wayland/Vulkan/VAAPI startup issues. On Linux, Brainlink opens the graph through the system default browser first (xdg-open), then $BROWSER/detected browsers as fallback. Chromium-family app-window mode is optional via BRAINLINK_LINUX_APP_WINDOW=1. Use --no-open to keep it headless. When native GUI is used, the GUI window automatically closes when the blink server process stops.

The graph UI shows:

  • notes as nodes
  • all non-self [[wiki links]] inside ## Context Links as weighted indexed edges
  • default cauliflower-style visual layout centered on the primary hub, with segment hubs anchoring surrounding lobes and visual edges simplified to root hub -> segment hubs -> local context nodes
  • details opened in a non-modal side panel (tags, outgoing links, backlinks, full Markdown content), so zoom and pan remain available while inspecting data
  • neutral graph nodes with segment/group metadata
  • agent selector (id-only labels) for isolated views
  • context selector for segment-scoped cauliflower subgraphs derived from the visual graph context
  • graph filter matches title, path, tags and note content
  • graph filter keeps hub context nodes visible (Memory Hub/MOC/high-degree fallback) to preserve relationship readability
  • realtime refresh while watch mode is enabled
  • graph controls for zoom in, zoom out, fit visible nodes and reset-to-fit-all
  • wheel zoom (including cmd+scroll and ctrl+scroll) anchored to cursor position for faster navigation in large graphs
  • wheel/button zoom updates immediately at the cursor anchor without delayed focus-transition interpolation
  • Bloom-like scene navigation: reset fits the current graph scene, wheel zoom stays anchored to the cursor, and worker-driven WebGL rendering keeps pan/zoom interaction responsive
  • zoom-out cluster mode that shows segment hub clusters first, then reveals local nodes as zoom increases
  • keyboard shortcuts: + zoom in, - zoom out, 0 reset fit
  • click on a node opens its details panel; double-click on empty canvas zooms in at cursor position
  • floating graph totals (notes, links, tags) below the Brainlink title
  • graph rendering safeguards (batched GPU draw calls, lower redraw rate, zoom-aware interaction)
  • adaptive CPU safeguards for large graphs: idle frame pacing, throttled background physics updates and cached viewport dimensions to reduce redraw/layout overhead while preserving interaction responsiveness
  • worker-first WebGL rendering with Canvas fallback when OffscreenCanvas or worker rendering is unavailable
  • large graph view keeps one indexed graph model across zoom levels, uses a stable visual hierarchy for rendering, uses segment clusters at high zoom-out, and shows node titles as zoom approaches readable scale

The server indexes before starting by default. Use --no-index to skip that step:

blink server --vault ./vault --no-index

HTTP API

The HTTP API is mostly read-oriented and exists to power the graph UI, local inspection workflows and the local document-import modal.

The server always refuses non-loopback hosts. Brainlink HTTP only runs on localhost.

Routes:

  • GET /api/agents
  • GET /api/graph-contexts
  • GET /api/graph
  • GET /api/graph-layout
  • GET /api/graph-view?x=<x>&y=<y>&w=<width>&h=<height>&scale=<scale>
  • GET /api/graph-stream?x=<x>&y=<y>&w=<width>&h=<height>&scale=<scale>&nodeBudget=<n>&edgeBudget=<n>
  • GET /api/graph-node?id=<node-id>
  • GET /api/search?q=<query>&limit=8&mode=hybrid
  • GET /api/context?q=<query>&limit=8&tokens=1500&mode=hybrid
  • GET /api/links
  • GET /api/backlinks?title=<title>
  • GET /api/stats
  • GET /api/broken-links
  • GET /api/orphans
  • GET /api/validate
  • POST /api/import-file with multipart field file

Read routes accept agent=<agent-id>:

/api/graph-layout?agent=coding-agent
/api/graph-layout?agent=coding-agent&context=Architecture
/api/search?q=typescript&agent=coding-agent&mode=hybrid
/api/context?q=module-boundaries&agent=coding-agent&mode=semantic

CLI Reference

Every command works with either brainlink or blink.

agent

blink agent install
blink agent install --self-test
blink agent upgrade
blink agent policy --preset fully-auto
blink agent policy --preset strict
blink agent policy --enforce-context-first false
blink agent install --plugin-path ./plugins/brainlink
blink agent install --mcp-only --allowed-vaults "/absolute/vault,/absolute/team-vault"
blink agent status

Installs/checks agent integration. install writes Brainlink MCP config into ~/.codex/config.toml. When plugin files are available, it also links Brainlink plugin files into ~/plugins/brainlink and updates ~/.agents/plugins/marketplace.json. With --self-test, install also validates MCP block presence, command wiring and local plugin registration signals. Use agent upgrade on legacy installations to reapply current defaults and run the same self-test diagnostics. Use agent policy --preset fully-auto for plug-and-play defaults, or agent policy --preset strict to require explicit bootstrap calls. Both presets keep enforceContextFirst=true so Brainlink stays the primary context source for MCP sessions.

quickstart

blink quickstart --json
blink quickstart --vault ./team-vault --agent coding-agent --query "architecture decisions" --json
blink quickstart --vault ./team-vault --mcp-only --json

Runs index + doctor + stats + validation, refreshes bootstrap session readiness, optionally returns context for a query, and (by default) upgrades local agent integration for plug-and-play MCP usage. When --mode, --limit or --tokens are omitted, quickstart uses agent profile defaults when available.

Practical Memory Workflows

blink remember --content "Keep Markdown as the source of truth. #architecture"
blink remember --content-file ./handoff.md --dry-run
blink inbox add --content "Quick note to triage later"
blink inbox list
blink inbox process --json
blink session-close --content "Validated release flow"
blink daily --dry-run
blink suggest-links --content "Architecture and release flow"
blink suggest-links --broken
blink repair-links
blink search "architecture" --explain
blink explain "architecture"
blink doctor --actionable
blink project init --path .

remember infers a title, tags and Context Links before writing a durable note. inbox captures quick untriaged memory and later suggests titles, tags and links. session-close/daily writes a handoff note with vault health and git status. suggest-links proposes Context Links or likely fixes for unresolved wiki links. repair-links retargets high-confidence broken links and creates #triage placeholder notes for unresolved targets that cannot be safely retargeted. doctor --actionable returns prioritized commands instead of only checks. project init seeds memory from project docs such as AGENTS.md, README.md and architecture docs.

config

blink config where
blink config get vault
blink config doctor
blink config doctor --fix
blink config set-vault /absolute/path/to/existing-vault
blink config set-vault /absolute/path/to/existing-vault --migrate-from ~/.brainlink/vault
blink config set-vault "s3://my-memory-bucket/brainlink" --global

config set-vault writes configuration through CLI (no manual file edits required).
By default it writes local config (./brainlink.config.json), appends the vault to allowedVaults, and migrates Markdown memory from the current configured vault when the target is empty.
When the configured default vault is changed manually in config files, Brainlink also performs automatic migration on the next command that uses the configured vault (without explicit --vault). Use --global to write to $BRAINLINK_HOME/brainlink.config.json, --no-migrate to skip migration, and --no-index to skip post-migration indexing. config doctor is dry-run by default; use --fix to apply safe config normalization and allowlist fixes.

vaults

blink vaults list
blink vaults list --json
blink vaults use /absolute/path/to/vault
blink vaults use /absolute/path/to/vault --global
blink vaults delete /absolute/path/to/vault --yes
blink vaults delete /absolute/path/to/vault --yes --prune-config

Lists known vaults from the configured default, allowedVaults, and the built-in default at $HOME/.brainlink/vault. vaults use chooses the default vault without migrating memory; use migrate-vault or config set-vault --migrate-from when you want to copy Markdown memory between vaults. vaults delete only deletes local filesystem vaults, requires --yes, refuses bucket vaults, and refuses deleting the current default vault. Choose another default first with vaults use.

delete-note

blink delete-note --title "Architecture" --yes
blink delete-note --path agents/shared/architecture.md --yes
blink delete-note --title "Architecture" --agent coding-agent --yes
blink delete-note --path agents/shared/architecture.md --yes --no-auto-index

Deletes a durable Markdown note from the selected vault. The command requires --yes, accepts exactly one selector (--title or --path), refuses non-Markdown/protected paths, and reindexes by default. Bucket vault note deletion is intentionally refused until provider-native object deletion is implemented safely.

migrate-vault

blink migrate-vault --from ~/.brainlink/vault --to ./team-vault --dry-run
blink migrate-vault --from ~/.brainlink/vault --to ./team-vault
blink migrate-vault --from ~/.brainlink/vault --to "s3://my-memory-bucket/brainlink"
blink migrate-vault --from ~/.brainlink/vault --to ./team-vault --report ./migration-report.json

Runs explicit markdown migration between vaults while preserving conflicts as .conflict-<timestamp> files.
Use --dry-run to preview copied, conflicted and unchanged counts before writing.

db-import

blink db-import --vault ./team-vault
blink db-import --vault ./team-vault --db ./legacy/brainlink.db
blink db-import --vault ./team-vault --db ./legacy/brainlink.db --table legacy_notes --dry-run

Imports durable memory from a legacy SQLite database into Markdown notes (agents/<agent-id>/*.md) and reindexes by default. When --db is omitted, Brainlink auto-detects common legacy paths such as <vault>/.brainlink/brainlink.db. Use --agent <id> to force all imported rows into one namespace, --limit for incremental imports, --dry-run to preview without writing files, and --no-index to defer reindexing.

import-file

blink import-file ./report.pdf --vault ./team-vault
blink import-file ./report.pdf --vault ./team-vault --agent coding-agent
blink import-file ./report.pdf --vault ./team-vault --title "Quarterly Report"
blink import-file ./report.pdf --vault ./team-vault --no-auto-index

Converts a document with Docling and imports the converted Markdown as a durable note. The docling executable must be installed and available in PATH. The graph UI exposes the same flow through the upload button in the toolbar.

init

blink init
blink init ./vault
blink init ./team-vault --migrate-from ~/.brainlink/vault

Initializes vault metadata. Without an argument, Brainlink initializes the default vault at $HOME/.brainlink/vault. When initializing an empty custom vault, existing Markdown content from the default vault is copied into it and reindexed so context is not left behind. Use --no-migrate-existing to start with an empty custom vault, or --migrate-from <vault> to copy from a specific source. Existing target files are never overwritten; conflicting source files are preserved with a .conflict-<timestamp> suffix.

add

blink add "Note Title" --agent coding-agent --content "Markdown content"
blink add "Note Title" --vault ./vault --agent coding-agent --content "Markdown content"
blink add "Note Title" --vault ./vault --content-file ./notes.md
blink add "Note Title" --vault ./vault --content-file ./notes.md --no-auto-index

--content and --content-file are mutually exclusive. Add --no-auto-index when you want to defer reindexing.

Creates a Markdown note under agents/<agent-id>/. Common secret patterns are blocked by default; use --allow-sensitive only for an intentionally protected vault. To avoid disconnected memory, Brainlink auto-adds a fallback wiki edge when a note is written without links, creating agent hub notes when needed. add also returns possibleDuplicates (exact hash + semantic candidates) so agents can resolve duplicate memory right after writes.

dedupe

blink dedupe --vault ./vault --json
blink dedupe --vault ./vault --agent coding-agent --limit 20 --min-score 0.92 --json
blink dedupe --vault ./vault --no-semantic --json

Detects possibleDuplicate pairs using exact content hashes and optional semantic similarity.

dedupe-resolve

blink dedupe-resolve --vault ./vault --left agents/shared/a.md --right agents/shared/b.md --action merge --json
blink dedupe-resolve --vault ./vault --left agents/shared/a.md --right agents/shared/b.md --action link --json
blink dedupe-resolve --vault ./vault --left agents/shared/a.md --right agents/shared/b.md --action ignore --json

Resolves a duplicate pair with merge, link or ignore. When action is not merge, Brainlink still creates a low-priority related edge (#related-to) so notes remain connected.

index

blink index
blink index --vault ./vault
blink index --vault ./vault --full

Rebuilds the local index from Markdown files. By default, unchanged notes reuse existing indexed chunks for speed. Use --full to force a complete source reindex of every Markdown note. Full reindex builds the replacement index before persisting it, so existing context is not cleared first. Brainlink also performs this complete source reindex automatically when it detects that the stored graph link model is older than the current model.

bench

blink bench --vault ./vault
blink bench --vault ./vault --watch
blink bench --vault ./vault --watch --debounce 500
blink bench --vault ./vault --json

Runs indexing with realtime phase telemetry (start, scan, parse, embed, persist, packs, complete) and prints a benchmark summary at the end of each run.

Summary includes compression behavior for .blpk packs when rebuild happens:

  • pack rebuild reason
  • pack count and pack build duration
  • uncompressed input bytes vs compressed output bytes
  • saved percentage
  • objective guardrails (minimum savings and maximum latency regression thresholds)

Use --watch to keep benchmarking incremental reindex runs after Markdown changes (local filesystem vaults only). When .brainlink/search-packs/manifest.json is missing but .blpk files exist, Brainlink repairs the manifest first and avoids unnecessary full pack rebuild on small edits.

pack-backup

blink pack-backup --vault ./vault
blink pack-backup --vault ./vault --output ./vault/.brainlink/backups/custom.blpkbak.gz
blink pack-backup --vault ./vault --json

Creates an offline backup artifact of encrypted search packs with a second compression pass. This is intentionally outside the online retrieval path (index, search, context).

agents

blink agents --vault ./vault
blink agents --vault ./vault --json

Lists indexed agent namespaces.

search

blink search "query" --vault ./vault --limit 10
blink search "query" --vault ./vault --agent coding-agent --json
blink search "query" --vault ./vault --mode semantic --json

Runs retrieval over indexed chunks. If --mode or --limit is omitted, Brainlink resolves values from the current agent profile before falling back to global defaults.

Modes:

  • hybrid: default; combines lexical matching with local embedding similarity.
  • fts: exact lexical retrieval from the file index.
  • semantic: local deterministic embedding similarity only.

Hybrid results are cached in-memory for a short TTL and invalidated automatically when the local index file changes. Context selection uses a middle-out strategy: it starts from the strongest chunk in a note and expands to neighboring chunks while respecting token budget.

context

blink context "question" --vault ./vault --limit 8 --tokens 1500
blink context "question" --vault ./vault --agent coding-agent --json
blink context "question" --vault ./vault --agent coding-agent --mode hybrid --json
blink context "question" --vault ./vault --agent coding-agent --strategy cag --json
blink context "question" --vault ./vault --agent coding-agent --strategy auto --json
blink context-packs --vault ./vault --json
blink context-packs --vault ./vault --stale --clear

Builds a compact context package for an agent. Repeated calls with the same vault, agent, query, mode and token/limit settings are served from a short in-memory cache while the index is unchanged. The default strategy is configured by defaultContextStrategy and starts as auto, which uses CAG when a fresh pack exists and RAG otherwise, refreshing a pack for future calls. --strategy cag enables cache-augmented context generation by reading or refreshing a persisted context pack under .brainlink/context-packs; --strategy rag forces fresh retrieval assembly from the current index. Context responses include cache, metrics, requestedStrategy and recommendedStrategy metadata. Packs are derived artifacts and become stale when the index or volatile memory signature changes.

links

blink links --vault ./vault
blink links --vault ./vault --agent coding-agent

Lists indexed wiki links. JSON output includes weight and priority for each relationship.

backlinks

blink backlinks "Architecture" --vault ./vault
blink backlinks "Architecture" --vault ./vault --agent coding-agent

Lists notes pointing to a target title, ordered by strongest relationship first. JSON output includes weight and priority.

graph

blink graph --vault ./vault --json
blink graph --vault ./vault --agent coding-agent --json

Prints indexed graph data. Edges include weight and priority so agents can categorize importance.

stats

blink stats --vault ./vault
blink stats --vault ./vault --agent coding-agent --json
blink stats --vault ./vault --agent coding-agent --extended --json

Prints vault metrics. Use --extended to include storage footprint, link quality ratios and observability probes (index, search, context latencies).

broken-links

blink broken-links --vault ./vault

Lists unresolved wiki links.

orphans

blink orphans --vault ./vault

Lists notes without incoming or outgoing links.

validate

blink validate --vault ./vault

Validates graph health. The command exits non-zero when required checks fail.

doctor

blink doctor --vault ./vault

Runs environment and vault checks. When vault has zero markdown and zero indexed documents, doctor prints recommended next steps (add note, inspect config source, migrate memory).

watch

blink watch --vault ./vault

Watches Markdown files and rebuilds the index when notes change.

canonicalize-context-links

blink canonicalize-context-links --vault ./vault --dry-run
blink canonicalize-context-links --vault ./vault

Ensures existing notes have canonical ## Context Links entries to inferred context hubs such as User Preferences Hub, GitHub Repositories Hub or Brainlink Hub. The command is idempotent, creates missing hub notes by default, and fully reindexes after writes unless --no-index is passed.

server

blink server
blink server --vault ./vault
blink server --vault ./vault --no-open
blink server --vault ./vault --no-watch

Starts the local graph UI and HTTP API. Watch mode is enabled by default for Markdown changes in local filesystem vaults. Use --no-watch to run without the watcher. By default, it tries to open a native desktop GUI window for the graph URL. On Linux, native GUI is disabled by default; enable it with BRAINLINK_LINUX_NATIVE_GUI=1. If native GUI launch is unavailable, it falls back to dedicated app-window mode and then browser open. When fallback opens Chromium-family browsers on Linux, Brainlink automatically uses compatibility launch flags for stable rendering on Ubuntu/Wayland setups. Use --no-open to skip that behavior.

The HTTP server only binds to loopback hosts such as 127.0.0.1, localhost or ::1.

Machine-Readable Output

Commands with finite output support --json:

blink context "question" --vault ./vault --agent coding-agent --json

When running through npm scripts, use --silent to keep stdout clean:

npm run --silent dev -- context "question" --vault ./vault --json

Configuration

Brainlink merges configuration in this order:

  1. Global: $BRAINLINK_HOME/brainlink.config.json (or $HOME/.brainlink/brainlink.config.json by default)
  2. Local: brainlink.config.json in the current working directory
  3. Local legacy compatibility: .brainlink.json in the current working directory

If no vault is configured and no --vault flag is passed, Brainlink uses $HOME/.brainlink/vault.

{
  "vault": ".brainlink-vault",
  "host": "127.0.0.1",
  "port": 4321,
  "allowedVaults": [".brainlink-vault"],
  "defaultAgent": "shared",
  "autoIndexOnWrite": true,
  "autoCanonicalContextLinks": true,
  "defaultSearchLimit": 8,
  "defaultContextTokens": 1500,
  "defaultContextStrategy": "auto",
  "embeddingProvider": "local",
  "defaultSearchMode": "hybrid",
  "chunkSize": 1200,
  "searchPack": {
    "rowChunkSize": 5000,
    "compressionLevel": 5,
    "useDictionary": true,
    "guardrailMinSavingsPercent": 8,
    "guardrailMaxLatencyRegressionPercent": 5
  },
  "agentProfiles": {
    "coding-agent": {
      "defaultSearchMode": "semantic",
      "defaultSearchLimit": 8,
      "defaultContextTokens": 1500,
      "defaultContextStrategy": "auto"
    },
    "*": {
      "defaultSearchMode": "hybrid"
    }
  }
}

defaultAgent is optional. When set, CLI and MCP calls that omit --agent/agent use this value automatically. If not set, behavior remains as before. agentProfiles is optional. When present, CLI and MCP resolve mode, limit, tokens and context strategy per agent automatically, then fallback to global defaults.

autoIndexOnWrite is optional and defaults to true. Set it to false to defer indexing after writes. autoCanonicalContextLinks is optional and defaults to true. When enabled, blink add, brainlink_add_note and brainlink_add_file add a canonical ## Context Links entry to the inferred context hub, creating that hub when needed.

Remote MCP Server

Brainlink can run as a centralized MCP service for clustered workloads. This keeps one shared memory service inside the cluster while applications and agents connect to the MCP endpoint over Streamable HTTP.

BRAINLINK_MCP_TOKEN="change-me" brainlink mcp-server \
  --vault /data/vault \
  --host 0.0.0.0 \
  --port 3333 \
  --path /mcp

The server exposes:

POST /mcp      MCP Streamable HTTP endpoint
GET /healthz  liveness probe
GET /readyz   readiness probe

When BRAINLINK_MCP_TOKEN or --token is set, MCP requests must include:

Authorization: Bearer <token>

For Kubernetes, run Brainlink as a central Deployment with a Service and a mounted vault volume:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: brainlink-mcp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: brainlink-mcp
  template:
    metadata:
      labels:
        app: brainlink-mcp
    spec:
      containers:
        - name: brainlink
          image: brainlink:latest
          args: ["brainlink", "mcp-server", "--vault", "/data/vault", "--host", "0.0.0.0", "--port", "3333"]
          env:
            - name: BRAINLINK_MCP_TOKEN
              valueFrom:
                secretKeyRef:
                  name: brainlink-mcp
                  key: token
          ports:
            - containerPort: 3333
          readinessProbe:
            httpGet:
              path: /readyz
              port: 3333
          livenessProbe:
            httpGet:
              path: /healthz
              port: 3333
          volumeMounts:
            - name: vault
              mountPath: /data/vault
      volumes:
        - name: vault
          persistentVolumeClaim:
            claimName: brainlink-vault
---
apiVersion: v1
kind: Service
metadata:
  name: brainlink-mcp
spec:
  selector:
    app: brainlink-mcp
  ports:
    - port: 3333
      targetPort: 3333

Use "embeddingProvider": "none" when you want FTS-only indexing.

For local security checks, set your Snyk token in the environment:

export SNYK_TOKEN="snyk_..."

For GitHub Actions, add a repository secret SNYK_TOKEN and the CI/publish workflows will consume it automatically during build/test.

Set BRAINLINK_ALLOWED_VAULTS for external wrappers, including MCP servers, so a tool cannot pass arbitrary --vault paths:

export BRAINLINK_ALLOWED_VAULTS="/absolute/path/to/project-vault,/absolute/path/to/team-vault"

Bucket vaults can be allowlisted with the same variable:

export BRAINLINK_ALLOWED_VAULTS="s3://my-memory-bucket/brainlink"

Note Format

Brainlink supports Markdown with optional frontmatter:

---
title: "Auth Decision"
agent: "coding-agent"
type: "decision"
---

# Auth Decision

We chose JWT for API clients.

Related:

- [[Architecture]]
- [[API Gateway]]

#auth #jwt #decision

Supported signals:

  • title frontmatter
  • agent frontmatter
  • first # Heading
  • file name fallback
  • [[Wiki Link]]
  • [[Wiki Link#Section]]
  • [[Wiki Link|Alias]]
  • #tags

Development

npm install
npm run build
npm run test
npm run check

Large vault benchmark:

npm run benchmark:large -- --notes 5000

Use --keep to keep the generated temporary vault for inspection.

Local CLI:

npm run dev -- --help
npm run dev -- server --vault .brainlink-vault

Package smoke test:

npm run pack:smoke

Architecture

src/
  application/      use cases
  cli/              command-line adapter
  domain/           pure knowledge rules
  infrastructure/   filesystem and index adapters

Detailed notes:

Current Limits

  • Semantic search uses deterministic local embeddings, not a remote model provider.
  • embeddingProvider currently supports local and none.
  • Link resolution is title-based inside each agent namespace, with shared as fallback.
  • HTTP API is local and unauthenticated.
  • Watch mode depends on the platform filesystem watcher.

Stable Scope

The 1.0.0 line is the first stable functional release of the local-first memory loop:

  • Markdown as durable memory.
  • Rebuildable file index plus local embeddings and encrypted pack exports.
  • CLI as the primary agent interface.
  • HTTP graph API and frontend as inspection tools.
  • Agent namespaces to avoid context mixing.
  • MCP tools for context retrieval, durable memory writes and graph maintenance.
  • Remote MCP server mode for centralized cluster access.
  • Vault management commands for listing, selecting and safely deleting local vaults.

The stable release includes local semantic retrieval, local-first storage, remote MCP transport and operational vault management. Remote embedding providers and deeper graph editing remain future milestones.

Security

Brainlink is local-first by default.

  • Do not expose the HTTP server publicly without authentication.
  • Brainlink HTTP is localhost-only and refuses non-loopback hosts.
  • Brainlink blocks common secret patterns by default when adding notes. Use --allow-sensitive only for intentional, protected vaults.
  • Do not store secrets, credentials, API keys or regulated personal data unless the vault is protected by your own storage controls.
  • Treat .brainlink/index.json and .brainlink/search-packs/ as disposable derived artifacts.

See SECURITY.md.

Contributing

See CONTRIBUTING.md.

License

MIT. See LICENSE. Copyright (c) 2026 Substructa. See COPYRIGHT.md.

Memory Optimization Loop (1-7)

Use this when your agent work needs consistent memory quality:

  1. Start with blink context "<task>" --agent "$BLINK_AGENT" --json.
  2. Keep notes focused with explicit [[wiki links]] and #tags.
  3. Route agent-specific knowledge to dedicated namespaces under agents/<agent-id>/.
  4. Keep shared as a curated global layer only.
  5. Use targeted queries (--limit, explicit terms, --mode hybrid) before broad scans.
  6. Run the sync command after writing notes:
npm run brainlink:sync -- --vault ./vault --agent "$BLINK_AGENT"
  1. Before final response, keep the returned context sources as the grounding baseline.