Knowledge in Markdown, versioned in git. Hybrid BM25 + semantic search. 100% local and offline. Agent-native via MCP.
Zero lock-in. You keep the .md files · the index rebuilds itself · $0 per query.
Every session, your agent trips over the same gotcha, re-decides what was already decided, re-reads what was already read. Pinky gives it durable, auditable memory — without sending your code anywhere.
The .md files with frontmatter that the agent (or you) writes. Readable, versioned in git, reviewable with git diff. It’s yours and it stays with you.
↓ pinky reindex
A SQLite index (FTS5 + sqlite-vec) derived from the Markdown. If it corrupts or the model changes, it rebuilds itself. Nothing critical lives only here.
↑ 100% regenerable
Local and offline, hybrid, markdown-as-truth, and agent-native. The others have one or two.
Local ONNX embeddings, or a deterministic embedder with no network. In-process SQLite, zero daemon. Ideal for sensitive or regulated code that can’t leave the machine.
--hash-embed → no network, everBM25 finds the exact match (pg_pool_timeout); the vector finds the similar ("the pool hangs"). Fused with Reciprocal Rank Fusion.
measurable quality: hit@k + MRRThe index is cache; the .md files are the truth. Zero lock-in: you keep readable files. Audit what your agent learned with a git diff.
reindex rebuilds everythingStandard MCP server with 7 tools — exposed as a token-conscious default of 3 (brain_search, brain_save, brain_stats) and an opt-in full set (PINKY_MCP_TOOLS=*). Plus Claude Code hooks. Not an app — infrastructure.
Semantic dedup, staleness decay, code↔knowledge backlinks, pruning telemetry, and an evergreen validator. Fights entropy; not a dumping ground.
pinky dedup · stale · telemetryNo mandatory Docker, no services, no database to manage. One disposable brain.db file and three small Rust binaries.
curl | sh → running in <2 minThe agent searches before acting, saves what it discovers, and leaves a diary when done. Knowledge grows on its own as you work.
The agent (guided by a rule), the stop hook, or you. YAML frontmatter + Markdown body.
Parse → chunk → embed → SQLite. Incremental: only re-embeds what changed.
Hybrid BM25 + vector, RRF fusion, optional lexical rerank, filters by project/type/tag.
Dedup, staleness, diary rollups, pruning telemetry, quality eval.
Default (3 tools) — token-aware; the agent pays only for tools it could call.
PINKY_MCP_TOOLS=* also exposes brain_update, brain_delete, brain_feedback, brain_similar for curation.
They inject context before read/write and write a diary when done. Time-budgeted: they never block.
It doesn’t just save and search: it understands time, learns what’s useful, and protects its own quality.
Mark what supersedes what (supersedes) and ask "what did we know on that date?" with search --as-of. The old stops confusing you, but stays auditable.
The stop hook correlates which entries the agent actually re-read and marks them useful. pinky stats --value shows you what the brain is giving you.
It understands your notes’ [[wikilinks]]: search --links promotes what’s linked to the top results. A graph’s value without dragging in a graph DB.
pinky sync versions the knowledge in git and auto-resolves diary and frontmatter conflicts. Your team shares the same memory.
The MCP server exposes 3 tools by default (brain_search, brain_save, brain_stats) and curates with brain_update, brain_delete, brain_feedback, brain_similar only when you set PINKY_MCP_TOOLS=*. The agent doesn't pay for tools it won't call.
The eval harness reports hit@k, MRR, and nDCG over a golden set; CI fails the build if relevance drops. It never degrades silently.
Push injections (stats per session, hits per Read) made sense in interactive sessions. In orchestration — one claude -p per stage — they multiplied silently. Pinky ships with knobs to silence the noise without losing the brain.
PINKY_HEADLESS=1 silences push hooksReturns Ok() before opening the index in session-start, pre-read, pre-write, and post-bash. The agent still calls brain_search (pull model) — exactly what it was designed for. Saves ~7k tok/agent in a typical 15-file exploration.
PINKY_HOOK_HITS tunes hits per hookDefault 3 → 0 (clean no-op) or up to 10. Snippets shrink with PINKY_HOOK_SNIPPET (240 → as low as 40 chars). A high-Read pipeline drops from ~21k tok to ~1k tok of injected context.
The session_id already recorded in the usage table is now read back to skip re-injecting an entry_id already served. Two Reads that match the same gotcha no longer double its tokens.
brain_search excludes diary by defaultSession logs are not knowledge — they pollute BM25 spacing. Set include_diary=true or --type diary when you want them; otherwise the agent doesn't pay ~90 tok/hit for stale entries it shouldn't see.
PINKY_MCP_TOOLS tailors the toolsetDefault 3 tools (brain_search, brain_save, brain_stats) saves ~1.6k tok/turn of system-prompt schema vs the full 7. Curation tools opt-in via PINKY_MCP_TOOLS=*.
The MCP's brain_search default omits the 4-decimal score (a human metric) and the .md path (only useful in interactive TUI). The agent keeps the id (for feedback/similar) and the snippet. verbose=true restores the full line.
All of these are opt-in to keep it off: the interactive single session behaves as before. Only orchestration (headless) and agent-pull paths benefit by default.
| Pinky | Platform memory | Vector-DB SaaS | grep + notes | |
|---|---|---|---|---|
| Local / offline | Yes | No | No | Yes |
| Hybrid BM25 + vector | Yes | No | partial | No |
| Portable Markdown (no lock-in) | Yes | No | No | Yes |
| Agent-native (MCP) | Yes | partial | No | No |
| Zero-ops (one binary) | Yes | Yes | No | Yes |
| Cost per query | $0 | included | 💲 | $0 |
Pinky is the only one combining local + offline, hybrid, markdown-as-truth, and agent-native at the same time.
Context tokens pulled in per knowledge query, same scenario, measured on a real 16-doc corpus (~59 KB).
Measured with the pinky binary: brain_search --json payload vs. grep + read the files vs. re-reading the code (tokens ≈ chars/4). It’s the retrieval payload; on larger corpora the gap widens.
One Rust binary, no runtime, no daemon. Everything below is measured and reproducible with pinky bench and pinky eval on your machine.
| Entries | Indexing | DB size | Search p50 | Search p95 |
|---|---|---|---|---|
| 1.000 | 0,4 s | 10 MB | 8,1 ms | 8,7 ms |
| 10.000 | 4,8 s | 104 MB | 49,4 ms | 52,7 ms |
| 100.000 | 56,6 s | 1,03 GB | 470,9 ms | 494,6 ms |
The real case of a personal or team brain (1k–10k entries) has plenty of headroom: p95 < 55 ms end to end. At 100k the brute-force KNN is around ½ s — usable, with binary quantization on the roadmap (justified ≥ 50k). Latency and quality measured with the deterministic embedder (pure engine); the ONNX semantic model is optional —downloaded once— or run with --hash-embed and no model. MacBook Apple Silicon, release build.
Gotchas are injected before it writes code. Fewer re-committed mistakes — not just fewer tokens.
Knowledge persists and accumulates; a new dev or agent starts out knowing what the team already learned.
100% local and offline: it unlocks sensitive or regulated projects a SaaS couldn’t touch. $0 per query.
Markdown versioned in git: review it with a git diff in a PR. Zero lock-in — you keep the files.
Dedup, staleness decay, and pruning telemetry; the CI eval fails the build if relevance drops.
One binary, no daemon; pinky init in one command; the hooks are time-budgeted and never block your agent.
Signed, reproducible, auditable, and tested offline. What a regulated team reviews before adopting a tool.
Opt-in feature with SQLCipher (AES-256, page-level): the brain.db is encrypted. The key travels via the environment; opening with the wrong one fails cleanly, never corrupts.
An agent with write access can destroy months of knowledge. snapshot makes a tar.gz + SHA-256 manifest; restore verifies every checksum before writing a byte.
Binaries signed with minisign + mandatory SHA-256 checksum. Bit-for-bit reproducible builds (pinned toolchain) and a CycloneDX SBOM per release.
minisign · SBOM · reproduciblepinky doctor --airgap fails if anything would need the network. And a CI job runs index + search inside an isolated network namespace: the claim is proven on every push.
The .md files are the stable interface; the index is disposable. An old binary over a newer index fails clearly instead of operating silently.
cargo-deny in CI (RUSTSEC advisories + licenses + sources), GitHub Actions pinned by commit hash, and publish = false so nothing leaks to crates.io.
Airgapped or on-prem: embeddings run locally and nothing leaves the machine. The agent’s memory complies without exfiltrating code.
The agent inherits accumulated gotchas, decisions, and patterns. Instant onboarding: a new dev (or agent) starts out knowing what the team already learned.
The stop hook leaves a diary entry per session; rollups build the weekly/monthly summary with no LLM.
The multilingual-e5-small model covers ES and IT: search in one language, find what was written in another.
Linux x86_64 and macOS Apple Silicon have prebuilt binaries. Other platforms: build from source.
# 1 · set up the project: creates documentation/ and registers the MCP pinky init # 2 · index the knowledge (hybrid search, multilingual model) pinky reindex documentation # 3 · search — or let the agent use the brain_search tool pinky search "timeout closing the postgres pool" # 4 · reopen the project in Claude Code → the 'pinky' MCP is available
Already have it? Update with pinky update (verified download from the CDN).
All installation options (manual download, Docker, source) →
For retrieval, the hybrid BM25 + vector closes the gap: BM25 nails exact terms and the vector handles semantics. And quality is measurable — the eval harness reports hit@k and MRR, and CI fails the build on a relevance regression.
The index is disposable: pinky reindex rebuilds it entirely from the .md files. Plus there are schema- and embedding-model version guards: if something doesn’t line up, it warns and regenerates — it never corrupts silently.
The core is agnostic and MCP is an open standard: it works with any MCP client, and the CLI works on its own. The hooks, though, are Claude Code-specific today.
The ONNX model (~450 MB, optional) downloads once, then everything runs offline. If you want zero-network and zero-model from minute one, use --hash-embed: a deterministic embedder that never touches the network and runs in ~13 MB of RAM (a bit less precise, ideal for airgapped/CI).
Measured and reproducible (pinky bench): at 10,000 entries the full hybrid search is ~50 ms (p95); at 1,000, ~9 ms. The bottleneck isn’t volume: it’s organization and retrieval, which is exactly what Pinky solves.
curl | sh installs the binaries; pinky init leaves the project ready with the MCP registered using relative (relocatable) paths. No baked-in absolute paths, no touching code.