{
  "markdown": "<!-- mcp-name: io.github.oleksiijko/pmb-ai -->\n\n<div align=\"center\">\n\n<img src=\"https://raw.githubusercontent.com/oleksiijko/pmb/main/docs/assets/logo.png\" width=\"100\" alt=\"PMB logo\">\n\n# PMB\n\n### Local-first memory for your AI coding agent.\n### SQLite is the source of truth. No cloud, no API keys, no re-explaining.\n\n[![Website](https://img.shields.io/badge/website-pmbai.dev-8B7FF0.svg)](https://pmbai.dev)\n[![PyPI](https://img.shields.io/pypi/v/pmb-ai.svg?label=pypi)](https://pypi.org/project/pmb-ai/)\n[![CI](https://github.com/oleksiijko/pmb/actions/workflows/ci.yml/badge.svg)](https://github.com/oleksiijko/pmb/actions/workflows/ci.yml)\n[![Docs](https://img.shields.io/badge/docs-online-475569.svg)](https://docs.pmbai.dev)\n[![Python](https://img.shields.io/pypi/pyversions/pmb-ai.svg)](https://pypi.org/project/pmb-ai/)\n[![License](https://img.shields.io/badge/license-Apache_2.0-blue.svg)](LICENSE)\n[![MCP](https://img.shields.io/badge/MCP-native-purple.svg)](https://modelcontextprotocol.io)\n[![GitHub MCP Registry](https://img.shields.io/badge/GitHub_MCP_Registry-listed-8B7FF0?logo=modelcontextprotocol&logoColor=white)](https://github.com/mcp/oleksiijko/pmb-ai)\n\n<img src=\"https://raw.githubusercontent.com/oleksiijko/pmb/main/docs/assets/dashboard-map.png\" width=\"760\" alt=\"PMB dashboard - your project's memory as a live entity graph\">\n\n*Local-first memory, visualized. 3,800+ entities and 41,000+ connections, captured automatically as you work.*\n\n[**Website**](https://pmbai.dev) · [**Docs**](https://docs.pmbai.dev) · [Quickstart](#quickstart) · [Demo](#demo) · [Why PMB](#why-pmb) · [How it works](#how-it-works) · [FAQ](#faq)\n\n**Your AI agent forgets everything between sessions.** So you re-explain the same\ndecisions, lessons and constraints over and over. PMB remembers them in one\nlocal workspace and feeds them back through MCP - no cloud, no API keys, no LLM\ncall on the read path. And it tells you **when memory is actually helping**,\ninstead of claiming \"+X%\".\n\n⭐ **Star the repo if PMB saves you a re-explanation.**\n\n</div>\n\n---\n\nPMB gives Claude Code, Cursor, Codex and the other MCP-aware agents a real\nmemory: decisions you made last week, lessons you taught them, personal facts,\nproject structure, PDFs. They survive every restart, every model upgrade, every\nagent switch - because they live in a **local workspace you own**, with SQLite\nas the durable source of truth and rebuildable search indexes beside it.\n\nNo API keys. No subscription. No LLM call on the read path. Just local files.\n\n## Quickstart\n\n```bash\npip install pmb-ai                 # 1. install\npmb setup                          # 2. detect your agent + wire the MCP entry\npmb warmup                         # 3. preload the model (first recall is instant)\n# 4. restart your agent, then just talk to it - memory is automatic\npmb stats                          # 5. see what's stored\npmb recall \"auth decision\"         # 6. search memory from the terminal\npmb doctor                         # 7. confirm everything is wired\n```\n\nThat's it - your agent now remembers. No account, no keys, nothing leaves your machine.\n\n> **Command name:** the CLI is **`pmb`**. Via `pip` you also get the alias\n> **`pmb-ai`**; via `npm` (`npx pmb-ai setup`) the command is `pmb-ai` and it\n> installs the Python package first, then runs setup. Same tool - use whichever\n> your install gave you.\n\n> **Links:** [pmbai.dev](https://pmbai.dev) (site) ·\n> [docs.pmbai.dev](https://docs.pmbai.dev) (docs) ·\n> [Getting started](docs/guide/getting-started.md) ·\n> [Deleting memories](docs/guide/deleting-memories.md).\n\n---\n\n## Demo\n\n*What it feels like - same prompt, with and without memory:*\n\n<div align=\"center\">\n\n<a href=\"https://github.com/oleksiijko/pmb/raw/main/docs/assets/pmb-setup.mp4\"><img src=\"https://raw.githubusercontent.com/oleksiijko/pmb/main/docs/assets/pmb-setup-poster.png\" width=\"820\" alt=\"Watch the 2-minute PMB setup\"></a>\n\n<sub>▶ Click to play the 2-minute setup</sub>\n\n<img src=\"https://raw.githubusercontent.com/oleksiijko/pmb/main/docs/assets/before-after.svg\" width=\"880\" alt=\"Same prompt, with and without memory: without PMB the agent asks which file and what the bug was; with PMB it recalls verdict-policy.ts:142 in 6 ms.\">\n\n</div>\n\n```\nYou:    fix that LoadGuard pricing bug we hit last Tuesday\n\nAgent:  prepare(message=\"fix LoadGuard pricing bug\")\n        ↓ (6 ms)\n        → project_context: 12 events about LoadGuard,\n          4 lessons (incl. \"never lower NEGOTIATE/SKIP under 25%\"),\n          3 decisions, 2 open goals\n        → active_arcs: \"LoadGuard verdict-policy refactor (started Tue)\"\n        → lessons: 1 directly matches \"pricing\"\n        → recent_activity: 8 commits this week\n\n        Looking at src/engine/verdict-policy.ts (you opened it Tuesday\n        14:32, last changed Wednesday). The pricing bug is on line 142\n        where the bundle fallback tightened below the rate-floor. Per the\n        lesson you saved, we never drop the threshold under 25% - restoring\n        the guard there.\n```\n\nThe agent didn't ask. It didn't guess. It read its memory in **6 ms** and\nshowed up already informed.\n\n---\n\n## Why PMB\n\n- **Local-first, zero-config.** SQLite holds the durable memory; rebuildable search indexes stay local. No account, API keys, telemetry, or cloud to trust.\n- **It actually gets used.** On Claude Code / Codex, hooks inject the right memory *before* the model thinks - you never have to remember to call a tool.\n- **Multilingual, no setup.** The embedder covers 50+ languages; a Russian query finds an English fact. No per-language config.\n- **MCP-native.** One `pmb connect` wires Claude Code, Cursor, Codex, Windsurf, Zed, VS Code, and more.\n- **Fast read path.** Recall in ~35 ms warm; writes return in under a millisecond - no LLM call to remember.\n- **Honest impact.** The dashboard shows which lessons actually changed outcomes, instead of claiming \"+X%\".\n- **Your data, in the open.** `pmb export` dumps everything to Markdown/JSON. Apache 2.0.\n\n---\n\n## See your memory\n\n`pmb dashboard` opens a local, liquid-glass web UI on `http://127.0.0.1:8765`\nover everything PMB captured - written automatically, just by working. It binds\nto `127.0.0.1` only, so nothing leaves your machine.\n\n<div align=\"center\">\n\n<img src=\"https://raw.githubusercontent.com/oleksiijko/pmb/main/docs/assets/dashboard-map.png\" width=\"820\" alt=\"PMB dashboard - Map (entity graph)\">\n\n*Map - every entity and connection in your project, as a live graph.*\n\n<img src=\"https://raw.githubusercontent.com/oleksiijko/pmb/main/docs/assets/dashboard-timeline.png\" width=\"820\" alt=\"PMB dashboard - Timeline (journal)\">\n\n*Timeline - your memory as a journal, newest first.*\n\n</div>\n\nNine tabs: **Map** (entity graph, live), **Timeline** (git-graph by project),\n**Overview**, **Entities**, **Arcs** (narrative threads), **Lessons** (per-rule\nfollow-rate, dead-lesson detection), **Duplicates** (inline merge),\n**Performance** (per-tool latency), **Recall** (debug ranker).\n\n---\n\n## What you can store\n\n```bash\n# Personal facts that change (time-travel: old values archived, never lost)\nrecord_keyed_fact(\"user\", \"city\", \"Warsaw\")\n\n# Project structure - symbols, imports, .gitignore-aware\npmb index project .\n\n# Why each file exists + the intent behind every commit (Haiku-summarised, local)\npmb track modules                # one-line purpose per indexed file\npmb track changes                # new commits: what changed and WHY\n\n# PDFs (research papers, manuals, contracts)\npmb index pdf paper.pdf\npmb index pdf ~/docs --recurse\n\n# Whatever your agent logs as it works: decisions, lessons, completed tasks, goals\n```\n\nPMB is content-agnostic. If it's text the agent will care about later, PMB\nremembers and retrieves it.\n\n## What the agent gets back\n\nA single MCP call - `prepare(message)` - returns the right things at the right\nlevel of detail, in 4-16 ms:\n\n| Field | What it is |\n|---|---|\n| `project_context` | Full project overview if the message mentions a project: key facts, lessons (RULES to follow), decisions, open goals, related entities, the project's narrative arc |\n| `lessons` | Procedural rules matching the query, each with a `surface_id` so the agent can confirm it followed the rule later |\n| `recent_activity` | Last 24 h of decisions / edits / completions for session continuity |\n| `open_goals` | In-progress goals so the agent knows what you're pursuing |\n| `active_arcs` | Narrative arcs the project is currently living in |\n\nFor everything else there's `recall(query)` (hybrid search, 35 ms warm) and 27\nother tools in [docs/reference/COMMANDS.md](docs/reference/COMMANDS.md).\n\n---\n\n## How it works\n\n```mermaid\nflowchart LR\n    A[Your agent] -->|MCP stdio| B[PMB MCP server]\n    B --> C[Engine]\n    C -->|read 35 ms| R[Hybrid recall<br/>BM25 + vector + graph + rerank]\n    C -->|write under 1 ms| W[Async embed queue<br/>SQLite first, vectors later]\n    R --> D[(SQLite)]\n    R --> E[(LanceDB)]\n    W --> D\n    W --> E\n    style A fill:#dbeafe,color:#1e3a8a\n    style B fill:#ede9fe,color:#5b21b6\n    style C fill:#dcfce7,color:#14532d\n```\n\n- **Storage** - every durable event lives in SQLite, the source of truth. Rebuildable vector indexes live in LanceDB beside it. The whole workspace stays on your disk and can be copied or exported anytime.\n- **Recall** - BM25 (lexical) + dense vector (semantic) + entity graph + optional cross-encoder rerank, fused via Reciprocal-Rank-Fusion.\n- **Writes** - async. The MCP tool returns in under a millisecond; the embed + LanceDB insert happen on a background thread.\n- **Dedup** - four layers: exact text match -> cosine >= 0.92 auto-merge -> cosine 0.80-0.92 borderline (LLM verify later) -> manual review in the dashboard. Old values are archived, never deleted; full history via `keyed_fact_as_of(t)`.\n- **Multilingual - no language packs.** The default embedder (`paraphrase-multilingual-MiniLM-L12-v2`) covers 50+ languages, so *где я живу* finds a keyed-fact stored as *user.city = Warsaw*. Intent detection rides English semantic anchors that transfer cross-lingually, and the cold lexical path self-compiles from your own traffic. Recall stays strong across ~11 languages (top-3 ~= 0.9 on a 101-query eval; top-1 = 1.00 for en/fr/pt/ru). See [docs/contributing/adding-a-language.md](docs/contributing/adding-a-language.md).\n\n---\n\n## Install\n\nThe [Quickstart](#quickstart) above is all most people need. Other ways:\n\n```bash\n# From source\ngit clone https://github.com/oleksiijko/pmb.git && cd pmb\npython -m venv .venv && source .venv/bin/activate\npip install -e .\npmb warmup                       # prime the ~450 MB embedder once\n```\n\nWire one or more agents (all stdio - the server runs as a child of your agent;\nno network, no port, no token):\n\n```bash\npmb connect claude-code   # also: codex · cursor · windsurf · gemini · vscode · zed · opencode · continue\n```\n\nPoint several agents at one memory:\n\n```bash\npmb connect claude-code --workspace personal\npmb connect cursor      --workspace personal   # both read/write the same workspace\n```\n\n> Sharing one memory across machines or a team? That's an optional HTTP mode\n> with bearer-token auth - see [docs/guide/TEAM.md](docs/guide/TEAM.md). Not needed for local use.\n\n> **Running the tests?** Use the venv's Python: `.venv/bin/python -m pytest`\n> (or `.venv\\Scripts\\python.exe -m pytest` on Windows). Bare `pytest` outside\n> the venv just reports missing `numpy`/`fastmcp`/`typer`.\n\n---\n\n## CLI cheat sheet\n\n```bash\n# Memory\npmb stats                                   show counts and storage info\npmb recall \"query\"                          search with full debug\npmb dashboard                               web UI on port 8765 (graph, settings, errors)\n\n# Ingest\npmb index pdf paper.pdf                     extract + chunk + embed\npmb index pdf ~/docs --recurse              entire directory\npmb index project .                         scan codebase\npmb track changes                           summarise commit intent (why)\npmb track modules                           one-line purpose per module\npmb import chatgpt ~/Downloads/export.json  bring existing history\n\n# Continuity & efficiency (opt-in)\npmb resume save                             write .pmb/resume.md (commit it)\npmb resume install                          refresh resume.md at every turn end\npmb health lessons-impact                   which lessons actually help outcomes\npmb memory ledger                           Memory Delta handles this session\n\n# Maintenance\npmb regraph                                 rebuild entity graph\npmb consolidate                             run sleep pass (optional)\npmb compact                                 archive old events\npmb dedupe                                  resolve borderline duplicates\n\n# Hooks (force-feed PMB at the protocol level - no model cooperation)\npmb hooks install claude-code               wire all lifecycle hooks\npmb hooks list                              show what's installed\npmb hooks capabilities                      ambient mechanism each agent supports\npmb hooks uninstall claude-code             remove them\npmb auto-context \"fix bug in PMB\"           preview per-turn injection\npmb session-restore -m 180                  preview post-compaction restore\npmb lesson-followcheck --dry-run            preview follow-through scoring\n\n# Ambient memory (the write side - memory journals the agent's work)\npmb autowrite --dry-run                     preview ambient auto-write for this turn\npmb ambient-watch .                         ambient auto-write for MCP-only hosts (git observer)\npmb forget-auto                             drop memory the ambient layer wrote itself\n\n# Config\npmb config list                             default tier (25 keys you care about)\npmb config list --pro                       every key, including 80 advanced knobs\npmb config set recall.ppr_enabled true      toggle a feature\npmb connect --rules-only                    refresh CLAUDE.md only\n```\n\nStep-by-step per agent: [docs/guide/usage.md](docs/guide/usage.md). Full\nreference: [docs/reference/COMMANDS.md](docs/reference/COMMANDS.md).\n\n---\n\n## Hooks - memory that doesn't wait to be asked\n\nThe hard part of agent memory isn't storing - it's getting the agent to *use*\nwhat's stored. Soft instructions in a rules file get skipped. So PMB wires hooks\nat the protocol level (`pmb hooks install claude-code`), each removing a\ndependency on the model remembering to act:\n\n- **UserPromptSubmit -> auto-recall.** Every message is classified (regex, multilingual, sub-ms) and the matching memory - lessons, past decisions, recall hits, project overview - is injected *before* the model thinks. Trivial messages inject nothing.\n- **PostToolUse -> ambient observe.** Every tool the agent runs is appended to a lightweight action journal (a single SQLite INSERT, no model). Reads and `ls` are filtered out; edits, tests and commits are kept.\n- **SessionStart -> session-restore.** After a context compaction the agent rebuilds \"where you left off\" from what the session recorded, instead of re-asking you.\n- **Stop -> follow-through + ambient auto-write.** (a) It checks which surfaced lessons actually showed up in what the agent did and marks them followed, *deterministically*. (b) If the agent did NOT call a `record_*` tool, it synthesizes one activity entry from the observed actions - so real work is captured even when the agent stays silent.\n\nPreview any without an agent: `pmb auto-context \"...\"`, `pmb session-restore -m\n180`, `pmb lesson-followcheck --dry-run`, `pmb autowrite --dry-run`.\n\n## Ambient memory - the write side\n\nAuto-recall fixed the *read* side; ambient memory does the same for the *write*\nside - the memory journals the agent's work even when it forgets `record_batch`:\n\n- **Coordinated.** If the agent already called a `record_*` tool this turn, ambient stays silent; it only fills the gap.\n- **Outcome-scored, not churn.** A turn is journaled only if results clear a quality bar (tests passed, a failure fixed, a deploy ran), not by file count alone.\n- **Honest + reversible.** Every ambient entry is tagged `source=autowrite`, shown as auto in the dashboard, and removable with `pmb forget-auto`. **On by default**; disable with `pmb config set autowrite.enabled false`.\n- **Works on every host.** Claude Code (hooks), Codex (`pmb codex-notify`), MCP-only hosts like Cursor/Zed/VS Code (git observer, `pmb ambient-watch .`). Check yours with `pmb hooks capabilities`.\n\nSynthesis is template-based by default (instant, no model). Opt into a local/API/CLI\nmodel summary with `pmb config set autowrite.synthesizer llm:ollama` or `llm:openai`\n(it has a timeout and falls back to the template).\n\n## Self-improvement loop\n\nEvery surfaced lesson carries a `surface_id`. Follow-through is recorded both\nways: the agent confirms via `mark_lesson_followed(surface_id, True)`, and the\n**Stop hook** infers it from recorded activity. The **Lessons tab** then shows,\nper rule: how often it was shown, how often it was followed, `★ USEFUL`\n(followed >= 2x), `? UNVERIFIED` (surfaced but unconfirmed), and `💀 DEAD` only\nwhen a rule is repeatedly **ignored** (>= 2). You see which rules help and prune\nthe ones that don't.\n\n---\n\n## Settings - 25 you care about, 80 you don't\n\nPMB has 105 tunables. The 25 that affect day-to-day quality are **default-tier**\n(`pmb config list`). The rest are internal weights and experimental flags,\nhidden behind `--pro` so the surface stays scannable. Every pro key still reads\nwith `pmb config get` and writes with `pmb config set` - hidden from `list`, not\ngated.\n\n| Key | Default | What it does |\n|---|---|---|\n| `recall.top_k` | 5 | How many results recall returns |\n| `recall.bm25_weight` | 0.7 | BM25 vs vector mix (1.0 = pure BM25) |\n| `recall.ppr_enabled` | **true** | Multi-hop graph diffusion, gated by intent |\n| `recall.keyed_fact_boost` | 0.35 | How hard personal-attr facts win on personal queries |\n| `recall.rerank` | false | Always-on cross-encoder (regresses LoCoMo, keep off) |\n| `embedding.model` | `paraphrase-multilingual-MiniLM-L12-v2` | The vector model |\n| `graph.extractor` | `regex` | `regex` / `spacy` / `llm:claude` / `llm:openai` / `llm:ollama` / `llm:codex` |\n| `mcp.record_batch_async` | true | Fire-and-forget writes (sub-ms return) |\n| `agent.apply_lessons` | true | Agent surfaces lessons before acting |\n| `dedup.enable` | true | All four dedup layers |\n| `decay.factor_per_day` | 0.985 | Importance half-life |\n| `chat.model` | `haiku` | Default model for `pmb-chat` |\n\n---\n\n## Numbers\n\n| | |\n|---|---|\n| Recall p50 / p95 warm | **35 ms / 110 ms** |\n| `prepare(message)` warm | **4-16 ms** |\n| `record_batch_async` | **&lt; 1 ms** |\n| MCP cold boot | **3.7 s** |\n| LoCoMo recall@10 (n=10) | **94.5 %** |\n| Multilingual mega-stress top-10 (900 q) | **99.2 %** |\n\n```bash\n# Reproduce locally\npython scripts/benchmarks/benchmark_locomo.py --n-conversations 10\npython scripts/benchmarks/mega_stress_test.py\n```\n\n---\n\n## <a name=\"privacy\"></a>Privacy\n\n- 100 % offline by default. No network calls from the engine, zero telemetry - there is no PMB server to call home to.\n- Workspace = a directory under `~/.pmb/<name>/`. Copy it to Dropbox, push it to git, share it on a USB drive. Your call.\n- Secrets are auto-redacted at write time (OpenAI / Anthropic / AWS / Stripe / GitHub keys; configurable).\n- Apache 2.0 licensed. Forks welcome.\n\n---\n\n## FAQ\n\n**Does PMB call an LLM?** On read: never. On write: never by default. Optional:\n`pmb consolidate` can run a local Ollama, Claude CLI, Anthropic, or OpenAI pass to write short\nreflections - opt-in.\n\n**What about cost?** $0. There is no PMB service.\n\n**Does the agent need to know about PMB?** After `pmb connect`, the rules are\nappended to `CLAUDE.md` / `AGENTS.md` automatically. The default profile exposes\n10 core MCP tools (including the `prepare()` read-first pattern); wider profiles\nexist for ingestion and admin.\n\n**Will it slow my agent down?** Tools return in single-digit milliseconds for\neverything except `recall` (35-110 ms warm), which is below human perception.\n\n**Can two agents share one memory?** Yes - point them at the same workspace.\nSQLite WAL + a 10 s busy-timeout handle concurrent writes.\n\n**Wipe a fact?** `pmb forget <ulid>` archives it (excluded from recall, restorable).\nHard-delete: `pmb delete <ulid> --hard`.\n\n**Windows?** Yes - tested on Windows 11, macOS 14, Ubuntu 22.04. Cyrillic paths\nand console encoding are handled.\n\n**PDFs / code / Markdown?** `pmb index pdf paper.pdf`, `pmb index project .`,\n`pmb import markdown ~/notes/`, `pmb import chatgpt path.json`.\n\n**Cold start is slow.** First recall loads the embedding model (~3 s). Run\n`pmb warmup` once, or let the prewarm thread handle it in the background.\n\n**Roadmap?** See [docs/ROADMAP.md](docs/ROADMAP.md): litestream backup, optional\ncloud-sync (BYO bucket), tree-sitter project indexing, image OCR.\n\n---\n\n## Contributing\n\nIssues and PRs welcome. There's one full-time maintainer; please open a\ndiscussion before a large change so we can align on direction.\n\n```bash\ngit clone https://github.com/oleksiijko/pmb.git && cd pmb\npython -m venv .venv && source .venv/bin/activate\npip install -e \".[dev]\"\npytest                  # full suite, ~4 minutes\npytest -k recall        # fast subset, ~12 s\n```\n\n### Dev commands\n\n```bash\nbash scripts/test.sh                 # whole suite (CI-equivalent)\nbash scripts/test.sh tests/recall    # a subset (any pytest args pass through)\nbash scripts/codeql_local.sh         # run CI's CodeQL security-extended locally\nbash scripts/install-dev-hooks.sh    # pre-commit hook: ruff + CodeQL before each commit\n```\n\n`scripts/codeql_local.sh` auto-installs the CodeQL bundle on first run and runs\nthe exact suite CI uses, so security findings are caught locally instead of on a\npush. The pre-commit hook bypasses with `git commit --no-verify` (or skip just\nthe scan with `SKIP_CODEQL=1`).\n\nLicense: **Apache 2.0**.\n",
  "bytes": 21926,
  "sha": "a40445bda6c7871c377eaa5d3812dd696811968ad4e479ffff6e5eea49aacd83",
  "repo_slug": "oleksiijko/pmb",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_oleksiijko_pmb_ai_1c048891/readme"
}