Model or dataset
basicmachines-co/basic-memory avatar
basicmachines-co/basic-memory

Basic Memory: Markdown Notes That Your AI Client Can Read and Write

AI conversations that actually remember. Never re-explain your project to your AI again. Join our Discord:.

4,048 stars297 forksPythonAGPL-3.0

At a glance

What is it?
Basic Memory is a local-first knowledge graph that stores notes as plain Markdown on disk and exposes them to MCP clients such as Claude, Codex and Cursor. The install is one uv command, the licence is AGPL-3.0, and the trade-off is that a hosted tier exists alongside the free local engine.
Who is it for?
Adopt Basic Memory if you already keep notes as Markdown and want an MCP client to read and write the same files without a hosted database. Skip it if you need mobile access, built-in cross-device sync or snapshots, because the README assigns those to the paid cloud tier, and skip it if a Python 3.12+ toolchain is not acceptable on the machine holding your notes.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository last received commits 4 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 27, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem Basic Memory targets: an AI client that starts every session blank

A chat client keeps context for one conversation. Close the window, open a new one, and the model knows nothing about your project, your naming conventions or the decision you made last week. The usual workaround is to paste a summary at the start of every session, which does not scale past a few hundred words and drifts as the project changes.

Basic Memory takes a different position: the durable store is a directory of Markdown files on your own disk, and the AI client is a reader and writer of that directory through the Model Context Protocol. The project describes itself in pyproject.toml as "Local-first knowledge management combining Zettelkasten with knowledge graphs". The intended audience is people who already think in notes (the README's own examples point at Obsidian vaults and knowledge directories) and who use an MCP-capable client such as Claude Desktop, Claude Code, Codex, Cursor, ChatGPT custom GPTs or VS Code. If you do not keep notes and do not use an MCP client, there is no problem here for you to solve.

How the graph is built: Markdown files, observations and wikilinks in SQLite or Postgres

The repository layout tells most of the story. Notes live in a knowledge directory that you mount or point the tool at. A local database indexes them; the dependency list in pyproject.toml includes sqlalchemy, aiosqlite and alembic, so the default backend is SQLite with migrations applied by Alembic, and .env.example documents BASIC_MEMORY_DATABASE_BACKEND with the values postgres or sqlite plus a BASIC_MEMORY_DATABASE_URL. The Dockerfile sets BASIC_MEMORY_HOME to /app/data/basic-memory and BASIC_MEMORY_PROJECT_ROOT to /app/data, which is the split between the index and the notes themselves.

Two mechanisms turn a folder of files into something closer to a graph. The first is observations: structured statements inside a note that the server can index separately from prose. The second is wikilinks, which the README calls out as the way "observations and wikilinks compound into context". A wikilink is not a hyperlink for a human reader; it is an edge the index can follow, so a query can start at one note and pull in what it points to. The README also advertises semantic search with "optional cross-encoder reranking", and the dependency list carries fastembed, sqlite-vec, openai and litellm, so embeddings are computed locally by default with a path to hosted models. The milvus extra exists for Postgres deployments that keep vectors in Milvus rather than the local vector store.

File watching is the piece that makes two-way editing work. watchfiles is a dependency, and docker-compose.yml sets BASIC_MEMORY_SYNC_CHANGES=true with BASIC_MEMORY_SYNC_DELAY=1000, meaning the server polls for changes roughly a second after they land. That delay is a real design choice: edit a note in Obsidian and the index is briefly stale. The README does not document what happens if an edit and an AI write collide inside that window.

Installing Basic Memory locally and connecting a first client

The local path needs Python 3.12 or newer and uv. The README is explicit that the pre-release flag is not optional: Basic Memory 0.23 depends on a FastMCP 4 pre-release, and without the flag uv silently installs an older release of the tool.

bash
uv tool install basic-memory --prerelease=allow

The same flag is required on every uvx and uv tool upgrade command, according to the README. If you plan to run against Postgres and keep semantic vectors in Milvus, the README gives a first-party extra instead:

bash
uv tool install "basic-memory[milvus]" --prerelease=allow

For a container deployment, the compose file pulls a prebuilt image and mounts two volumes. The knowledge directory is the one you must change.

yaml
services:
  basic-memory:
    image: ghcr.io/basicmachines-co/basic-memory:latest
    container_name: basic-memory-server
    volumes:
      - basic-memory-config:/home/appuser/.basic-memory:rw
      - ./knowledge:/app/data:rw
    environment:
      - BASIC_MEMORY_DEFAULT_PROJECT=main
      - BASIC_MEMORY_SYNC_CHANGES=true
      - BASIC_MEMORY_LOG_LEVEL=INFO
      - BASIC_MEMORY_SYNC_DELAY=1000
    ports:
      - "8000:8000"

The container's default command is `basic-memory mcp --transport sse --host 0.0.0.0 --port 8000`, so port 8000 is the HTTP/SSE endpoint, and the health check runs `basic-memory --version`. Note the comment in the compose file: the container runs as appuser, so the CLI config directory is /home/appuser/.basic-memory, not /root. Mount the wrong path and your project configuration disappears on restart. The README's client table lists stdio and http transports per client; pick the row that matches your client before writing any config, because the two are not interchangeable.

Where Basic Memory is the wrong tool

The README's own comparison table is the most honest source of limitations. Mobile access is listed as "No" for local and "Yes (web + app)" for cloud. Cross-device sync is "Manual (Git, Syncthing, etc.)" locally and "Built in" in the cloud. Snapshots and backups are "Roll your own" locally and "Built in" in the cloud. If your workflow depends on any of those three, the free install does not give it to you, and the paid tier is the documented answer rather than a workaround.

The second limitation is the toolchain. Local install requires Python via uv, and the Dockerfile pins Python 3.13 inside the image while pyproject.toml declares requires-python >=3.12. There is also a pinned constraint worth reading: litellm is held below 1.92.0 because, per the comment in pyproject.toml, that release added a Rust bridge whose PyO3 version rejects Python 3.14. If you are standardising on Python 3.14, you are working against a documented ceiling.

The third is operational. The vector stack, the file watcher and the database all live on the machine holding your notes. That is the point of local-first, but it also means the index is a second copy of state that can fall out of step with the files, and the README does not document a rollback procedure for a bad migration or a corrupted index. Back up the knowledge directory, not just the database.

Basic Memory compared with Mem0 and with Obsidian alone

The comparison people search for most is against Mem0, and the difference is where the memory lives. Mem0 is a memory layer for applications: you call it, it stores extracted memories, and the store is typically a service or a database you operate. Basic Memory inverts that. The primary artefact is a Markdown file in a directory you control, and the database is an index built from those files. You can open the notes in any editor, diff them in Git, and delete the index without losing content. The cost of that inversion is that the AI sees what the files contain, not a distilled memory object, so retrieval quality depends on how you write and link notes.

The comparison against Obsidian alone is a question of who does the reading. Obsidian is an editor and a link graph for a human. Basic Memory does not replace it; the README's own examples point at mounting an Obsidian vault as the knowledge directory. What Basic Memory adds is an MCP surface so an agent can search, read and write the same vault. If you never connect an MCP client, the extra layer buys you an index you are not querying.

Maintenance, licence and upgrade cost

The last push to main was on 2026-08-25, the same day as the v0.23.2 release, and v0.23.0 and v0.23.1 landed within the two days before that. The repository is not archived. Three releases in three days is a burst, not a cadence, and the README does not publish a support policy or a deprecation window, so you should read CHANGELOG.md before upgrading rather than assuming compatibility.

The upgrade path carries a specific tax. Every uvx and uv tool upgrade command needs --prerelease=allow, because the FastMCP 4 pre-release sits in the dependency chain. That flag also lets uv pull pre-releases of other transitive dependencies, which is a wider aperture than most teams run in production. The litellm ceiling below 1.92.0 is a second constraint that will need revisiting when Python 3.14 support becomes a requirement.

On licensing: pyproject.toml declares AGPL-3.0-or-later and the README badge points at AGPL-3.0. The repository also contains a CLA.md and a CLAUDE.md, which is common for projects that offer a hosted tier alongside the open source engine. If you intend to embed the server in a product you distribute, read the licence text itself rather than this summary; nothing here is legal advice, and the network-copyleft terms of the AGPL are the part that matters for a server product.

Editorial conclusion

Adopt Basic Memory if you already keep notes as Markdown and want an MCP client to read and write the same files without a hosted database. Skip it if you need mobile access, built-in cross-device sync or snapshots, because the README assigns those to the paid cloud tier, and skip it if a Python 3.12+ toolchain is not acceptable on the machine holding your notes. Before committing, verify three things yourself: that `uv tool install basic-memory --prerelease=allow` actually resolves the FastMCP 4 pre-release on your platform, that your chosen client transport (stdio or http) is in the support table, and that the AGPL-3.0-or-later terms in pyproject.toml are compatible with how you intend to distribute anything built on top of the server.

Frequently asked questions

Is Basic Memory free to use?

The local install is free forever under AGPL-3.0, as the README's comparison table states. The hosted cloud tier is $15.00/mo with a 7-day free trial, and the README lists a code, BMFOSS, giving OSS users another 20% off for three months.

What is Basic Memory in simple terms?

It is a local-first knowledge base that keeps your notes as Markdown files on disk and serves them to AI clients over MCP, so the client can read, write and search the same files you edit. pyproject.toml describes it as local-first knowledge management combining Zettelkasten with knowledge graphs.

How does Basic Memory compare with Mem0?

The README does not mention Mem0, so no direct comparison is documented. The structural difference is that Basic Memory's primary store is Markdown on your disk with a database as an index, whereas a memory layer for applications typically stores extracted memories in a service you operate.

How does Basic Memory compare with Obsidian?

The README does not present them as alternatives; its examples mount an Obsidian vault or knowledge directory as the Basic Memory data directory. Obsidian remains the editor, and Basic Memory adds an MCP surface so an agent can search and write the same vault.

What are the alternatives to basic-memory?

The README does not name a direct alternative. The nearest structural comparison it supports is Mem0, which stores memories in an application-facing service rather than as Markdown files with a local index, and running Obsidian alone, which gives you the same files without an MCP interface.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
For maintainers

Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/basicmachines-co-basic-memory.svg)](https://hysenlabs.com/projects/basicmachines-co-basic-memory)
Community notes

Community notes