Basic Memory
Memory serverOfficial Basic Machines project
Created by Basic Machines
Published in basicmachines-co/basic-memory. Publisher page
4,552 GitHub stars
What it is
AI conversations that actually remember. Never re-explain your project to your AI again. Join our Discord: https://discord.gg/tyvKNccgqN
AutoGineer overview, from the brain’s own files
Basic Memory is a memory system designed to give AI agents persistent, long-term recall. It operates as an MCP server that bridges the gap between human-readable Markdown files and AI agent context. By treating a directory of Markdown files as a knowledge graph, it allows agents to read, write, and search information across sessions. It supports both local-first operation for privacy and an optional cloud-hosted service for cross-device synchronization. The system includes advanced features like semantic vector search, hybrid full-text retrieval, and a schema system for validating knowledge structure, ensuring that agents can reliably store and retrieve project context, learnings, and documentation.
How it works
Memory model: Hybrid
AutoGineer overview, from the brain’s own files
Basic Memory functions as an MCP server that monitors and manages a collection of Markdown files on your disk. It uses a hybrid memory model that combines standard file-based storage with a database layer (SQLite or Postgres) to enable semantic search and vector indexing. When an agent interacts with the server, it uses specific tools to ingest, curate, or retrieve information from these files. The system automatically handles file synchronization and provides metadata-rich search results, allowing agents to maintain context across different tasks and projects without needing to re-learn information.
| Folder | Role | Files |
|---|---|---|
| .claude | agent-config | 15 |
| .codex | agent-config | 1 |
| .github | agent-config | 20 |
| docs | docs | 41 |
| scripts | scripts | 16 |
| skills | agent-instructions | 33 |
| src | source-code | 529 |
| tests | tests | 595 |
| .agents | folder | 58 |
| .claude-plugin | folder | 1 |
| benchmarks | folder | 155 |
| integrations | folder | 175 |
| plugins | folder | 72 |
| test-int | folder | 179 |
The agent reads
- plugins/ evidence: AGENTS.md
- skills/ evidence: AGENTS.md
- integrations/ evidence: AGENTS.md
- integrations/hermes/plugin.yaml evidence: AGENTS.md
The agent writes
- scripts/update_versions.py evidence: AGENTS.md
- src/basic_memory/__init__.py evidence: AGENTS.md
- server.json evidence: AGENTS.md
Requirements
Runtimes: Python >=3.12
Databases: Milvus, PostgreSQL, Redis, SQLite
API keys (by name): COHERE_API_KEY, OPENAI_API_KEY
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Google Antigravity, Kiro, OpenCode, Amp, Roo Code, Cline, JetBrains Junie, Devin (ex-Windsurf)
Set it up
This brain runs code automatically: 4 hooks (claude-code, codex), 1 script. Review plugins/claude-code/hooks/hooks.json, plugins/codex/hooks/hooks.json, src/basic_memory/cli/commands/install.py before opening the folder in Claude Code. No step below turns a hook on for you.
plugins/claude-code/hooks/hooks.json:uv run --quiet --script "${CLAUDE_PLUGIN_ROOT}/hooks/session_start.py"plugins/claude-code/hooks/hooks.json:uv run --quiet --script "${CLAUDE_PLUGIN_ROOT}/hooks/pre_compact.py"plugins/codex/hooks/hooks.json:uv run --quiet --script "${PLUGIN_ROOT}/hooks/session_start.py"plugins/codex/hooks/hooks.json:uv run --quiet --script "${PLUGIN_ROOT}/hooks/pre_compact.py"src/basic_memory/cli/commands/install.py:python src/basic_memory/cli/commands/install.py
- Not scanned by AutoGineerIts dependencies are installed by pip or uv when you run it and were not scanned by AutoGineer (43 declared). https://pypi.org/project/basic-memory/
Created by Basic Machines. Published in basicmachines-co/basic-memory. Licence: GNU Affero General Public License v3.0 only.
Usage
AutoGineer overview, from the brain’s own files
- Connect the server to an MCP-compatible AI client like Claude Desktop, Cursor, or Codex.
- Use natural language prompts to save project decisions, research findings, or daily logs directly into your memory vault.
- Query the agent to retrieve specific information from past conversations or project documentation.
- Edit notes manually in any Markdown editor while the agent simultaneously updates or references the same files.
- “Create a note about our project architecture decisions.”
- The agent creates a new Markdown file in the vault containing the documented architecture, which is then indexed for future retrieval.
- “Find information about JWT auth in my notes.”
- The agent performs a semantic search across the vault and returns relevant snippets or links to notes discussing JWT implementation.
- “What have I been working on this week?”
- The agent analyzes the recent file activity and notes to provide a summary of your progress and active tasks.
Documentation by Basic Machines
<!-- mcp-name: io.github.basicmachines-co/basic-memory -->
Image: License: AGPL v3 Image: PyPI version Image: Python 3.12+ Image: Tests Image: Ruff Image: untitled Image: untitled Image: Ask DeepWiki
Skip the install — try Basic Memory in the cloud
Claude, Codex, or Cursor connected in 30 seconds. No Python, no JSON, no
terminal. $15.00/mo locked in for life (12.50/mo yearly pricing). 7-day free
trial — cancel any time before day 7 if it's not for you. Beta pricing —
sign up now and your rate never goes up. OSS users: code BMFOSS takes
another 20% off for 3 months.
Basic Memory Teams is now available!
Give your team a single, shared cloud workspace. Knowledge isn't confined to one person — anything a teammate writes is immediately available to everyone else and to their AI assistants. Edit a note together in real time, hand work off between humans and agents, and build one connected knowledge base instead of scattered copies. Same pricing - start with one user and add more as needed.
Basic Memory
Your AI never forgets again.
Pick up right where you left off — in Claude, Codex, Cursor, ChatGPT, or anything that speaks MCP. Your knowledge lives as Markdown files that both you and your AI can read, write, and search.
Local-first. Plain text on your disk. Forever.
Two-way. AI and humans write to the same files; sync keeps them in step.
A real knowledge graph. Observations and wikilinks compound into context.
Semantic search. Find notes by meaning, not just keywords, with optional cross-encoder reranking for higher-quality vector and hybrid results.
MCP-native. Works with every major AI client and IDE.
Progressive tool discovery. Every tool is tagged with behavior hints (read-only, destructive, idempotent) so agents pick the right tool on demand — no wasted context trying things to see what they do.
Cloud, optional. Sync across devices when you want — never required.
Get started
Pick the path that fits you. Both run the same product on the same Markdown.
<table> <tr> <th width="50%">☁️ Cloud</th> <th width="50%">💻 Local install</th> </tr> <tr> <td valign="top">
30 seconds. Sign up, connect your AI client, done.
Works in any browser
Mobile, web, desktop
Cross-device sync built in
We handle hosting, backups, snapshots
$15.00/mo locked for life · 7-day free trial · cancel any time
</td> <td valign="top">
2 minutes. Install, configure your AI client, run.
Free forever (AGPL-3.0)
All data on your disk
Air-gapped friendly
Requires Python via
uv
uv tool install basic-memory --prerelease=allow--prerelease=allow is required: Basic Memory 0.23 depends on a FastMCP 4
pre-release, and uv only accepts pre-releases of transitive dependencies when
told to — without the flag it silently installs an older release. The same flag
goes on every uvx / uv tool upgrade command below.
For Postgres deployments that store semantic vectors in Milvus, install the first-party optional extra instead:
uv tool install "basic-memory[milvus]" --prerelease=allowConfigure your client ↓
</td> </tr> </table>
What people are saying
Basic Memory changed my whole relationship with LLMs. I switched from GPT and Gemini to exclusively Claude and Claude Code because of this integration and am completely revamping all our company's processes around a Basic Memory workflow.
— Alex, TrainerDay
Basic Memory is the missing 'wow' factor in AI chatbots. Now I can't imagine Claude or Claude Code without it.
— Caleb, Caleb Picker Consulting
I don't code without Basic Memory anymore. It's such a time saver to be able to refer to projects I don't currently have active and keep a running log of all my learnings and ProTips.
— @groksrc, Developer
More on basicmemory.com.
Basic Memory Cloud
The hosted version of Basic Memory. Same product, same Markdown files, same MCP tools — we just host the database, run the sync, and put it on your phone.
What you get
Every device, same brain. Your knowledge graph on web, mobile, and desktop. No copy-paste between machines.
Connect any MCP client. Claude Desktop, Claude Code, Codex, Cursor, ChatGPT (Custom GPTs), VS Code — one-click connect from the web app.
Bidirectional sync to local. Edit on your phone, see it in Obsidian on your laptop. rclone-powered with conflict resolution.
Snapshots and backups. Point-in-time restore. Browse history. Never lose a note.
No lock-in. Your notes are plain Markdown. Export to local Markdown any time — same files, same format, same wikilinks. Cancel anytime, your data stays yours.
Built on WorkOS AuthKit, Neon Postgres, and Tigris S3.
Pricing
$15.00/mo, locked in for the life of your subscription (regular price $19). Sign up during beta and the rate never goes up — as long as you stay subscribed, you keep the price. One plan, no tiers, no surprise upgrades. Unlimited notes, unlimited projects, every feature.
7-day free trial. Cancel any time before day 7 if it's not for you.
Cancel anytime after that too — export your notes whenever you want.
OSS users: code
BMFOSSfor another 20% off for 3 months (~$11.40/mo).
Cloud vs. local
| Cloud | Local | |
|---|---|---|
| Setup time | 30 seconds | 2 minutes (requires Python) |
| Cost | $15.00/mo, locked for life (7-day trial) | Free |
| Storage | We host (Tigris S3) | Your disk |
| Cross-device sync | Built in | Manual (Git, Syncthing, etc.) |
| Mobile access | Yes (web + app) | No |
| Air-gapped | No | Yes |
| Your data stays yours | Yes — export anytime | Yes — already there |
| Source code | AGPL-3.0 | AGPL-3.0 |
| Snapshots & backups | Built in | Roll your own |
Both paths use the same OSS engine and the same Markdown files. There's no lock-in either way — flip between them when your needs change.
Works with the tools you already use
| Client | Transport | Notes |
|---|---|---|
| Cloud web app | https | Sign in at basicmemory.com — no install |
| Claude Desktop | stdio/https | macOS / Windows / Linux |
| Claude Code | stdio/https | claude mcp add |
| Codex | stdio/https | OpenAI's coding agent |
| Cursor | stdio/https | .cursor/mcp.json |
| VS Code | stdio/https | Native MCP support |
| ChatGPT | https | Custom GPT actions (search / fetch) |
| Obsidian | — | Reads/writes the same Markdown directly |
| Anything MCP | stdio/https | If it speaks MCP, it works |
Official agent packages
This repository is also the canonical home for Basic Memory's host-native agent packages. The core Python package, Claude Code plugin, shared skills, Hermes plugin, and OpenClaw plugin all ship from the same source tree.
Maintainers can verify the whole consolidated surface from the repo root:
just package-checkPackage-local justfiles are also available when working inside one host:
just package-check-claude-code
just package-check-skills
just package-check-hermes
just package-check-openclawClaude Code plugin
The Claude Code plugin is the bridge between Claude's working memory and Basic
Memory — session-start briefings, pre-compaction checkpoints, an opt-in capture
output style, and /basic-memory:bm-setup · :remember · :share · :status.
Connect the Basic Memory MCP server first — see Connect your AI client. The plugin's hooks and skills call it, so it's a hard prerequisite. Then install the plugin:
bm install claude-codeThat registers the marketplace and installs the plugin through Claude Code. Add
--scope project to declare both in the repository's settings for a team, or
--dry-run to see the underlying claude plugin commands without running them.
Source: plugins/claude-code.
Shared skills
Framework-agnostic SKILL.md files live in skills/. If your
Skills CLI supports repository subdirectory sources:
npx skills add basicmachines-co/basic-memory/skills -gFor Claude and ChatGPT, upload basic-memory.zip or basic-memory-chatgpt.zip
from the skills-latest
release; see skills/README.md.
If your installed Skills CLI cannot load that source, update the CLI or copy
the memory-* directories from skills/ into your agent's skills directory.
Hermes
Hermes keeps its native plugin shape under integrations/hermes:
hermes plugins install basicmachines-co/basic-memory/integrations/hermesHermes does not install a plugin's Python dependencies, so also add the mcp
package to the Hermes venv — see the plugin README
for that step and the supported Hermes releases.
OpenClaw
OpenClaw stays package-native and publishes from
integrations/openclaw:
openclaw plugins install @basicmemory/openclaw-basic-memoryPick up where you left off
https://github.com/user-attachments/assets/a55d8238-8dd0-454a-be4c-8860dbbd0ddc
Connect your AI client
If you went the Cloud route, the web app walks you through client connect. The snippets below are for local installs.
Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"basic-memory": {
"command": "uvx",
"args": ["--prerelease=allow", "basic-memory", "mcp"]
}
}
}Restart Claude Desktop. Notes live in ~/basic-memory by default.
<details> <summary><b>Claude Code, Codex CLI, Cursor, VS Code, ChatGPT, Obsidian</b></summary>
Claude Code
claude mcp add basic-memory -- uvx --prerelease=allow basic-memory mcpFor the full memory bridge — session briefings, pre-compaction checkpoints, and
the /basic-memory:* commands — also install the Claude Code
plugin on top of this.
Codex CLI
Add to ~/.codex/config.toml:
[mcp_servers.basic-memory]
command = "uvx"
args = ["--prerelease=allow", "basic-memory", "mcp"]Codex can keep its default MCP approval behavior, or you can pre-approve eligible Basic Memory tools by adding this server-scoped setting to the same table:
[mcp_servers.basic-memory]
command = "uvx"
args = ["--prerelease=allow", "basic-memory", "mcp"]
default_tools_approval_mode = "approve"This does not disable Codex approvals globally or expand which Basic Memory projects the server can access. Codex still requires approval for tools that advertise a destructive annotation, including Basic Memory's writes, edits, and deletes. If you installed the Basic Memory Codex plugin, use its plugin-scoped configuration instead.
Cursor
Add to .cursor/mcp.json (project) or ~/.cursor/mcp.json (global):
{
"mcpServers": {
"basic-memory": {
"command": "uvx",
"args": ["--prerelease=allow", "basic-memory", "mcp"]
}
}
}VS Code
Add to your User Settings (JSON):
{
"mcp": {
"servers": {
"basic-memory": {
"command": "uvx",
"args": ["--prerelease=allow", "basic-memory", "mcp"]
}
}
}
}ChatGPT
Basic Memory exposes OpenAI-compatible search and fetch tools for Custom
GPT actions. See the ChatGPT integration
guide.
Obsidian
No setup. Point Obsidian at ~/basic-memory (or your project folder) and the
same wikilinks, frontmatter, and Markdown your AI writes appear in your graph
view. Edit either side — sync handles the rest.
</details>
Try a prompt:
"Create a note about our project architecture decisions."
"Find information about JWT auth in my notes."
"What have I been working on this week?"What's New
Automatic updates. Basic Memory keeps itself up to date for
uv tooland Homebrew installs;bm updatetriggers a manual check.Semantic vector search. Find notes by meaning, not just keywords. Hybrid full-text + vector ranking with FastEmbed embeddings, on SQLite or Postgres.
Optional search reranking. Rescore the strongest vector and hybrid candidates with a local FastEmbed cross-encoder or a LiteLLM-backed provider.
Schema system. Infer, validate, and diff the structure of your knowledge base with
bm_schema_infer(),bm_schema_validate(), andbm_schema_diff().Per-project cloud routing. Route individual projects through the cloud while others stay local, via API key (
bm project set-cloud).Explicit note changes.
bm_editupdates existing notes;bm_writecreates notes and guards against accidental overwrites.Richer search results. Matched chunk text is included so the LLM gets context, not just hits.
FastMCP 3.0 + tool annotations. Every tool ships with MCP behavior hints (
readOnlyHint,destructiveHint,idempotentHint,openWorldHint) so agents can discover capabilities progressively at runtime instead of guessing or burning tokens.CLI overhaul.
--jsonoutput for scripting, workspace-aware commands, and an htop-inspired project dashboard.
Full CHANGELOG for v0.18 → v0.20.
Optional cross-encoder reranking
Reranking adds a second relevance pass after vector or hybrid retrieval. It is disabled by default because it adds inference latency and, for the local provider, a first-run model download. Text, title, and permalink searches keep their existing ranking.
Enable the default local FastEmbed reranker:
export BASIC_MEMORY_RERANKER_ENABLED=trueThe default model is jinaai/jina-reranker-v1-tiny-en. To use a hosted
reranker through LiteLLM instead, first install the optional LiteLLM
SDK, then configure it:
export BASIC_MEMORY_RERANKER_ENABLED=true
export BASIC_MEMORY_RERANKER_PROVIDER=litellm
export BASIC_MEMORY_RERANKER_MODEL=cohere/rerank-v3.5
export COHERE_API_KEY=...The feature fails fast on invalid configuration and does not silently fall back to retrieval order when an enabled provider fails. See the semantic search guide for provider setup, all settings, tuning, pagination, and failure behavior.
Why Basic Memory
Most LLM conversations are ephemeral. You ask a question, get an answer, then everything is forgotten. Workarounds have limits:
Chat history captures conversations but isn't structured knowledge.
RAG lets the LLM query your documents but not write back to them.
Vector DBs need complex infra and usually live in someone else's cloud.
Knowledge graphs need specialized tooling to maintain.
Basic Memory takes a simpler path: structured Markdown files that humans and LLMs both read and write.
All knowledge stays in plain files you control.
Both sides read and write to the same files.
Familiar Markdown with semantic patterns — no new format to learn.
A traversable graph the LLM can follow link by link.
Works with the editors you already use (Obsidian, VS Code, anything).
Just files plus a local SQLite index. No servers required.
How it works
You're chatting normally about coffee:
I've been experimenting with brewing methods. Pour over gives more clarity than French press, water at 205°F seems best, and freshly ground beans make a huge difference.
Ask the LLM to capture it:
"Make a note on coffee brewing methods."
A Markdown file appears in your project directory in real time:
---
title: Coffee Brewing Methods
permalink: coffee-brewing-methods
tags: [coffee, brewing]
---
# Coffee Brewing Methods
## Observations
- [method] Pour over highlights subtle flavors over body
- [technique] Water at 205°F (96°C) extracts optimal compounds
- [principle] Freshly ground beans preserve aromatics
## Relations
- relates_to [[Coffee Bean Origins]]
- requires [[Proper Grinding Technique]]
- affects [[Flavor Extraction]]Next session, the LLM picks up the thread. It follows the relations to surface what you already know about Ethiopian beans and burr grinders, and builds on it instead of starting over. You see the same files in Obsidian or your editor. Edit them by hand — the AI sees your changes too.
Real two-way flow: humans edit Markdown, LLMs read/write through MCP, sync keeps everything consistent, and the source of truth is always your files.
The Markdown format
Each file is an Entity. Entities have Observations (facts about them) and
Relations (links to other entities). That's the whole grammar.
Frontmatter
---
title: <Entity title>
type: note
permalink: <uri-slug>
tags: [optional, list]
---Observations
Facts about the entity. Categories in [brackets], tags with #, optional
context in parens.
- [method] Pour over highlights subtle flavors
- [tip] Grind medium-fine for V60 #brewing
- [fact] Lighter roasts contain more caffeine than dark
- [resource] James Hoffmann's V60 technique on YouTube
- [question] How does temperature affect compound extraction?Relations
Wiki-style links that form the graph. Single-token relation types, or quote multi-word ones.
- pairs_well_with [[Chocolate Desserts]]
- grown_in [[Ethiopia]]
- requires [[Burr Grinder]]
- "pairs well with" [[Dark Chocolate]]Bare - [[Target]] and prose - Worth checking out [[Target]] index as
links_to. Full reference in the
docs.
MCP tools
Basic Memory exposes these tools to any MCP client. Every tool is annotated with MCP behavior hints (read-only, destructive, idempotent, open-world) so agents can pick the right one without trial-and-error:
Content:
bm_write,bm_read,bm_edit,bm_move,bm_deleteSearch & discovery:
bm_search,bm_list,bm_findKnowledge graph:
bm_contextProjects:
bm_project_list,bm_project_create,bm_recent;bm_project_deleteis separate and requires server opt-in.Schema:
bm_schema_validate,bm_schema_infer,bm_schema_diffManual:
bm_manCloud connector adapters:
searchandfetchare registered by Cloud only. Local diagnostics usebm doctor.
Most tools default to text; bm_context defaults to JSON. Pass
output_format="json" for structured responses. Project-scoped tools accept a
name, workspace/project, or external UUID through project.
Use bm_man(page="bm-search(3)") for the installed contract, or see the
tool guide. CLI commands retain their shell names.
CLI essentials
# Projects
basic-memory project list
basic-memory project add research ~/research
basic-memory project set-cloud research # route through cloud
basic-memory project set-local research # revert
# Config
basic-memory config list # all settings, effective values, env overrides
basic-memory config set cli_output_style plain # validated through the config model
basic-memory config unset cli_output_style # revert to default
# Health & maintenance
basic-memory status
basic-memory doctor # report project problems and the commands that fix them
basic-memory tool edit ... # CLI access to MCP tools
basic-memory update # check for and install updates
# Imports
basic-memory import claude conversations
basic-memory import chatgpt
basic-memory import memory-jsonRouting flags (--local / --cloud) force a target when you're in mixed
mode. Full CLI reference in the
docs.
Auto-updates
CLI installs check for updates every 24 hours by default and apply them silently (so the MCP server keeps responding).
Supported install sources:
uv tool, HomebrewSkipped for
uvx(ephemeral runtime managed by uv)Manual:
bm update(check + apply) orbm update --check(check only)
Disable in ~/.basic-memory/config.json:
{ "auto_update": false }Telemetry
Minimal, anonymous events to understand the CLI-to-cloud conversion funnel.
What we collect: cloud promo impressions, cloud login attempts and outcomes, promo opt-out events.
What we don't: file contents, note titles, knowledge base data, PII, IP addresses, per-command or per-tool tracking.
Events go to our Umami Cloud instance (open-source, privacy-focused) on a background thread — never blocks the CLI.
Opt out:
export BASIC_MEMORY_NO_PROMOS=1This disables promos and all telemetry.
Logging
Basic Memory uses Loguru. Defaults vary by entry point:
| Entry point | Default | Why |
|---|---|---|
| CLI commands | File only | Doesn't interfere with command output |
| MCP server | File only | Stdout would corrupt JSON-RPC |
| API server | File (local) or stdout (cloud) | Docker/cloud uses stdout |
Log file: ~/.basic-memory/basic-memory.log (10MB rotation, 10 days
retention).
Environment variables
| Variable | Default | Description |
|---|---|---|
BASIC_MEMORY_LOG_LEVEL | INFO | DEBUG / INFO / WARNING / ERROR |
BASIC_MEMORY_CLOUD_MODE | false | API logs to stdout with structured context |
BASIC_MEMORY_FORCE_LOCAL | false | Force local API routing |
BASIC_MEMORY_FORCE_CLOUD | false | Force cloud API routing |
BASIC_MEMORY_EXPLICIT_ROUTING | false | Mark route selection as explicit |
BASIC_MEMORY_ENV | dev | Set to test for test mode (stderr only) |
BASIC_MEMORY_NO_PROMOS | false | Disable cloud promos and telemetry |
BASIC_MEMORY_IMPORT_UPLOAD_MAX_BYTES | 104857600 | Max uploaded import size |
BASIC_MEMORY_LOG_LEVEL=DEBUG basic-memory reindex
tail -f ~/.basic-memory/basic-memory.logDevelopment
Basic Memory supports SQLite (default, fast, no Docker) and Postgres (via testcontainers — Docker required).
just install # Install with dev dependencies
just test-sqlite # All tests, SQLite
just test-postgres # All tests, Postgres (testcontainers)
just test # Both backends
just fast-check # fix/format/typecheck + impacted tests
just doctor # File <-> DB consistency check (temp config)
just package-check # Claude Code, skills, Hermes, OpenClaw package checks
just lint
just typecheck # Pyright (primary)
just typecheck-ty # ty (supplemental)
just format
just check # All quality checks
just migration "msg" # New Alembic migrationTests use pytest markers: windows, benchmark, smoke. See
justfile for the full list.
Contributions welcome — see CONTRIBUTING.md.
License
Built with ♥️ by Basic Machines
CHANGELOG.md
CHANGELOG
Unreleased
Breaking Changes
Note formatting is removed. The
format_on_save,formatter_command,formattersandformatter_timeoutsettings, theirBASIC_MEMORY_*environment variables, thebm formatcommand and the bundled mdformat dependency are gone. Since 1.0 accepts a note's bytes before writing the file,format_on_savehad stopped running forbm_writeandbm_edit(#2005). Formatting the file after the write would make it differ from the accepted note, so the next sync would record it as an outside edit and the agent's nextexpected_checksumwould conflict. Notes are now stored exactly as written. Old keys inconfig.jsonare ignored. To format notes, run your formatter from your editor, or over the project folder yourself.
v1.0.0 (2026-10-29)
Basic Memory 1.0 is a clean-house release. The MCP server exposes only the bm_*
tools, the CLI is built on those same tools, and the pre-1.0 tools, commands and
compatibility code are removed rather than aliased. docs/1.0.md and
bm man tools-migration map every old tool and command to its replacement.
Breaking Changes
SPEC-35.2: the MCP server exposes only the 1.0
bm_*tools:bm_read,bm_write,bm_edit,bm_delete,bm_move,bm_search,bm_context,bm_list,bm_find,bm_project,bm_schemaandbm_man, plus the separate, opt-inbm_project_delete. They replace the earlier tools one for one or by command:read_note/read_content/view_note/catbecomebm_read,search_notes/grepbecomebm_search,build_contextbecomesbm_context,recent_activityand the project tools becomebm_project, and the schema tools becomebm_schema. The old tools and their modules are deleted, with no aliases. Arguments change too:projecttakes a name, a workspace-qualified name or an external ID; search takesmode,filters,items,sinceandall_projects; edits takecommand; context takesidentifierandsince. Refusals are MCP tool errors with a typederror(NOT_FOUND,ALREADY_EXISTS,REVISION_CONFLICT,LOCKED,OUTSIDE_PROJECT, ...). Update MCP allowlists, agent instructions, hooks and recorded fixtures, then restart clients so they reload the tool schemas (#1838, #1839, #1849, #1944, #1947, #1959, #1962, #1963, #1964).Every project-scoped tool requires
project.bm_read,bm_write,bm_edit,bm_move,bm_delete,bm_list,bm_find,bm_contextandbm_schemarequire a nonemptyproject, even with one project or a configured default.bm_searchrequiresproject,projectsorall_projects=true, andbm_project(command="recent")requiresproject. A relative path no longer selects a project because it contains a slash.bm_list(path="/")lists the project's root;bm_project(command="list")lists projects (#1934).The ChatGPT
search/fetchadapters are no longer in the local server. The hosted Cloud server provides them (#1964).bm toolmirrors thebm_*tools. One subcommand per tool (read,write,edit,move,delete,list,find,search,context,project,schema), with flags named after the tool's parameters (--directory,--note-type,--command,--since,--mode,--items,--filters). The subcommandsrecent,projects,workspaces,validate,inferanddiffare removed, as are the old flags (--folder,--operation,--after_date,--meta),--project-id(--projecttakes an ID),--plain, and automatic JSON when piped. Output is the tool's text, or its JSON with--json(#1943).bm cat,head,grep,ls,findandtreerun on thebm_*tools, andbm tailis removed (usebm tool project recent) (#1960). Behavior changes:--plain, the Rich tables and JSON-when-piped are gone; output is the tool's text, or--json.--project-idis gone; pass the ID to--project.Without
--project, the default project is used. A<project>/pathprefix no longer selects the project by itself, and a prefix that disagrees with--projectis refused.bm ls /lists the default project's root;bm project listlists projects.bm cat --linesalways counts the whole file, frontmatter included, and slices print numbered lines under aLines N-M of Theader.bm headloses--frontmatter/--no-frontmatterand prints numbered lines.bm grep -C/--context-linesbecomes-C/--lines, andgrep -Cdrops notes with no matching line.bm grepreturns notes only.--page-sizeis 1-100 on every verb, andbm find --fieldsprints the tool's text. New flags:bm grep --path,bm ls --glob,bm ls --sort.
bm cloud sync,bisyncandbisync-resetare removed. They could delete cloud-only or local files. Usebm cloud pullandbm cloud push, which never delete on the destination and stop on conflicts until you pick--on-conflict. The old commands print the matching pull/push command and exit 1 without touching files (#1953, fixes #1845).bm schemaresolves its project likebm tool.--projectaccepts aworkspace/projectname or a project ID, an unknown project fails with the tool's error, and with no--projectand no default project it exits 1 (#1959).LiteLLM is an optional extra. The default install no longer includes the LiteLLM SDK. If you use LiteLLM embeddings or reranking, install
basic-memory[litellm](441166185).
Features
bm_readreads line ranges of plain text files, such as.txtand logs, withstart_line/end_line(#1960).Chat imports return the paths of the files they wrote (#1878).
bm_manand 1.0 manual pages: everybm_*tool has a section 3 manual page, served over MCP and bybm man(aa8bf2644).bm doctorreports problems in your real projects, with the command that fixes each one. It checks the project path, index readiness, search index integrity (duplicate, orphaned and missing rows) and note materialization, and only reads: it never changes a project, the config or the database.--jsonprints the full report. The write/index/search self-test runs in a sandbox with its own home, config and database. Cloud projects are listed as skipped (e607f817d,60845266d,d52dbc986).memory-doctorskill teaches an agent to runbm doctorand walk you through its suggested fixes (573c3dfab).
Bug Fixes
Startup project indexes were unowned background tasks that could outlive the server's database. They now run with the watcher, stop with it, and a project whose index fails is logged without stopping the watcher (#1967).
#1956: Title search ranks the note whose title equals the query first, ahead of longer titles that contain it. Thanks @Flynn-Kawolsky for the report and the minimal repro (#1957).
#1852: File events that arrived while the watcher reloaded its project list were dropped. They are now kept and indexed. Thanks @SWSAmor for the precise reproduction (#1951).
One project whose directory no longer exists stopped file watching for every project. The watcher now leaves that project out and logs it (#1971).
On SQLite,
a AND NOT breturned no results; it now meansa NOT b, as it already did on Postgres (#1972).#1826: A note whose search rows were lost (a migration that recreated the search index, a dropped refresh) stayed unsearchable, with no vectors, because its unchanged file never reached an index batch. Each index pass now rebuilds missing search rows and their vectors, and project status counts those notes (#1954).
#1862: With an OpenAI-compatible endpoint that returns unnormalized vectors (such as Volcengine Ark), every semantic match fell below the similarity floor, so vector and hybrid search returned nothing on SQLite. The OpenAI provider now normalizes vectors; with a custom
api_base, the next index pass re-embeds stored vectors automatically. Thanks @MbappeWU, who diagnosed this and proposed the fix in #1869 (#1948).Search ranking weights a note's title above its body in the SQLite bm25 score and keeps weighted scores across metadata filters (
56ba5a96a,e2a1a0780,6eda1221c).Relation sources are re-embedded after a forward reference resolves (#1884).
Ignore rules for a directory apply to the files under it, nested directory rules match by ancestry, and a byte-order mark at the start of an ignore file is skipped (#1929, #1949).
Moves keep the configured project root (#1930). A timed-out search is reported as a tool error (#1942). Malformed
memory://context locators return 400 (#1885). The JSON project list honors a server's project constraint (#1937).Tool output reads better: retry hints name the project as the call did, filter-only results show no score,
tag:queries are repeated as typed, and section errors end their list with a period (#1974).The OpenClaw plugin works on OpenClaw 2026.10 (#1966).
#1817: Files copied into a newly created project's folder before the watcher reloaded were never indexed, and the watcher ignored projects added after startup. The watcher now reloads project config, and after it attaches to a new project it runs a catch-up index pass, including while hidden-file activity continues. Thanks @TPSJASPER (#1861, #1866).
#1850, #1853: On SQLite, deleting a large set of vector chunks failed with "Expression tree is too large", and an interrupted search-index migration left a scratch table that blocked the next startup. Deletes now run in batches of 200, and the migration drops a leftover scratch table before rebuilding. Thanks @MbappeWU (#1857, #1859, #1865).
A stale read from object storage could save an older version of a note as a new accepted version, silently rolling the note back. A version that a newer accepted change replaced is now promoted only after an authoritative re-read confirms it (
a5b557acd). A move that was superseded by a later one now cleans up its old file (2e2c1be8e).#1798:
bm doctoroffers a recovery for note saves left in flight by a process that exited. While file indexing still has work owed, duplicate, missing and orphaned search rows are warnings that the index pass may clear; they become errors once indexing settles.FastAPI is upgraded to 0.162.0, with the read cache keeping request identities stable on the new version. This replaces the 0.139.0 pin from v0.24.1 (
2f66021c1).#1811: Creating a local project with the name of an existing one but a different path is refused with
ALREADY_EXISTS, naming both paths, instead of reporting success. The same path stays an idempotent re-index. Cloud creates skip the check, since hosted paths come from the project name (efd157061,e03c2f28f).Search normalizes recognized project prefixes in queries (
9a0211f96).OpenClaw keeps explicit search filters and ignores empty tag shortcuts (
20cbcb538,bef49f458). Tau prefers its native tool registrations (2506147f9).Recovery guidance in tool errors and the manuals now name the
bm_*tools (#1864, #1868).
Security
These come from a security review of the codebase (CodeRabbit deep scan).
Project boundaries are enforced where imports and storage write files, against the resolved project root (#1931,
e46f1b4c5).Note YAML rejects aliases and merge keys, which could expand without bound (#1933).
ZIP imports, search queries, CSV previews, Markdown directive scanning, find/replace output, section heading suffixes and ChatGPT conversation graphs are bounded (#1939, #1927, #1926,
74e41b739,5f8a0303a, #1916).Atomic file writes stage privately, and rclone credentials are created with private permissions (#1925,
1b8713e49,df611b0dc).Literal directory prefixes are escaped before moves (#1915). Legacy directory uploads skip file symlinks, and upload destinations are validated after normalization (
d6d289d3e, #1928).bm cloud api-key saveprompts for the key without echoing it, so the key no longer has to appear in shell history (#1938).
v0.24.1 (2026-10-22)
Bug Fixes
On a fresh install,
bm statusand other commands that load the API failed withcannot import name 'get_flat_dependant' from 'fastapi.dependencies.utils'. The read cache imports that FastAPI helper, FastAPI removed it in 0.140.7, and thefastapi>=0.136.1floor let new installs pick up 0.140.13 or later. FastAPI is now pinned to exactly 0.139.0, the version CI tests. Existing installs can work around it withuv tool install basic-memory --with 'fastapi==0.139.0'. Reported by lastguru.
v0.24.0 (2026-10-22)
Security
GHSA-4gfv-c2mm-mvj2 (high): A web page could reach a
basic-memory mcp --transport sseorstreamable-httpserver bound to127.0.0.1through DNS rebinding and call every MCP tool, including reading and deleting notes. The HTTP transports have no authentication, and the server did not check theHostorOriginheader, so binding to localhost was not enough. Both HTTP transports now reject a foreignHostorOriginon a loopback bind and bind to127.0.0.1by default (#1697, see Breaking Changes). Releases before v0.24.0 are affected. Stdio, the default transport, is not.GHSA-pqm2-2wxw-p5hx (low): In hosted deployments a project's path is an object-storage prefix, but path validation still resolved it on the API host and followed the host's symlinks. A project named after a host directory, such as
etc, let a caller learn which host paths are symlinks from whether a request was refused or returned "not found". No file contents were exposed. Remote project paths are now checked lexically and never touch the host filesystem. Local projects keep the symlink-aware check (#1807).#1804:
build_contextandrecent_activityaccepted anydepth, and/memory/recenthad no limit onpage_size,pageormax_related. On a densely linked project one deep call could run until the client timed out, and any authenticated caller, including a read-only API key, could repeat it.depthis now 1-5 (the default stays 1), andpage_sizeandmax_relatedon/memory/recentare at most 100. The MCP tools refuse out-of-range values with an error naming the limit; the API returns 422.#1805: Security floors for direct dependencies: pyjwt >= 2.15.0 (14 advisories, reached through FastMCP's bearer auth) and litellm >= 1.91.5. The lock refreshes aiohttp, urllib3, multidict, cryptography, certifi and yarl, and FastMCP moves to 4.1.3. Pillow cannot move to 13 while fastembed pins
pillow<13, soread_contentnow decodes only PNG, JPEG and WebP and refuses other formats, GIF included (GHSA-74r2-7ff9-mjj2), before Pillow parses them. The Docker image requires Debian's October 2026ca-certificatesupdate and upgrades pip's own CA bundle.
Breaking Changes
#1805:
read_contentshows only PNG, JPEG and WebP images. GIF, TIFF, BMP and other image files return "Unsupported image format" instead of a JPEG. Text, JSON and other binary files are unchanged.#1683: A refused
write_noteis an MCP tool error (isError), as a faileddelete_noteormove_noteis (#1641). This covers an existing note withoutoverwrite, a revision conflict onexpected_checksum, a note that moved, and a directory outside the project. Nothing is written in any of these cases. They used to come back as ordinary results, so a client checkingisErrorcounted a refused write as written. In JSON mode the error message is the same payload as before (action: "conflict",error: "NOTE_ALREADY_EXISTS"and so on).bm tool write-noteis unchanged: error on stderr, payload on stdout, exit status 1.#1688: A failed or refused
edit_noteis an MCP tool error (isError), as a refusedwrite_noteis (#1683). A refused write, such as the "modified concurrently" conflict when two clients append to one note, came back as an ordinary result whose text said "Edit Failed", so a client checkingisErrorcounted the append as written and never retried it. A refusal comes only from a write that rolled back, so a refused append is never in the note. In JSON mode the error message is the same payload as before.bm tool edit-noteprints the error and exits with status 1. This reinstates #1662, which was reverted when its concurrency test found appends reported as refused that had landed; #1688 fixed that cause first. Thanks to @sammywachtel.#1696: Semantic search is always on, and the
semantic_search_enabledsetting is removed. FastEmbed and sqlite-vec are core dependencies, so the setting only mattered for installs that turned it off by hand; those installs now download the embedding model and build vectors. Oldconfig.jsonfiles andBASIC_MEMORY_SEMANTIC_SEARCH_ENABLEDare ignored rather than rejected.bm reindex --embeddingsno longer refuses.EmbeddingStatusgainsvector_runtime_available;semantic_search_enabledis still emitted as a deprecated alias of it, so older CLIs keep reading upgraded servers, and a status from an older server is still accepted. Where sqlite-vec cannot load (python.org Python on macOS), search still falls back to keyword-only, and a vector or hybrid query says semantic search is unavailable and points at the log.#1697:
basic-memory mcp --transport streamable-http|ssebinds to127.0.0.1by default instead of0.0.0.0, so the unauthenticated HTTP server is no longer reachable from the network unless you ask for it. A non-loopback--hostprints a warning. On a loopback bind, both HTTP transports also reject requests whoseHostorOriginheader is foreign (DNS rebinding), honoring FastMCP'sFASTMCP_HTTP_ALLOWED_HOSTS/_ORIGINS. A non-loopback bind gets that check only when those allowlists are set. The Docker image already passes--host 0.0.0.0and keeps working as before (#1578).#1704:
bm import documentresolves a relative path against the project root, not the current directory, matchingbm lsandbm cat. A command that relied on the old behavior now fails with "File not found" and the resolved path.#1702:
build_context(compact=True)no longer loads observations, and compact JSON no longer has anobservationskey (text-mode compact already hid them). Primary results, relations and related results are unchanged (#1571).#1600:
bm project removeon a cloud-routed project always deletes the project's cloud files; there is no longer a way to keep them. It warns that the files can be recovered only from a cloud snapshot (bm cloud snapshot list) and asks for confirmation (--yesskips it). It no longer deletes the local sync directory as a side effect of--delete-notes; the new--delete-local-filesflag does that. MCPdelete_projecton a cloud route also always deletes files, anddelete_notesis now documented as local-only. Local projects behave as before. A cloud-only project removed without--cloudis now correctly treated as cloud-routed.#1476: The POSIX read tools (
cat,grep,ls,find,tail,man) are on by default, so an MCP client now sees six more tools alongside the existing rich tools, and the server instructions describe projects as mount points. Setenable_posix_tools=false(orBASIC_MEMORY_ENABLE_POSIX_TOOLS=false) to hide them.#1395: Markdown notes always get a permalink. The
disable_permalinkssetting andBASIC_MEMORY_DISABLE_PERMALINKSare retired: an existing value is ignored rather than rejected, and the key is dropped fromconfig.jsonwhen it is next normalized. Notes indexed without a permalink under the old setting are backfilled during ordinary scans, which writes apermalinkinto their frontmatter. Non-Markdown files are unchanged.#1495: Reading a note that does not exist exits with status 1 from the CLI in every output mode, and JSON reads carry
error: "NOTE_NOT_FOUND". Scripts that relied on exit status 0 with null fields need to check the status instead.#1531:
edit_note(operation="replace_section")fails when the exact heading is not in the note, instead of appending a duplicate section and reporting success. A heading such as## Open items #urgentmust be given in full; useappendto create a new section on purpose.#1343:
bm project add --cloud --visibility privateis refused. The cloud has onlyworkspaceandsharedvisibility, soprivatehad created a team-visible project while reporting success.#1596:
bm cloud sync,bm cloud bisyncandbm cloud bisync-resetare deprecated and will be removed in a future release.bm cloud pull/bm cloud pushare the supported sync workflow on Personal and Team workspaces. The mirror commands are marked deprecated in--help, print a notice with the pull/push command on every run, still work on Personal workspaces, and on Team workspaces exit with that notice instead of a "Personal only" error.bm project listno longer shows Team projects with a local sync path ascloud-only:sync_supportedis now true for every workspace, andlist_memory_projectsreports the same. Help examples no longer pass--workspace Personal.
Features
#1552:
edit_notecan edit only the revision you read. Passexpected_checksum(the fullchecksumfrom a JSONread_note,write_noteoredit_noteresult) and the edit applies only while the note is still that revision. Otherwise nothing is written and the tool error is a revision conflict carrying the current checksum (JSONerror: "NOTE_REVISION_CONFLICT",currentChecksum, with the note's title, permalink and file path while it still exists, the same shape aswrite_note's, #1719). A guardedappendorprependon a missing note is a conflict, not an auto-create. The v2PATCHentity route accepts the samex-bm-cloud-note-base-checksumheader thePUTroute does.#1552:
read_note(include_content=False)returns only a note's title, permalink, file path, full checksum andupdated_at, without the body. Use it to refresh a staleexpected_checksumwithout reading the whole note.#1642:
write_notecan overwrite only the revision you read. Passexpected_checksumwithoverwrite=True(CLI:--overwrite --expected-checksum) and the note is replaced only while it is still that revision. Otherwise nothing changes and the result is a revision conflict carrying the current checksum (JSONerror: "NOTE_REVISION_CONFLICT"andcurrentChecksum, withchecksumnull because nothing was written, and the note at the path named by its stored title and permalink, #1719). A checksum for a path no note owns is also a conflict, so a note deleted since you read it is not recreated. Withoutexpected_checksum,overwrite=Truestill replaces unconditionally.#1636: Note deletes record their actor in the accepted-change journal, as creates, updates, edits and moves already did. The delete route now asks the actor resolver like the other mutations (with a new
deletemutation kind), so a runtime that identifies its callers can say who removed a note. With no resolver, which is every local install, the row is written exactly as before and deletes keep thedelete_notesource. Thanks to @sammywachtel (#1638).#1550:
bm okf export DESTINATION --project NAMEwrites a static OKF v0.2 bundle from a local project, andbm okf check BUNDLE_PATHvalidates one. Export keeps concept frontmatter, categorized observations and relative asset paths, rewrites wikilinks to standard Markdown links resolved the way the graph resolves them, and records the original relation types in abm.okf_exportextension. It generates per-folderindex.mdfiles and a dated rootlog.mdfrom the accepted-write journal. Export stages beside the destination, validates before publishing, refuses to overwrite without--replace, and restores the previous bundle if publication fails.okf checkreports per-file, per-rule diagnostics and exits nonzero on any violation, including unreadable or non-regular files. Both commands take--json.#1608: Accepted note writes stamp
created_byandupdated_byinto frontmatter when the runtime supplies an author, so the file itself says who wrote it. Cloud composes<member> via <key name>for API-key writes. The keys are server-stamped: whatever a writer submits for them is overwritten.created_byis set once and carried forward, and a note written before this change never gains one. Unchanged authorship does not rewrite the file, moves and deletes do not restamp, and local runtimes, which supply no author, leave both keys untouched.#1558:
QUERY /v2/search/(andPOST /v2/search/for clients that cannot send QUERY) searches an explicit set of projects in one database with one query. The body is the project search body plusproject_ids, a required list of internal ids the caller has already authorized; an empty list answers no rows and there is no way to ask for every project. Full-text, vector, and hybrid retrieval run the same reader the project route runs, so one project here ranks exactly as its own route does, and results are one ranking over the union rather than merged per-project pages. Hits are hydrated only from projects in scope. Every search result, on both routes, now carriesproject_idandproject_external_id.#1558:
search_notes(search_all_projects=True)runs one scoped query per database instead of one search per project, so a local vault with many projects is one query, and each cloud workspace is one query, with results attributed to their project by the server rather than by which request they came back on. A newprojectsparameter searches a chosen subset by name or external id; an unknown name is an error. Cross-database results are still merged by score, one failing database is skipped with a warning and an inexact total, and a retryable outage or a server too old to attribute its results fails the whole page.#1558: Vector retrieval reads only the projects in scope and fills the window it asks for. The sqlite-vec table gains a
project_idpartition key, so a scoped nearest-neighbour query ranks each project's own vectors instead of taking the k nearest across the whole database and discarding the out-of-scope ones, which could leave a small project with an empty page for a query its notes answered. Existing local storage is carried into the partitioned table without re-embedding. On Postgres the nearest-neighbour statement now runs on the HNSW index (its tie-break sort keys had kept the planner on an exact scan of every vector), withhnsw.ef_searchsized to the candidate window and an iterative scan that keeps going until the scope and manifest filters have admitted enough rows. That scan needs pgvector 0.8 or later; an older extension is reported as a dependency error instead of quietly returning short windows.#1558: A vector or hybrid search with structured filters (note types, dates, categories, metadata, path prefixes, valid time) now fills its candidate window. The vector index ranks by similarity alone, so a window taken straight from it and filtered afterwards could hold few admitted rows while more sat just past it, and the page came back short although matches existed. The reader re-reads the window with a bounded geometric overfetch until it holds enough admitted rows, the ranking is exhausted, or its tail falls below the similarity threshold. Unfiltered searches read their window once, as before.
#1512: Word, PowerPoint, and CSV files get the same sidecar Markdown note a PDF gets.
bm import document <path>indexes the project, extracts the file, and writes<file>.<ext>.mdnext to it plus a run note underdocument-ingestion-runs/, all through the existing parser-neutral document contract. Office formats run through Microsoft'smarkitdownconverters (basic-memory[documents]) inside the same killable, byte-capped worker process as pdf-inspector; CSV renders a bounded stdlib preview with strict UTF-8. Re-running is a no-op while the source is unchanged, and the command refuses to overwrite a hand-written or enriched note at the sidecar path. PDF keeps pdf-inspector and works through the same command.#610: The manual's SYNOPSIS blocks are now generated from the tool registry.
just man-regenrenders the MCP call on every section-3 page from the schema clients actually receive (required parameters first, then defaults, in schema order) and a test holds the shipped blocks byte-equal to the rendering -- change a tool signature without regenerating and CI points at the fix. Those pages declaregenerated: registry; curated sections stay hand-owned. The manual also gainsbasic-memory-diagnostics(3), closing the one gap between the section-3 corpus and the tool registry.Notes are readable as MCP resources. Every
memory://URL Basic Memory hands out now answers the standardresources/read:memory://<project>/<path>returns the note's raw markdown, frontmatter included, with the identifier accepted as a permalink, title, or file path. Unknown notes point atsearch_notes; binary files point atread_content.memory://man/...keeps answering as the manual andmemory://<workspace>/<project>/infoas project info, whichever template the server matches first.#610: The manual ships in the package and is served over MCP. The 21 section-3 pages (one per MCP tool --
search-notes(3),write-note(3), ...) now live insrc/basic_memory/man/man3/as canonical, portable notes. The MCP server exposes them as resources:memory://manis the index andmemory://man/<page>is a page, with every page also listed as a concrete resource so clients that browseresources/listsee each one with its summary. Page references parse the way people and models actually write them --search-notes(3),3/search-notes,search_notes,man3/search-notes.md-- and the server instructions point agents at a tool's page before first use.bm man <topic>prints a page as Markdown andbm man listis apropos;bm man installis unchanged.#1259:
write_notenow tells the caller when a freshly created note looks like notes that already exist. On a server with semantic search enabled, a create probes the vector index with the new note's title and opening content and appends a "Similar existing notes" section listing the closest matches, phrased as a question -- did you mean to write to one of these? -- with the ways out spelled out: merge into the existing note withedit_noteand delete the new one, link the two with a relation, or ignore it. JSON output carries the same list assimilar_notes. No similarity scores are shown and nothing is overwritten on the caller's behalf: on the default embedding model a near-duplicate and a merely related note score in the same band, so the decision stays with the agent, which has the context the score does not.#1398: POSIX-style read tools. MCP gains
cat,grep,ls,find,tail, andmannext to the rich tools, and the CLI gains the same verbs (bm cat,bm head,bm grep,bm ls,bm find,bm tail,bm tree) over one shared translation layer. Notes are indexed by heading, socatcan read one section, a line range, or a token budget instead of the whole note. Projects act as mount points:ls /lists them, and a path whose first segment names a project routes there, so the paths the tools return can be passed straight back.findtakes metadata predicates (status=active,confidence>0.6) and a--fieldsprojection of frontmatter values. This ships an Alembic migration adding thenote_sectiontable.#1501:
read_noteacceptsstart_line/end_lineand returns numbered lines with the next range to read, andgrep(context_lines=N)returns merged match windows instead of whole notes, withmax_matchesbounding the lines per note. The CLI equivalents arebm grep "retry" -C 3andbm tool read-note NAME --start-line 120 --end-line 180.#686:
search_notes(compact=True)andbuild_context(compact=True)return identifiers, metadata, relation targets, and pagination without note content, so an agent can pick what to read before paying for the bodies.bm tool search-notesandbm tool build-contexttake--compact. Default responses are unchanged.#1426: Observations can say when a claim holds (SPEC-82). An authored qualifier such as
- [decision] @effective:2026-06-10 The cache layer will use Redis., a range (@effective[2026-06-10,2026-07-27)), or a quoted multi-word date (@occurred:"June 10, 2026") is indexed as valid time; the kinds areeffective,valid(the default),occurred,due, andmentioned.search_notesgainsvalid_at,valid_overlaps, andtime_kindfilters, and a malformed filter is refused instead of ignored. Searches without them rank as before. A qualifier that does not parse stays in the observation text. This ships an Alembic migration adding the time index table.#1246: Ordinary Markdown links to files in the project (
[Guide](../guides/Guide.md), reference-style links,/-rooted paths) becomelinks_torelations, the way wikilinks do. External URLs, images, code, fragment-only links, and paths outside the project are ignored, and the authored Markdown is not rewritten. (PR #1514; see the #1514 fix below for how the paths resolve.)#1422: Wiki projection.
bm wiki status,bm wiki validate, andbm wiki rebuild(withinitandupdateas aliases) generate root and per-folderindex.mdandlog.mdnavigation pages for a local project, with--project,--all,--json, and--dry-run. The projector is deterministic, so local and cloud produce the same bytes; eachlog.mdkeeps the 25 most recent changes. It never overwrites a hand-writtenindex.mdorlog.md(those are reported as conflicts), links empty folders from their parents, and does not recreate pages for a deleted folder. The change order comes from a new per-project accepted-change journal. This ships an Alembic migration (#1381, #1382, #1396, #1433, #1434, #1436, #1484).#1006: PDF ingestion.
basic-memory[pdf]adds a pdf-inspector extraction adapter that runs in a bounded worker process and turns a PDF into an extracted-text sidecar note plus atype: document_ingestion_runprovenance note, under the same parser-neutral contract local and cloud share (#1178, #1377). Generated document bodies are searchable but cannot mint observations or relations from extracted text.#1366: Document observations can cite the PDF page they came from. The enrichment contract (
enrich_document_markdown) writes OKF-compatiblesourcesentries and Markdown footnotes pointing atfile.pdf#page=N, with an optional printed page label, and the page is checked against the extraction's page count. Provenance also keeps the extraction's page map, so a span of the raw text can be traced to its pages without re-parsing the PDF (#1490, #1519).New extracted-text sidecars use
type: extracted_text. Sidecars written earlier keeptype: document; both are accepted, the stored value is preserved, and old sidecars still match their run notes and are reused on re-import. The per-page page map now lives only on the ingestion-run note (document-ingestion-runs/<run_id>.md), and the sidecar keeps a summary without it, so a 424-page PDF's sidecar frontmatter drops from about 23 KB to about 1 KB.#1744: An extracted-text sidecar is linked to its source file by a
derived_fromrelation, projected from the validatedsource.entity_external_idin its frontmatter. The relation exists even while the sidecar's raw body semantics are disabled, and it does not change the extracted text or its page offsets.Non-Markdown files (PDFs, images, Office documents) store
content_typeandformatin their entity metadata at index time, and directory listings exposeformat. MIME types for every supported or extracted extension (docx, pptx, xlsx, webp, canvas, ...) are pinned before falling back tomimetypes, so slim images without/etc/mime.typesno longer record Office files astext/plain. Metadata filters still match Markdown notes only.#993:
locked: truein a note's frontmatter makes it read-only to the note API. Edits, overwrites, deletes, and directory deletes that include it are refused with HTTP 423, and no API call can unlock it. Direct filesystem edits and deletes still win, and imports are not bound by the lock. Seedocs/LOCKED_NOTES.md.#1254:
bm pruneremoves index entries for files that the current.bmignoreor.gitignorenow excludes. It lists the entries first, takes--dry-runand--yes, and points cloud projects atbm cloud prune. Indexing does not do this on its own because an upgrade that changed the ignore defaults would otherwise drop notes.#1414:
bm project addindexes a local project before returning (--no-waitopts out), andbm project index NAMEreindexes one.bm status --jsonreports readiness per stage (files, relations, embeddings) with a phase that tells a never-indexed project from an idle one, andbm status --waitnow waits until every stage settles or--timeoutpasses. This ships an Alembic migration backfillinglast_indexed_at.#1294: Full-text search finds words inside unsegmented scripts (Chinese, Japanese, Korean, Thai, Lao, Tibetan, Myanmar, Khmer) on SQLite and Postgres, by indexing character unigrams and bigrams alongside the existing word index. This ships an Alembic migration; existing notes gain this recall after a reindex.
#1336: The
openaiembedding provider honorssemantic_embedding_api_baseandsemantic_embedding_api_key, so it can point at any OpenAI-compatible endpoint (llama.cpp, vLLM, TEI, LM Studio, Ollama) without the experimental litellm path. Thanks to @mikemikimike (#1365).#610: The manual's
## PARAMETERSsections on section-3 pages are generated from the tool schemas (#1478), and the section-1 SYNOPSIS and OPTIONS blocks are generated from the Typer command tree (#1524, thanks to @FBISiri), with drift tests for both.#1455: Search results carry
content_lengthandcontent_truncated, metadata fields keep their JSON types (numbers, booleans, lists), andbm ls --plainandbm find --plainreport further pages on stderr so stdout stays pipe-clean (#1456, #1457).bm install codex,bm install claude-code,bm install tau, andbm install piinstall the Basic Memory plugin or package for that host, with--dry-runand--yes. Codex and Claude Code installs delegate to the host's own plugin CLI, andclaude-codetakes--scope user|project|local; Tau and Pi copy the packaged resources and keep existing config. None of them touch the Basic Memory database (#1497, #1498, #1493, #1492).#1487: Tau integration. Tau sessions recall the active branch's latest checkpoint, tasks, and decisions at startup, capture knowledge as work settles, and write an awaited checkpoint before compaction. Coding sessions are keyed by repository identity and write shared Coding Session, Session, Task, and Decision schemas that the Claude Code and Codex packages also use (#1489, #1493).
#1488: Pi integration. The
@basicmemory/pi-basic-memorypackage adds/bm-status,/bm-recall,/bm-capture, andbm_recall/bm_capturetools, over either thebmCLI orpi-mcp-adapter, configured per project in.pi/basic-memory.json. Automatic recall and capture run only in a trusted workspace (BASIC_MEMORY_PI_TRUST_WORKSPACE=1), and/bm-statusreports whether they are on, off, or blocked and why (#1492, #1509).OpenClaw's
write_noteacceptsmetadata,tags, andnote_type, andedit_noteacceptsmetadata, matching the core MCP tools. Thanks to @lastguru-net (#1474).The manual gains
comark(7), a quick reference for the Comark::bm-*components notes can embed (bm man comark,memory://man/comark(7)), and a newmemory-comarkskill teaches agents to author them: the component vocabulary, directive and body rules, live query pipelines, how to check numbers they cannot see rendered, and the coded errors a broken component shows. Component problems never block a write. The skill is registered in the OpenClaw manifest.Skills:
memory-reflectandmemory-defragwork on a project's notes instead ofMEMORY.md. Reflect folds recent activity into the notes each topic belongs in, writes a dated reflection note, and resumes from its last one. Defrag writes a plan note, applies what loses nothing, and merges or deletes only when told to. Both passexpected_checksumon every edit. The note-writing skills date facts with temporal qualifiers (@effective,@due, ...). The wheel ships the distributed skills underbasic_memory/data/skills, so hosts that load skills from the installed package can use them.New
memory-okfskill: makes a project ready for OKF export with the note tools. It finds non-.mdnotes, notes at the Wiki's reservedindex.md/log.mdnames and reserved export frontmatter, then fixes them withmove_noteand guarded writes.New
memory-agentsskill: write, run and check Basic Memory Cloud agents (notes withtype: agent), including their frontmatter, watch triggers, run logs and skip reasons.
Bug Fixes
Fixes from the v0.24.0 release live run:
build_contextrefuses amemory://title URL that names more than one note, asread_notedoes, instead of building context for one of them. Pass the permalink.build_contextrelated results reportcreated_atwith a timezone offset, like primary results.delete_project(delete_notes=True)on a local project reports that the files were deleted, instead of "did not report a completion status".write_note's "Similar existing notes" advisory skips notes the new note already links to.view_notesets the note off with<note>markers instead of---, which ran into the note's own frontmatter fence, and its instructions are no longer indented.Vector and hybrid searches report
totalas the results seen through the current page, still withtotal_is_exact: false, instead of0.tailrows carryupdated_at, the time they are ordered by, andbm tailshows it.bm reindex --helpno longer says--embeddingsrequires semantic search (#1696).Tool docs, the manual and the
list_memory_projectsfooter no longer promise a "session's active project". MCP requests carry no session state under the current protocol, so a call withoutprojectalways uses the default project, locally and in the cloud.write_noteandedit_noteend with[Project: 'name']instead of[Session: Using project 'name'], and say when no project was given and the default was used.
#1726:
bm reindex --embeddingsnow finishes oversized notes before it reports success. Vector sync embeds at most 256 chunks of one note per pass and defers the rest, and the explicit reindex ran a single pass, then printed "Embeddings complete" and forced its progress bar to 100% with those chunks still missing from semantic search. A--fullrerun cleared vectors and repeated the same first shard. The reindex now re-runs deferred notes until none remain, clearing vectors only once for--full. If a pass stops making progress, it reports how many notes still have pending chunks, says how to continue, and exits non-zero. Reported by @beru-ant-king; @lastguru-net independently reached the same fix in #1730.#1732: An API edit no longer leaves a note's observations and relations without vectors. The accept path publishes only the note body as a temporary search row, and the observation and relation rows appear when the file is written and indexed in the background. The route also scheduled its own embed, which often ran first, embedded the body alone, and left nothing to embed the rest. A background index pass did not repair it, because the file looked unchanged. Now the materialization job embeds the note once, right after it indexes the written file, as cloud's materialize job already did. Routes no longer schedule vector sync for note writes, edits or moves. Embeds run in a separate bounded pool keyed by note, so a slow embedding provider no longer holds up other notes' file writes; one note's embeds still run in write order. Reported by @beru-ant-king with a reproducer.
#1691: Editing a note no longer re-embeds all of its observations and relations. Vector chunks were keyed by the search row id they were cut from, and every rewrite recreates those rows with new ids, so nothing matched the previous manifest: about 86 chunks per edit on large ledger notes. Chunks are now keyed by a hash of their text, so unchanged text keeps its embedding. This ships an Alembic migration that re-keys existing chunks in place; nothing is re-embedded by it.
#1720: CLI output prints project names, paths, and error messages as typed. Rich used to read bracketed text in them as markup:
proj [x]printed asproj,[bold]restyled the line, and a value containing a closing tag such asa[/b]ccrashed the command withMarkupError. The deprecatedbm cloud sync,bisyncandbisync-resetnow print only their own deprecation notice, without Click's extra "DeprecationWarning: The command ... is deprecated." line.#1718:
write_note's "Similar existing notes" advisory no longer suggests notes on unrelated topics. It used search's relevance floor (0.55), which the nearest neighbor of almost any note clears on the default model. On the default model it now lists only notes scoring 0.70 or higher: rewrites of an existing note scored 0.77 to 0.93, and unrelated neighbors at most 0.67. Other embedding models keepsemantic_min_similarity, since their scores sit on a different scale. Hybrid search's handling of gibberish queries is unchanged; the measurements showed no threshold that separates it from real matches.#1716: A note's
created_atno longer resets on every edit, move or reindex. Without a frontmattercreated, the parser falls back to the file's ctime, which each atomic rewrite or rename moves, and reindexing an existing note copied that time into the row. Now an existing row keeps its creation time, and only a declared frontmattercreatedchanges it. A brand-new file still takes its file time.#1717:
build_contexttext output names the source of relations the primary note does not own. An incomingrelates_toused to be listed bare under its target, so it read as a self-link; it now reads- [[Brewing Notes]] relates_to [[Bean Origins]]. Relations the note owns keep the bare form, and JSON output is unchanged.#1720:
edit_noteinsert_after_sectionno longer puts a blank line between an inserted list item and the section's list, which split one list in two. The item joins the list directly, below any blank line under the heading. A paragraph inserted above a paragraph still gets the blank line that keeps them apart.#1595:
basic_memory_diagnosticslists theBASIC_MEMORY_*environment variables that overrideconfig.json, redacted the same way as the file dump. It used to print only the file, which can disagree with what the server is using. OtherBASIC_MEMORY_*variables are listed by name only. Env names now match config fields in any letter case, as pydantic-settings reads them: a lowercasebasic_memory_log_levelused to lose to the file value, or, when the file lacked the key, take effect and then get written intoconfig.json.#1593: The CLI's list of commands that skip startup initialization no longer names
syncandwatch, which are not commands. A test now keeps the list to registered commands. Thanks to @FBISiri.#1651: A document import's ingestion-run note no longer says "exact storage materialization is pending", which read as a live status long after processing finished. New run notes say what they record and link the original file and its extracted-text note. Existing run notes keep their old text.
#1653: The
write_notedocumentation now says whatoverwrite=Truedoes to frontmatter: the body is replaced, keys the write sets replace the old values, and keys only the existing note has are kept. Existing frontmatter that cannot be parsed is discarded. Behavior is unchanged.bm tool edit-note --helplists all six edit operations and documents--sectionforreplace_section,insert_before_sectionandinsert_after_section. Thanks to @xhkzdepartedream (#1708).#1604:
bm cloud pushandbm cloud pullon Team workspaces are much faster. The project is listed with oneDepth: infinityPROPFIND instead of one request per directory, and eight files transfer at once. File bodies stream to and from disk, so memory does not grow with file size. This needs a cloud service that answers recursive listings; against an older one, or a project too large for one listing, the command stops with a message naming the cause.#1654: A Markdown file kept in step by a one-way sync tool (rclone sync, a backup script) is no longer re-indexed and rewritten forever. Indexing writes a
permalink(andtitleandtypewithensure_frontmatter_on_sync) into a file that arrived without them. The sync tool then copied its original back, which read as a change. The entity now also records the checksum the file arrived with (a newentity.sync_checksumcolumn, added by a migration), and a file matching either checksum counts as already indexed. Frontmatter is still written. #1655 applies the same check to single-file indexing, using the checksum storage reports.#1667: Moving a directory moves its notes the same way
move_notedoes. The directory move used the old storage-first path, which moved the file and the entity row but left the note's accepted content at its old path and revision. Each note now moves as an accepted note move. Regular files still move their bytes, and per-file failures are reported as before (#1670).#1641: A failed
delete_noteormove_noteis reported as an MCP tool error. A refusal, for example from a read-only API key, came back as an ordinary result whose text said "Delete Failed" or "Move Failed", so clients read it as success.delete_notestill returnsFalsefor a note that does not exist.#1683:
read_contentnever returns another file for a path that does not exist. It resolved through the fuzzy fallback, which matched any note sharing a word with the path (disk/nope.txtreturned a note indisk/). It now resolves only exact paths, permalinks, titles and ids, and a miss is "Resource not found".#1683:
NOTexcludes a term found anywhere in the note.coffee NOT pourreturned a note whose title has "coffee" and whose body has "pour": SQLite evaluatedNOTin each column separately, and the vector half of hybrid search ignores Boolean operators. A search that usesAND,ORorNOTwithout an explicitsearch_typenow runs as full-text.#1683:
read_notewith JSON output (andcat) returnschecksum, the revisionwrite_note'sexpected_checksumcompares, so an agent can overwrite only the revision it read.#1685:
grepmatches keywords by default, so a pattern found in no note returns no results. It ranked by meaning whenever semantic search was on, and nearest-neighbour ranking always returns something:grep("Ethio.ia")listed unrelated notes. Passsemantic=True(bm grep --semantic) to rank by meaning. This replaces theliteralparameter and the-Fflag, andcontext_lines(-C) no longer needs either.#1681: On Postgres, saving a note twice in quick succession no longer answers 500. Two refreshes of the same note's search rows could deadlock or collide on
search_index_pkey, and the loser failed the save even though search rows are derived state. A refresh that loses that race now logs a warning and leaves the winner's rows for the next refresh. The save's search row is written after its accept commits rather than inside it, so a failed refresh can no longer roll back the note. Thanks to#1686: The file watcher logs a warning when a new directory cannot be read. On Linux, notify drops the error when it cannot watch a new directory, so files written into it were never indexed and nothing said why. The warning names the directory and says to run
bm project index <name>once its permissions are fixed. Thanks to @sammywachtel.#1676:
search_notesaccepts the metadata filter shapes agents actually write. Bare operator names (gte,in) work as aliases for$gteand$in, one field can take several operators ({"$gte": a, "$lte": b}), and$contains(array contains) and$existsare new. An unknown operator's error now lists the valid ones. A rejected filter no longer leaves its count query running after the request returns: search and count run in one task group, so a failure cancels the other (#1675).#1657: A full-text query that mixes a punctuated word with other words finds notes that contain all of them.
IT-644 cacheabilityreturned nothing: one punctuated word made SQLite quote the whole query as a single exact phrase, which only matches when the words are adjacent. Now only the punctuated word is quoted, and every word must match in any order:"IT-644"* AND cacheability*. Thanks to @dougvann.#1701: Environment overrides are no longer written into
config.json. Any config save (a project add, a migration, first run) wrote the merged settings, so a one-offBASIC_MEMORY_*variable became permanent. A save now keeps the file's own value for every env-overridden setting. Commands that name a setting still save it:bm config set/unset,bm cloud api-key save,bm cloud workspace set-default,bm cloud logout,bm cloud promoandbm project default(#1631, #1598).#1699: A case-only rename (
config.mdtoConfig.md) on a case-insensitive filesystem no longer leaves a permanent ghost note. The index pass's delete check now matches the exact spelling against the directory listing, so the next pass removes the stale entry (#1627).#1700: In a local project, a note too large to embed in one pass finishes embedding on later index passes without a manual
bm reindex; #1691 already stopped unchanged observations from being re-embedded (#1605). The hosted runtime does not resume these notes yet.#1698: Appending
---or===after a paragraph withedit_noteno longer turns the paragraph into a heading. When an append or prepend would form a setext heading over existing text, a blank line separates them; every other join, including list items and observations, is unchanged (#1585).#1705: Note-tool fixes from the live run (#1634):
A line read that starts past the end of a note is an error ("start_line 500 is past the end of the document (17 lines)") instead of "Lines 500-17".
A link that climbs out of the project is no longer stored as an unresolved relation.
A
write_noteconflict after a move names the note that actually owns the path; thealready_existsoutcome gainsexternal_idandpermalink.recent_activitydescribes its scope accurately, and an empty result from any tool returns an explicit[]text block.
#1704: CLI polish from the live run (#1635).
bm project addandbm project indexshow embedding progress.bm config set default_projectrejects an unknown project and accepts display names.bm project index --helpshows user-facing text, the.bmignorepath in help points at the real config directory, and a refused OKF export no longer prints a misleading summary.#1663: An unhandled API error no longer stalls the server for seconds while it is logged, and logs no longer contain the values of local variables from tracebacks. Loguru's
diagnosemode calledrepr()on every frame's locals, and each ASGI frame holds the whole request scope. The file, stdout and Logfire sinks still log the full traceback without those values. Test mode keeps them. Thanks to @sammywachtel (#1679).#1643: Project status is served over
GET /v2/projects/{id}/status. It was a POST, so a read-only API key got "This API key is read-only" on any empty search, because the empty-result guidance checks project status.POSTremains as a hidden, deprecated alias for older clients. When workspace discovery fails in every workspace, the error gives each workspace's reason, such as a reached spending limit.#1645: An empty search no longer says a project "has never been indexed" when it has indexed notes. Readiness required a completed full index pass, which a project indexed note by note (every project created in Basic Memory Cloud) never records. A project with files and no indexed notes still gets the "index first" guidance.
#1656: On Postgres, vector storage is created when the database is initialized, never while serving. Each embedding job ran
CREATE INDEX IF NOT EXISTSon first use, which locks the table, so concurrent chunk and embedding writes queued behind it and timed out. Initializing an already-initialized database reads the catalog and takes no locks.#1659: On Postgres, two processes initializing the same new database no longer race on
CREATE EXTENSION vectorand fail with a unique violation. Vector storage DDL takes a transaction advisory lock and rechecks the catalog inside it. Extension availability is checked directly, so a real error is no longer reported as "pgvector extension is unavailable".#1586:
write_noteandedit_notereport the note's real checksum instead ofchecksum: unknown. The typed client parsed a response model without checksum fields, and file materialization runs after the response is built, so neither value reached the tool. The tools now report the checksum recorded when the write was accepted, which is the value checksum-guarded edits compare against. Thanks to @tonydzi for the report and fix (#1617, landed as #1619).#1624: A local project whose name is not already its permalink (
My Research,Gamma-Mixed) is indexed at startup and watched again. Startup rewrites config keys to permalinks, but the database keeps the display name, and config was then looked up by that name with an exact match. The project was skipped as "not locally indexable" and treated as cloud-routed. Config entries are now matched by permalink.#1632: On an install with no cloud credentials, an unknown or deleted project name reports "project not found" instead of "Cloud routing requested but no credentials found". Unknown names still route to cloud when cloud is available.
#1628: The MCP
mantool no longer asks a local install for cloud credentials. Without amanualproject, an unbundled page returns "No manual entry for ...", and query mode says it needs that project.#1626:
build_contextresolves amemory://title URL to that note, and returns nothing for a URL that names no note. The routed URL carries the project prefix (main/Cache Layer Design), which the title and file-path lookups never matched. Titles therefore resolved only through a fuzzy search that often picked a note linking to the target, and a miss returned whatever ranked first. The resolver now tries the exact lookups on the remainder before any fuzzy match, andbuild_contextno longer fuzzy matches at all.#1625:
bm wikiprojects local projects that have had API or MCP writes. The projector waits until every accepted change is materialized, and the local runtime never recorded that, so a single write left the wikipartialfor good. Local writes and deletes now mark their journal rows once the file work settles, as cloud does.#1629:
read_content,catandread_noteonnotes/foo.txtreturn that file, not the same-stemnotes/foo.md. An identifier with a non-Markdown extension now matches its exact file path before the extension-less permalink candidates.#1630: When
BASIC_MEMORY_MCP_PROJECTdiffers from the project name only in case (ALPHAforalpha),search_notes(search_all_projects=True)andprojects=[...]find the project again, andprojects=["BETA"]matchesbeta. Search scoping now compares project names by permalink, as routing does.#1633: Tool descriptions, docstrings and error guidance now pass every argument after the first by keyword in their example calls. Several showed the old project-first positional order (
read_note("qa", "notes/x")reads a note namedqafrom projectnotes/x), a retiredlist_projects()tool, or akind=parameter thatsearch_notesdoes not have. A test now checks every example against the registered tool signatures.#1549: A note whose frontmatter sets a permalink that is not already a slug (
s/2026/09/ses_AbCdEfGhIj) is reachable bymemory://URL again, inbuild_contextandread_note. The stored permalink is kept verbatim, but the resolver stripped the routed project prefix only from the slug form of the URL (ses-ab-cd-ef-gh-ij), sobuild_contextreturned an empty result andread_notefound nothing. The resolver now tries the caller's own spelling of the path before its slug.#1621: A failed search refresh no longer removes a note from search. Refreshing an entity deleted its old search rows in one committed transaction and wrote the replacement rows (and, on Postgres, their full-text chunks) in another, so a timeout while writing the replacement left an existing note with no search rows, and nothing rebuilt them until the note was edited or the project re-indexed. The delete and the replacement now commit together: a failure keeps the previous rows, and a failed first index leaves nothing partial behind to retry against.
#1598: Under
BASIC_MEMORY_PROJECT_ROOT, a project name whose permalink contains/(such asResearch/2026) is refused, so every project under a shared root stays a single top-level directory. Cloud stores and purges projects by that top-level prefix, and a nested name could overlap another project's files. The rule lives inproject_permalink, which cloud calls when it creates projects.#1606: Deleting a non-Markdown file (an image, a PDF) now removes it from storage. The delete runner compared the accepted checksum with a SHA-256 of the stored bytes, but an accepted checksum is not always a content hash (cloud records ETags), so the delete was skipped and the next reindex brought the file back. Storage now owns the compare-and-delete through
delete_file_if_matches. This changes theNoteFileDeleteStorageprotocol.#1601: Wiki-projected
index.mdfiles no longer carrybm_parse_semantics: false, so the wikilinks they list become graph relations.log.mdstays graph-silent.#1603: Model-facing text (tool descriptions, server instructions, prompts, skills) was audited against the real tool contracts. Suggested calls use keyword arguments (a positional
delete_noteexample would have deleted a note named after the project), skills use real parameter names and operations, and under-described tools such assearch_notes,grep,edit_noteandmove_notenow send their full contract to clients. Prompts no longer push agents to create notes unprompted.#1581: The sqlite-vec stale-vector cleanup no longer stalls on large vaults. Its DELETE compared each chunk's
source_hashagainst the outer vector row, which made the subquery correlated, so SQLite re-ran it once per vector: quadratic work that held the write lock long enough for concurrent writers to fail withdatabase is locked. The subquery now joins the vector row by rowid, and the cleanup deletes the same rows in one pass. Thanks to @mikemikimike for the report and fix (#1584).#1609:
read_noteon a Markdown file path that does not exist (notes/x.md) returns the ordinary not-found response again. Strict resolution already checks file path, permalink, and exact title, so a miss there confirms absence, and the tool no longer falls back to title and text search for an explicit path. That fallback was what surfaced the problem: in a project with no recorded full index pass, which is common for hosted projects whose notes read fine, an empty search answers with the "Project Index Required" guidance, and JSON reads raised it asFallback search failed: # Project Index Requiredinstead ofNOTE_NOT_FOUND. Title and free-text identifiers keep the search fallback and the guidance.#1607:
move_noteapplies its cross-project guard to directory moves as well as file moves. The guard ran only after the directory branch had returned, sowork/movedwas refused for a note and accepted for a directory. The guard also no longer rejects a destination whose first folder is named after another project when that folder already holds notes in the current project: a knowledge base organised by domain has such folders, and an existing local folder is evidence of a same-project move. A first folder named after another project that does not exist locally is still rejected.#1514: Markdown path links resolve against the note's own path at resolution time, the way wikilinks do, instead of at parse time from the file's location on disk. The parser had derived the note's project path with
relative_toon the filesystem path, which raised for content parsed from anywhere outside the project root (a hosted note read from object storage, for one) and gave a wrong base for any other temporary location. The graph now stores the path as authored (../guides/Guide.md,./same.md,/root.md); both resolvers turn it into a project path from the source note, and background resolution keys path targets by their source note. Wikilinks spelled[[../x.md]]or[[./x.md]]resolve by the same rule.#1558:
search_notes(search_all_projects=True)andprojects=[...]rank merged full-text hits by score strength instead of raw value. SQLite bm25 scores are negative with lower meaning better, so sorting raw values put the weakest hit first and cut every page from the wrong end of the ranking; page two repeated page one. Every hit on a page that spans projects now carriesproject(JSON) or a- project:line (text), so the next call can be routed to the right project.#1557: A vector or hybrid search with reranking enabled retrieves once per request. A page reaching past the fixed reranked prefix used to run a second full retrieval (query embedding, vector query, and for hybrid a second FTS pass) only to rebuild that prefix. The prefix is now read from the request's own window at the fixed window's chunk bound, on the project route and the scoped
QUERY /v2/search/route alike, so every page still reranks the same rows with the same passages. Hybrid tail rows are ordered by where each row first entered either ranking, counting vector chunks before they collapse into rows, so a deep page cannot move a row across one already returned. SQLite full-text results break score ties by row id, as Postgres already did, so a smaller window is always a prefix of a larger one. Thestable_pool_refetchedfield is gone from the internal search trace.#1458: A note whose file stem equals its project's name is now readable by its bare identifier.
split_project_permalink_prefixmatches a leading path segment against a project's permalink viagenerate_permalink, which drops file extensions -- so a single segment likemoby-dick.txtin projectmoby-dickcollapsed to the project's own permalink with an empty remainder, andcat/findrefused it as "names a project, not a note" instead of resolving the note. A prefix claim that would leave no remainder now requires the raw segment to spell the permalink exactly, extension included; a claim that still has a remainder after it is unaffected, since project names never carry a real extension in that position.#1437: An observation and a relation can no longer collide in the search index. A relation's permalink is
from/type/towith the type authored by the user, so a note that says- [decision] redisand- observations [[decision/redis]]gives both rows the identical address; Postgres raised anIntegrityErroron write, and SQLite -- whose FTS5 table has no unique index to object -- kept both under one address, then dropped one of them on the next single-row index pass. Nothing surfaced either way. The search index's uniqueness now includes the row kind, which the table's own primary key already carried, so the two rows stay separately addressable. This ships an Alembic migration replacinguix_search_index_permalink_projectwithuix_search_index_permalink_type_projecton Postgres; no permalink changes and no data is dropped on upgrade, and SQLite's FTS5 index needs no schema change.The
memory://{workspace}/{project}/inforesource is now actually readable overresources/read: it returned a Pydantic model, which the resource runtime rejects (contents must be str, bytes, or list[ResourceContent]), so every served read failed. It returns the validated response as JSON text now. Found by the new note-resource tests, which read through a real client session instead of calling the handler directly.#1344: Deleting a note no longer erases the relations pointing at it. The
relation.to_idforeign key is nowON DELETE SET NULLrather thanON DELETE CASCADE, andEntity.incoming_relationsno longer cascades deletes through the ORM. Deleting a target leaves its inbound relations in the unresolved state the indexer already produces for a link to a note that does not exist yet --to_idnull,to_nameholding the source's original link text -- so a broken-link report stops coming back clean over a vault full of them, and recreating the target re-links the references through the existing forward-reference pass.from_idkeepsCASCADE: an entity does own the relations it declares. Rows already lost to the old behavior stay lost; re-index the affected notes to bring them back as unresolved.#1451: A markdown file whose leading
---block is not a YAML mapping (a letterhead between horizontal rules) is now indexed as plain markdown instead of being dropped. The parser already treated such a block as body; the indexer separately saw fences, tried to write a permalink into them, hit the "refusing to update malformed frontmatter" guard, and excluded the file while readiness reported idle. The guard stands: the file is never rewritten, andremove_frontmatterno longer strips such a block from search content. Frontmatter is now classified once, by the parser, as present, absent, or malformed, and only the first two are ever written to.#1334: A fresh install that runs a CLI command first (
bm status,bm project add) no longer fails with "Project not found" for the seededmainproject; config projects are reconciled into the database on first use.#1340:
bm project removeon a cloud project also removes its local routing entry, so the name can be added again and no stub appears inproject list.#1441:
bm project add --cloudcreates the local sync directory before saving config, so a bad path leaves config unchanged; rerunning adopts the remote project already created.#1333:
bm schema validateand other commands exit on Python 3.12 and 3.13 instead of hanging after printing their result. Thanks to @WebKingdom for the diagnosis (#1346).#1338: Every uv install path the project controls (
bm hook install,bm update, the Hermes and OpenClaw bootstraps,server.json, README snippets) passes--prerelease=allow, which the v0.23.x FastMCP beta pin required. Development builds are no longer published to PyPI, because that flag made them outrank the stable release.#1506: Core, the Codex hooks, and the Claude Code hooks move from the FastMCP 4.0.0b1 pre-release to stable FastMCP 4.0.3. Installed Codex hooks had exited before running because uv could not resolve the beta.
#1339: The Hermes plugin manifest declares
manifest_version: 1, which the current Hermes installer accepts.#1341: The Hermes and OpenClaw tool descriptions and prompts tell agents to call the write tool in the same turn when asked to remember something, never to claim a save without a tool result, and to quote the returned permalink.
#1332: A
[[wikilink]]inside inline code no longer creates a relation. Thanks to @yaodong-shen (#1337).#1359: Quoted Postgres searches such as
"incident response" OR "database recovery"no longer raise ato_tsquerysyntax error that aborted the transaction; quoted groups are searched as grouped terms and unmatched quotes are recovered.#1281: Case-only renames (
config.mdtoConfig.md) stick on case-insensitive filesystems instead of being reverted by the next scan.#1351: Deleting a note through the API or MCP refreshes the search rows of notes that linked to it, so relation search no longer returns the deleted note.
#1335: The entity-body vector is no longer split into one chunk per bullet. It splits on headings and the size budget, and oversized sections break at line boundaries. Per-fact vectors still come from the observation and relation rows.
#1432: MCP identifiers and
memory://URLs resolve against the session's own projects, so a bare prefix no longer routes to another workspace and multi-segment project names are reachable.find --metaresults round-trip as inputs (#1435, #1428).#1431: A filtered vector or hybrid search no longer drops matches that fell outside the first 50,000 rows of the filter's match set, which had hidden the newest notes.
#1388:
BASIC_MEMORY_MCP_PROJECTmatches projects case-insensitively by permalink, so startup indexing and watching pick up a mixed-case name.edit_note(metadata={"type": ...})changes an existing note's type, and append or prepend that creates a note honors the requested type (#1472).bm hookinstalls and reads Claude Code hooks in the profile named byCLAUDE_CONFIG_DIRinstead of always~/.claude(#1473).#1430: On Windows, file-backed SQLite uses a bounded five-connection pool instead of
NullPool, which failed concurrent writes withdatabase is locked.Moving a PDF or other non-Markdown file preserves its bytes; the move had tried to add frontmatter to it (#1485).
#1378: MCP API calls retry an HTTP 429 that carries a valid
Retry-After, up to three attempts within a 30-second budget. Non-replayable request bodies are not retried.bm cloud pullandbm cloud pushover WebDAV (Team workspaces) wait out rate limits usingRetry-Afterinstead of aborting the transfer on the first 429 (#1532).#1479:
write_notedecides between create, update, and conflict in one typed operation instead of matching exception text. A write to a vacant path whose permalink belongs to a moved note returnsNOTE_PATH_CONFLICTwith the note's current path, and locked-note refusals are reported as such.#1538: A Markdown note indexed as a plain resource is repaired by the next scan. Thanks to @wangzhengzhuo05 (#1542).
#1539:
.bmignoreand.gitignorepatterns honor escaped hashes (\#*#) and escaped or leading whitespace. Thanks to @wangzhengzhuo05 (#1540).#1537: Emacs
#note.md#autosave files are not indexed.#1534:
search_notesandrecent_activityon a project that has never been indexed return "Project Index Required" guidance instead of an empty result. Thanks to @wangzhengzhuo05 (#1535).#1533: An empty search for an unspaced CJK compound returns a
query_hintsuggesting a shorter word or spaces between words.#1390: Relation search refresh cleanup deletes markers in batches of 500, so a backlog larger than asyncpg's 32,767-parameter limit no longer fails relation resolution.
Indexing converges under production load: a note rewritten faster than it indexes settles on the newer accepted write, a MIME-marked
.mdpath with no note basename stays a resource, and a relation refresh for an entity whose content is gone no longer crash-loops (#1374). A file deleted between the existence probe and the checksum read is treated as absent instead of failing materialization (#1383).#1714: Wiki projector pages are no longer embedded. A page counts as projector-owned while its current accepted revision came from the projector (
note_content.last_source), not by file name. Vector sync deletes such a page's vectors, embeds nothing, and reports it as skipped. Full-text rows and relations are unchanged, so generatedindex.mdlinks still feed the graph. A hand-writtenindex.mdis embedded as before, and a generated page someone edits is embedded on its next sync. In Cloud, the embedding jobs queued for projector writes become cheap deletes.#1275: On macOS, file paths are normalized to NFC where they enter the index. macOS resolves NFC and NFD spellings to one file but reports whichever is on disk, and Syncthing keeps NFD names, so a flipped name could create a
-1twin and makeedit_notefail on the permalink constraint. Migration 0042 merges existing twins (macOS only). Linux and Windows keep byte-exact paths. #1801: the migration no longer fails withno such module: vec0when a vector table exists.#1775:
edit_noteappend/prepend that creates a missing note from a project-qualified identifier no longer nests it under a folder named after the project. The server decides where the note goes from the folders that already hold notes (indexed, accepted or on storage), refuses an identifier that two folders could match withAMBIGUOUS_NOTE_PATH, and refuses any reading outside the project before looking at a folder.#1769: A full-document
PUTof a note (Cloud's web editor) deletes frontmatter keys the request leaves out, instead of keeping them from the stored note.write_note(overwrite=True)still merges frontmatter.#1781: A new note without a frontmatter
createdkeeps the file's creation time instead of the time of the index run. Thanks to @ningyixi.#1778: In a hosted session that can reach several workspaces, a POSIX refusal for a path naming a project in another workspace names that workspace and the spelling that reaches it, and
ls /lists the accessible workspace slugs. A discovery failure no longer turnsls /or a refusal into an error. Local sessions make no new control-plane calls.move_notecan rename a.markdownnote to.md. Other extension changes are still refused.write_note's similar-notes advisory skips notes withgenerated:in their frontmatter (Wiki indexes and logs, agent run logs).#1789: A Wiki run reports source folders that differ only by letter case or Unicode normalization (
customers/CPCandcustomers/cpc) instead of failing the whole run every time.#1790:
bm import chatgptimports conversations that have no title, naming themUntitled conversation <id prefix>, instead of failing the import withKeyError.#1788: Editing a note with many vector chunks updates the reused chunks' metadata in set-based batches instead of one statement per chunk.
#1762: Read-cache invalidation deletes the entries it retires instead of leaving them in Redis until their TTL. #1761: Read-cache hits are no longer recorded as error spans.
The Hermes plugin masks credentials on its capture path, including bearer tokens and quoted field names.
Skill tooling reads and writes skill files as UTF-8 with LF line endings, which fixes the Windows unit job.
Internal
FastMCP 4.0.3 → 4.1.3 and mcp 2.0.0 → 2.3.0, including the Claude Code and Codex hook pins. FastMCP now applies its Host/Origin guard to the SSE transport, so
basic-memory mcp --transport sseuses it instead of installing its own copy. Streamable HTTP sessions now expire after 30 idle minutes (the MCP SDK default); clients start a new one.#1672: Indexing and embedding results report the work they did.
FileIndexResult,IndexedEntityandSyncedMarkdownFilecarryindexed_bytes, the stored bytes read and parsed (zero for a file that was already current). Embedding results carrychunks_embedded, the chunks actually sent to the embedder, andsync_entity_vectorsreturns aVectorSyncBatchResult. How indexing and embedding run is unchanged.#1660, #1671, #1673: A note's storage echo is recognized instead of re-indexed. Materialization records the written object's storage checksum, storage and content checksums are compared only with their own kind, and an object whose content matches the note's accepted content counts as current even before its storage checksum is recorded. Index-file results carry the content checksum, so a live update for an accepted write matches its existing activity. Locally both checksums are the same sha256, so this only changes behavior where storage reports its own checksum (S3).
#1661: The accept transaction writes the pending relation-publication marker, so an accepted note is never visible without it, and a successful publication leaves exactly one unit of refresh work. A PUT that renames a note carries the previous path into materialization, as an explicit move does. The accepted-note runner tests run against a real database (#1668).
#1658: Alembic revisions after
z9a0b1c2d3e4are named by sequential schema version (0040,0041, ...).migrations.schema_version()reports a revision's number andmigrations.next_revision_id()assigns the next one.#1669: CI balances the Postgres test shards by recorded durations and runs the Windows jobs only on
main.#1613: Note object metadata keeps an origin for
agentandmcp_clientactors, not only MCP clients, so cloud can attribute API-key writes to the key's name.systemwriters still carry no named origin.#1602: Hot paths emit far fewer Logfire spans and INFO logs: per-sub-step read-cache and indexing spans collapse to one span per operation, and per-item INFO logs move to DEBUG. Counters and error logs are unchanged.
#1558: Search filter compilation now runs over an explicit
ProjectScopeinstead of a repository-boundproject_id. FTS term preparation and filter compilation moved out of the SQLite and Postgres repositories intosqlite_search_queryandpostgres_search_queryas pure functions returning aCompiledFilter, and the filters both backends share (scope, permalink, directory, item type, category, note type,after_date, valid time, candidate keys) are compiled once insearch_filters. The note-type and valid-time predicates match search rows on their full(project_id, ...)identity. Project repositories call the compilers with a scope of one; no query behavior changes. First step of the shared single/multi-project reader.#1558: Full-text execution leaves the project repositories.
SQLiteFtsandPostgresFtsrun a compiled statement for anyProjectScopeand own their engine's failure semantics (FTS5 syntax errors answer empty, Postgres retries a malformed strict tsquery relaxed inside a savepoint).SearchRepositoryBase.searchandcountare concrete: shared vector/hybrid dispatch, then the engine'sFtsBackend. The base read path binds every statement to the repository's scope (manifest hydration, candidate row fetch, readiness and drop classification).PreparedSearchQuerymoves to the repository layer with defaults, and the filter helpers both backends share move from the base intosearch_filters. No query behavior changes.#1558: Retrieval leaves
SearchRepositoryBase.SearchReaderruns one prepared query over oneProjectScopein whichever mode it asks for, andSemanticSearchowns vector and hybrid retrieval (adapter lookup, manifest hydration, the structured filter pass, score fusion, reranking, pagination) over aVectorRetrievalthat is present or absent rather than probed withhasattr. The repository keeps what only it knows (whether semantic search is enabled and its vector tables exist) and builds a reader per call from its current state. Hydrated chunks are a typedHydratedChunk, which retires thebest_distancecompatibility branch and the per-backend_distance_to_similarityhooks the adapters had already replaced. Test doubles construct the pipeline directly instead of subclassing the repository. No query behavior changes.#1558: Vector adapters are bound to the database, not to a project.
VectorIndexScopeis the database namespace plus embedding schema; every write names the project it touches (upsert(project_id, ...),delete(project_id, ...),delete_entity(project_id, ...),delete_orphans(project_id, ...)) andsearchtakes aProjectScope, so one sqlite-vec or pgvector adapter answers a query across any set of projects with one statement. Milvus keeps a collection per project and searches the collections in scope.SemanticSearchpasses its scope through, so a project repository's vector search is unchanged. No query behavior changes.#1556: A hybrid hit found only by full-text search returns
matched_chunk: nulland relies on the boundedcontentpreview, instead of copying the whole note intomatched_chunk; vector-matched passages are unchanged. Search stages (hybrid FTS, query embedding, vector lookup, hydration, fusion, reranking, cache) get their own trace spans.#1555: The local FastEmbed reranker scores candidates in batches of eight with the ONNX CPU memory arena disabled, so hybrid searches stop leaving inference buffers resident after the request.
#1446: The first
bm statuson a never-indexed project no longer reads every file to hash it.#1454:
QUERY /v2/projects/{project_id}/knowledge/entities/batchreturns accepted Markdown for up to 25 notes in one query, for hosted search hydration, and the search read cache now keeps entries for 30 minutes instead of 30 seconds.#1347: The portable batch indexer applies the caller's metadata concurrency limit to the search-index refresh phase too, so cloud batch jobs stay within their database connection budget.
Extension seams for cloud: a subclass can write inside the accept transaction (#1483), completed schema validation has an overridable observer that reports the resolved schema identity (#1491, #1494), and
agent_runtimeis an accepted note source so managed-agent writes materialize (#1505).#1400: The benchmarks package gains BEAM and xAFS dataset adapters and an agent-task harness that compares the rich and POSIX tool surfaces, with resumable scoring, configurable model endpoints, and secret redaction in saved errors. A multilingual embedding benchmark covers chunk boundaries and model-cache measurement.
#1791 (#1793, #1794, #1795, #1802): Postgres search is faster on large projects. The admitted-chunk count reads the chunk manifest alone, FTS text conditions run only on GIN candidates, chunk candidates come from the GIN index, and multiword queries collect each operand's matches through GIN once.
#1779: A dev-mode
.envrckeeps a development checkout's Basic Memory config separate from the installed one.
v0.23.2 (2026-08-25)
Patch release fixing case-duplicate folder creation.
Bug Fixes
#1326:
write_noteandmove_noteno longer create case-duplicate folders (schemas/beside an existingSchemas/). When a requested directory is not an existing folder but matches exactly one existing folder case-insensitively, the note lands in the existing folder — nested paths resolve per segment; unknown folders are still created as given, and existing case-variant siblings keep today's exact behavior. Folders are resolved from the indexed database paths, so local and cloud runtimes behave identically, and content-only note updates skip resolution entirely.move_notereports the actual landing path on a case-corrected move instead of a false failure, while a basename divergence still fails honestly.
v0.23.1 (2026-08-25)
Fast-follow patch to v0.23.0 focused on PostgreSQL search parity and a
search-destroying reindex bug. Postgres now indexes complete note bodies for
full-text search (previously only titles and capped content stems, unlike
SQLite), and the per-project search reindex no longer wipes every other
project's search rows in the same database. Also adds a #bm:links_to
directive for disambiguating prose wiki-links, and hardens bm update output
after in-place upgrades.
Features
Added the
#bm:links_todirective: ending a list item with#bm:links_toforces the reference to the implicitlinks_torelation, so a single-token prose prefix (- Mother [[Alice]] #bm:links_to) is not parsed as an explicit relation type. The directive stays in the source file but is stripped from indexed observation and relation content.
Bug Fixes
PostgreSQL full-text search now covers complete note bodies. Note content is indexed as bounded, overlapping chunks in a new
search_index_fts_chunkstable (a migration backfills existing notes), so deep content matches on Postgres the way it always has on SQLite FTS5. The work includes correct Boolean AND/NOT semantics across chunk boundaries, apostrophe and punctuated-operand handling (can't,v0.13.0b2,auth-service), metadata-filter composition, 100+ operand queries, and candidate preselection so both GIN indexes stay in play.The per-project search reindex (
POST /search/reindex) no longer drops the sharedsearch_indextable. Dropping it destroyed every project's search rows in the same database — and on Postgres nothing outside migrations recreates the table, so cloud tenants lost search entirely until manual repair. The rebuild now deletes only the reindexed project's rows (chunk rows cascade), and the chunks migration recreates a missingsearch_indexso databases hit by the old behavior migrate cleanly.#1316:
bm updatestatus output no longer crashes after an in-place upgrade removes the running install's files: rich's deferred Unicode width table is preloaded before upgrading, and status lines fall back to plain output instead of failing a completed update.#1323:
bm doctorno longer fails whenBASIC_MEMORY_PROJECT_ROOTpoints at an existing project's directory. Doctor now asks the server for a disposabledoctor-*project under the configured root — the only sanctioned exception to the nested-project guard — and cleanup deletes the project's directory along with its registration.bm doctorwaits for deferred note materialization before verifying the API-written file, matching the accepted-write contract instead of racing it.
v0.23.0 (2026-08-23)
Semantic search grows up and concurrent writes stop deadlocking. Search gains
opt-in cross-encoder reranking, pluggable vector indexes with a first-party
Milvus adapter, and a batch of embedding-correctness fixes; the indexing and
persistence path is rebuilt around generation-versioned, compare-and-swap
writes so concurrent multi-agent workloads can no longer deadlock or lose
observations and relations. Day-to-day operation gets a real front door with
bm config, Rich bm tool output, a diagnostics tool, an honest reindex,
and a retrieval inspector — bm inspect chunks shows a note exactly as the
index sees it and bm inspect query traces how a search ranked its results;
bm hook brings harness lifecycle capture into the package; and cloud adds
bm cloud share, bm cloud prune, an optional Redis read cache, and Team
workspace bm cloud push/pull over permissioned WebDAV. Five database
migrations run automatically on first start, including a one-time repair
that dedupes duplicate observation rows and purges their stale full-text
search entries.
Breaking Changes
#1111: The
canvasMCP tool is removed, along with the API resource write endpoints that backed it (#1106). Obsidian canvas generation is no longer available.#1145: The
cloud_infoandrelease_notesMCP tools are removed.#1121: Pre-v0.18.0 legacy HTTP API routes are dropped (#1116). Old clients still calling them now get 404s.
#1035: The ChatGPT-compatibility
search/fetchtools now refuse non-OpenAI MCP clients with a clear rejection; other clients should usesearch_notes/read_noteinstead.#1061: One-way
bm cloud syncnow deletes newly-.bmignored files from the cloud instead of leaving them there forever (#1032). Intentional, but destructive relative to prior behavior — review your.bmignorebefore the first mirror after upgrading.#1002:
bm statusis redesigned around project index status; scripts that scraped the old sync-report output will break. As part of this, the config keyssync_delay/sync_changesare renamedindex_delay/index_changes— legacy config.json keys andBASIC_MEMORY_SYNC_*env vars are auto-migrated, no action needed.The
sync_thread_pool_sizeandsync_max_concurrent_filesconfig keys are removed with no alias and are silently ignored if present; the closest replacement knob is the newmaterialization_workerssetting.#1240:
bm reindex --embeddingsnow exits nonzero when entities fail to embed, surfaces the failures, and reports which index identity it wrote (#1237). Wrappers that relied on unconditional exit 0 must handle real failures.#1063:
edit_note'sreplace_sectionis heading-level-aware and now replaces nested subsections by default instead of silently preserving content past the next heading; passreplace_subsections=falsefor the shallow behavior (#1012).#1082:
list_directoryresults are bounded and paginated (#1048). Consumers expecting one exhaustive listing must page.#1198: The MCP server now runs on FastMCP 4.0.0b1 and MCP SDK v2 — a beta framework release. Downstream embedders pinning FastMCP 3.x must upgrade together.
Features
#1143: Opt-in cross-encoder reranking of vector/hybrid search candidates (#950, #618, #666):
reranker_enabled(default off) with a local FastEmbed ONNX reranker or LiteLLM API rerankers (Cohere, Jina, Voyage), plus candidates, timeout, char-cap, and API tuning knobs.#1141: Pluggable semantic vector indexes on Postgres (SPEC-81):
semantic_vector_indexselectspgvector(default) ormilvus, and a new index identity/readiness manifest lets vector search tell "no ready index" from "no results". SQLite keeps sqlite-vec. After switching backends, runbm reindex --embeddings.#1158: First-party Milvus, Milvus Lite, and Zilliz Cloud vector index adapter via
pip install basic-memory[milvus]; existing collections reload after restart (#1185), with identical rankings verified across sqlite-vec, pgvector, and Milvus Lite.#1043: LiteLLM embeddings accept a custom
api_baseand directapi_keyfor OpenAI-compatible and self-hosted servers (#1005), and literal document/query prefixes support prefix-sensitive asymmetric models (#1044, #1008).#1249 / #1250: New retrieval inspector (#1155).
bm inspect chunks <note>shows a note exactly as the index sees it — its search rows, the vector chunks each row produced, and per-chunk ready/pending/stale/orphaned status — separating chunking problems from freshness problems in one command.bm inspect query "<query>"captures an opt-in execution trace from the same search call that returns the results: FTS and vector candidates, fusion, filtering, reranking, and the final page window, with stable JSON output and--show-missesfor rejected candidates. Ordinary search behavior and responses are unchanged.#1088: New
bm configcommand group:list(effective values with env overrides marked),get,set(validated through the config model), andunset(#991).#967: Interactive
bm toolcommands render Rich panels, tables, and trees on a TTY, with acli_output_stylesetting and per-invocation--plain/--jsonoverrides; piped output stays machine-readable (#678).#963: New
basic_memory_diagnosticsMCP tool reports version and system info for bug reports (#187).#1018: The local Postgres backend is usable end to end: migrations, connection pooling, and default-project resolution.
SQLite write-path tuning is exposed via new
sqlite_synchronous,sqlite_mmap_size,sqlite_wal_autocheckpoint, andsqlite_page_sizesettings.#1100:
created/modifiedfrontmatter timestamps are honored as note timestamps (#238). Recency ordering can change after the first re-sync for notes carrying historical dates.#1079: Notes written through the API/MCP persist their observations and relations immediately instead of waiting for the next file re-index (#1076).
#1227 / #1220 / #1228: Persistence is generation-versioned with compare-and-swap publication — a stale indexing pass can never clobber or deadlock against a newer write, so observations and relations stay intact under concurrent agent write load (#1224, #1213, #1214).
#1204 / #1132 / #1131: Relation resolution and vector prepare work are batched instead of serial, and a new
materialization_workerssetting (default 4) bounds concurrent write materializations.#1165: Relation-derived search refreshes are durable, retryable work items (#1163), pending relations refresh from accepted content (#1161, #1159), and forward references back-resolve when their target note is created, without a full reindex (#1015).
#1070: Added the
bm hookharness front door (SPEC-55, #997). Lifecycle verbs (session-start,pre-compact,stop) move plugin hook logic into the package behind per-harness stdin adapters. Default-on bounded envelope capture records lifecycle metadata into a local inbox WAL;bm hook flusharchives it locally,bm hook statusshows the surface, andcaptureEvents: falsedisables capture.bm hook install/bm hook removewire hooks into user-level harness config for standalone users with ownership-tagged, surgical merging. The Claude Code and Codex plugin hooks are now zero-logic PEP 723 uv scripts invokingbasic-memory hookin-process, withBM_BINoverriding the uv-managed environment for development.#1119: Plugins surface hook capture setup and health (#1117), and Claude Code hook config falls back to user-level
~/.claudesettings (#924).#1123 / #1138 / #1142 / #1147: Codex hooks and memory notes are reliable, checkpoints are authored and prompted after compaction, and checkpoints are directly resumable.
#1124 / #1126 / #1050: New skills:
bm-writingwith coding setup,bm-decide/bm-orient, and the sharedmemory-onboardingskill; coding session profiles are queryable (#1125).#965: New
bm cloud sharecommand group:create,list,update,revoke(#880).#1061: New
bm cloud pruneremoves.bmignored files from the cloud on demand (#1032; see Breaking Changes for the one-way sync behavior change).#1263: Team-workspace
bm cloud push/pullrun over the service's permissioned WebDAV surface instead of tenant-wide storage credentials, so any member can sync the projects they have access to — previously only workspace owners could provision the required credentials and every other member got a 403 (#1262). Same flags and semantics:--on-conflictstill defaults tofail, and transfers stay additive — nothing is ever deleted. Requires the updated cloud server, already deployed in production; the Personal rclone path is untouched.#1168 / #1172: Optional Redis read caching accelerates standalone MCP reads via the
basic-memory[redis]extra (redis_url,redis_max_connections) (#980).#1255: Semantic note reads make the minimum number of API requests — exact-ID reads skip resolve and resource calls entirely — and ordinary read-cache entries live 300 seconds instead of 60.
#1062 / #1074: Cloud project deletion errors are surfaced, with an optional notes purge and a visible deletion job (#1033, #1034).
#1145: First-connect MCP onboarding: server instructions, empty-state guidance, and a
getting_startedprompt for new users.#1090:
edit_noteaccepts ametadataparam to update frontmatter fields (#1011).#1075:
move_notereturns the previous accepted path (#1072).#1040 / #1101 / #1103:
external_idis exposed inlist_directory,recent_activity, search results, andsearch_notesmarkdown output.#1268:
list_directoryaccepts asortparameter (title_asc,title_desc,updated_asc,updated_desc) with deterministic folders-first ordering applied before pagination (#1267); omitting it keeps the existing filename order.#1031 / #1036 / #1037: MCP tool annotations are directory-compliant, destructive hints are explicit, and
edit_noteexposes its operation enum.
Bug Fixes
#1193 / #1202: Two indexing deadlock families are eliminated: Entity/NoteContent lock-order inversions during materialization and Entity/Observation inversions between indexing and accepted writes (#1187, #1199, #1209).
A one-time migration dedupes historical duplicate observation rows and purges their orphaned full-text search entries (companion to #1228).
#1247: Incremental
bm reindex --searchpurges stale search-index rows whose backing entity, observation, or relation is gone, so DB-only search divergence on unchanged files converges without a--fullrebuild (#1226; the last loose end of the #1214 repair).#1152 / #1160: Moves record a durable vacate marker, so a byte-identical copy at the old path indexes as a new note instead of being skipped as a lingering move source.
#1258: A note accepted while a project scan is in flight can no longer be deleted as "externally removed" — destructive project-index deletes re-verify the database lineage and the path's current absence from storage at apply time (#1256).
#1016: Direct on-disk edits picked up by the file watcher are now vector-embedded, so externally edited notes no longer go missing from semantic search until a reindex (closed by the vector-sync overhaul, #1129–#1131, #1141).
#1023: FastEmbed embeddings are L2-normalized for non-bge models, so semantic search no longer silently degrades to FTS-only.
#1071: SQLite full-text search covers complete note content — previously content beyond ~6000 characters was invisible (#1065) — and CJK terms work in the relaxed FTS fallback (#1022).
#1269: Full-text query relaxation counts non-Latin tokens, so Cyrillic, Greek, Hebrew, Arabic, and other non-Latin queries relax to an OR retry instead of silently degrading hybrid search to vector-only ranking, and combining marks stay inside their word so Devanagari and Thai terms are not shredded into fragments (extends the CJK-only fix from #1022).
#1069: Unknown semantic/hybrid result totals are explicit in structured search responses (#1068).
#1190:
bm reindex --embeddingswarns when the project has no synced entities instead of silently no-opping (#1184).#1196: A legacy pgvector embeddings schema no longer breaks
bm project info(#1195).#1151: Ambiguous identifier resolution fails loudly instead of returning the wrong note (#1148), and project-scoped entity resolution is separated from cross-project wikilink resolution (#1192, #1170).
#1272: Root-level wikilinks written as filename stems resolve via the
.mdfile-path fallback, and a forgiving underscore/hyphen/case alias resolves links in directly edited vaults — tried only after every exact identity, and failing closed when two files collide on the same alias (#1253).#1189: Note-type filters are case-canonicalized, so
Personandpersonmatch the same population (#1180).#1081:
write_noterejects filename-convention twins (kebab-case vs Title Case) instead of creating duplicate notes (#1077).#1073:
edit_notewith amemory://URL routes to the target project instead of creating phantom notes (#1066), and scopedmemory://URL paths are preserved (#1092).#1299:
build_contextbounds its traversal requests — primary pages cap at 50 results, related context at 100 per page, and negativemax_relatedis rejected instead of acting as an unbounded SQL limit — so a traversal call can no longer become a multi-megabyte vault export (#1296). Callers paginate or follow returnedmemory://links.#1285: Glob-filtered directory listings traverse subdirectories again:
file_name_globfilters results instead of accidentally pruning recursion, so*.mdwith depth 2 finds files inside subdirectories.#1188: Sync preserves malformed frontmatter instead of prepending a second frontmatter block that shadows
name/description(#1171).#1239: Timestamp-prefixed transcript lines and checkbox markers (
[x],[/],[>],[?]) no longer mint junk observation categories (#1219, #1241).#1271: Transcript timestamp ranges like
[24:33.098 - 24:41.260]no longer mint junk observation categories either — the remaining range-shaped case from #1239 (#1270).#1291: Prose bullets no longer mint typed relations: a sentence like
- Added [[Target]] to the rosterfiled a relation type calledAddedand silently dropped the rest of the line, including any further links in it. An explicit relation now ends at its target or its(context); anything else keeps every wikilink as a plainlinks_toedge (#1260).#1060:
schema_validatewith no arguments validates all schema-covered types instead of type "unknown" (#1013), and invalid schema-validation modes are rejected instead of silently degrading to warn (#1223, #1222).#1085: Re-adding a retained cloud project reindexes its existing notes (#1084).
#1010:
bm project listshows configured cloud-mode projects even when uncredentialed (#1003), and deleting the default project auto-reassigns the default instead of refusing (#1139).#1273: Re-selecting the project that is already the default no longer clears the default flag — a state that broke project discovery and every project-scoped MCP tool until a default was set again.
#1290: ChatGPT import no longer crashes on conversations missing
create_time— timestamps fall back toupdate_time, then the earliest message time, so the whole archive imports (#1276); undecodable import uploads return a 400 with the parse error instead of a 500.#1298: The update check no longer reports "up to date" when the Homebrew probe fails, no longer auto-runs
brew upgradefor an update inferred from PyPI metadata, and names the actual Homebrew target version it will install.#1300 / #1302: The multilingual-E5 prefix contract is documented — asymmetric FastEmbed models need
semantic_embedding_query_prefix/semantic_embedding_document_prefix, which already drive reindex through the embedding identity — along with custom-model selection, the installed FastEmbed catalog, and dimensions (#1264).#1058 / #1094:
bm doctornever prints a blank failure message, and migrations adapt to existing event loops (#1027).#1080: Loading config no longer recreates an empty
~/basic-memorydirectory as a side effect (#1029).#1057: Large projects no longer crash reindex on SQLite's bound-parameter limit (#1045).
#1218 / #1216: Windows: the MCP server no longer dies at startup on a log-cleanup race (#1211), note content no longer crashes log formatting during index retries (#1212), the watch service no longer crashes on mapped network drives (#1047), and a PermissionError during project scan no longer triggers mass index deletion (#1007).
#1059 / #1179: Hermes:
bm mcpchild processes no longer leak (#1017), and bm subprocesses no longer inherit Hermes's Python environment (#1093).#1274: Hermes: commands and skills register through Hermes's own registration APIs instead of private PluginManager writes, preserving the lifecycle ownership that cleans them up on provider unload (#1257); the slash-command monkeypatch docs are split by Hermes version so modern installs skip the legacy collector workaround (#1278), and the install docs require a Hermes release with managed manifest-v2 installation instead of the nonexistent
--pathoption (#1280, #1303).
Maintenance
#1113 / #1114: Dependency injection is consolidated behind the v2 composition roots (#1109).
#1122 / #1133–#1136 / #1229: The largest service god-files are split into focused modules (#1108).
Removed the hook-specific redaction subsystem, its
detect-secretsdependency, and the retired lifecycle projector compatibility module.Kept Milvus as a first-party optional vector backend while removing the unused Python entry-point registry for separately packaged vector adapters.
#1292 / #1293: The dev-release pipeline publishes again via PyPI trusted publishing — its version gate imported a hardcoded module version and had silently skipped every dev publish since the 0.22.1 bump.
#1304 / #1307: The concurrent-write convergence benchmark is ported into the canonical
/benchmarkspackage, and the read-load benchmark runs against the current MCP SDK's typed result fields.
v0.22.1 (2026-06-12)
Follow-up patch to v0.22.0. Fixes project and default-project resolution on fresh installs, MCP workspace routing, sync project selection, and CLI startup latency, plus a few MCP parity additions.
Features
Added a
workspaceparameter towrite_notefor parity withedit_note.#826: Added
titleandtagsannotations to all MCP tool decorators (phase 1).#930:
search_notesnow comma-splitsnote_types,entity_types, andcategories.#971: Added the manual-pages flow — manpage seed schema, flow docs, and verification fixes.
Bug Fixes
Fresh installs no longer fail when the projects table is empty: resolve now points them at project setup, the first project is promoted to default when the config default is missing from the database, the promoted default state is returned from the project-create API, and a default can be set when none is currently set. An existing database default is preserved when repairing a missing config default.
#949: Sync skips projects without an absolute local path and excludes orphan DB projects that are absent from config.
#952 / #981: Resolved workspace display names and tenant ids in qualified project routes, closing out the manual verification findings.
note_types/entity_types/categoriesare normalized on the direct-call path, with non-string list elements rejected.Vector-search hydration keys on
(type, id)to prevent id collisions.file_utilsrequires line-anchored frontmatter fences.CLI startup is faster: FastAPI and app imports are deferred out of CLI startup, and rich/typer modules are preloaded before an in-place upgrade.
config.jsonis written atomically.In-memory SQLite sessions are serialized so concurrent rollbacks cannot destroy writes.
Maintenance
Release recipes route through PRs and wait for the release PR merge to land before tagging; the release runbook is refreshed and stripped of user-specific absolute paths.
v0.22.0 (2026-06-11)
Team-safe cloud sync. New additive bm cloud push and bm cloud pull
commands work safely on shared Team workspaces, while the destructive mirror
commands are gated to Personal workspaces. Also: a large batch of MCP tool
fixes, search improvements, and embedding reliability work.
Features
#917: Added Team-safe
bm cloud push/bm cloud pull. Both are additive (they never delete on the destination) and abort on conflicts by default, git-style, with--on-conflict {fail|keep-local|keep-cloud|keep-both}. The destructivebm cloud sync/bm cloud bisyncmirrors are now gated to Personal workspaces.#920: Team push/pull uses per-workspace rclone remotes, so remotes and credentials stay scoped to each workspace.
#908: Search supports an observation category filter.
#809: Added an experimental LiteLLM embedding provider for semantic search (marked experimental, see #899).
#907:
bm tool write-noteaccepts--type.#906:
bm statusaccepts--waitand--timeout.Added the
bm tool delete-notecommand.#905: Improved workspace and cloud bisync command discoverability.
Bug Fixes
#931 / #946: Truncated observation permalinks are disambiguated to prevent search-index collisions, and
build_contextresolves observations by the same permalink the search index uses (#909, #929).#934:
edit_noterecovers when the file exists on disk but is not yet indexed (#581).#911 / #932 / #941: Comma-separated tags are split consistently in
parse_tagsand thesearch_notestags parameter, with input normalized for direct callers (#910).#933:
read_noteacceptspage/page_sizefor parity with sibling tools (#883).#914 / #904 / #916:
move_noteresolvesmemory://URLs, stops falsely rejecting same-project moves as cross-project, no longer reports false success across project boundaries, and mismatch guidance points at the landing path.#915: Navigation pagination is validated, and
recent_activityshows the correct project.#913:
bm toolcommands align with MCP behavior (error exit codes, overwrite handling, category support, defaults).#923:
bm cloud setupno longer overwrites an existing rclone remote (#922).#912: The
note_typessearch filter is case-insensitive.build_contextallows cross-project context traversal,write_noteresolves overwrite conflicts, and sync uses strict deferred relation resolution.Embedding reliability: FastEmbed vectors are L2-normalized (#843), corrupt FastEmbed model caches self-heal (#900), a single embedding provider is reused per process (#903),
sqlite-vecloads for the embedding-status query (#901), and engine disposal no longer crashes on the Postgres backend (#902).
Maintenance
Leaner, faster CI: testmon-selected branch builds, sharded Postgres jobs, and faster default test fixtures (#928, #938, #945).
Documented personal-vs-team cloud sync semantics (#947, closes #851).
Fixed npx skill install docs (#927).
Added
glama.jsonto claim the Glama MCP directory listing (#953).
v0.21.6 (2026-06-04)
Monorepo consolidation plus a redesigned Claude Code plugin. The satellite
repositories now live in the main basic-memory tree, and the plugin is
rebuilt as a memory bridge with a guided setup interview, capture skills, and
team workspaces. Codex, Hermes, and OpenClaw integration packages ship
alongside it.
Core
Consolidated the Basic Memory satellite repositories into the main
basic-memorytree as the canonical source, discovery, documentation, issue, and release home.Added root marketplace/package validation for the consolidated repository layout.
Added root and package-local justfile targets so Claude Code, Codex, skills, Hermes, and OpenClaw builds can be verified from the monorepo.
Removed the legacy
ui/directory.
API
Entity resolution now exposes the owning project on resolved entities so callers can route follow-up reads to the correct workspace/project.
CLI
Added an "auto BM" GitHub CI workflow that captures notes from CI runs.
Exposed project sync-support metadata and surfaced copyable workspace identifiers in project listings.
cloud loginnow surfaces non-subscription errors instead of masking them.Team workspaces block
rclone sync, with the team-workspace guard limited tobisync.
Claude Code
Rebuilt the Claude Code plugin as a memory bridge with SessionStart and PreCompact hooks, a bundled output style, and seeded note schemas.
Added the
/basic-memory:setupbootstrap interview and the/basic-memory:remember,/basic-memory:status, and/basic-memory:shareskills.Added team workspace support with attribution for shared writes.
Prefixed plugin skills with
bm-and installed the sharedmemory-*skills instead of duplicating them in the plugin.Hooks fall back to
uvx/uvwhen no CLI binary is on PATH.
Codex
Added the Codex plugin under
plugins/codex/with its native.codex-plugin, hooks, seeded schemas, andbm-*skills.
Skills
Added the shared Basic Memory
SKILL.mdcollection under top-levelskills/and ported useful retired plugin skills into thememory-*set.Fixed invalid picoschema enum YAML in the memory skills.
Hermes
Added the Hermes memory provider plugin under
integrations/hermes/with its native Python module,plugin.yaml, skill, tests, docs, and release metadata.
OpenClaw
Added the OpenClaw plugin under
integrations/openclaw/with its native npm/TypeScript package shape, tests, docs, and release metadata; skill bundling copies from the top-levelskills/source.
v0.21.5 (2026-05-26)
Workspace/project routing fixes for MCP, plus a SQLite vector reindex stability fix.
Bug Fixes
#854: MCP project listing now keeps duplicate cloud project rows distinct by workspace, so only the selected workspace row inherits local project state.
#853:
write_notereturns workspace-qualified permalinks for cloud workspace writes, allowing follow-upmemory://reads to route back to the correct workspace/project.#852: Full SQLite vector reindex now loads
sqlite-vecbefore droppingvec0virtual tables, preventing reindex crashes.#838: Local ASGI database initialization is preloaded so MCP routing can safely enter local project contexts.
v0.21.1 (2026-05-16)
CI-only release. No user-facing changes.
Maintenance
#833: Replace
mislav/bump-homebrew-formula-actionwith an inline bash bump step. The action'sresolveRedirectHEAD-requestsapi.github.com /repos/.../tarball/<ref>expecting HTTP 302; GitHub now returns 303 for authenticated requests on that endpoint, which broke the v0.21.0 Homebrew job and required a manual tap bump. The inline step does the same work (curl + sha256sum, clone tap, sed-bumpurl/sha256, commit, push) without any third-party dependency.
v0.21.0 (2026-05-16)
Workspace-aware everywhere: every MCP tool and CLI command now routes through the same workspace/project model, the search and sync paths are noticeably faster, and a handful of long-standing parsing and routing footguns are gone.
Breaking Changes
Relation parsing no longer treats unquoted multi-word text before a wikilink as a custom relation type. Use single-token relation types like
relates_to [[Target]], or quote multi-word relation types like"relates to" [[Target]]or'relates to' [[Target]].Bare list wikilinks like
- [[Target]]now index aslinks_to.Prose list items like
- some other thing [[Target]]now index aslinks_to.To preserve existing multi-word relation types on re-sync, quote them before upgrading.
See #824.
Features
#816:
bm orphanCLI command surfaces entities whose underlying markdown files are gone, with a flag to clean them out.#789: Create projects directly by cloud workspace slug from MCP (
create_memory_project(workspace=...)).#757: Discover projects across every accessible cloud workspace in MCP's project list — no more per-workspace blind spots.
#766: MCP tools accept training-data-friendly parameter aliases (
q/search/textforquery, etc.) so models reach for them naturally.#776:
bm db resetrefuses to run while abasic-memory mcpprocess is alive, so resets can no longer corrupt an open session.#791: Search responses include result totals so pagers can stop guessing.
#719: Cloud
note_contenttenant schema primitive lands on the backend.#715:
bm project addaccepts a--visibilityflag for cloud projects.
Bug Fixes
Search and recent activity
#832: SQLite project deletion now sweeps
search_index,search_vector_chunks, andsearch_vector_embeddings, so a project that reuses a recycled auto-increment id can't inherit the previous tenant's content.#812:
recent_activityorders and filters byupdated_at, so edits bubble to the top instead of staying pinned to creation time.#807: Multi-project
search_notesis opt-in (search_all_projects=True); default search stays scoped to the resolved project.#785:
recent_activitycaps responses and emits an explicit truncation footer instead of silently dropping rows.#713: Eliminated an N+1 query in search result hydration.
Workspace / project routing
#822:
bm project listnow includes projects from every workspace, not just the current one.#813, #808, #806, #803, #801, #795, #790, #778, #777, #722, #712, #704: Workspace-qualified permalink routing is centralized and applied consistently across
edit_note,delete_project,build_context,memory://URLs, factory-mode project listing, cloud uploads, and the API client.
Sync
#827:
rclone bisyncfilters from.bmignoreare preserved across syncs.#815: Watch service ignores hidden paths relative to the watched project, not just relative to
$HOME.#814:
scansubprocesses no longer go through the shell, avoiding quoting issues with paths that contain special characters.#759: Watch service stays inside
--projectscope.#746: Canonical markdown is preserved during single-file sync.
Parsing
#796: Picoschema modifier descriptions (
field?(modifier, description)) parse correctly.#769: Obsidian callout blocks are skipped by the observation parser instead of being mis-extracted as observations.
CLI
#775:
bm project set-cloud/set-localcleans up local DB state for the affected project.#773:
bm cloud logoutclearsdefault_workspace.#780:
bm cloud setuphint points atbm cloud sync-setup.#734:
bm project infoshows cloud index freshness.#718: Private cloud projects display under their
display_nameinstead of raw UUID.#768:
read_note/view_notedrop no-op pagination params from their signatures.
Stability
#774:
sqlite-vecfailures during init degrade gracefully to keyword-only search instead of crashing startup.#733: Delete-vector and cloud-sync cleanup is now consistent.
#702: Race conditions in concurrent
delete_entityare resolved.#724:
external_idis preserved when entities are re-upserted during a re-index.#728: Vector init no longer issues runtime
ALTER TABLE.#744:
BASIC_MEMORY_CONFIG_DIRis honored across remaining call sites.#743: FastEmbed cache lives under the data dir instead of
/tmp.#752: Cloud projects report
source=cloudin factory mode.Stripped null bytes from markdown content before DB insert.
Allowed long
relation_typevalues in API responses.
Installer
#772: Docker-compose config volume mounts under the
appuserhome.#695: Bumped
brew outdatedtimeout from 15s to 60s.
Performance
#828: CLI startup no longer pulls in the local ASGI FastAPI app when it isn't needed.
#751, #726, #717, #714, single-file/batch indexing: marked speedups on the sync hot path; unchanged markdown is skipped entirely.
#731, #723: Vector sync is faster on both backends, with tuned fastembed defaults.
Maintenance
#825: Dependency refresh + security hardening.
Updated to
fastmcp3.3.1.#754: Removed in-house telemetry wrappers in favor of direct
logfireusage.#736:
tyis now the default typechecker.#771, #770, #716: New regression guards for vector-row cleanup, long relation types, and recent activity hydration.
v0.20.3 (2026-03-26)
Bug Fixes
#698: CLI cloud commands now use API key when configured
get_authenticated_headers()only checked OAuth tokens, ignoringconfig.cloud_api_keyAll CLI cloud commands (
upload,status,snapshot,restore, etc.) failed for API-key-only users while MCP tools worked fineNow mirrors the same credential priority as MCP: API key first, OAuth fallback
Fixes
bm cloud upload --projectreturning "project does not exist" when authenticated withbmc_*API key
v0.20.2 (2026-03-10)
Bug Fixes
Fix auto-update Homebrew detection:
brew outdatedexits 1 when a formula is outdated, not on errorPreviously treated exit code 1 as a failure, causing "Automatic update check failed" instead of detecting the available update
v0.20.1 (2026-03-10)
Bug Fixes
#661: Fix
bm project listMCP column to show transport type (stdio/https) instead of DB presenceRenamed "MCP (stdio)" column to "MCP"
Shows actual routing mode:
stdiofor local,httpsfor cloud projectsClears local path display for cloud-mode projects
#662: Invalidate config cache when file is modified by another process
Adds mtime-based cache validation to
ConfigManager.load_config()Long-lived processes (MCP stdio server) now detect external config changes
Fixes
bm project set-cloudhaving no effect on running MCP server
v0.20.0 (2026-03-10)
Features
#643: Default-on auto-update system and
bm updatecommandAutomatic background update checks for CLI installs (uv tool, Homebrew)
Install-source detection (homebrew, uv_tool, uvx, unknown) with uvx skip behavior
Periodic check gating via
auto_update_last_checked_at+update_check_intervalconfigManager-specific update flows: Homebrew (
brew upgrade) and uv tool (uv tool upgrade)Silent, non-blocking MCP behavior via daemon thread before server run
Manual commands:
bm update(force check + apply) andbm update --check(check only)New config fields:
auto_update,update_check_interval,auto_update_last_checked_at
v0.19.2 (2026-03-09)
Bug Fixes
#657: Coerce string params to list/dict in MCP tools
MCP clients that serialize
list/dictarguments as JSON strings no longer fail Pydantic validationAdds
BeforeValidatorcoercion tosearch_notes(entity_types,note_types,tags,metadata_filters),write_note(metadata), andcanvas(nodes,edges)
#655: Handle SQLite and Windows semantic search regressions
Fix embedding status query for non-semantic SQLite databases
Windows-safe log file rotation with per-process log filenames
Robust
setup_loggingthat handles all environments cleanly
v0.19.1 (2026-03-08)
Bug Fixes
#649: Enforce strict entity resolution in destructive MCP tools (
edit_note,move_note,delete_note)Prevents fuzzy-match fallback from silently editing/moving/deleting the wrong note
DST-related timeframe validation fix (round instead of truncate days)
Features
#648: Add
insert_before_sectionandinsert_after_sectionedit operationsAdd
GET /knowledge/graphendpoint for full graph visualization
Dependencies
Bump authlib from 1.6.6 to 1.6.7
v0.19.0 (2026-03-07)
Highlights
Semantic vector search for SQLite and Postgres with FastEmbed embeddings
Schema system for validating and inferring knowledge base structure
Per-project cloud routing with API key authentication
Upgraded to FastMCP 3.0 with tool annotations
CLI overhaul with JSON output, workspace awareness, and project dashboard
Features
#550: Add semantic vector search for SQLite and Postgres
FastEmbed-based embeddings with automatic backfill
Hybrid search combining full-text and vector similarity
Score-based fusion replacing RRF for better ranking
min_similarityoverride for tuning search precisionSemantic dependencies are now default, with optional extras fallback
#549: Schema system for Basic Memory
schema_infer— infer schema from existing notesschema_validate— validate notes against a schema definitionschema_diff— compare schemas across projectsFrontmatter validation support (#597)
Read schema definitions from file instead of stale DB metadata (#635)
#555: Per-project local/cloud routing with API key auth
Individual projects route through cloud while others stay local
basic-memory cloud set-keyandbasic-memory project set-cloud/set-localStdio MCP honors per-project cloud routing (#590)
#598: Upgrade FastMCP 2.12.3 to 3.0.1 with tool annotations
#585: Add JSON output mode for MCP tools (default text)
--jsonoutput for CLI commands for scripting and CI
#576: Add workspace selection flow for MCP and CLI
Workspace-aware cloud project listing
CLI refactoring for workspace support
#544: Project-prefixed permalinks and memory URL routing
#632: Add overwrite guard to
write_notetool#614:
edit_noteappend/prepend auto-creates note if not found#609: Richer content context in search results
Return matched chunk text in search results (#601)
Improved content hit rate
#602: Add
created_byandlast_updated_byuser tracking to Entity#600: Rename
entity_typetonote_typeacross codebase#574: Add
display_nameandis_privateto ProjectItem#569: Expose
external_idin EntityResponse and link resolver#567: Isolate default SQLite DB by config dir
#560: Enable
default_project_modeby default#559: Add
basic-memory watchCLI command#546: Add cloud discovery touchpoints to CLI and MCP
#572: CLI analytics via Umami event collector
Replace project info with htop-inspired dashboard
Merge
search_by_metadataintosearch_noteswith optional queryAdd
--strip-frontmattertobasic-memory tool read-noteAdd
destination_folderparameter tomove_notetool
Bug Fixes
#644: Fix default project resolution in cloud mode
ChatGPT search/fetch tools broken in cloud mode
resolve_project_parameterfalls back to projects API
#638: Restore API backward compatibility for v0.18.x clients
#637: Create backup before config migration overwrites old format
#636:
list_workspacesbypasses factory pattern on cloud MCP server#631:
build_contextrelated_results schema validation failure#613: Reduce excessive log volume by demoting per-request noise to DEBUG
#612: Handle quoted picoschema enum strings in YAML frontmatter
#607: Guard against closed streams in promo and missing vector tables
#606: Accept null for
expected_replacementsinedit_note#595:
recent_activitydedup and pagination across MCP tools#593: Backend-specific distance-to-similarity conversion
#582: Use LinkResolver fallback in
build_contextfor flexible identifier matching#577: Replace RRF with score-based fusion in hybrid search
#575: Remove hardcoded "main" default from
default_project#534: Speed up
bm --versionstartupFix semantic embeddings not generated on fresh DB or upgrade
Clarify
search_notesparameter naming and fixnote_typescase sensitivityParse
tag:prefix at MCP tool level to avoid hybrid search failureCap sqlite-vec knn k parameter at 4096 limit
Parameterize SQL queries in search repository type filters
Coerce list frontmatter values to strings for title and type fields
Avoid
Post(**metadata)crash when frontmatter contains 'content' or 'handler' keysUpgrade cryptography and python-multipart for security advisories
Internal
#594: Add
tyas supplemental type checkerBatched vector sync orchestration across repositories
FastEmbed parallel guardrails and provider caching
Improved cloud CLI status and error messages
CI coverage and Postgres test fixes
v0.18.5 (2026-02-13)
Bug Fixes
Strip NUL bytes from content before PostgreSQL search indexing (
ec9b2c4)
v0.18.4 (2026-02-12)
Bug Fixes
Use global
--headerflag for Tigris consistency on all rclone transactions (0eae0e1)--header-download/--header-uploadonly apply to GET/PUT requests, missing S3 ListObjectsV2 calls that bisync issues first. Non-US users saw stale edge-cached metadata.--headerapplies to ALL HTTP transactions (list, download, upload), fixing bisync for users outside the Tigris origin region.
v0.18.2 (2026-02-11)
Bug Fixes
#562: Use VIRTUAL instead of STORED columns in SQLite migration (
344e651)Fixes compatibility issue with SQLite STORED generated columns
v0.18.1 (2026-02-11)
Features
#552: Add
--format jsonto CLI tool commands (a47c9c0)CLI tool commands now support
--format jsonfor machine-readable output
#535: Support
tag:query shorthand in search (f1d50c2)Use
tag:mytagas a convenient shorthand in search queries
#532: Fast edit entities, refactors for webui, enhanced search (
530cbac)Performance improvements for entity editing and search operations
Bug Fixes
#558: Add X-Tigris-Consistent headers to all rclone commands (
8489a3d)Ensures consistent reads from Tigris object storage during sync
#541: Handle EntityCreationError as conflict (
343a6e1)#536: Stabilize metadata filters on Postgres (
009e849)#533: Fix recent_activity prompt defaults (
24ca5f6)#530: Prevent spurious
metadata: {}in frontmatter output (e3ced49)Add POST legacy compat routes for v0.18.0 CLI (
c46d7a6)Restore legacy
/projects/projectsendpoint for older CLI versions (a0e754b)
Internal
#538: Add fast feedback loop tooling (
just fast-check,just doctor,just testmon) (8072449)
v0.18.0 (2026-01-28)
Features
#527: Add context-aware wiki link resolution with source_path support (
0023e73)Add
source_pathparameter toresolve_link()for context-aware resolutionRelative path resolution:
[[nested/note]]fromfolder/file.md→folder/nested/note.mdProximity-based resolution for duplicate titles (prefers notes in same folder)
Strict mode to disable fuzzy search fallback for wiki links
#518: Add directory support to move_note and delete_note tools (
0b20801)Add
is_directoryparameter tomove_noteanddelete_noteMCP toolsNew
POST /move-directoryand delete directory API endpointsRename
folder→directoryparameter across codebase for consistency
#522: Local MCP cloud mode routing (
8730067)Add
--localand--cloudCLI routing flagsLocal MCP server (
basic-memory mcp) automatically uses local routingEnables simultaneous use of local Claude Desktop and cloud-based clients
Environment variable
BASIC_MEMORY_FORCE_LOCAL=truefor global override
Bug Fixes
#524: Fix MCP prompt rendering errors (
e14ba92)Fix "Error rendering prompt recent_activity" error
Change
TimeFrametostrin prompt type annotations for FastMCP compatibility
v0.17.9 (2026-01-24)
Bug Fixes
#523: Fix
remove_project()checking stale config in cloud mode (17c0e0a)In cloud mode, only check database
is_defaultfield (source of truth)Config file can become stale when users set default project via v2 API
v0.17.8 (2026-01-24)
Bug Fixes
#521: Fix
get_default_project()returning multiple results (6888eff)Query incorrectly matched any project with non-NULL
is_default(both True and False)Now correctly checks for
is_default=Trueonly
v0.17.7 (2026-01-24)
Features
#476: Add SPEC-29 Phase 3 bucket snapshot CLI commands (
369ad37)New
basic-memory cloud snapshotcommands for managing cloud snapshotsCommands:
create,list,delete,show,browse
#515: Add MCP registry publication files (
7a502e6)
Bug Fixes
#520: Read default project from database in cloud mode (
38616c3)#513: Ensure external_id is set on entity creation (
c7835a9)
Internal
v0.17.6 (2026-01-17)
Bug Fixes
#510: Fix Docker container Python symlink broken at runtime (
1799c94)
Internal
Remove logfire config and specs docs, reduce lifespan and sync logging to debug level (
d1d433d,803f3ef)
v0.17.5 (2026-01-11)
Bug Fixes
#505: Prevent CLI commands from hanging on exit (Python 3.14 compatibility) (
863e0a4)Skip
nest_asyncioon Python 3.14+ where it causes event loop issuesSimplify CLI test infrastructure for cross-version compatibility
Update pyright to 1.1.408 for Python 3.14 support
Fix SQLAlchemy rowcount typing for Python 3.14
v0.17.4 (2026-01-05)
Bug Fixes
#503: Preserve search index across server restarts (
26f7e98)Fixes critical bug where search index was wiped on every MCP server restart
Bug was introduced in v0.16.3, affecting v0.16.3-v0.17.3
User action: Run
basic-memory resetonce after updating to rebuild search index
Internal
#502: Major architecture refactor with composition roots and typed API clients (
5947f04)Add composition roots for API, MCP, and CLI entrypoints
Split deps.py into feature-scoped modules (config, db, projects, repositories, services, importers)
Add ProjectResolver for unified project selection
Add SyncCoordinator for centralized sync/watch lifecycle
Introduce typed API clients for MCP tools (KnowledgeClient, SearchClient, MemoryClient, etc.)
v0.17.3 (2026-01-03)
Features
#485: Add stable external_id (UUID) to Project and Entity models (
a4000f6)Projects and entities now have immutable UUID identifiers
API v2 endpoints use external_id for stable references
Directory responses include external_id for entities
Bug Fixes
#501: Update mcp dependency to support protocol version 2025-11-25 (
c6baf58)Fixes "Unsupported protocol version" error when using Claude Code
Bump mcp from >=1.2.0 to >=1.23.1
#499: Fix route ordering for cloud deployments (
53c4c20)#486: Skip config file update for set_default_project in cloud mode (
fd732aa)#484: Make RelationResponse.from_id optional to handle null permalinks (
537e58a)Use upsert to prevent IntegrityError during parallel search indexing (
4ce2198)Use relative file paths in importers for cloud storage compatibility (
8adf1f4)
Internal
Refactor importers to use FileService for cloud compatibility (
45ce181)Strengthen integration test coverage, remove stdlib mocks (
b4486d2)
v0.17.2 (2025-12-29)
Bug Fixes
Allow recent_activity discovery mode in cloud mode (
0bcda4a)Add
allow_discoveryparameter toresolve_project_parameter()Tools like
recent_activitycan now work across all projects in cloud modeFix circular import in project_context module
Internal
Optimize release workflow by running lint/typecheck only (skip full tests) (
0b5425f)
v0.17.1 (2025-12-29)
Bug Fixes
#482: Only set BASIC_MEMORY_ENV=test during pytest runs (
98fbd60)Fixes environment variable pollution affecting alembic migrations
Test environment detection now scoped to pytest execution only
v0.17.0 (2025-12-28)
Features
#478: Add anonymous usage telemetry with Homebrew-style opt-out (
856737f)Privacy-respecting anonymous usage analytics
Easy opt-out via
BASIC_MEMORY_NO_ANALYTICS=1environment variableHelps improve Basic Memory based on real usage patterns
#474: Add auto-format files on save with built-in Python formatter (
1fd680c)Automatic markdown formatting on file save
Built-in Python formatter for consistent code style
Configurable formatting options
#447: Complete Phase 2 of API v2 migration - MCP tools use v2 endpoints (
1a74d85)All MCP tools now use optimized v2 API endpoints
Improved performance for knowledge graph operations
Foundation for future API enhancements
Bug Fixes
Fix UTF-8 BOM handling in frontmatter parsing (
85684f8)Handles files with UTF-8 byte order marks correctly
Prevents frontmatter parsing failures
#475: Handle null titles in ChatGPT import (
14ce5a3)Gracefully handles conversations without titles
Improved import robustness
Remove MaxLen constraint from observation content (
45d6caf)Allows longer observation content without truncation
Removes arbitrary 2000 character limit
Handle FileNotFoundError gracefully during sync (
1652f86)Prevents sync failures when files are deleted during sync
More resilient file watching
Use canonical project names in API response messages (
c23927d)Consistent project name formatting in all responses
Suppress CLI warnings for cleaner output (
d71c6e8)Cleaner terminal output without spurious warnings
Prevent DEBUG logs from appearing on CLI stdout (
63b9849)Debug logging no longer pollutes CLI output
#473: Detect rclone version for --create-empty-src-dirs support (
622d37e)Automatic rclone version detection for compatibility
Prevents errors on older rclone versions
#471: Prevent CLI commands from hanging on exit (
916baf8)Fixes CLI hang on shutdown
Proper async cleanup
Add cloud_mode check to initialize_app() (
ef7adb7)Correct initialization for cloud deployments
Internal
Centralize test environment detection in config.is_test_env (
3cd9178)Unified test environment detection
Disables analytics in test environments
Make test-int-postgres compatible with macOS (
95937c6)Cross-platform PostgreSQL testing support
v0.16.3 (2025-12-20)
Features
#439: Add PostgreSQL database backend support (
fb5e9e1)Full PostgreSQL/Neon database support as alternative to SQLite
Async connection pooling with asyncpg
Alembic migrations support for both backends
Configurable via
BASIC_MEMORY_DATABASE_BACKENDenvironment variable
#441: Implement API v2 with ID-based endpoints (Phase 1) (
28cc522)New ID-based API endpoints for improved performance
Foundation for future API enhancements
Backward compatible with existing endpoints
Add project_id to Relation and Observation for efficient project-scoped queries (
a920a9f)Enables faster queries in multi-project environments
Improved database schema for cloud deployments
Add bulk insert with ON CONFLICT handling for relations (
0818bda)Faster relation creation during sync operations
Handles duplicate relations gracefully
Performance
Lightweight permalink resolution to avoid eager loading (
6f99d2e)Reduces database queries during entity lookups
Improved response times for read operations
Bug Fixes
#464: Pin FastMCP to 2.12.3 to fix MCP tools visibility (
f227ef6)Fixes issue where MCP tools were not visible to Claude
Reverts to last known working FastMCP version
#458: Reduce watch service CPU usage by increasing reload interval (
897b1ed)Lowers CPU usage during file watching
More efficient resource utilization
#456: Await background sync task cancellation in lifespan shutdown (
efbc758)Prevents hanging on shutdown
Clean async task cleanup
#434: Respect --project flag in background sync (
70bb10b)Background sync now correctly uses specified project
Fixes multi-project sync issues
#446: Fix observation parsing and permalink limits (
73d940e)Handles edge cases in observation content
Prevents permalink truncation issues
#424: Handle periods in kebab_filenames mode (
b004565)Fixes filename handling for files with multiple periods
Improved kebab-case conversion
Fix Postgres/Neon connection settings and search index dedupe (
b5d4fb5)Optimized connection pooling for Postgres
Prevents duplicate search index entries
Testing & CI
Replace py-pglite with testcontainers for Postgres testing (
c462faf)More reliable Postgres testing infrastructure
Uses Docker-based test containers
Add PostgreSQL testing to GitHub Actions workflow (
66b91b2)CI now tests both SQLite and PostgreSQL backends
Ensures cross-database compatibility
#416: Add integration test for read_note with underscored folders (
0c12a39)Verifies folder name handling edge cases
Internal
Cloud compatibility fixes and performance improvements (#454)
Remove logfire instrumentation for cleaner production deployments
Truncate content_stems to fix Postgres 8KB index row limit
v0.16.2 (2025-11-16)
Bug Fixes
#429: Use platform-native path separators in config.json (
6517e98)Fixes config.json path separator issues on Windows
Uses os.path.join for platform-native path construction
Ensures consistent path handling across platforms
#427: Add rclone installation checks for Windows bisync commands (
1af0539)Validates rclone installation before running bisync commands
Provides clear error messages when rclone is not installed
Improves user experience on Windows
#421: Main project always recreated on project list command (
cad7019)Fixes issue where main project was recreated unnecessarily
Improves project list command reliability
Reduces unnecessary file system operations
v0.16.1 (2025-11-11)
Bug Fixes
#422: Handle Windows line endings in rclone bisync (
e9d0a94)Added
--compare=modtimeflag to rclone bisync to ignore size differences from line ending conversionsFixes issue where LF→CRLF conversion on Windows was treated as file corruption
Resolves "corrupted on transfer: sizes differ" errors during cloud sync on Windows
Users will need to run
--resynconce after updating to establish new baseline
v0.16.0 (2025-11-10)
Features
#417: Add run_in_background parameter to sync endpoint (
7ccec7e)New
run_in_backgroundparameter for async sync operationsImproved API flexibility for long-running sync tasks
Comprehensive test coverage for background sync behavior
#405: SPEC-20 Simplified Project-Scoped Rclone Sync (
0b3272a)Simplified and more reliable cloud synchronization
Project-scoped rclone configuration
Better error handling and status reporting
#384: Streaming Foundation & Async I/O Consolidation (SPEC-19) (
e78345f)Foundation for streaming support in future releases
Consolidated async I/O patterns across codebase
Improved performance and resource management
#364: Add circuit breaker for file sync failures (
434cdf2)Prevents cascading failures during sync operations
Automatic recovery from transient errors
Better resilience in cloud sync scenarios
#362: Add --verbose and --no-gitignore options to cloud upload (
7f9c1a9)Enhanced upload control with verbose logging
Option to bypass gitignore filtering when needed
Better debugging and troubleshooting capabilities
#391: Add delete_notes parameter to remove project endpoint (
c9946ec)Option to delete notes when removing projects
Safer project cleanup workflows
Prevents accidental data loss
Bug Fixes
#420: Skip archive files during cloud upload (
49b2adc)Prevents uploading of zip, tar, gz and other archive files
Reduces storage usage and upload time
Better file filtering during cloud operations
#419: Rename write_note entity_type to note_type for clarity (
1646572)Clearer parameter naming in write_note tool
Improved API consistency and documentation
Better developer experience
#418: Quote string values in YAML frontmatter to handle special characters (
f0d7398)Fixes YAML parsing errors with special characters
More robust frontmatter handling
Prevents data corruption in edge cases
#415: Handle dict objects in write_resource endpoint (
4614fd0)Fixes errors when writing dictionary resources
Better type handling in resource endpoints
Improved API robustness
#414: Replace Unicode arrows with ASCII for Windows compatibility (
fc01f6a)Fixes display issues on Windows terminals
Better cross-platform compatibility
Improved CLI user experience on Windows
#411: Windows CLI Unicode encoding errors (
0ba6f21)Resolves Unicode encoding issues on Windows
Better handling of international characters
Improved Windows platform support
#410: Various rclone fixes for cloud sync on Windows (
c9946ec)Fixes cloud sync reliability on Windows
Better path handling for Windows filesystem
Improved rclone integration on Windows
#402: Normalize YAML frontmatter types to prevent AttributeError (
a7d7cc5)Fixes AttributeError when reading frontmatter
More robust type normalization
Better error handling in markdown parsing
#396: Strip duplicate headers in edit_note replace_section (
021af74)Prevents duplicate headers when replacing sections
Cleaner note editing behavior
Better content consistency
#395: Simplify search_notes schema by removing Optional wrappers (
d775f7b)Cleaner API schema definition
Better type safety and validation
Improved developer experience
#394: Add explicit type annotations to MCP tool parameters (
581b7b1)Better type safety in MCP tools
Improved IDE support and autocomplete
Clearer tool documentation
#389: Handle null, empty, and string 'None' title in markdown frontmatter (
bb8da31)Fixes errors with malformed frontmatter titles
More robust title handling
Better error recovery
#380: Optimize sync memory usage to prevent OOM on large projects (
4fd6d0c)Prevents out-of-memory errors on large knowledge bases
Better memory management during sync
Improved scalability
#379: Handle YAML parsing errors gracefully in update_frontmatter (
32236cd)Better error handling for malformed YAML
Graceful degradation instead of crashes
Improved robustness
#377: Preserve mtime on WebDAV upload (
e6c8e36)Maintains file modification times during upload
Better sync accuracy
Prevents unnecessary re-syncing
#370: Prevent deleted projects from being recreated by background sync (
449b62d)Fixes race condition with project deletion
Better lifecycle management
Prevents unwanted project recreation
#369: Use filesystem timestamps for entity sync instead of database operation time (
b7497d7)More accurate sync detection
Better handling of external file modifications
Improved sync reliability
#368: Handle YAML parsing errors and missing entity_type in markdown files (
d1431bd)Better error handling for malformed markdown
Graceful handling of missing metadata
Improved robustness
#367: Resolve UNIQUE constraint violation in entity upsert with observations (
171bef7)Fixes database constraint errors during sync
Better handling of duplicate observations
Improved data integrity
#366: Terminate sync immediately when project is deleted (
729a5a3)Faster project deletion
Better resource cleanup
Improved user experience
#357: Make project creation endpoint idempotent (
53fb13b)Prevents errors when creating existing projects
Better API reliability
Improved cloud integration
#353: Handle None text values in Claude conversations importer (
bd6c834)Fixes import errors with empty messages
Better error handling in importers
Improved data migration
Performance Improvements
Force full database sync after project sync/bisync operations (
2ad0ee9)Ensures database consistency after cloud operations
Better sync reliability
Improved data integrity
Documentation
Add free trial information to README (
a7d7cc5,8aaddb6)Updated README with Basic Memory Cloud trial info
Better onboarding experience
Clearer pricing information
Announce Basic Memory Cloud launch in README (
d756531)Official cloud service announcement
Updated documentation for cloud features
Improved product positioning
Migration Guide
No manual migration required. Upgrade with:
# Update via uv
uv tool upgrade basic-memory
# Or install fresh
uv tool install basic-memoryWhat's New in v0.16.0:
Streaming foundation and consolidated async I/O (SPEC-19)
Simplified project-scoped rclone sync (SPEC-20)
Circuit breaker for sync failure resilience
Enhanced Windows platform support
Improved cloud upload with verbose and gitignore options
Better error handling across YAML parsing and frontmatter
Memory optimization for large projects
Archive file filtering during upload
Breaking Changes:
write_noteparameter renamed:entity_type→note_typefor clarity
Installation
# Latest stable release
uv tool install basic-memory
# Update existing installation
uv tool upgrade basic-memory
# Docker
docker pull ghcr.io/basicmachines-co/basic-memory:v0.16.0v0.15.2 (2025-10-14)
Features
#356: Add WebDAV upload command for cloud projects (
5258f45)New
bm cloud uploadcommand for uploading local files/directories to cloud projectsWebDAV-based file transfer with automatic directory creation
Support for
.gitignoreand.bmignorepattern filteringAutomatic project creation with
--create-projectflagOptional post-upload sync with
--syncflag (enabled by default)Human-readable file size reporting (bytes, KB, MB)
Comprehensive test coverage (28 unit tests)
Migration Guide
No manual migration required. Upgrade with:
# Update via uv
uv tool upgrade basic-memory
# Or install fresh
uv tool install basic-memoryWhat's New:
Upload local files to cloud projects with
bm cloud uploadStreamlined cloud project creation and management
Better file filtering with gitignore integration
Installation
# Latest stable release
uv tool install basic-memory
# Update existing installation
uv tool upgrade basic-memory
# Docker
docker pull ghcr.io/basicmachines-co/basic-memory:v0.15.2v0.15.1 (2025-10-13)
Performance Improvements
#352: Optimize sync/indexing for 43% faster performance (
c0538ad)Significant performance improvements to file synchronization and indexing operations
43% reduction in sync time for large knowledge bases
Optimized database queries and file processing
#350: Optimize directory operations for 10-100x performance improvement (
00b73b0)Dramatic performance improvements for directory listing operations
10-100x faster directory traversal depending on knowledge base size
Reduced memory footprint for large directory structures
Exclude null fields from directory endpoint responses for smaller payloads
Bug Fixes
#355: Update view_note and ChatGPT tools for Claude Desktop compatibility (
2b7008d)Fix view_note tool formatting for better Claude Desktop rendering
Update ChatGPT tool integration for improved compatibility
Enhanced artifact display in Claude Desktop interface
#348: Add permalink normalization to project lookups in deps.py (
a09066e)Fix project lookup failures due to case sensitivity
Normalize permalinks consistently across project operations
Improve project switching reliability
#345: Project deletion failing with permalink normalization (
be352ab)Fix project deletion errors related to permalink handling
Ensure proper cleanup of project resources
Improve error messages for deletion failures
#341: Correct ProjectItem.home property to return path instead of name (
3e876a7)Fix ProjectItem.home to return correct project path
Resolve configuration issues with project paths
Improve project path resolution consistency
#339: Prevent nested project paths to avoid data conflicts (
795e339)Block creation of nested project paths that could cause data conflicts
Add validation to prevent project path hierarchy issues
Improve error messages for invalid project configurations
#338: Normalize paths to lowercase in cloud mode to prevent case collisions (
07e304c)Fix path case sensitivity issues in cloud deployments
Normalize paths consistently across cloud operations
Prevent data loss from case-insensitive filesystem collisions
#336: Cloud mode path validation and sanitization (bmc-issue-103) (
2a1c06d)Enhanced path validation for cloud deployments
Improved path sanitization to prevent security issues
Better error handling for invalid paths in cloud mode
#332: Cloud mode path validation and sanitization (
7616b2b)Additional cloud mode path fixes and improvements
Comprehensive path validation for cloud environments
Security enhancements for path handling
Features
#344: Async client context manager pattern for cloud consolidation (SPEC-16) (
8d2e70c)Refactor async client to use context manager pattern
Improve resource management and cleanup
Enable better dependency injection for cloud deployments
Foundation for cloud platform consolidation
#343: Add SPEC-15 for configuration persistence via Tigris (
53438d1)Design specification for persistent configuration storage
Foundation for cloud configuration management
Tigris S3-compatible storage integration planning
#334: Introduce BASIC_MEMORY_PROJECT_ROOT for path constraints (
ccc4386)Add environment variable for constraining project paths
Improve security by limiting project creation locations
Better control over project directory structure
Documentation
#335: v0.15.0 assistant guide updates (
c6f93a0)Update AI assistant guide for v0.15.0 features
Improve documentation for new MCP tools
Better examples and usage patterns
#339: Add tool use documentation to write_note for root folder usage (
73202d1)Document how to use empty string for root folder in write_note
Clarify folder parameter usage
Improve tool documentation clarity
Fix link in ai_assistant_guide resource (
2a1c06d)Correct broken documentation links
Improve resource accessibility
Refactoring
Add SPEC-17 and SPEC-18 documentation (
962d88e)New specification documents for future features
Architecture planning and design documentation
Breaking Changes
None - This release maintains full backward compatibility with v0.15.0
Migration Guide
No manual migration required. Upgrade with:
# Update via uv
uv tool upgrade basic-memory
# Or install fresh
uv tool install basic-memoryWhat's Fixed:
Significant performance improvements (43% faster sync, 10-100x faster directory operations)
Multiple cloud deployment stability fixes
Project path validation and normalization issues resolved
Better Claude Desktop and ChatGPT integration
What's New:
Context manager pattern for async clients (foundation for cloud consolidation)
BASIC_MEMORY_PROJECT_ROOT environment variable for path constraints
Enhanced cloud mode path handling and security
SPEC-15 and SPEC-16 architecture documentation
Installation
# Latest stable release
uv tool install basic-memory
# Update existing installation
uv tool upgrade basic-memory
# Docker
docker pull ghcr.io/basicmachines-co/basic-memory:v0.15.1v0.15.0 (2025-10-04)
Critical Bug Fixes
Permalink Collision Data Loss Prevention - Fixed critical bug where creating similar entity names would overwrite existing files (
2a050ed)Issue: Creating "Node C" would overwrite "Node A.md" due to fuzzy search incorrectly matching similar file paths
Solution: Added
strict=Trueparameter to link resolution, disabling fuzzy search fallback during entity creationImpact: Prevents data loss from false positive path matching like "edge-cases/Node A.md" vs "edge-cases/Node C.md"
Testing: Comprehensive integration tests and MCP-level permalink collision tests added
Status: Manually verified fix prevents file overwrite in production scenarios
Bug Fixes
#330: Remove .env file loading from BasicMemoryConfig (
f3b1945)Clean up configuration initialization to prevent unintended environment variable loading
#329: Normalize underscores in memory:// URLs for build_context (
f5a11f3)Fix URL normalization to handle underscores consistently in memory:// protocol
Improve knowledge graph navigation with standardized URL handling
#328: Simplify entity upsert to use database-level conflict resolution (
ee83b0e)Leverage SQLite's native UPSERT for cleaner entity creation/update logic
Reduce application-level complexity by using database conflict resolution
#312: Add proper datetime JSON schema format annotations for MCP validation (
a7bf42e)Fix MCP schema validation errors with proper datetime format annotations
Ensure compatibility with strict MCP schema validators
#281: Fix move_note without file extension (
3e168b9)Allow moving notes by title alone without requiring .md extension
Improve move operation usability and error handling
#310: Remove obsolete update_current_project function and --project flag reference (
17a6733)Clean up deprecated project management code
Remove unused CLI flag references
#309: Make sync operations truly non-blocking with thread pool (
1091e11)Move sync operations to background thread pool for improved responsiveness
Prevent blocking during file synchronization operations
Features
#327: CLI Subscription Validation (SPEC-13 Phase 2) (
ace6a0f)Implement subscription validation for CLI operations
Foundation for future cloud billing integration
#322: Cloud CLI sync via rclone bisync (
99a35a7)Add bidirectional cloud synchronization using rclone
Enable local-cloud file sync with conflict detection
#315: Implement SPEC-11 API performance optimizations (
5da97e4)Comprehensive API performance improvements
Optimized database queries and response times
#314: Integrate ignore_utils to skip .gitignored files in sync process (
33ee1e0)Respect .gitignore patterns during file synchronization
Prevent syncing build artifacts and temporary files
#313: Add disable_permalinks config flag (
9035913)Optional permalink generation for users who don't need them
Improves flexibility for different knowledge management workflows
#306: Implement cloud mount CLI commands for local file access (
2c5c606)Mount cloud files locally using rclone for real-time editing
Three performance profiles: fast (5s), balanced (10-15s), safe (15s+)
Cross-platform rclone installer with package manager fallbacks
#305: ChatGPT tools for search and fetch (
f40ab31)Add ChatGPT-specific search and fetch tools
Expand AI assistant integration options
#298: Implement SPEC-6 Stateless Architecture for MCP Tools (
a1d7792)Redesign MCP tools for stateless operation
Enable cloud deployment with better scalability
#296: Basic Memory cloud upload (
e0d8aeb)Implement file upload capabilities for cloud storage
Foundation for cloud-hosted Basic Memory instances
#291: Merge Cloud auth (
3a6baf8)OAuth 2.1 authentication with Supabase integration
JWT-based tenant isolation for multi-user cloud deployments
Platform & Infrastructure
#331: Add Python 3.13 to test matrix (
16d7edd)Ensure compatibility with latest Python version
Expand CI/CD testing coverage
#316: Enable WAL mode and add Windows-specific SQLite optimizations (
c83d567)Enable Write-Ahead Logging for better concurrency
Platform-specific SQLite optimizations for Windows users
#320: Rework lifecycle management to optimize cloud deployment (
ea2e93d)Optimize application lifecycle for cloud environments
Improve startup time and resource management
#319: Resolve entity relations in background to prevent cold start blocking (
324844a)Move relation resolution to background processing
Faster MCP server cold starts
#318: Enforce minimum 1-day timeframe for recent_activity (
f818702)Fix timezone-related issues in recent activity queries
Ensure consistent behavior across time zones
#317: Critical cloud deployment fixes for MCP stability (
2efd8f4)Multiple stability improvements for cloud-hosted MCP servers
Enhanced error handling and recovery
Technical Improvements
Comprehensive Testing - Extensive test coverage for critical fixes
New permalink collision test suite with 4 MCP-level integration tests
Entity service test coverage expanded to reproduce fuzzy search bug
Manual testing verification of data loss prevention
All 55 entity service tests passing with new strict resolution
Windows Support Enhancements (
7a8b08d,9aa4024)Fix Windows test failures and add Windows CI support
Address platform-specific issues for Windows users
Enhanced cross-platform compatibility
Docker Improvements (
105bcaa)Implement non-root Docker container to fix file ownership issues
Improved security and compatibility in containerized deployments
Code Quality
Enhanced filename sanitization with optional kebab case support
Improved character conflict detection for sync operations
Better error handling across the codebase
Path traversal security vulnerability fixes
Documentation
#321: Corrected dead links in README (
fc38877)Fix broken documentation links
Improve navigation and accessibility
#308: Update Claude Code GitHub Workflow (
8c7e29e)Enhanced GitHub integration documentation
Better Claude Code collaboration workflow
Breaking Changes
None - This release maintains full backward compatibility with v0.14.x
All changes are either:
Bug fixes that correct unintended behavior
New optional features that don't affect existing functionality
Internal optimizations that are transparent to users
Migration Guide
No manual migration required. Upgrade with:
# Update via uv
uv tool upgrade basic-memory
# Or install fresh
uv tool install basic-memoryWhat's Fixed:
Data loss bug from permalink collisions is completely resolved
Cloud deployment stability significantly improved
Windows platform compatibility enhanced
Better performance across all operations
What's New:
Cloud sync capabilities via rclone
Subscription validation foundation
Python 3.13 support
Enhanced security and stability
Installation
# Latest stable release
uv tool install basic-memory
# Update existing installation
uv tool upgrade basic-memory
# Docker
docker pull ghcr.io/basicmachines-co/basic-memory:v0.15.0v0.14.2 (2025-07-03)
Bug Fixes
#204: Fix MCP Error with MCP-Hub integration (
3621bb7)Resolve compatibility issues with MCP-Hub
Improve error handling in project management tools
Ensure stable MCP tool integration across different environments
Modernize datetime handling and suppress SQLAlchemy warnings (
f80ac0e)Replace deprecated
datetime.utcnow()with timezone-aware alternativesSuppress SQLAlchemy deprecation warnings for cleaner output
Improve future compatibility with Python datetime best practices
v0.14.1 (2025-07-03)
Bug Fixes
#203: Constrain fastmcp version to prevent breaking changes (
827f7cf)Pin fastmcp to compatible version range to avoid API breaking changes
Ensure stable MCP server functionality across updates
Improve dependency management for production deployments
#190: Fix Problems with MCP integration
(bd4f551)Resolve MCP server initialization and communication issues
Improve error handling and recovery in MCP operations
Enhance stability for AI assistant integrations
Features
Add Cursor IDE integration button - One-click setup for Cursor IDE users (
5360005)Direct installation button for Cursor IDE in README
Streamlined setup process for Cursor users
Enhanced developer experience for AI-powered coding
Add Homebrew installation instructions - Official Homebrew tap support (
39f811f)Official Homebrew formula in basicmachines-co/basic-memory tap
Simplified installation process for macOS users
Package manager integration for easier dependency management
v0.14.0 (2025-06-26)
Features
Docker Container Registry Migration - Switch from Docker Hub to GitHub Container Registry for better security and integration
(616c1f0)Automated Docker image publishing via GitHub Actions CI/CD pipeline
Enhanced container security with GitHub's integrated vulnerability scanning
Streamlined container deployment workflow for production environments
Enhanced Search Documentation - Comprehensive search syntax examples for improved user experience (
a589f8b)Detailed examples for Boolean search operators (AND, OR, NOT)
Advanced search patterns including phrase matching and field-specific queries
User-friendly documentation for complex search scenarios
Cross-Project File Management - Intelligent move operations with project boundary detection (
db5ef7d)Automatic detection of cross-project move attempts with helpful guidance
Clear error messages when attempting unsupported cross-project operations
Bug Fixes
#184: Preserve permalinks when editing notes without frontmatter permalinks (
c2f4b63)Fix permalink preservation during note editing operations
Ensure consistent permalink handling across different note formats
Maintain note identity and searchability during incremental edits
#183: Implement project-specific sync status checks for MCP tools (
12b5152)Fix sync status reporting to correctly reflect current project state
Resolve inconsistencies where sync status showed global instead of project-specific information
Improve project isolation for sync operations and status reporting
#180: Handle Boolean search syntax with hyphenated terms (
546e3cd)Fix search parsing issues with hyphenated terms in Boolean queries
Improve search query tokenization for complex term structures
Enhanced search reliability for technical documentation and multi-word concepts
#174: Respect BASIC_MEMORY_HOME environment variable in Docker containers (
9f1db23)Fix Docker container configuration to properly honor custom home directory settings
Improve containerized deployment flexibility with environment variable support
Ensure consistent behavior between local and containerized installations
#168: Scope entity queries by project_id in upsert_entity method (
2a3adc1)Fix entity isolation issues in multi-project setups
Prevent cross-project entity conflicts during database operations
Strengthen project boundary enforcement at the database level
#166: Handle None from_entity in Context API RelationSummary (
8a065c3)Fix null pointer exceptions in relation processing
Improve error handling for incomplete relation data
Enhanced stability for knowledge graph traversal operations
#164: Remove log level configuration from mcp_server.run() (
224e4bf)Simplify MCP server startup by removing redundant log level settings
Fix potential logging configuration conflicts
Streamline server initialization process
#162: Ensure permalinks are generated for entities with null permalinks during move operations (
f506507)Fix move operations for entities without existing permalinks
Automatic permalink generation during file move operations
Maintain database consistency during file reorganization
Technical Improvements
Comprehensive Test Coverage - Extensive test suites for new features and edge cases
Enhanced test coverage for project-specific sync status functionality
Additional test scenarios for search syntax validation and edge cases
Integration tests for Docker CI workflow and container publishing
Comprehensive move operations testing with project boundary validation
Docker CI/CD Pipeline - Production-ready automated container publishing (
74847cc)Automated Docker image building and publishing on release
Multi-architecture container support for AMD64 and ARM64 platforms
Integrated security scanning and vulnerability assessments
Streamlined deployment pipeline for production environments
Release Process Improvements - Enhanced automation and quality gates (
a52ce1c)Homebrew formula updates limited to stable releases only
Improved release automation with better quality control
Enhanced CI/CD pipeline reliability and error handling
Code Quality Enhancements - Improved error handling and validation
Better null safety in entity and relation processing
Enhanced project isolation validation throughout the codebase
Improved error messages and user guidance for edge cases
Strengthened database consistency guarantees across operations
Infrastructure
GitHub Container Registry Integration - Modern container infrastructure
Migration from Docker Hub to GitHub Container Registry (ghcr.io)
Improved security with integrated vulnerability scanning
Better integration with GitHub-based development workflow
Enhanced container versioning and artifact management
Enhanced CI/CD Workflows - Robust automated testing and deployment
Automated Docker image publishing on releases
Comprehensive test coverage validation before deployment
Multi-platform container building and publishing
Integration with GitHub's security and monitoring tools
Migration Guide
This release includes several behind-the-scenes improvements and fixes. All changes are backward compatible:
Docker Users: Container images now served from
ghcr.io/basicmachines-co/basic-memoryinstead of Docker HubSearch Users: Enhanced search syntax handling - existing queries continue to work unchanged
Multi-Project Users: Improved project isolation - all existing projects remain fully functional
All Users: Enhanced stability and error handling - no breaking changes to existing workflows
Installation
# Latest stable release
uv tool install basic-memory
# Update existing installation
uv tool upgrade basic-memory
# Docker (new registry)
docker pull ghcr.io/basicmachines-co/basic-memory:latestv0.13.7 (2025-06-19)
Bug Fixes
Homebrew Integration - Automatic Homebrew formula updates
Documentation - Add git sign-off reminder to development guide
v0.13.6 (2025-06-18)
Bug Fixes
Custom Entity Types - Support for custom entity types in write_note (
7789864)Fixed
entity_typeparameter forwrite_noteMCP tool to respect value passed inFrontmatter
typefield automatically respected when no explicit parameter providedMaintains backward compatibility with default "note" type
#139: Fix "UNIQUE constraint failed: entity.permalink" database error (
c6215fd)Implement SQLAlchemy UPSERT strategy to handle permalink conflicts gracefully
Eliminates crashes when creating notes with existing titles in same folders
Seamlessly updates existing entities instead of failing with constraint errors
Database Migration Performance - Eliminate redundant migration initialization (
84d2aaf)Fix duplicate migration calls that slowed system startup
Improve performance with multiple projects (tested with 28+ projects)
Add migration deduplication safeguards with comprehensive test coverage
User Experience - Correct spelling error in continue_conversation prompt (
b4c26a6)Fix "Chose a folder" → "Choose a folder" in MCP prompt instructions
Improve grammar and clarity in user-facing prompt text
Documentation
Website Updates - Add new website and community links to README (
3fdce68)Project Documentation - Update README.md and CLAUDE.md with latest project information (
782cb2d)
Technical Improvements
Comprehensive Test Coverage - Add extensive test suites for new features
Custom entity type validation with 8 new test scenarios
UPSERT behavior testing with edge case coverage
Migration deduplication testing with 6 test scenarios
Database constraint handling validation
Code Quality - Enhanced error handling and validation
Improved SQLAlchemy patterns with modern UPSERT operations
Better conflict resolution strategies for entity management
Strengthened database consistency guarantees
Performance
Database Operations - Faster startup and improved scalability
Reduced migration overhead for multi-project setups
Optimized conflict resolution for entity creation
Enhanced performance with growing knowledge bases
Migration Guide
This release includes automatic database improvements. No manual migration required:
Existing notes and entity types continue working unchanged
New
entity_typeparameter is optional and backward compatibleDatabase performance improvements apply automatically
All existing MCP tool behavior preserved
Installation
# Latest stable release
uv tool install basic-memory
# Update existing installation
uv tool upgrade basic-memoryv0.13.5 (2025-06-11)
Bug Fixes
MCP Tools: Renamed
create_projecttool tocreate_memory_projectfor namespace isolationNamespace: Continued namespace isolation effort to prevent conflicts with other MCP servers
Changes
Tool functionality remains identical - only the name changed from
create_projecttocreate_memory_projectAll integration tests updated to use the new tool name
Completes namespace isolation for project management tools alongside
list_memory_projects
v0.13.4 (2025-06-11)
Bug Fixes
MCP Tools: Renamed
list_projectstool tolist_memory_projectsto avoid naming conflicts with other MCP serversNamespace: Improved tool naming specificity for better MCP server integration and isolation
Changes
Tool functionality remains identical - only the name changed from
list_projectstolist_memory_projectsAll integration tests updated to use the new tool name
Better namespace isolation for Basic Memory MCP tools
v0.13.3 (2025-06-11)
Bug Fixes
Projects: Fixed case-insensitive project switching where switching succeeded but subsequent operations failed due to session state inconsistency
Config: Enhanced config manager with case-insensitive project lookup using permalink-based matching
MCP Tools: Updated project management tools to store canonical project names from database instead of user input
API: Improved project service to handle both name and permalink lookups consistently
Technical Improvements
Added comprehensive case-insensitive project switching test coverage with 5 new integration test scenarios
Fixed permalink generation inconsistencies where different case inputs could generate different permalinks
Enhanced project URL construction to use permalinks consistently across all API calls
Improved error handling and session state management for project operations
Changes
Project switching now preserves canonical project names from database in session state
All project operations use permalink-based lookups for case-insensitive matching
Enhanced test coverage ensures reliable case-insensitive project operations
v0.13.2 (2025-06-11)
Features
Release Management: Added automated release management system with version control in
__init__.pyAutomation: Implemented justfile targets for
releaseandbetacommands with comprehensive quality gatesCI/CD: Enhanced release process with automatic version updates, git tagging, and GitHub release creation
Development Experience
Added
.claude/commands/release/directory with automation documentationImplemented release validation including lint, type-check, and test execution
Streamlined release workflow from manual process to single-command automation
Technical Improvements
Updated package version management to use actual version numbers instead of dynamic versioning
Added release process documentation and command references
Enhanced justfile with comprehensive release automation targets
v0.13.1 (2025-06-11)
Bug Fixes
CLI: Fixed
basic-memory projectproject management commands that were not working in v0.13.0 (#129)Projects: Resolved case sensitivity issues when switching between projects that caused "Project not found" errors (#127)
API: Standardized CLI project command endpoints and improved error handling
Core: Implemented consistent project name handling using permalinks to avoid case-related conflicts
Changes
Renamed
basic-memory project synccommand tobasic-memory project sync-configfor clarityImproved project switching reliability across different case variations
Removed redundant server status messages from CLI error outputs
v0.13.0 (2025-06-11)
Overview
Basic Memory v0.13.0 is a major release that transforms Basic Memory into a true multi-project knowledge management system. This release introduces fluid project switching, advanced note editing capabilities, robust file management, and production-ready OAuth authentication - all while maintaining full backward compatibility.
What's New for Users:
🎯 Switch between projects instantly during conversations with Claude
✏️ Edit notes incrementally without rewriting entire documents
📁 Move and organize notes with full database consistency
📖 View notes as formatted artifacts for better readability in Claude Desktop
🔍 Search frontmatter tags to discover content more easily
🔐 OAuth authentication for secure remote access
⚡ Development builds automatically published for beta testing
Key v0.13.0 Accomplishments:
✅ Complete Project Management System - Project switching and project-specific operations
✅ Advanced Note Editing - Incremental editing with append, prepend, find/replace, and section operations
✅ View Notes as Artifacts in Claude Desktop/Web - Use the view_note tool to view a note as an artifact
✅ File Management System - Full move operations with database consistency and rollback protection
✅ Enhanced Search Capabilities - Frontmatter tags now searchable, improved content discoverability
✅ Unified Database Architecture - Single app-level database for better performance and project management
Major Features
1. Multiple Project Management
Switch between projects instantly during conversations:
💬 "What projects do I have?"
🤖 Available projects:
• main (current, default)
• work-notes
• personal-journal
• code-snippets
💬 "Switch to work-notes"
🤖 ✓ Switched to work-notes project
Project Summary:
• 47 entities
• 125 observations
• 23 relations
💬 "What did I work on yesterday?"
🤖 [Shows recent activity from work-notes project]Key Capabilities:
Instant Project Switching: Change project context mid-conversation without restart
Project-Specific Operations: Operations work within the currently active project context
Project Discovery: List all available projects with status indicators
Session Context: Maintains active project throughout conversation
Backward Compatibility: Existing single-project setups continue to work seamlessly
2. Advanced Note Editing
Edit notes incrementally without rewriting entire documents:
# Append new sections to existing notes
edit_note("project-planning", "append", "\n## New Requirements\n- Feature X\n- Feature Y")
# Prepend timestamps to meeting notes
edit_note("meeting-notes", "prepend", "## 2025-05-27 Update\n- Progress update...")
# Replace specific sections under headers
edit_note("api-spec", "replace_section", "New implementation details", section="## Implementation")
# Find and replace with validation
edit_note("config", "find_replace", "v0.13.0", find_text="v0.12.0", expected_replacements=2)Key Capabilities:
Append Operations: Add content to end of notes (most common use case)
Prepend Operations: Add content to beginning of notes
Section Replacement: Replace content under specific markdown headers
Find & Replace: Simple text replacements with occurrence counting
Smart Error Handling: Helpful guidance when operations fail
Project Context: Works within the active project with session awareness
3. Smart File Management
Move and organize notes:
# Simple moves with automatic folder creation
move_note("my-note", "work/projects/my-note.md")
# Organize within the active project
move_note("shared-doc", "archive/old-docs/shared-doc.md")
# Rename operations
move_note("old-name", "same-folder/new-name.md")Key Capabilities:
Database Consistency: Updates file paths, permalinks, and checksums automatically
Search Reindexing: Maintains search functionality after moves
Folder Creation: Automatically creates destination directories
Project Isolation: Operates within the currently active project
Link Preservation: Maintains internal links and references
4. Enhanced Search & Discovery
Find content more easily with improved search capabilities:
Frontmatter Tag Search: Tags from YAML frontmatter are now indexed and searchable
Improved Content Discovery: Search across titles, content, tags, and metadata
Project-Scoped Search: Search within the currently active project
Better Search Quality: Enhanced FTS5 indexing with tag content inclusion
Example:
---
title: Coffee Brewing Methods
tags: [coffee, brewing, equipment]
---Now searchable by: "coffee", "brewing", "equipment", or "Coffee Brewing Methods"
5. Unified Database Architecture
Single app-level database for better performance and project management:
Migration from Per-Project DBs: Moved from multiple SQLite files to single app database
Project Isolation: Proper data separation with project_id foreign keys
Better Performance: Optimized queries and reduced file I/O
Complete MCP Tool Suite
New Project Management Tools
list_projects()- Discover and list all available projects with statusswitch_project(project_name)- Change active project context during conversationsget_current_project()- Show currently active project with statisticsset_default_project(project_name)- Update default project configurationsync_status()- Check file synchronization status and background operations
New Note Operations Tools
edit_note()- Incremental note editing (append, prepend, find/replace, section replace)move_note()- Move notes with database consistency and search reindexingview_note()- Display notes as formatted artifacts for better readability in Claude Desktop
Enhanced Existing Tools
All existing tools now support:
Session context awareness (operates within the currently active project)
Enhanced error messages with project context metadata
Improved response formatting with project information footers
Project isolation ensures operations stay within the correct project boundaries
User Experience Improvements
Installation Options
Multiple ways to install and test Basic Memory:
# Stable release
uv tool install basic-memory
# Beta/pre-releases
uv tool install basic-memory --preBug Fixes & Quality Improvements
Major issues resolved in v0.13.0:
#118: Fixed YAML tag formatting to follow standard specification
#110: Fixed
--projectflag consistency across all CLI commands#107: Fixed write_note update failures with existing notes
#93: Fixed custom permalink handling in frontmatter
#52: Enhanced search capabilities with frontmatter tag indexing
FTS5 Search: Fixed special character handling in search queries
Error Handling: Improved error messages and validation across all tools
Breaking Changes & Migration
For Existing Users
Automatic Migration: First run will automatically migrate existing data to the new unified database structure. No manual action required.
What Changes:
Database location: Moved to
~/.basic-memory/memory.db(unified across projects)Configuration: Projects defined in
~/.basic-memory/config.jsonare synced with database
What Stays the Same:
All existing notes and data remain unchanged
Default project behavior maintained for single-project users
All existing MCP tools continue to work without modification
Documentation & Resources
New Documentation
Project Management Guide - Multi-project workflows
Note Editing Guide - Advanced editing techniques
Updated Documentation
README.md - Installation options and beta build instructions
CONTRIBUTING.md - Release process and version management
CLAUDE.md - Development workflow and CI/CD documentation
Claude.ai Integration - Updated MCP tool examples
Quick Start Examples
Project Switching:
💬 "Switch to my work project and show recent activity"
🤖 [Calls switch_project("work") then recent_activity()]Note Editing:
💬 "Add a section about deployment to my API docs"
🤖 [Calls edit_note("api-docs", "append", "## Deployment\n...")]File Organization:
💬 "Move my old meeting notes to the archive folder"
🤖 [Calls move_note("meeting-notes", "archive/old-meetings.md")]v0.12.3 (2025-04-17)
Bug Fixes
Add extra logic for permalink generation with mixed Latin unicode and Chinese characters (
73ea91f)
Signed-off-by: phernandez <e-mail address on the upstream page>
Modify recent_activity args to be strings instead of enums (
3c1cc34)
Signed-off-by: phernandez <e-mail address on the upstream page>
v0.12.2 (2025-04-08)
Bug Fixes
Signed-off-by: phernandez <e-mail address on the upstream page>
v0.12.1 (2025-04-07)
Bug Fixes
v0.12.0 (2025-04-06)
Bug Fixes
[bug]
#character accumulation in markdown frontmatter tags prop (#79,6c19c9e)[bug] Some notes never exit "modified" status (#77,
7930ddb)[bug] write_note Tool Fails to Update Existing Files in Some Situations. (#80,
9bff1f7)Write_note preserves frontmatter fields in content (#84,
3f4d9e4)
Documentation
Features
Avoiding "useless permalink values" for files without metadata - Enable permalinks to be updated on move via config setting
v0.11.0 (2025-03-29)
Bug Fixes
Signed-off-by: phernandez <e-mail address on the upstream page>
Signed-off-by: phernandez <e-mail address on the upstream page>
Documentation
Features
Signed-off-by: phernandez <e-mail address on the upstream page>
Signed-off-by: phernandez <e-mail address on the upstream page>
v0.10.1 (2025-03-25)
Bug Fixes
Make set_default_project also activate project for current session to fix #37 (
cbe72be)
This change makes the 'basic-memory project default <name>' command both: 1. Set the default project for future invocations (persistent change) 2. Activate the project for the current session (immediate change)
Added tests to verify this behavior, which resolves issue #37 where the project name and path weren't changing properly when the default project was changed.
🤖 Generated with Claude Code
Co-Authored-By: Claude <e-mail address on the upstream page>
Make set_default_project also activate project for current session to fix #37 (
46c4fd2)
This change makes the 'basic-memory project default <name>' command both: 1. Set the default project for future invocations (persistent change) 2. Activate the project for the current session (immediate change)
Added tests to verify this behavior, which resolves issue #37 where the project name and path weren't changing properly when the default project was changed.
🤖 Generated with Claude Code
Co-Authored-By: Claude <e-mail address on the upstream page>
Signed-off-by: phernandez <e-mail address on the upstream page>
Move ai_assistant_guide.md into package resources to fix #39 (
390ff9d)
This change relocates the AI assistant guide from the static directory into the package resources directory, ensuring it gets properly included in the distribution package and is accessible when installed via pip/uv.
🤖 Generated with Claude Code
Co-Authored-By: Claude <e-mail address on the upstream page>
Move ai_assistant_guide.md into package resources to fix #39 (
cc2cae7)
This change relocates the AI assistant guide from the static directory into the package resources directory, ensuring it gets properly included in the distribution package and is accessible when installed via pip/uv.
🤖 Generated with Claude Code
Co-Authored-By: Claude <e-mail address on the upstream page>
Signed-off-by: phernandez <e-mail address on the upstream page>
Preserve custom frontmatter fields when updating notes (
78f234b)
Fixes #36 by modifying entity_service.update_entity() to read existing frontmatter from files before updating them. Custom metadata fields such as Status, Priority, and Version are now preserved when notes are updated through the write_note MCP tool.
Added test case that verifies this behavior by creating a note with custom frontmatter and then updating it.
🤖 Generated with Claude Code
Co-Authored-By: Claude <e-mail address on the upstream page>
Preserve custom frontmatter fields when updating notes (
e716946)
Fixes #36 by modifying entity_service.update_entity() to read existing frontmatter from files before updating them. Custom metadata fields such as Status, Priority, and Version are now preserved when notes are updated through the write_note MCP tool.
Added test case that verifies this behavior by creating a note with custom frontmatter and then updating it.
🤖 Generated with Claude Code
Co-Authored-By: Claude <e-mail address on the upstream page>
Signed-off-by: phernandez <e-mail address on the upstream page>
Chores
Remove duplicate code in entity_service.py from bad merge (
681af5d)
Signed-off-by: phernandez <e-mail address on the upstream page>
Documentation
Add help docs to mcp cli tools (
731b502)
Signed-off-by: phernandez <e-mail address on the upstream page>
Add mcp badge, update cli reference, llms-install.md (
b26afa9)
Signed-off-by: phernandez <e-mail address on the upstream page>
fix spelling in CLAUDE.md: environment typo Signed-off-by: Ikko Eltociear Ashimine <e-mail address on the upstream page>
Refactoring
Move project stats into project subcommand (
2a881b1)
Signed-off-by: phernandez <e-mail address on the upstream page>
v0.10.0 (2025-03-15)
Bug Fixes
Ai_resource_guide.md path (
da97353)
Signed-off-by: phernandez <e-mail address on the upstream page>
Signed-off-by: phernandez <e-mail address on the upstream page>
Fixes #30
Signed-off-by: phernandez <e-mail address on the upstream page>
Drop search_index table on db reindex (
31cca6f)
Signed-off-by: phernandez <e-mail address on the upstream page>
fixes #29
Signed-off-by: phernandez <e-mail address on the upstream page>
Chores
Remove logfire (
9bb8a02)
Signed-off-by: phernandez <e-mail address on the upstream page>
Documentation
Signed-off-by: phernandez <e-mail address on the upstream page>
This PR updates the CLAUDE.md file to document the GitHub integration capabilities that enable Claude to participate directly in the development workflow.
Features
This PR adds support for deploying Basic Memory on the Smithery platform.
Signed-off-by: bm-claudeai <e-mail address on the upstream page>
v0.9.0 (2025-03-07)
Chores
fix: drop search_index table on db reindex
fix: ai_resource_guide.md path
chore: remove logfire
Signed-off-by: phernandez <e-mail address on the upstream page>
Documentation
Update README.md and CLAUDE.md (
182ec78)
Features
Signed-off-by: phernandez <e-mail address on the upstream page>
feat: Add multiple projects support
feat: enhanced read_note for when initial result is not found
fix: merge frontmatter when updating note
fix: handle directory removed on sync watch
v0.8.0 (2025-02-28)
Chores
Features
Summary - Add comprehensive documentation to all MCP prompt modules - Enhance search prompt with
detailed contextual output formatting - Implement consistent logging and docstring patterns across prompt utilities - Fix type checking in prompt modules
Prompts Added/Enhanced - search.py: New formatted output with relevance scores, excerpts, and
next steps - recent_activity.py: Enhanced with better metadata handling and documentation -
continue_conversation.py: Improved context management
Resources Added/Enhanced - ai_assistant_guide: Resource with description to give to LLM to
understand how to use the tools
Technical improvements - Added detailed docstrings to all prompt modules explaining their purpose
and usage - Enhanced the search prompt with rich contextual output that helps LLMs understand results - Created a consistent pattern for formatting output across prompts - Improved error handling in metadata extraction - Standardized import organization and naming conventions - Fixed various type checking issues across the codebase
This PR is part of our ongoing effort to improve the MCP's interaction quality with LLMs, making the system more helpful and intuitive for AI assistants to navigate knowledge bases.
🤖 Generated with Claude Code
Co-authored-by: phernandez <e-mail address on the upstream page>
Add new canvas tool to create json canvas files in obsidian.
Co-authored-by: phernandez <e-mail address on the upstream page>
incremental sync on watch - sync non-markdown files in knowledge base - experimental
read_resourcetool for reading non-markdown files in raw form (pdf, image)
v0.7.0 (2025-02-19)
Bug Fixes
Add logfire instrumentation to tools (
3e8e3e8)Add logfire spans to cli (
00d23a5)Add logfire spans to cli (
812136c)Search query pagination params (
bc9ca07)
Chores
Features
Add cli commands for mcp tools (
f5a7541)Add pagination to build_context and recent_activity (
0123544)Add pagination to read_notes (
02f8e86)
v0.6.0 (2025-02-18)
Chores
Re-add sync status console on watch (
66b57e6)
Features
Co-authored-by: phernandez <e-mail address on the upstream page>
v0.5.0 (2025-02-18)
Features
Co-authored-by: phernandez <e-mail address on the upstream page>
v0.4.3 (2025-02-18)
Bug Fixes
Co-authored-by: phernandez <e-mail address on the upstream page>
v0.4.2 (2025-02-17)
v0.4.1 (2025-02-17)
Bug Fixes
v0.4.0 (2025-02-16)
Features
Co-authored-by: phernandez <e-mail address on the upstream page>
Import Claude.ai conversation and project data to basic-memory Markdown format.
Co-authored-by: phernandez <e-mail address on the upstream page>
v0.3.0 (2025-02-15)
Bug Fixes
Refactor db schema migrate handling (
ca632be)
v0.2.21 (2025-02-15)
Bug Fixes
Fix osx installer github action (
65ebe5d)Handle memory:// url format in read_note tool (
e080373)Remove create schema from init_db (
674dd1f)
Features
Set version in var, output version at startup (
a91da13)
v0.2.20 (2025-02-14)
Bug Fixes
Fix installer artifact (
8de84c0)
v0.2.19 (2025-02-14)
Bug Fixes
Get app artifact for installer (
fe8c3d8)
v0.2.18 (2025-02-14)
Bug Fixes
Don't zip app on release (
8664c57)
v0.2.17 (2025-02-14)
Bug Fixes
Fix app zip in installer release (
8fa197e)
v0.2.16 (2025-02-14)
Bug Fixes
Debug inspect build on ci (
1d6054d)
v0.2.15 (2025-02-14)
Bug Fixes
Debug installer ci (
dab9573)
v0.2.14 (2025-02-14)
v0.2.13 (2025-02-14)
Bug Fixes
v0.2.12 (2025-02-14)
Bug Fixes
Fix cx_freeze options for installer (
854cf83)
v0.2.11 (2025-02-14)
Bug Fixes
Ci installer app fix #37 (
2e215fe)
v0.2.10 (2025-02-14)
Bug Fixes
Fix build on github ci for app installer (
29a2594)
v0.2.9 (2025-02-14)
v0.2.8 (2025-02-14)
Bug Fixes
Fix installer on ci, maybe (
edbc04b)
v0.2.7 (2025-02-14)
Bug Fixes
Try to fix installer ci (
230738e)
v0.2.6 (2025-02-14)
Bug Fixes
v0.2.5 (2025-02-14)
Bug Fixes
Refix virtual env in installer build (
052f491)
v0.2.4 (2025-02-14)
v0.2.3 (2025-02-14)
Bug Fixes
Workaround unsigned app (
41d4d81)
v0.2.2 (2025-02-14)
Bug Fixes
Fix path to installer app artifact (
53d220d)
v0.2.1 (2025-02-14)
Bug Fixes
v0.2.0 (2025-02-14)
Features
feat(ci): build installer via github action
enforce conventional commits in PR titles
feat: add icon to installer
Co-authored-by: phernandez <e-mail address on the upstream page>
v0.1.2 (2025-02-14)
Bug Fixes
Fix installer for mac (
dde9ff2)Remove unused FileChange dataclass (
eb3360c)Update uv installer url (
2f9178b)
v0.1.1 (2025-02-07)
v0.1.0 (2025-02-07)
Bug Fixes
Create virtual env in test workflow (
8092e6d)Fix permalink uniqueness violations on create/update/sync (
135bec1)Fix recent activity bug (
3d2c0c8)Install fastapi deps after removing basic-foundation (
51a741e)Recreate search index on db reset (
1fee436)Remove basic-foundation from deps (
b8d0c71)Run tests via uv (
4eec820)
Chores
Rename import tool (
af6b7dc)
Features
Add memory-json importer, tweak observation content (
3484e26)
v0.0.1 (2025-02-04)
Bug Fixes
Fix versioning for 0.0.1 release (
ba1e494)
v0.0.0 (2025-02-04)
Chores
Remove basic-foundation src ref in pyproject.toml (
29fce8b)
512 files · 461 not served here
- .agents/plugins/marketplace.json (not served here)
- .agents/skills/adversarial-review/SKILL.md (not served here)
- .agents/skills/adversarial-review/prompts/refute.md (not served here)
- .agents/skills/adversarial-review/prompts/review.md (not served here)
- .agents/skills/adversarial-review/schemas/findings.schema.json (not served here)
- .agents/skills/adversarial-review/schemas/verdicts.schema.json (not served here)
- .agents/skills/cmux-markdown/SKILL.md (not served here)
- .agents/skills/cmux-markdown/agents/openai.yaml (not served here)
- .agents/skills/cmux-markdown/references/commands.md (not served here)
- .agents/skills/cmux-markdown/references/live-reload.md (not served here)
- .agents/skills/cmux-settings/SKILL.md (not served here)
- .agents/skills/cmux-settings/agents/openai.yaml (not served here)
- .agents/skills/cmux-settings/references/all-keys.md (not served here)
- .agents/skills/cmux-settings/references/shortcut-actions.md (not served here)
- .agents/skills/cmux-settings/scripts/cmux-settings (not served here)
- .agents/skills/cmux-workspace/SKILL.md (not served here)
- .agents/skills/cmux-workspace/agents/openai.yaml (not served here)
- .agents/skills/cmux-workspace/references/commands.md (not served here)
- .agents/skills/cmux/SKILL.md (not served here)
- .agents/skills/cmux/agents/openai.yaml (not served here)
- .agents/skills/cmux/references/handles-and-identify.md (not served here)
- .agents/skills/cmux/references/panes-surfaces.md (not served here)
- .agents/skills/cmux/references/trigger-flash-and-health.md (not served here)
- .agents/skills/cmux/references/windows-workspaces.md (not served here)
- .agents/skills/code-review/SKILL.md (not served here)
- .agents/skills/fix-pr-issues/SKILL.md (not served here)
- .agents/skills/fix-pr-issues/agents/openai.yaml (not served here)
- .agents/skills/fix-pr-issues/assets/icon.svg (not served here)
- .agents/skills/infographics/SKILL.md (not served here)
- .agents/skills/infographics/agents/openai.yaml (not served here)
- .agents/skills/infographics/assets/icon.svg (not served here)
- .agents/skills/infographics/references/prompt-blueprint.md (not served here)
- .agents/skills/infographics/references/style-balance.md (not served here)
- .agents/skills/instrumentation/SKILL.md (not served here)
- .agents/skills/instrumentation/references/javascript/frameworks.md (not served here)
- .agents/skills/instrumentation/references/javascript/patterns.md (not served here)
- .agents/skills/instrumentation/references/python/integrations.md (not served here)
- .agents/skills/instrumentation/references/python/logging-patterns.md (not served here)
- .agents/skills/instrumentation/references/rust/patterns.md (not served here)
- .agents/skills/pr-create/SKILL.md (not served here)
- .agents/skills/pr-create/agents/openai.yaml (not served here)
- .agents/skills/pr-create/assets/icon.svg (not served here)
- .agents/skills/pr-description/SKILL.md (not served here)
- .agents/skills/pr-description/references/pr-body-template.md (not served here)
- .agents/skills/pr-review-loop/SKILL.md (not served here)
- .agents/skills/pull-request/SKILL.md (not served here)
- .agents/skills/pythonic-code/SKILL.md (not served here)
- .agents/skills/pythonic-code/agents/openai.yaml (not served here)
- .agents/skills/pythonic-code/evals/context/AGENTS.md (not served here)
- .agents/skills/pythonic-code/evals/context/pyproject.toml (not served here)
- .agents/skills/pythonic-code/evals/evals.json (not served here)
- .agents/skills/pythonic-code/evals/files/accepted_preparation.py (not served here)
- .agents/skills/pythonic-code/evals/files/accepted_snapshot.py (not served here)
- .agents/skills/pythonic-code/evals/files/shared_runtime_ownership.md (not served here)
- .agents/skills/pythonic-code/evals/files/test_accepted_preparation.py (not served here)
- .agents/skills/pythonic-code/evals/files/test_accepted_snapshot.py (not served here)
- .agents/skills/pythonic-code/justfile (not served here)
- .agents/skills/pythonic-code/scripts/run_evals.py (not served here)
- .claude-plugin/marketplace.json (not served here)
- .claude/commands/release/beta.md (not served here)
- .claude/commands/release/changelog.md (not served here)
- .claude/commands/release/release-check.md (not served here)
- .claude/commands/release/release.md (not served here)
- .claude/commands/spec.md (not served here)
- .claude/commands/test-live.md (not served here)
- .claude/settings.json
- .claude/skills/adversarial-review (not served here)
- .claude/skills/basic-machines-review (not served here)
- .claude/skills/cmux (not served here)
- .claude/skills/cmux-markdown (not served here)
- .claude/skills/cmux-settings (not served here)
- .claude/skills/cmux-workspace (not served here)
- .claude/skills/instrumentation (not served here)
- .claude/skills/pythonic-code (not served here)
- .codex/basic-memory.json (not served here)
- .dockerignore (not served here)
- .env.example (not served here)
- .envrc (not served here)
- .gitattributes (not served here)
- .github/ISSUE_TEMPLATE/bug_report.md (not served here)
- .github/ISSUE_TEMPLATE/config.yml (not served here)
- .github/ISSUE_TEMPLATE/documentation.md (not served here)
- .github/ISSUE_TEMPLATE/feature_request.md (not served here)
- .github/basic-memory/SOUL.md (not served here)
- .github/basic-memory/config.yml (not served here)
- .github/basic-memory/memory-ci-capture.md (not served here)
- .github/dco.yml (not served here)
- .github/dependabot.yml (not served here)
- .github/workflows/claude-code-review.yml (not served here)
- .github/workflows/claude-issue-triage.yml (not served here)
- .github/workflows/claude.yml (not served here)
- .github/workflows/consolidated-packages.yml (not served here)
- .github/workflows/docker.yml (not served here)
- .github/workflows/mcp-registry-publish.yml (not served here)
- .github/workflows/pr-title.yml (not served here)
- .github/workflows/publish-skills.yml (not served here)
- .github/workflows/release.yml (not served here)
- .github/workflows/sqlite-lifecycle.yml (not served here)
- .github/workflows/test.yml (not served here)
- .gitignore (not served here)
- .python-version (not served here)
- .test_durations (not served here)
- AGENTS.md
- ATTRIBUTION.md
- AUTOGINEER-RUNS.md
- CHANGELOG.md
- CITATION.cff (not served here)
- CLA.md
- CLAUDE.md (not served here)
- CODE_OF_CONDUCT.md
- CONTRIBUTING.md
- Dockerfile (not served here)
- LICENSE
- NOTE-FORMAT.md
- README.md
- SECURITY.md
- benchmarks/.github/workflows/benchmark-nightly.yml (not served here)
- benchmarks/.github/workflows/benchmark-smoke.yml (not served here)
- benchmarks/.gitignore (not served here)
- benchmarks/.python-version (not served here)
- benchmarks/AGENTS.md (not served here)
- benchmarks/README.md (not served here)
- benchmarks/benchmarks/datasets/README.md (not served here)
- benchmarks/benchmarks/datasets/agent-tasks/corpus/architecture/api-design-decisions.md (not served here)
- benchmarks/benchmarks/datasets/agent-tasks/corpus/architecture/oauth-migration-plan.md (not served here)
- benchmarks/benchmarks/datasets/agent-tasks/corpus/architecture/oauth-token-design.md (not served here)
- benchmarks/benchmarks/datasets/agent-tasks/corpus/architecture/redis-cache-architecture.md (not served here)
- benchmarks/benchmarks/datasets/agent-tasks/corpus/man3/bm-edit-3.md (not served here)
- benchmarks/benchmarks/datasets/agent-tasks/corpus/man3/bm-read-3.md (not served here)
- benchmarks/benchmarks/datasets/agent-tasks/corpus/man3/bm-search-3.md (not served here)
- benchmarks/benchmarks/datasets/agent-tasks/corpus/notes/coffee-brewing-log.md (not served here)
- benchmarks/benchmarks/datasets/agent-tasks/corpus/notes/feature-x.md (not served here)
- benchmarks/benchmarks/datasets/agent-tasks/corpus/notes/kubernetes-migration.md (not served here)
- benchmarks/benchmarks/datasets/agent-tasks/corpus/notes/oauth-rollout-notes.md (not served here)
- benchmarks/benchmarks/datasets/agent-tasks/corpus/notes/postgres-vacuum-notes.md (not served here)
- benchmarks/benchmarks/datasets/agent-tasks/corpus/notes/rate-limiter.md (not served here)
- benchmarks/benchmarks/datasets/agent-tasks/corpus/notes/redis-cache-tuning.md (not served here)
- benchmarks/benchmarks/datasets/agent-tasks/corpus/notes/redis-quota-store.md (not served here)
- benchmarks/benchmarks/datasets/agent-tasks/corpus/schemas/task.md (not served here)
- benchmarks/benchmarks/datasets/agent-tasks/corpus/specs/spec-8-sync-rework.md (not served here)
- benchmarks/benchmarks/datasets/agent-tasks/corpus/specs/spec-9-search-rework.md (not served here)
- benchmarks/benchmarks/datasets/agent-tasks/corpus/tasks/migrate-ci-to-uv.md (not served here)
- benchmarks/benchmarks/datasets/agent-tasks/corpus/tasks/refactor-search-index.md (not served here)
- benchmarks/benchmarks/datasets/agent-tasks/corpus/tasks/upgrade-flyio.md (not served here)
- benchmarks/benchmarks/datasets/agent-tasks/corpus/tasks/write-release-notes.md (not served here)
- benchmarks/benchmarks/datasets/agent-tasks/corpus/worklog/2026-08-20-spec-9-session-1.md (not served here)
- benchmarks/benchmarks/datasets/agent-tasks/corpus/worklog/2026-08-27-infra-notes.md (not served here)
- benchmarks/benchmarks/datasets/agent-tasks/corpus/worklog/2026-08-27-spec-9-session-2.md (not served here)
- benchmarks/benchmarks/datasets/agent-tasks/smoke-script.json (not served here)
- benchmarks/benchmarks/datasets/beam/README.md (not served here)
- benchmarks/benchmarks/datasets/beam/download.sh (not served here)
- benchmarks/benchmarks/datasets/beam/source.json (not served here)
- benchmarks/benchmarks/datasets/locomo/README.md (not served here)
- benchmarks/benchmarks/datasets/locomo/download.sh (not served here)
- benchmarks/benchmarks/datasets/locomo/source.json (not served here)
- benchmarks/benchmarks/datasets/longmemeval/README.md (not served here)
- benchmarks/benchmarks/datasets/longmemeval/download.sh (not served here)
- benchmarks/benchmarks/datasets/xafs/README.md (not served here)
- benchmarks/benchmarks/datasets/xafs/audit-2026-09-03.md (not served here)
- benchmarks/benchmarks/datasets/xafs/corrections.json (not served here)
- benchmarks/benchmarks/datasets/xafs/download.sh (not served here)
- benchmarks/benchmarks/datasets/xafs/source.json (not served here)
- benchmarks/benchmarks/results/matrix-v1.2-summary.md (not served here)
- benchmarks/benchmarks/results/matrix-v2-summary.md (not served here)
- benchmarks/benchmarks/results/structured-ingestion-findings.md (not served here)
- benchmarks/benchmarks/synthetic/docs/agent-memory.md (not served here)
- benchmarks/benchmarks/synthetic/docs/auth-memory.md (not served here)
- benchmarks/benchmarks/synthetic/docs/sync-memory.md (not served here)
- benchmarks/benchmarks/synthetic/queries.json (not served here)
- benchmarks/docs/benchmarks.md (not served here)
- benchmarks/docs/read-load-benchmark.md (not served here)
- benchmarks/docs/write-load-benchmark.md (not served here)
- benchmarks/justfile (not served here)
- benchmarks/pyproject.toml (not served here)
- benchmarks/scripts/read_load_bench.py (not served here)
- benchmarks/scripts/write_load_bench.py (not served here)
- benchmarks/src/basic_memory_benchmarks/__init__.py (not served here)
- benchmarks/src/basic_memory_benchmarks/__main__.py (not served here)
- benchmarks/src/basic_memory_benchmarks/agent_tasks/__init__.py (not served here)
- benchmarks/src/basic_memory_benchmarks/agent_tasks/corpus.py (not served here)
- benchmarks/src/basic_memory_benchmarks/agent_tasks/driver.py (not served here)
- benchmarks/src/basic_memory_benchmarks/agent_tasks/grading.py (not served here)
- benchmarks/src/basic_memory_benchmarks/agent_tasks/loop.py (not served here)
- benchmarks/src/basic_memory_benchmarks/agent_tasks/manifest.py (not served here)
- benchmarks/src/basic_memory_benchmarks/agent_tasks/models.py (not served here)
- benchmarks/src/basic_memory_benchmarks/agent_tasks/spec.py (not served here)
- benchmarks/src/basic_memory_benchmarks/agent_tasks/surfaces.py (not served here)
- benchmarks/src/basic_memory_benchmarks/agent_tasks/tasks.py (not served here)
- benchmarks/src/basic_memory_benchmarks/bm_runtime.py (not served here)
- benchmarks/src/basic_memory_benchmarks/cli.py (not served here)
- benchmarks/src/basic_memory_benchmarks/concurrent_write.py (not served here)
- benchmarks/src/basic_memory_benchmarks/converters/__init__.py (not served here)
- benchmarks/src/basic_memory_benchmarks/converters/beam_to_corpus.py (not served here)
- benchmarks/src/basic_memory_benchmarks/converters/convomem_to_corpus.py (not served here)
- benchmarks/src/basic_memory_benchmarks/converters/locomo_to_corpus.py (not served here)
- benchmarks/src/basic_memory_benchmarks/converters/longmemeval_to_corpus.py (not served here)
- benchmarks/src/basic_memory_benchmarks/converters/structure_corpus.py (not served here)
- benchmarks/src/basic_memory_benchmarks/converters/xafs_to_corpus.py (not served here)
- benchmarks/src/basic_memory_benchmarks/datasets/__init__.py (not served here)
- benchmarks/src/basic_memory_benchmarks/datasets/beam.py (not served here)
- benchmarks/src/basic_memory_benchmarks/datasets/convomem.py (not served here)
- benchmarks/src/basic_memory_benchmarks/datasets/locomo.py (not served here)
- benchmarks/src/basic_memory_benchmarks/datasets/locomo_audit.py (not served here)
- benchmarks/src/basic_memory_benchmarks/datasets/longmemeval.py (not served here)
- benchmarks/src/basic_memory_benchmarks/datasets/xafs.py (not served here)
- benchmarks/src/basic_memory_benchmarks/exceptions.py (not served here)
- benchmarks/src/basic_memory_benchmarks/fairness.py (not served here)
- benchmarks/src/basic_memory_benchmarks/llm/__init__.py (not served here)
- benchmarks/src/basic_memory_benchmarks/llm/runners.py (not served here)
- benchmarks/src/basic_memory_benchmarks/llm/tool_agent.py (not served here)
- benchmarks/src/basic_memory_benchmarks/models.py (not served here)
- benchmarks/src/basic_memory_benchmarks/providers/__init__.py (not served here)
- benchmarks/src/basic_memory_benchmarks/providers/base.py (not served here)
- benchmarks/src/basic_memory_benchmarks/providers/baseline_fullcontext.py (not served here)
- benchmarks/src/basic_memory_benchmarks/providers/baseline_grep.py (not served here)
- benchmarks/src/basic_memory_benchmarks/providers/bm_cloud.py (not served here)
- benchmarks/src/basic_memory_benchmarks/providers/bm_local.py (not served here)
- benchmarks/src/basic_memory_benchmarks/providers/mem0_local.py (not served here)
- benchmarks/src/basic_memory_benchmarks/providers/supermemory_local.py (not served here)
- benchmarks/src/basic_memory_benchmarks/providers/zep_reference.py (not served here)
- benchmarks/src/basic_memory_benchmarks/reporting/__init__.py (not served here)
- benchmarks/src/basic_memory_benchmarks/reporting/artifacts.py (not served here)
- benchmarks/src/basic_memory_benchmarks/reporting/compare.py (not served here)
- benchmarks/src/basic_memory_benchmarks/runner.py (not served here)
- benchmarks/src/basic_memory_benchmarks/scoring/__init__.py (not served here)
- benchmarks/src/basic_memory_benchmarks/scoring/beam.py (not served here)
- benchmarks/src/basic_memory_benchmarks/scoring/diagnose.py (not served here)
- benchmarks/src/basic_memory_benchmarks/scoring/qa.py (not served here)
- benchmarks/src/basic_memory_benchmarks/scoring/retrieval.py (not served here)
- benchmarks/src/basic_memory_benchmarks/scoring/review.py (not served here)
- benchmarks/src/basic_memory_benchmarks/utils.py (not served here)
- benchmarks/test-int/test_compare_regression.py (not served here)
- benchmarks/test-int/test_runner_orchestration.py (not served here)
- benchmarks/tests/agent_tasks/__init__.py (not served here)
- benchmarks/tests/agent_tasks/test_corpus.py (not served here)
- benchmarks/tests/agent_tasks/test_driver.py (not served here)
- benchmarks/tests/agent_tasks/test_grading.py (not served here)
- benchmarks/tests/agent_tasks/test_loop.py (not served here)
- benchmarks/tests/agent_tasks/test_manifest_source.py (not served here)
- benchmarks/tests/agent_tasks/test_models.py (not served here)
- benchmarks/tests/agent_tasks/test_surfaces.py (not served here)
- benchmarks/tests/agent_tasks/test_task_fixture.py (not served here)
- benchmarks/tests/beam_fixture.py (not served here)
- benchmarks/tests/converters/__init__.py (not served here)
- benchmarks/tests/converters/test_beam_converter.py (not served here)
- benchmarks/tests/converters/test_convomem_converter.py (not served here)
- benchmarks/tests/converters/test_locomo_audit_corrections.py (not served here)
- benchmarks/tests/converters/test_longmemeval_converter.py (not served here)
- benchmarks/tests/converters/test_xafs_converter.py (not served here)
- benchmarks/tests/llm/test_runners.py (not served here)
- benchmarks/tests/llm/test_tool_agent.py (not served here)
- benchmarks/tests/providers/test_baseline_providers.py (not served here)
- benchmarks/tests/providers/test_bm_cloud_provider.py (not served here)
- benchmarks/tests/providers/test_bm_local_provider.py (not served here)
- benchmarks/tests/providers/test_mem0_normalization.py (not served here)
- benchmarks/tests/providers/test_supermemory_provider.py (not served here)
- benchmarks/tests/test_beam_dataset.py (not served here)
- benchmarks/tests/test_beam_scoring.py (not served here)
- benchmarks/tests/test_cli_surface.py (not served here)
- benchmarks/tests/test_concurrent_write.py (not served here)
- benchmarks/tests/test_diagnose.py (not served here)
- benchmarks/tests/test_fairness.py (not served here)
- benchmarks/tests/test_manifest_schema.py (not served here)
- benchmarks/tests/test_qa_scoring.py (not served here)
- benchmarks/tests/test_retrieval_metrics.py (not served here)
- benchmarks/tests/test_review.py (not served here)
- benchmarks/tests/test_runner_grouped.py (not served here)
- benchmarks/tests/test_structure_corpus.py (not served here)
- benchmarks/tests/test_xafs_dataset.py (not served here)
- benchmarks/tests/xafs_fixture.py (not served here)
- benchmarks/uv.lock (not served here)
- conftest.py (not served here)
- docker-compose-postgres.yml (not served here)
- docker-compose.yml (not served here)
- docs/1.0.md
- docs/ARCHITECTURE.md
- docs/COMPACT_DISCOVERY.md
- docs/DOCTOR.md
- docs/DOCUMENT_CITATIONS.md
- docs/DOMAIN_MODEL.md
- docs/Docker.md
- docs/ENGINEERING_STYLE.md
- docs/LOCKED_NOTES.md
- docs/MARKDOWN_RELATIONS.md
- docs/NOTE-FORMAT.md
- docs/PI_MEMORY_E2E_RESULTS.md
- docs/PI_MEMORY_HANDOFF.md
- docs/PI_MEMORY_PLAN.md
- docs/PI_MEMORY_SHIPPING.md
- docs/PI_MEMORY_TRANSPORT_DECISION.md
- docs/REDIS_READ_CACHE_PLAN.md
- docs/SPEC-PER-PROJECT-ROUTING.md
- docs/TRANSACTION_ISOLATION.md
- docs/ai-assistant-guide-extended.md
- docs/archive/mcp-ui-bakeoff-instructions.md (not served here)
- docs/archive/post-v0.18.0-test-plan.md (not served here)
- docs/auto-bm-webhook-test.md
- docs/character-handling.md
- docs/cloud-cli.md
- docs/cloud-semantic-search-value.md
- docs/litellm-provider.md (not served here)
- docs/logfire-instrumentation-strategy.md
- docs/manual-pages.md
- docs/metadata-search.md
- docs/multilingual-embedding-benchmark.md
- docs/postgres-fts-large-project-benchmark.md
- docs/releases/v0.19.0.md (not served here)
- docs/schema/document-extraction.md (not served here)
- docs/semantic-search-test-log.md
- docs/semantic-search.md (not served here)
- docs/specs/SPEC-LOCAL-PLUS-PUBLISH.md (not served here)
- docs/specs/SPEC-SCHEMA-IMPL.md (not served here)
- docs/specs/SPEC-SCHEMA.md (not served here)
- docs/test-performance.md
- docs/testing-coverage.md
- glama.json (not served here)
- integrations/hermes/.coveragerc (not served here)
- integrations/hermes/.github/workflows/integration.yml (not served here)
- integrations/hermes/.github/workflows/pr-title.yml (not served here)
- integrations/hermes/.github/workflows/release.yml (not served here)
- integrations/hermes/.github/workflows/test.yml (not served here)
- integrations/hermes/.gitignore (not served here)
- integrations/hermes/CHANGELOG.md (not served here)
- integrations/hermes/LICENSE
- integrations/hermes/MONKEYPATCH.md (not served here)
- integrations/hermes/README.md (not served here)
- integrations/hermes/__init__.py (not served here)
- integrations/hermes/justfile (not served here)
- integrations/hermes/plugin.yaml (not served here)
- integrations/hermes/pytest.ini (not served here)
- integrations/hermes/requirements-dev.txt (not served here)
- integrations/hermes/skill/SKILL.md (not served here)
- integrations/hermes/tests/__init__.py (not served here)
- integrations/hermes/tests/conftest.py (not served here)
- integrations/hermes/tests/stubs/agent/__init__.py (not served here)
- integrations/hermes/tests/stubs/agent/memory_provider.py (not served here)
- integrations/hermes/tests/stubs/tools/__init__.py (not served here)
- integrations/hermes/tests/stubs/tools/registry.py (not served here)
- integrations/hermes/tests/test_actor.py (not served here)
- integrations/hermes/tests/test_capture.py (not served here)
- integrations/hermes/tests/test_child_env.py (not served here)
- integrations/hermes/tests/test_commands.py (not served here)
- integrations/hermes/tests/test_helpers.py (not served here)
- integrations/hermes/tests/test_hermes_contract.py (not served here)
- integrations/hermes/tests/test_integration.py (not served here)
- integrations/hermes/tests/test_lifecycle.py (not served here)
- integrations/hermes/tests/test_prefetch.py (not served here)
- integrations/hermes/tests/test_prompts.py (not served here)
- integrations/hermes/tests/test_provider.py (not served here)
- integrations/hermes/tests/test_status.py (not served here)
- integrations/openclaw/.githooks/pre-commit (not served here)
- integrations/openclaw/.github/workflows/ci.yml (not served here)
- integrations/openclaw/.github/workflows/release.yml (not served here)
- integrations/openclaw/.gitignore (not served here)
- integrations/openclaw/AGENTS.md (not served here)
- integrations/openclaw/BASIC_MEMORY.md (not served here)
- integrations/openclaw/CLAUDE.md (not served here)
- integrations/openclaw/CONTEXT_ENGINE_PLAN.md (not served here)
- integrations/openclaw/DEVELOPMENT.md (not served here)
- integrations/openclaw/LICENSE
- integrations/openclaw/MEMORY_TASK_FLOW.md (not served here)
- integrations/openclaw/README.md (not served here)
- integrations/openclaw/SECURITY.md (not served here)
- integrations/openclaw/biome.json (not served here)
- integrations/openclaw/bm-client.test.ts (not served here)
- integrations/openclaw/bm-client.ts (not served here)
- integrations/openclaw/bun.lock (not served here)
- integrations/openclaw/commands/cli.ts (not served here)
- integrations/openclaw/commands/skills.test.ts (not served here)
- integrations/openclaw/commands/skills.ts (not served here)
- integrations/openclaw/commands/slash.ts (not served here)
- integrations/openclaw/config.test.ts (not served here)
- integrations/openclaw/config.ts (not served here)
- integrations/openclaw/context-engine/basic-memory-context-engine.test.ts (not served here)
- integrations/openclaw/context-engine/basic-memory-context-engine.ts (not served here)
- integrations/openclaw/context-engine/types.ts (not served here)
- integrations/openclaw/docs/agent-guide.md (not served here)
- integrations/openclaw/hooks/capture.test.ts (not served here)
- integrations/openclaw/hooks/capture.ts (not served here)
- integrations/openclaw/hooks/recall.test.ts (not served here)
- integrations/openclaw/hooks/recall.ts (not served here)
- integrations/openclaw/index.test.ts (not served here)
- integrations/openclaw/index.ts (not served here)
- integrations/openclaw/integration/bm-client.integration.test.ts (not served here)
- integrations/openclaw/justfile (not served here)
- integrations/openclaw/logger.test.ts (not served here)
- integrations/openclaw/logger.ts (not served here)
- integrations/openclaw/memory/basic-memory-capability.test.ts (not served here)
- integrations/openclaw/memory/basic-memory-capability.ts (not served here)
- integrations/openclaw/openclaw.plugin.json (not served here)
- integrations/openclaw/package.json (not served here)
- integrations/openclaw/schema/conversation-schema.ts (not served here)
- integrations/openclaw/schema/task-schema.ts (not served here)
- integrations/openclaw/scripts/bm-local.sh (not served here)
- integrations/openclaw/scripts/fetch-skills.test.ts (not served here)
- integrations/openclaw/scripts/fetch-skills.ts (not served here)
- integrations/openclaw/scripts/setup-bm.sh (not served here)
- integrations/openclaw/tools/build-context.test.ts (not served here)
- integrations/openclaw/tools/build-context.ts (not served here)
- integrations/openclaw/tools/delete-note.test.ts (not served here)
- integrations/openclaw/tools/delete-note.ts (not served here)
- integrations/openclaw/tools/edit-note.test.ts (not served here)
- integrations/openclaw/tools/edit-note.ts (not served here)
- integrations/openclaw/tools/list-memory-projects.test.ts (not served here)
- integrations/openclaw/tools/list-memory-projects.ts (not served here)
- integrations/openclaw/tools/list-workspaces.test.ts (not served here)
- integrations/openclaw/tools/list-workspaces.ts (not served here)
- integrations/openclaw/tools/move-note.test.ts (not served here)
- integrations/openclaw/tools/move-note.ts (not served here)
- integrations/openclaw/tools/read-note.test.ts (not served here)
- integrations/openclaw/tools/read-note.ts (not served here)
- integrations/openclaw/tools/schema-diff.test.ts (not served here)
- integrations/openclaw/tools/schema-diff.ts (not served here)
- integrations/openclaw/tools/schema-infer.test.ts (not served here)
- integrations/openclaw/tools/schema-infer.ts (not served here)
- integrations/openclaw/tools/schema-validate.test.ts (not served here)
- integrations/openclaw/tools/schema-validate.ts (not served here)
- integrations/openclaw/tools/search-notes.test.ts (not served here)
- integrations/openclaw/tools/search-notes.ts (not served here)
- integrations/openclaw/tools/write-note.test.ts (not served here)
- integrations/openclaw/tools/write-note.ts (not served here)
- integrations/openclaw/tsconfig.build.json (not served here)
- integrations/openclaw/tsconfig.json (not served here)
- integrations/pi/LICENSE
- integrations/pi/README.md (not served here)
- integrations/pi/SKILLS.md (not served here)
- integrations/pi/extensions/bm-cli.ts (not served here)
- integrations/pi/extensions/config.ts (not served here)
- integrations/pi/extensions/index.ts (not served here)
- integrations/pi/extensions/session.ts (not served here)
- integrations/pi/justfile (not served here)
- integrations/pi/package-lock.json (not served here)
- integrations/pi/package.json (not served here)
- integrations/pi/scripts/fetch-skills.ts (not served here)
- integrations/pi/skill-references/manifest.json (not served here)
- integrations/pi/skill-references/memory-capture/REFERENCE.md (not served here)
- integrations/pi/skill-references/memory-continue/REFERENCE.md (not served here)
- integrations/pi/skill-references/memory-notes/REFERENCE.md (not served here)
- integrations/pi/skill-references/memory-tasks/REFERENCE.md (not served here)
- integrations/pi/skills/basic-memory-pi-setup/SKILL.md (not served here)
- integrations/pi/skills/basic-memory-pi/SKILL.md (not served here)
- integrations/pi/test/config.test.ts (not served here)
- integrations/pi/test/recall.test.ts (not served here)
- integrations/pi/test/session.test.ts (not served here)
- integrations/pi/test/status.test.ts (not served here)
- integrations/pi/tsconfig.json (not served here)
- integrations/shared/README.md (not served here)
- integrations/shared/schemas/coding-session.md (not served here)
- integrations/shared/schemas/decision.md (not served here)
- integrations/shared/schemas/session.md (not served here)
- integrations/shared/schemas/task.md (not served here)
- integrations/tau/Basic Memory.py (not served here)
- integrations/tau/DESIGN.md (not served here)
- integrations/tau/README.md (not served here)
- integrations/tau/bridge.py (not served here)
- integrations/tau/continuity.py (not served here)
- integrations/tau/extension.py (not served here)
- integrations/tau/justfile (not served here)
- integrations/tau/knowledge.py (not served here)
- integrations/tau/privacy.py (not served here)
- integrations/tau/prompts/bm-decide.md (not served here)
- integrations/tau/prompts/bm-plan.md (not served here)
- integrations/tau/prompts/bm-resume.md (not served here)
- integrations/tau/prompts/bm-wrap-up.md (not served here)
- integrations/tau/pyproject.toml (not served here)
- integrations/tau/results.py (not served here)
- integrations/tau/schemas/coding-session.md (not served here)
- integrations/tau/schemas/decision.md (not served here)
- integrations/tau/schemas/session.md (not served here)
- integrations/tau/schemas/task.md (not served here)
- integrations/tau/skills/basic-memory-setup/SKILL.md (not served here)
- integrations/tau/tests/conftest.py (not served here)
- integrations/tau/tests/fake_server.py (not served here)
- integrations/tau/tests/test_boundaries.py (not served here)
- integrations/tau/tests/test_cancellation.py (not served here)
- integrations/tau/tests/test_continuity.py (not served here)
- integrations/tau/tests/test_extension.py (not served here)
- integrations/tau/tests/test_extension_name.py (not served here)
- integrations/tau/tests/test_integration.py (not served here)
- integrations/tau/tests/test_knowledge.py (not served here)
- integrations/tau/tests/test_privacy.py (not served here)
- integrations/tau/tests/test_profile_safety.py (not served here)
- integrations/tau/tests/test_prompts.py (not served here)
- integrations/tau/tests/test_provider_privacy.py (not served here)
- integrations/tau/tests/test_recall_contract.py (not served here)
- integrations/tau/tests/test_recovery.py (not served here)
- integrations/tau/tests/test_schema_interop.py (not served here)
- integrations/tau/tests/test_setup_skill.py (not served here)
- integrations/tau/tests/test_startup.py (not served here)
- integrations/tau/tests/test_tool_registration.py (not served here)
- integrations/tau/uv.lock (not served here)
- justfile (not served here)
- llms-install.md
- plugins/chatgpt/.codex-plugin/plugin.json (not served here)
- plugins/chatgpt/.mcp.json (not served here)
- plugins/chatgpt/assets/app-icon.png (not served here)
- plugins/claude-code/.claude-plugin/marketplace.json (not served here)
- plugins/claude-code/.claude-plugin/plugin.json (not served here)
- plugins/claude-code/CHANGELOG.md (not served here)
- plugins/claude-code/DESIGN.md (not served here)
- plugins/claude-code/README.md (not served here)
- plugins/claude-code/docs/architecture.md (not served here)
- plugins/claude-code/docs/getting-started.md (not served here)
- plugins/claude-code/docs/why-combine-memory.md (not served here)
- plugins/claude-code/hooks/hooks.json (not served here)
- plugins/claude-code/hooks/pre_compact.py (not served here)
- plugins/claude-code/hooks/session_start.py (not served here)
- plugins/claude-code/hooks/test_claude_pre_compact.py (not served here)
- plugins/claude-code/hooks/test_claude_session_start.py (not served here)
- server.json
- smithery.yaml
- tests/fixtures/okf/LICENSE.md
Advantages
- Local-first architecture ensures data remains on your disk, providing air-gapped compatibility and full ownership. evidence: README.md
- Bidirectional synchronization allows both humans and AI agents to edit the same files, keeping the knowledge base consistent. evidence: README.md
- Progressive tool discovery via MCP behavior hints allows agents to select the most appropriate tool for a task without wasting context. evidence: README.md
Limitations
- Local installation requires Python 3.12+ and familiarity with command-line tools. evidence: README.md
- Cross-device synchronization for local-only setups requires manual configuration of tools like Git or Syncthing. evidence: README.md
- Advanced features like cross-encoder reranking may introduce inference latency and require additional model downloads. evidence: README.md
Security
Risk level: Medium risk
This brain runs
Agent instructions that run or fetch something (322)
.agents/skills/adversarial-review/SKILL.md:To **run** it, use `"${DIFF[@]}"` (quoted, no word-splitting)..agents/skills/adversarial-review/SKILL.md:Run `"${DIFF[@]}"`..agents/skills/adversarial-review/SKILL.md:`RUN=$(mktemp -d)` — scratch dir for the other model's output..agents/skills/adversarial-review/SKILL.md:**The other model's pass** — run, from the repo root, the row that matches you:.agents/skills/adversarial-review/SKILL.md:# You are Claude → run Codex:.agents/skills/adversarial-review/SKILL.md:-o "$RUN/other_findings.json" \.agents/skills/adversarial-review/SKILL.md:# You are Codex → run Claude (read-only via plan mode; parse the JSON block it returns):.agents/skills/adversarial-review/SKILL.md:$(cat "$SKILL_DIR/schemas/findings.schema.json")" </dev/null > "$RUN/other_raw.json".agents/skills/fix-pr-issues/SKILL.md:Run the smallest meaningful verification first, then widen as needed..agents/skills/fix-pr-issues/SKILL.md:Commit changed code or documentation with `git commit -s`..agents/skills/fix-pr-issues/SKILL.md:For each addressed comment or blocker, reply with the fix commit, verification run, and current Codex gate status..agents/skills/infographics/SKILL.md:uv run --script scripts/generate_pr_infographic.py \.agents/skills/infographics/SKILL.md:uv run --script scripts/generate_pr_infographic.py \.agents/skills/infographics/SKILL.md:`--dry-run` is an alias for `--print-prompt`;.agents/skills/infographics/SKILL.md:changed-file orientation: `git diff --stat` plus key file reads.agents/skills/infographics/SKILL.md:uv run --script scripts/generate_infographic.py \.agents/skills/instrumentation/SKILL.md:The reason this skill exists is that Claude tends to get a few things subtly wrong with Logfire - especially the ordering of `configure()` vs `instrument_*()` calls, the structured logging syntax, and which extras to install..agents/skills/instrumentation/SKILL.md:Install `logfire` with extras matching the detected frameworks..agents/skills/instrumentation/SKILL.md:uv add 'logfire[pydantic-ai]'.agents/skills/instrumentation/SKILL.md:For PydanticAI, each agent run becomes a parent span containing child spans for every tool call and LLM request..agents/skills/instrumentation/SKILL.md:Launch with: `node --require ./instrumentation.js app.js`.agents/skills/instrumentation/SKILL.md:Run `logfire auth` to check authentication (or set `LOGFIRE_TOKEN`).agents/skills/pr-create/SKILL.md:Return the PR URL, current head SHA, validation run, check status, and Codex gate evidence..agents/skills/pr-description/SKILL.md:git log --oneline --decorate -n 10.agents/skills/pr-description/SKILL.md:Testing section must include exact commands run and outcomes..agents/skills/pr-review-loop/SKILL.md:If the comment identifies a real issue, patch it, run focused validation, push, and restart the loop on the new head..agents/skills/pr-review-loop/SKILL.md:Only run `gh pr merge` when the gate is `approved` or `overridden` and tests are passing on that same head..agents/skills/pull-request/SKILL.md:After activation, run Python scripts as `python ...`..agents/skills/pull-request/SKILL.md:For one-off commands where activation is awkward, prefer `./.venv/bin/python ...` or the repo's `uv run ...` patterns..agents/skills/pull-request/SKILL.md:Run focused tests for the changed surface..agents/skills/pull-request/SKILL.md:Run the repo's required gate, such as `just fast-check` for source changes or `just package-check` for agent/package changes, before calling the branch ready..agents/skills/pull-request/SKILL.md:`Testing`: exact commands run and whether they passed..agents/skills/pull-request/SKILL.md:If the feedback is correct and in scope, patch, run focused validation, push, and restart the loop on the new head..agents/skills/pythonic-code/SKILL.md:Run the narrowest command that proves the change, then widen according to risk:.agents/skills/pythonic-code/evals/context/AGENTS.md:Run the focused tests under `evals/files` and the configured Ruff checks for changed Python..claude/commands/release/beta.md:When the user runs `/beta`, execute the following steps:.claude/commands/release/beta.md:While `pyproject.toml` pins a FastMCP pre-release (`fastmcp==X.Y.Zb1`), `just beta` refuses to run: every documented install passes `--prerelease=allow`, which uv applies to basic-memory itself, so a beta on PyPI would become the default install for stable users (#1338)..claude/commands/release/beta.md:Execute the automated beta release process:.claude/commands/release/beta.md:Test beta installation: `uv tool install basic-memory --pre`.claude/commands/release/beta.md:# Install/upgrade to beta.claude/commands/release/beta.md:uv tool install basic-memory --pre.claude/commands/release/beta.md:uv tool upgrade basic-memory --prerelease=allow.claude/commands/release/beta.md:Install/test with:.claude/commands/release/beta.md:uv tool install basic-memory --pre.claude/commands/release/beta.md:**Test features**: Install and validate new functionality.claude/commands/release/changelog.md:When the user runs `/changelog`, execute the following steps:.claude/commands/release/changelog.md:git tag -l "v*" --sort=-version:refname | grep -v "b\|rc" | head -1.claude/commands/release/changelog.md:git log --oneline ${last_tag}..HEAD.claude/commands/release/changelog.md:uv tool install basic-memory --prerelease=allow.claude/commands/release/release-check.md:When the user runs `/release-check`, execute the following validation steps:.claude/commands/release/release-check.md:2. Run `/release v0.13.0` when ready.claude/commands/release/release-check.md:Can be run multiple times safely.claude/commands/release/release.md:When the user runs `/release`, execute the following steps:.claude/commands/release/release.md:Execute the automated release process:.claude/commands/release/release.md:✅ Builds the package using `uv build`.claude/commands/release/release.md:Test installation: `uv tool install basic-memory --prerelease=allow`.claude/commands/release/release.md:Test Homebrew installation: `brew install basicmachines-co/basic-memory/basic-memory`.claude/commands/release/release.md:gh workflow run mcp-registry-publish.yml.claude/commands/release/release.md:curl "https://registry.modelcontextprotocol.io/v0.1/servers?search=basic-memory"· uses the network.claude/commands/release/release.md:Pull latest from GitHub: `git pull origin main`· uses the network.claude/commands/release/release.md:Create release branch: `git checkout -b release/v{VERSION}`.claude/commands/release/release.md:Commit (`git commit -s -m "..."`), push, and open a PR against `basicmachines-co/basicmemory.com`.claude/commands/release/release.md:Pull latest from GitHub: `git pull origin main`· uses the network.claude/commands/release/release.md:Create release branch: `git checkout -b release/v{VERSION}`.claude/commands/release/release.md:Commit: `git commit -s -m "docs: add v{VERSION} release notes"`.claude/commands/release/release.md:Install with pip/uv:.claude/commands/release/release.md:uv tool install basic-memory --prerelease=allow.claude/commands/release/release.md:Install with Homebrew:.claude/commands/release/release.md:brew install basicmachines-co/basic-memory/basic-memory.claude/commands/release/release.md:uv tool upgrade basic-memory --prerelease=allow.claude/commands/release/release.md:To bump only the plugin/agent artifacts out of band, use `just set-packages-version <version>` (preview with `just set-packages-version-dry-run <version>`)..claude/commands/spec.md:Execute the spec command: `/spec $ARGUMENTS`.claude/commands/test-live.md:Execute comprehensive real-world testing of Basic Memory using the installed version..claude/commands/test-live.md:`phase` (optional): Specific test phase to run (`recent`, `core`, `features`, `edge`, `workflows`, `stress`, or `all`).claude/commands/test-live.md:When the user runs `/project:test-live`, execute comprehensive test plan:.claude/commands/test-live.md:Run `git log --oneline -20` to examine recent commits.claude/commands/test-live.md:Run the bash `date` command to get the current date/time..claude/commands/test-live.md:Execute test scenarios systematicallyAGENTS.md:Install: `just install` or `pip install -e ".[dev]"`AGENTS.md:Run all tests (SQLite + Postgres): `just test`AGENTS.md:Run all tests against SQLite: `just test-sqlite`AGENTS.md:Run all tests against Postgres: `just test-postgres` (uses testcontainers)AGENTS.md:Run unit tests (SQLite): `just test-unit-sqlite`AGENTS.md:Run unit tests (Postgres): `just test-unit-postgres`AGENTS.md:Run integration tests (SQLite): `just test-int-sqlite`AGENTS.md:Run integration tests (Postgres): `just test-int-postgres`AGENTS.md:Run impacted tests: `just fast-test` or `just testmon` (pytest-testmon;AGENTS.md:Run MCP smoke test: `just test-smoke`AGENTS.md:Run all consolidated agent package checks: `just package-check`AGENTS.md:Run Claude Code plugin checks: `just package-check-claude-code`AGENTS.md:Run shared skills checks: `just package-check-skills`AGENTS.md:Run Hermes plugin checks: `just package-check-hermes`AGENTS.md:Run OpenClaw plugin checks: `just package-check-openclaw`AGENTS.md:Run host-native agent harness checks: `just agent-harness-check`AGENTS.md:Run benchmarks: `pytest test-int/test_sync_performance_benchmark.py -v -m "benchmark and not slow"`AGENTS.md:Type check: `just typecheck` or `uv run ty check src tests test-int`AGENTS.md:Type check (pyright): `just typecheck-pyright` or `uv run pyright`AGENTS.md:Format: `just format` or `uv run ruff format .`AGENTS.md:Run all static code checks: `just check` (runs lint, format, typecheck)AGENTS.md:Run development MCP Inspector: `just run-inspector`AGENTS.md:**Test:** `just fast-test` for pytest-testmon impacted tests, or a targeted `uv run pytest ...` command.AGENTS.md:Run `just test-smoke` when you specifically need the MCP smoke flow.AGENTS.md:If testmon is “cold,” the first run may be long.AGENTS.md:`just package-check-openclaw` — runs the OpenClaw package install, copies top-level skills into the generated bundle, typechecks, lints, builds `dist/`, runs Bun tests, and performs `npm pack --dry-run`.AGENTS.md:Before opening or updating a PR, run the checks that mirror the common required CI failures:AGENTS.md:Run `just typecheck` in addition to targeted `ruff` and `pytest` commands when tests were added or changed.AGENTS.md:Sign commits with `git commit -s` so DCO passes.AGENTS.md:Add or update meaningful regression tests for bugs and risky behavior, prefer real code paths over mocks, and run the narrowest command that proves the change before widening verification.AGENTS.md:connection.execute("PRAGMA journal_mode=WAL")AGENTS.md:By default, tests run against SQLite (fast, no Docker needed)AGENTS.md:Set `BASIC_MEMORY_TEST_POSTGRES=1` to run against Postgres (uses testcontainers - Docker required)AGENTS.md:The recipes bump version metadata, run pre-flight checks, land the bump on `main` through a release PR, tag, and push the tag.AGENTS.md:PyPI consumers install with `pip install basic-memory --pre`.AGENTS.md:The recipe refuses a beta whenever `pyproject.toml` pins a FastMCP pre-release (`fastmcp==X.Y.ZbN`): installs then need `--prerelease=allow`, which uv also applies to basic-memory itself, so a beta on PyPI would become the default install for stable users.AGENTS.md:**Release dry run:** `just release-dry-run v0.21.4` previews the consolidated version update without writing files.AGENTS.md:**Development builds are not published to PyPI.** Documented installs pass `--prerelease=allow` (published releases through v0.23.2 pin a FastMCP pre-release), and uv applies that flag to basic-memory itself, so a `.devN` build on PyPI would outrank the stable release for every fresh install.AGENTS.md:To try unreleased `main`, install from git: `uv tool install "basic-memory @ git+https://github.com/basicmachines-co/basic-memory" --prerelease=allow`.AGENTS.md:**Post-release tasks** the recipe surfaces but doesn't run:AGENTS.md:MCP Registry — after the version is live on PyPI, dispatch `.github/workflows/mcp-registry-publish.yml` (`gh workflow run mcp-registry-publish.yml`);CLAUDE.md:Install: `just install` or `pip install -e ".[dev]"`CLAUDE.md:Run all tests (SQLite + Postgres): `just test`CLAUDE.md:Run all tests against SQLite: `just test-sqlite`CLAUDE.md:Run all tests against Postgres: `just test-postgres` (uses testcontainers)CLAUDE.md:Run unit tests (SQLite): `just test-unit-sqlite`CLAUDE.md:Run unit tests (Postgres): `just test-unit-postgres`CLAUDE.md:Run integration tests (SQLite): `just test-int-sqlite`CLAUDE.md:Run integration tests (Postgres): `just test-int-postgres`CLAUDE.md:Run impacted tests: `just fast-test` or `just testmon` (pytest-testmon;CLAUDE.md:Run MCP smoke test: `just test-smoke`CLAUDE.md:Run all consolidated agent package checks: `just package-check`CLAUDE.md:Run Claude Code plugin checks: `just package-check-claude-code`CLAUDE.md:Run shared skills checks: `just package-check-skills`CLAUDE.md:Run Hermes plugin checks: `just package-check-hermes`CLAUDE.md:Run OpenClaw plugin checks: `just package-check-openclaw`CLAUDE.md:Run host-native agent harness checks: `just agent-harness-check`CLAUDE.md:Run benchmarks: `pytest test-int/test_sync_performance_benchmark.py -v -m "benchmark and not slow"`CLAUDE.md:Type check: `just typecheck` or `uv run ty check src tests test-int`CLAUDE.md:Type check (pyright): `just typecheck-pyright` or `uv run pyright`CLAUDE.md:Format: `just format` or `uv run ruff format .`CLAUDE.md:Run all static code checks: `just check` (runs lint, format, typecheck)CLAUDE.md:Run development MCP Inspector: `just run-inspector`CLAUDE.md:**Test:** `just fast-test` for pytest-testmon impacted tests, or a targeted `uv run pytest ...` command.CLAUDE.md:Run `just test-smoke` when you specifically need the MCP smoke flow.CLAUDE.md:If testmon is “cold,” the first run may be long.CLAUDE.md:`just package-check-openclaw` — runs the OpenClaw package install, copies top-level skills into the generated bundle, typechecks, lints, builds `dist/`, runs Bun tests, and performs `npm pack --dry-run`.CLAUDE.md:Before opening or updating a PR, run the checks that mirror the common required CI failures:CLAUDE.md:Run `just typecheck` in addition to targeted `ruff` and `pytest` commands when tests were added or changed.CLAUDE.md:Sign commits with `git commit -s` so DCO passes.CLAUDE.md:Add or update meaningful regression tests for bugs and risky behavior, prefer real code paths over mocks, and run the narrowest command that proves the change before widening verification.CLAUDE.md:connection.execute("PRAGMA journal_mode=WAL")CLAUDE.md:By default, tests run against SQLite (fast, no Docker needed)CLAUDE.md:Set `BASIC_MEMORY_TEST_POSTGRES=1` to run against Postgres (uses testcontainers - Docker required)CLAUDE.md:The recipes bump version metadata, run pre-flight checks, land the bump on `main` through a release PR, tag, and push the tag.CLAUDE.md:PyPI consumers install with `pip install basic-memory --pre`.CLAUDE.md:The recipe refuses a beta whenever `pyproject.toml` pins a FastMCP pre-release (`fastmcp==X.Y.ZbN`): installs then need `--prerelease=allow`, which uv also applies to basic-memory itself, so a beta on PyPI would become the default install for stable users.CLAUDE.md:**Release dry run:** `just release-dry-run v0.21.4` previews the consolidated version update without writing files.CLAUDE.md:**Development builds are not published to PyPI.** Documented installs pass `--prerelease=allow` (published releases through v0.23.2 pin a FastMCP pre-release), and uv applies that flag to basic-memory itself, so a `.devN` build on PyPI would outrank the stable release for every fresh install.CLAUDE.md:To try unreleased `main`, install from git: `uv tool install "basic-memory @ git+https://github.com/basicmachines-co/basic-memory" --prerelease=allow`.CLAUDE.md:**Post-release tasks** the recipe surfaces but doesn't run:CLAUDE.md:MCP Registry — after the version is live on PyPI, dispatch `.github/workflows/mcp-registry-publish.yml` (`gh workflow run mcp-registry-publish.yml`);benchmarks/AGENTS.md:Install: `uv sync --group dev`benchmarks/AGENTS.md:Run tests: `uv run pytest -q`benchmarks/AGENTS.md:Lint: `uv run ruff check .`benchmarks/AGENTS.md:Type check: `uv run pyright`benchmarks/AGENTS.md:`uv run pytest -q`benchmarks/AGENTS.md:`uv run ruff check .`benchmarks/AGENTS.md:`uv run pyright`benchmarks/AGENTS.md:CLI entrypoint: `uv run bm-bench ...`benchmarks/AGENTS.md:`uv run bm-bench datasets fetch --dataset locomo`benchmarks/AGENTS.md:`uv run bm-bench convert locomo --dataset-path benchmarks/datasets/locomo/locomo10.json --output-dir benchmarks/generated/locomo`benchmarks/AGENTS.md:`bash benchmarks/datasets/beam/download.sh` (BEAM data is never vendored;benchmarks/AGENTS.md:`uv run bm-bench convert beam --tier 100K --output-dir benchmarks/generated/beam-100k`benchmarks/AGENTS.md:Run retrieval:benchmarks/AGENTS.md:`uv run bm-bench run retrieval --providers bm-local,mem0-local --dataset-id locomo --dataset-path benchmarks/datasets/locomo/locomo10.json --corpus-dir benchmarks/generated/locomo/docs --queries-path benchmarks/generated/locomo/queries.json --output-root benchmarks/runs --allow-provider-skip`benchmarks/AGENTS.md:Run end-to-end QA scoring:benchmarks/AGENTS.md:`uv run bm-bench run qa --run-dir benchmarks/runs/<run-id> --answerer claude:claude-haiku-4-5 --judge claude:claude-sonnet-4-6`benchmarks/AGENTS.md:BEAM nugget scoring (post-hoc, after `run qa` on a BEAM run):benchmarks/AGENTS.md:`uv run bm-bench run beam-score --run-dir benchmarks/runs/<run-id> --judge claude:claude-sonnet-4-6`benchmarks/AGENTS.md:`uv run bm-bench run agent-tasks --surfaces bm --model openai-compat:<model>@<base_url> --bm-local-path <bm-checkout>`benchmarks/AGENTS.md:`uv run bm-bench validate-artifacts --run-dir benchmarks/runs/<run-id>`benchmarks/AGENTS.md:`uv run bm-bench publish --run-dir benchmarks/runs/<run-id> --destination benchmarks/results/public`benchmarks/AGENTS.md:`just bench-run-beam-100k`benchmarks/AGENTS.md:`just bench-beam-score benchmarks/runs/<run-id>`benchmarks/AGENTS.md:`just bench-run-bm-local`benchmarks/AGENTS.md:`just bench-run-mem0-local`benchmarks/AGENTS.md:`just bench-run-full`benchmarks/AGENTS.md:`just bench-qa benchmarks/runs/<run-id>`benchmarks/AGENTS.md:`just bench-publish benchmarks/runs/<run-id>`benchmarks/AGENTS.md:`src/basic_memory_benchmarks/runner.py` - run orchestrationbenchmarks/AGENTS.md:`benchmarks/runs/` - raw run artifactsbenchmarks/AGENTS.md:The benchmark command is typically invoked through `uv run ...` so `.venv/bin/bm` is used.benchmarks/AGENTS.md:Ingest and search use a stable benchmark `user_id` namespace per run.benchmarks/AGENTS.md:Prefer setting only required credentials for run reproducibility.benchmarks/AGENTS.md:Always publish conversion code and run artifacts.benchmarks/AGENTS.md:Sign commits: `git commit -s`.integrations/hermes/skill/SKILL.md:**Search before answering.** If the user asks "what did we decide about X?", run `bm_search` first.integrations/openclaw/AGENTS.md:**Build output** — `bun run build` emits `dist/` for `runtimeExtensions`;integrations/openclaw/AGENTS.md:`scripts/bm-local.sh` runs BM from the monorepo root via `uv run --project ...` when available, then falls back to `bm` on PATHintegrations/openclaw/AGENTS.md:**Package CI** (root `.github/workflows/consolidated-packages.yml`): validates skills, typechecks, lints, builds, tests, and runs `npm pack --dry-run`.integrations/openclaw/CLAUDE.md:**Build output** — `bun run build` emits `dist/` for `runtimeExtensions`;integrations/openclaw/CLAUDE.md:`scripts/bm-local.sh` runs BM from the monorepo root via `uv run --project ...` when available, then falls back to `bm` on PATHintegrations/openclaw/CLAUDE.md:**Package CI** (root `.github/workflows/consolidated-packages.yml`): validates skills, typechecks, lints, builds, tests, and runs `npm pack --dry-run`.integrations/pi/skills/basic-memory-pi-setup/SKILL.md:If the user wants MCP mode, install the adapter and switch transport:integrations/pi/skills/basic-memory-pi-setup/SKILL.md:pi install npm:pi-mcp-adapterintegrations/pi/skills/basic-memory-pi-setup/SKILL.md:Run `/bm-status` and check the effective auto recall/capture state, then `/bm-recall setup` or `/bm-capture Pi setup checkpoint` to verify the path.integrations/pi/skills/basic-memory-pi-setup/SKILL.md:For local Basic Memory development in a trusted workspace, set `BASIC_MEMORY_PI_TRUST_BM_COMMAND=1` and use `bmCommand` as an argv array such as `["uv", "run", "--project", "/path/to/basic-memory", "basic-memory"]`;integrations/tau/skills/basic-memory-setup/SKILL.md:Locate the integration directory: the installed `~/.tau/extensions/basic-memory` from `bm install tau`, or `integrations/tau` in an explicitly identified Basic Memory checkout.integrations/tau/skills/basic-memory-setup/SKILL.md:A packaged install does not require a source checkout.integrations/tau/skills/basic-memory-setup/SKILL.md:If the extension is loaded, ask the user to run `/bm-status`.integrations/tau/skills/basic-memory-setup/SKILL.md:A text reply does not run a slash command or control the current Tau session.integrations/tau/skills/basic-memory-setup/SKILL.md:Consult current Basic Memory install docs rather than guessing package versions or changing the user's global Tau installation.integrations/tau/skills/basic-memory-setup/SKILL.md:For a packaged install, with approval for dependency installation, use:integrations/tau/skills/basic-memory-setup/SKILL.md:bm install tau --syncintegrations/tau/skills/basic-memory-setup/SKILL.md:Then give the user this command to run in their terminal:integrations/tau/skills/basic-memory-setup/SKILL.md:uv run --project ~/.tau/extensions/basic-memory tauintegrations/tau/skills/basic-memory-setup/SKILL.md:For source development, with approval, run `uv sync --project <integration-directory>` and launch `uv run --project <integration-directory> tau -e <integration-directory>`.integrations/tau/skills/basic-memory-setup/SKILL.md:`bm install tau` installs this setup skill and the prompt templates separately;plugins/claude-code/skills/bm-checkpoint/SKILL.md:`git status --short`plugins/claude-code/skills/bm-checkpoint/SKILL.md:tests or checks actually runplugins/claude-code/skills/bm-checkpoint/SKILL.md:`## Verification`, for checks actually run and their outcomesplugins/claude-code/skills/bm-orient/SKILL.md:If no config is present, continue against the default Basic Memory project and mention that setup has not been run.plugins/claude-code/skills/bm-setup/SKILL.md:Run a short, adaptive interview (~2-3 minutes) and then write the configuration.plugins/claude-code/skills/bm-setup/SKILL.md:Install it: `uv tool install basic-memory --prerelease=allow` (or `pip install basic-memory`), a version exposing the 1.0 `bm_*` tools.plugins/claude-code/skills/bm-setup/SKILL.md:A purely local server (`uvx --prerelease=allow basic-memory mcp`) treats the path as a local directory and fails to create it (e.g. read-only `/`).plugins/claude-code/skills/bm-setup/SKILL.md:Run `bm_project_list()`.plugins/claude-code/skills/bm-setup/SKILL.md:Inspect it: `bm_list(path="/", project="<primaryProject>")` for the top-level folder layout (`bm_find` for recursive discovery), sample a few notes per folder (and, where a folder holds recurring typed notes, you may run `bm_schema_infer()` to see their shape).plugins/claude-code/skills/bm-setup/SKILL.md:(This is the single knob for how proactive the assistant is — the hooks always run regardless.)plugins/claude-code/skills/bm-setup/SKILL.md:I can install them alongside this plugin." These are the canonical, framework-agnostic skills (the same set OpenClaw bundles).plugins/claude-code/skills/bm-setup/SKILL.md:(See "Install the shared skills" below.)plugins/claude-code/skills/bm-setup/SKILL.md:**First, guard against clobbering a source checkout.** If `./skills` already exists, is tracked in git, and holds `memory-*` directories, you're inside the skills' own source repo (e.g. `basic-memory` itself) — the install would overwrite the working copy with published versions.plugins/claude-code/skills/bm-setup/SKILL.md:In that case **skip the install** and tell the user the skills are already present as source;plugins/claude-code/skills/bm-setup/SKILL.md:Otherwise, run:plugins/claude-code/skills/bm-setup/SKILL.md:If `npx` / the `skills` CLI isn't available, point the user at the manual install in the top-level [`skills/README.md`](../../../../skills/README.md).plugins/claude-code/skills/bm-setup/SKILL.md:Writing the `basicMemory` block is also what stops the SessionStart hook's first-run nudge — the config's presence is the signal that setup has run.plugins/claude-code/skills/bm-setup/SKILL.md:Use the CLI the hook uses (`basic-memory` / `bm` / `uvx --prerelease=allow basic-memory`).plugins/claude-code/skills/bm-setup/SKILL.md:**Primary:** run the open-decision query the SessionStart hook runs against `primaryProject`: `… tool search --note-types decision --filters '{"status": "open"}' --page-size 5 --project <primaryProject>`.plugins/claude-code/skills/bm-setup/SKILL.md:**Hook health:** run `basic-memory hook status --harness claude --project-dir <project-root>` with the first available `basic-memory`, `bm`, or `uvx --prerelease=allow basic-memory` launcher.plugins/claude-code/skills/bm-setup/SKILL.md:the hooks already run.plugins/claude-code/skills/bm-setup/SKILL.md:Run `/basic-memory:bm-status` anytime to see what I'm tracking."*plugins/claude-code/skills/bm-status/SKILL.md:**CLI reachable?** Run `basic-memory --version`, then `bm --version`, then `uvx --prerelease=allow basic-memory --version`.plugins/claude-code/skills/bm-status/SKILL.md:**Core hook health.** With the first available launcher, run `basic-memory hook status --harness claude --project-dir <project-root>`.plugins/codex/skills/bm-checkpoint/SKILL.md:`git status --short`plugins/codex/skills/bm-checkpoint/SKILL.md:tests or checks actually runplugins/codex/skills/bm-checkpoint/SKILL.md:`## Verification`, for checks actually run and their outcomesplugins/codex/skills/bm-orient/SKILL.md:Mention that setup has not been run.plugins/codex/skills/bm-orient/SKILL.md:Run the `coding_session` topic search separately and include it only when `sessionProfile=coding` and the configured `repository` is present.plugins/codex/skills/bm-setup/SKILL.md:If MCP tools are not available, run `basic-memory --version` or `bm --version`.plugins/codex/skills/bm-setup/SKILL.md:If neither works, stop and tell the user to install Basic Memory and connect the MCP server.plugins/codex/skills/bm-setup/SKILL.md:The plugin bundles an `.mcp.json` that starts `uvx --prerelease=allow basic-memory mcp`.plugins/codex/skills/bm-setup/SKILL.md:`checkpointOnCompact`: whether post-compaction SessionStart asks Codex to run `bm-checkpoint`.plugins/codex/skills/bm-setup/SKILL.md:Run `basic-memory hook status --harness codex --project-dir <repo-root>` (using `bm` or `uvx --prerelease=allow basic-memory` if needed).plugins/codex/skills/bm-setup/SKILL.md:Tell the user that plugin hooks need to be reviewed and trusted in Codex before they run.plugins/codex/skills/bm-share/SKILL.md:If no team projects are configured, stop and ask the user to run setup or add a target.plugins/codex/skills/bm-status/SKILL.md:fallback `uvx --prerelease=allow basic-memory --version`plugins/codex/skills/bm-status/SKILL.md:with the first available launcher, run `basic-memory hook status --harness codex --project-dir <repo-root>`plugins/codex/skills/bm-status/SKILL.md:check `uv --version` in the current environment independently of CLI reachability;plugins/codex/skills/bm-status/SKILL.md:uv is a required hook prerequisiteplugins/codex/skills/bm-status/SKILL.md:remind the user that Codex plugin hooks must be reviewed and trusted before they runskills/AGENTS.md:Skills can be installed via `npx skills add` or copied manually into any agent's skills directory.skills/AGENTS.md:memory-agents/SKILL.md # Create, run, and check Basic Memory Cloud agentsskills/AGENTS.md:memory-doctor/SKILL.md # Run bm doctor, explain findings, and apply fixes with consentskills/AGENTS.md:Run `just check` from `skills/` or `just package-check-skills` from the monorepo root to validate the `memory-*/SKILL.md` frontmatter before committing changes.skills/CLAUDE.md:Skills can be installed via `npx skills add` or copied manually into any agent's skills directory.skills/CLAUDE.md:memory-agents/SKILL.md # Create, run, and check Basic Memory Cloud agentsskills/CLAUDE.md:memory-doctor/SKILL.md # Run bm doctor, explain findings, and apply fixes with consentskills/CLAUDE.md:Run `just check` from `skills/` or `just package-check-skills` from the monorepo root to validate the `memory-*/SKILL.md` frontmatter before committing changes.skills/memory-agents/SKILL.md:Agents run in Basic Memory Cloud only, on plans that include them.skills/memory-agents/SKILL.md:Asked to create, change, run, or turn off an agentskills/memory-agents/SKILL.md:Asked how an agent run went, what it changed, or why it did not runskills/memory-agents/SKILL.md:with `agent`, whether that agent can run | | `bm_agent_run(agent="<agent>", project="<project>")` | Starts an agent on a note (`identifier`), a folder, or nothing;skills/memory-agents/SKILL.md:returns the run id | | `bm_agent_get(run_id="<run id>")` | One run: status, notes changed, and the agent's last reply;skills/memory-agents/SKILL.md:`whole_workspace=True` lists every run waiting for review | | `bm_agent_mark(decision="kept", run_id="<run id>")` | Mark a run `kept` or `dismissed`;skills/memory-agents/SKILL.md:with no `run_id`, `kept` keeps every waiting run |skills/memory-agents/SKILL.md:Read the meeting note you run on.skills/memory-agents/SKILL.md:An agent changes notes only in its own project, and it runs only if both the person who last edited the agent note and the person the run is for can edit that project.skills/memory-agents/SKILL.md:An agent note last edited by another agent cannot run.skills/memory-agents/SKILL.md:**Ask for a reply.** The last reply is the run's summary: what it created, linked, or left alone, and anything it was unsure about.skills/memory-agents/SKILL.md:**Keep each run small.** A run has about seven minutes, including startup.skills/memory-agents/SKILL.md:| Agent | Run it on | |---|---| | Cleanup | A hub or project index note;skills/memory-agents/SKILL.md:# -> run id. Runs usually take one to a few minutes.skills/memory-agents/SKILL.md:bm_agent_get(run_id="<run id>", project="work")skills/memory-agents/SKILL.md:Ask before running one, unless the user has just asked for that run.skills/memory-agents/SKILL.md:`bm_agent_get(run_id="<run id>", project="<project>")` shows the status, the notes the run created, edited, moved, or deleted, and the agent's last reply.skills/memory-agents/SKILL.md:Every reply is also kept in a run log note, `agents/runs/<agent> run <id>`.skills/memory-agents/SKILL.md:A queued run may be waiting: for the target note to settle, for a free slot (a workspace runs a few agents at once), or for another run on the same note.skills/memory-agents/SKILL.md:When a run is skipped, its reason says why:skills/memory-agents/SKILL.md:the detail names the field | | `agent_disabled` | Set `enabled: true` | | `agent_changed` | The agent note changed after the run was queued;skills/memory-agents/SKILL.md:run it again | | `agent_not_by_a_person` | A person, or an assistant acting for one, saves the agent note again | | `agent_removed`, `trigger_changed` | The agent note or the target note was deleted | | `instruction_author_has_no_access`, `requester_has_no_access` | That person needs a …[+123 chars]skills/memory-agents/SKILL.md:A failed run says why as well: `timeout` (the run ran out of time;skills/memory-agents/SKILL.md:give it a smaller job) or a model error (run it again).skills/memory-capture/SKILL.md:**Always run the same-thread lookup** before deciding to create or update.skills/memory-ci-capture/SKILL.md:Treat it as the immutable source of truth for repository, event type, PR number, workflow run, SHA, source URL, timestamps, and deployment environment.skills/memory-ci-capture/SKILL.md:For production deploys, focus on what reached production, the deployed SHA, environment, workflow run, and verification evidence.skills/memory-comark/SKILL.md:In Basic Memory Cloud, `bm_read(identifier="<note>", view="text", project="<project>")` returns the note as a reader sees it: every component as plain Markdown, with live queries run now.skills/memory-comark/SKILL.md:Elsewhere, only the browser runs the query, so run the equivalent read yourself (for example `bm_search` with metadata filters;skills/memory-doctor/SKILL.md:The fixes it suggests do change things, so run them only after the user agrees.skills/memory-doctor/SKILL.md:Without `--skip-self-test`, doctor also runs a self-test: it writes, indexes and searches a note in a throwaway sandbox, which takes a few seconds and proves the install itself works.skills/memory-doctor/SKILL.md:Run it when the report is clean but something still seems broken.skills/memory-doctor/SKILL.md:Run the commands the user approves.skills/memory-doctor/SKILL.md:Run `bm doctor --skip-self-test --json` again and confirm the findings are gone.skills/memory-ingest/SKILL.md:**A file instead of pasted text.** For a PDF, Word, PowerPoint, or CSV file in the project, and if the `bm` CLI is available, run `bm import document <path>`.skills/memory-literary-analysis/SKILL.md:The two rules that matter across a 100+ chapter run:skills/memory-literary-analysis/SKILL.md:Store the map in the project (a note or a small JSON file) so later batches — and a resumed run after context compaction — do not have to rediscover it.skills/memory-literary-analysis/SKILL.md:fix the spelling or add the alias, then re-run the chapter.skills/memory-literary-analysis/SKILL.md:**Validate periodically.** Run `bm_schema_validate(project="<work-name>")` after each batch, not just at the end.skills/memory-notes/SKILL.md:Day points run "from that date onward", so a due-date window also returns items that are already overdue.skills/memory-okf/SKILL.md:With the `bm` CLI and a local project, you can run the export and check it:skills/memory-okf/SKILL.md:Run `bm okf check` on a bundle, not on the project.skills/memory-onboarding/SKILL.md:**Check the live docs when unsure.** Basic Memory's documentation is agent-readable: fetch `https://docs.basicmemory.com/llms.txt` for an index, and any page as clean markdown via its `raw/....md` URL (e.g. `raw/reference/mcp-tools-reference.md`, `raw/concepts/schema-system.md`).· uses the networkskills/memory-onboarding/SKILL.md:**Migrate existing notes** *(restructure path)* → execute the approved old→new mapping from Phase 2 before seeding anything: move each existing note to its new home, set its note type, add the observations its schema requires, and update indexes as notes land.skills/memory-onboarding/SKILL.md:**Validate** → run `bm_schema_validate` on the seed notes AND any migrated notes;skills/memory-onboarding/SKILL.md:Run short exercises:skills/memory-quest/SKILL.md:When you tell the user to run Memory Quest again, use their host's form: `/memory-quest` in Claude Code, `$memory-quest` in Codex, or just asking for it in a chat app.skills/memory-quest/SKILL.md:Tell the user to connect it and run Memory Quest again.skills/memory-quest/SKILL.md:Tell the user to install the Basic Memory plugin for their assistant, or to save the memory routine from the Memory Quest panel in their assistant's instructions, then start a fresh conversation and run Memory Quest again.skills/memory-quest/SKILL.md:Ask the user to open **https://app.basicmemory.com/memory-quest** and paste the code it shows.· uses the networkskills/memory-quest/SKILL.md:Say that the mission stays incomplete and they can run Memory Quest again any time.skills/memory-quest/SKILL.md:When this machine has a local project with the same name as a cloud one, which is common because every local install creates `main`, a local Basic Memory server writes the note to the local copy however you address it, by name, workspace-qualified name, or ID.skills/memory-quest/SKILL.md:If no project is listed as `cloud`, stop and tell the user to create one in Basic Memory Cloud (or connect their cloud account), then run Memory Quest again.skills/memory-quest/SKILL.md:If Memory Quest still shows Mission 8 as current after a minute, the usual cause is an expired or replaced code: get a new code and run Memory Quest again.skills/memory-schema/SKILL.md:**Run diff** to see current state: `bm_schema_diff(note_type="Meeting", project="<project>")`skills/memory-tasks/SKILL.md:**Schema validation is your friend** — Run `bm_schema_validate(note_type="Task", project="<project>")` periodically to catch incomplete tasks
MCP servers (4)
README.md(basic-memory):uvx --prerelease=allow basic-memory mcpREADME.md(basic-memory):uvx --prerelease=allow basic-memory mcpplugins/chatgpt/.mcp.json(basic-memory):https://cloud.basicmemory.com/mcp· uses the networkplugins/codex/.mcp.json(basic-memory):uvx --prerelease=allow basic-memory mcp
Hooks (4)
plugins/claude-code/hooks/hooks.json(SessionStart):uv run --quiet --script "${CLAUDE_PLUGIN_ROOT}/hooks/session_start.py"plugins/claude-code/hooks/hooks.json(PreCompact):uv run --quiet --script "${CLAUDE_PLUGIN_ROOT}/hooks/pre_compact.py"plugins/codex/hooks/hooks.json(SessionStart):uv run --quiet --script "${PLUGIN_ROOT}/hooks/session_start.py"plugins/codex/hooks/hooks.json(PreCompact):uv run --quiet --script "${PLUGIN_ROOT}/hooks/pre_compact.py"
Install scripts (1)
src/basic_memory/cli/commands/install.py:python src/basic_memory/cli/commands/install.py
- Medium risk: runs-instruction-instruction-network (.claude/commands/release/release.md:106)
- Medium risk: runs-instruction-instruction-network (.claude/commands/release/release.md:119)
- Medium risk: runs-instruction-instruction-network (.claude/commands/release/release.md:135)
- Medium risk: runs-mcp-server-unpinned-runner (README.md:284)
- Medium risk: runs-mcp-server-unpinned-runner (README.md:340)
- Medium risk: runs-mcp-server-unpinned-runner (plugins/codex/.mcp.json)
- Medium risk: runs-instruction-instruction-network (skills/memory-onboarding/SKILL.md:66)
- Low risk: network-instructions (AGENTS.md:17)
- Low risk: network-instructions (CLAUDE.md:17)
- Low risk: scripts-present (plugins/claude-code/hooks/pre_compact.py)
- Low risk: scripts-present (plugins/claude-code/hooks/session_start.py)
- Low risk: network-instructions (plugins/claude-code/skills/bm-setup/SKILL.md:24)
- Low risk: scripts-present (plugins/codex/hooks/pre_compact.py)
- Low risk: scripts-present (plugins/codex/hooks/session_start.py)
- Low risk: scripts-present (src/basic_memory/cli/commands/install.py)
Attribution and licence
- Created by
- Basic Machines
- Declared authors
- Basic Machines (declared in pyproject.toml)
- Paul Hernandez (declared in CITATION.cff)
- Publisher
- Basic Machines (Official Basic Machines project)
- Source
- basicmachines-co/basic-memory · commit 370ae9d
- Licence
- GNU Affero General Public License v3.0 only (files served here)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Basic Machines.
Install from source
461 of its files are not served here, so there is no ZIP. basicmachines-co/basic-memory at 370ae9d