memory-notes
How to write well-structured Basic Memory notes: frontmatter, observations with semantic categories, relations with wiki-links, and best practices for building a rich knowledge graph. Use when creating or improving notes.
By basicmachines-co · 823 installs
npx skills add basicmachines-co/basic-memory --skill memory-notes
Source repository · Upstream listing
Memory Notes
Write well structured notes that Basic Memory can parse into a searchable knowledge graph. Every note is a markdown file with three key sections: frontmatter, observations, and relations.
Project scope
If the project is unknown, discover it with bm project(command="list") .
Pass a nonempty project on every note, folder, context and schema call, even
with one project or a qualified memory:// URL. Use the chosen project's name,
workspace/project , or external ID; <project below is a placeholder for it.
Recent activity also requires project . Search accepts project for one
project, projects for selected projects, or all projects=True explicitly.
Discovery and bundled manuals need no project. Keep the same scope when following
returned paths, paginating, or recovering from a refusal.
Note Anatomy
Frontmatter
Every note starts with YAML frontmatter:
The title must match the Heading in the body
Tags are searchable and help with discovery
Custom type values (Task, Meeting, Person, etc.) work with the schema system. See the memory schema skill for defining schemas, validating notes against them, and detecting drift.
The permalink is auto generated from the title and directory . For example, title "API Design Decisions" in directory "specs" produces permalink specs/api design decisions and memory URL memory://specs/api design decisions . If no directory is specified, the permalink is just the kebab cased title. By default permalinks stay stable across file moves (unless the project enables update permalinks on move ). You rarely need to set one manually.
Note: bm write accepts an exact file path as identifier , or title + directory . content may include YAML frontmatter; alternatively, supply title , tags , note type , and metadata separately and let Basic Memory generate it. For an overwrite, use the file path returned by bm read as identifier and pass its checksum as expected checksum .
Body / Context
Free form markdown between the heading and the Observations section. This is the heart of the note — write generously here:
Background, motivation, and history
Detailed explanation of what happened and why it matters
Analysis, reasoning, and trade offs considered
Context that someone (or an AI) needs to understand this note later
Write complete, substantive prose. Basic Memory's search retrieves relevant chunks from note bodies, so longer, richer context makes notes more discoverable and more useful when found. Don't reduce everything to bullet points — tell the story.
Observations
Observations are categorized facts — the atomic units of knowledge. Each one becomes a searchable entity in the knowledge graph.
Syntax
Square brackets define the semantic category
Content is the fact, decision, insight, or note
Hash tags (optional) add extra metadata for filtering
Categories Are Arbitrary
The category in brackets is free form — use whatever label makes sense for the observation. There is no fixed list. The only rule is the [category] content syntax. Consistency within a project helps searchability, but invent categories freely.
A few examples to illustrate the range:
Observation Tips
One fact per observation. Don't pack multiple ideas into one line.
Be specific. [decision] Use JWT is less useful than [decision] Use JWT with 15 minute expiry for API auth .
Use tags for cross cutting concerns. [risk] Rate limiting needed api security makes this findable under both topics.
Categories are queryable. bm search(items=["observation"], categories=["decision"], project="<project ") returns every decision observation across your knowledge base.
When a Claim Holds
An observation can say when it is true. Put a qualifier after the category:
Kinds : effective (a decision or rule takes effect), occurred (an
event happened), due (a commitment), mentioned (when it was said), and
valid , the default ( @2026 06 10 means @valid:2026 06 10 ).
Points cover the span their precision names: @2026 is that year,
@2026 06 that month, and @2026 06 10 from that date onward.
Ranges use [start,end) , and either end can be open: @effective[2026 06 10,) .
Dates are written out. An unquoted date is one token ( @occurred:2026 06 10 ).
Quote anything longer: @occurred:"June 10, 2026" . A relative date like
yesterday is never read as a qualifier; it stays in the text.
When a fact changes , close the old one's range and start the new one,
instead of deleting the old one. Both stay searchable by date.
Search by what notes say was true, rather than by when they were edited:
A valid time filter returns only dated observations; drop it to search
everything. Day points run "from that date onward", so a due date window also
returns items that are already overdue.
Relations
Relations create edges in the knowledge graph, linking notes to each other. They're how you build structure beyond individual notes.
Syntax
relation type is a descriptive verb or phrase (snake case by convention)
Double brackets [[...]] identify the target note by title or permalink
Relations are directional: this note → target note
Relation Types
Type Purpose Example
implements One thing implements another implements [[Auth Spec]]
requires Dependencies requires [[Database Setup]]
relates to General connection relates to [[Performance Notes]]
part of Hierarchy/composition part of [[Backend Architecture]]
extends Enhancement or elaboration extends [[Base Config]]
pairs with Things that work together pairs with [[Frontend Client]]
inspired by Source material inspired by [[CRDT Research Paper]]
replaces Supersedes another note replaces [[Old Auth Design]]
depends on Runtime/build dependency depends on [[MCP SDK]]
contrasts with Alternative approaches contrasts with [[GraphQL Approach]]
Inline Relations
Wiki links anywhere in the note body — not just the Relations section — also create graph edges:
These create references relations automatically. Use the Relations section for explicit, typed relationships; use inline links for natural prose references.
Relation Tips
Link liberally. Relations are what turn isolated notes into a knowledge graph. When in doubt, add the link.
Create target notes if they don't exist yet. [[Future Topic]] is valid — BM will resolve it when that note is created.
Use bm context to traverse. bm context(identifier="memory://note title", project="<project ") follows relations to gather connected knowledge.
Custom relation types are fine. taught by , blocks , tested in — use whatever is descriptive.
Memory URLs
Every note is addressable via a memory:// URL, built from its permalink. These URLs are how you navigate the knowledge graph programmatically.
URL Patterns
Project Scoped URLs
In multi project setups, prefix with the project name:
Always pass project explicitly, even with a project qualified URL or one
configured project. A recognized project prefix must agree with that parameter;
it does not replace it. Use a project external ID or workspace/project when
names collide across workspaces.
Using Memory URLs
Memory URLs work with bm context to assemble related knowledge by traversing relations:
Before Creating a Note
Always search Basic Memory before creating a new note. Duplicates fragment your knowledge graph — updating an existing note is almost always better than creating a second one.
Search with Multiple Variations
A single search often misses. Try the full name, abbreviations, acronyms, and keywords:
For people, try full name and last name. For organizations, try the full name and common abbreviations.
Decision Tree
Entity exists → Update it with bm edit (append observations, add relations, find and replace outdated info)
Entity doesn't exist → Create it with bm write
Unsure if it's the same entity → Read the existing note first, then decide
Granular Updates with bm edit
When a note already exists, make targeted edits instead of rewriting the whole file:
This preserves existing content and keeps the edit history clean.
Writing Notes with Tools
Creating a Note
Basic Memory auto generates frontmatter (including the permalink and memory URL) from the parameters. This note would get permalink architecture/api design decisions and be addressable at memory://architecture/api design decisions .
Editing an Existing Note
Use bm edit to update a note in place — seven commands: append , prepend ,
find replace , replace section , insert before section , insert after section ,
and set metadata (merge frontmatter without changing the body).
When an edit is destructive ( replace section , find replace ), read the note first
and pass its checksum, so the edit applies only to the revision you read:
A checksum conflict means someone changed the note after you read it. Read it
again and redo the edit against the new text. bm write(overwrite=True, project="<project ") takes
expected checksum the same way.
Moving a Note
Use bm move to reorganize notes into different directories:
By default the permalink stays the same after a move, so links keep resolving. Projects with update permalinks on move enabled rewrite it from the new path.
Best Practices
1. Start with context. Before listing observations, explain why this note exists. Future you (or your AI collaborator) will thank you.
2. Favor completeness. Write rich, substantive notes. Basic Memory's search pulls relevant chunks from note bodies, so longer notes with more context are more discoverable, not less. Use prose in the body to tell the full story — the background, the reasoning, the nuance. Then distill key facts into [category] content observations for structured queries. Both matter: prose gives meaning, observations give precision.
3. Build incrementally. Add to existing notes rather than creating duplicates. Use bm edit to append new observations or relations as you learn more.
4. Use consistent titles. Note titles are identifiers in the knowledge graph. API Design Decisions and Api Design decisions are different entities. Pick a convention and stick with it.
5. Link related concepts. The value of a knowledge graph compounds with connections. A note with zero relations is an island — useful, but not as powerful as a connected one.
6. Let the graph grow naturally. Don't try to design a perfect taxonomy upfront. Write notes as you work, add relations as connections emerge, and periodically use the memory reflect or memory defrag skills to consolidate.