AI Assistant Guide
Guide for AI assistants using Basic Memory through the Model Context Protocol (MCP)
This guide is for AI assistants using Basic Memory tools through MCP. For setup instructions, see Getting Started. Download this AI Assistant Guide and customize it to your own workflow. A condensed version of this guide is available as an MCP Resource in Basic Memory.
This guide explains how to use Basic Memory tools effectively when working with users through the Model Context Protocol.
Overview
Basic Memory creates a semantic knowledge graph from markdown files stored locally on the user’s computer. Knowledge persists across sessions, enabling continuity in conversations and collaborative development.
Architecture:
- Local-First: Plain text markdown files as source of truth
- SQLite Index: Fast search and navigation
- MCP Integration: 17 tools for AI interaction
- Semantic Graph: Observations and relations create connections
Your role: Help users build structured knowledge that outlasts any particular AI model or session. Focus on creating observations and relations that provide lasting value. These markdown files are artifacts worth keeping.
Project Management
All tools require explicit project specification. No implicit project context is maintained between calls.
Discovery and Selection
Start conversations by discovering available projects:
# List all projects
projects = await list_memory_projects()
# Response includes:
# - name
# - path
# - is_default
# - note_count
# - last_synced
Recommended workflow:
- Call
list_memory_projects()
at conversation start - Identify active project from metadata
- Ask user which project to use
- Store choice for the session
- Pass project parameter to all tool calls
Cross-Project Operations
Some tools work across all projects when project parameter is omitted:
# Recent activity across all projects
activity = await recent_activity(timeframe="7d")
# Recent activity for specific project
activity = await recent_activity(timeframe="7d", project="main")
Tools supporting cross-project mode:
recent_activity()
list_memory_projects()
sync_status()
Knowledge Graph Structure
The knowledge graph consists of three core elements: entities, observations, and relations.
Entities
Each markdown file represents an entity with:
- Title: Unique identifier
- Permalink: Auto-generated from title
- Frontmatter: YAML metadata (tags, type, dates)
- Observations: Categorized facts
- Relations: Links to other entities
Entity types:
note
- General knowledge (default)person
- People and contactsproject
- Projects and initiativesmeeting
- Meeting notesdecision
- Documented decisionsspec
- Technical specifications
Observations
Observations are categorized facts with optional tags.
Syntax: - [category] content #tag1 #tag2
Common categories:
[fact]
- Objective information[idea]
- Thoughts and concepts[decision]
- Choices made[technique]
- Methods and approaches[requirement]
- Needs and constraints[problem]
- Issues identified[solution]
- Resolutions[insight]
- Key realizations
Examples:
## Observations
- [decision] Use JWT tokens for authentication #security
- [technique] Hash passwords with bcrypt before storage #best-practice
- [requirement] Support OAuth 2.0 providers #auth
- [fact] Session timeout set to 24 hours #configuration
Relations
Relations are directional links between entities.
Syntax: - relation_type [[Target Entity]]
Common relation types:
relates_to
- General connectionimplements
- Implementation relationshiprequires
- Dependencyextends
- Enhancementpart_of
- Hierarchical membershipcontrasts_with
- Alternative approachleads_to
- Sequential relationshipcaused_by
- Causal relationship
Examples:
## Relations
- implements [[Authentication Spec v2]]
- requires [[User Database Schema]]
- extends [[Base Security Model]]
- part_of [[API Backend Services]]
- contrasts_with [[API Key Authentication]]
Forward References
Reference entities that don’t exist yet - relations resolve automatically when targets are created:
# Create note with forward reference
await write_note(
title="API Implementation",
content="## Relations\n- implements [[API Specification]]",
folder="api",
project="main"
)
# Forward reference created
# Later, create referenced entity
await write_note(
title="API Specification",
content="# API Specification\n...",
folder="specs",
project="main"
)
# Forward reference automatically resolved
Core Tools
Writing Knowledge
Create or update notes:
await write_note(
title="Topic",
content="# Topic\n## Observations\n- [category] fact\n## Relations\n- relates_to [[Other]]",
folder="notes",
project="main"
)
Parameters:
title
(required) - Note titlecontent
(required) - Markdown contentfolder
(required) - Destination foldertags
(optional) - List of tagsentity_type
(optional) - Entity typeproject
(required unless default_project_mode) - Target project
Reading Knowledge
Read notes with knowledge graph context:
# By title
note = await read_note("Topic", project="main")
# By folder and title
note = await read_note("specs/Authentication System", project="main")
# By memory:// URL
note = await read_note("memory://specs/auth", project="main")
Response includes:
- Content
- Observations (categorized)
- Relations (typed, with targets)
- Metadata (dates, tags, type)
Searching
Find notes across the knowledge base:
results = await search_notes(
query="authentication",
project="main",
page_size=10
)
Advanced filtering:
# Filter by entity type
specs = await search_notes(
query="authentication",
types=["spec"],
project="main"
)
# Filter by date
recent = await search_notes(
query="api",
after_date="2025-01-01",
project="main"
)
Building Context
Navigate the knowledge graph:
context = await build_context(
url="memory://specs/auth",
project="main",
depth=2,
timeframe="1 week"
)
Parameters:
url
(required) - memory:// URLdepth
(optional) - Traversal depth (default: 1)timeframe
(optional) - Time window (e.g., “7d”, “1 week”)project
(required unless default_project_mode) - Target project
Response includes:
- Root entity
- Related entities (with distance and relation types)
- Connection paths
- Summary statistics
Depth control:
depth=1
- Immediate connections onlydepth=2
- Two levels of relationsdepth=3+
- Comprehensive (may be slow)
Editing Notes
Edit existing notes incrementally:
# Append content
await edit_note(
identifier="Topic",
operation="append",
content="\n## New Section\nContent here",
project="main"
)
# Prepend content
await edit_note(
identifier="Topic",
operation="prepend",
content="## Update\nImportant note\n\n",
project="main"
)
# Find and replace
await edit_note(
identifier="Topic",
operation="find_replace",
find_text="old text",
content="new text",
expected_replacements=1,
project="main"
)
# Replace section
await edit_note(
identifier="Topic",
operation="replace_section",
section="## Status",
content="## Status\nUpdated status here",
project="main"
)
Operations:
append
- Add to endprepend
- Add to beginningfind_replace
- Replace specific textreplace_section
- Replace markdown section
Moving Notes
Organize notes by moving them between folders:
await move_note(
identifier="Note Title",
destination_path="archive/note-title.md",
project="main"
)
Behavior:
- Folders created automatically
- Database updated automatically
- Relations preserved
- Both
.md
extension and without work
memory:// URL Format
Basic Memory uses special URLs to reference entities:
By title:
memory://title
By folder and title:
memory://folder/title
By permalink:
memory://permalink
All in folder:
memory://folder/*
- Underscores converted to hyphens automatically
memory://my_note
finds entity with permalinkmy-note
Recording Conversations
Capture conversations to enable long-term context and knowledge accumulation.
Permission and Transparency
Always ask before recording:
AI: "Would you like me to save our discussion about API authentication
to Basic Memory? This helps us continue this conversation later."
User: "Yes, please"
AI: [Saves to Basic Memory]
"I've saved our discussion as 'API Authentication Discussion'."
Principles:
- Ask permission before saving
- Confirm after saving
- Explain what was saved
- Describe how it helps future conversations
What to Record
Good candidates:
- Decisions and Rationales
await write_note(
title="Decision: GraphQL vs REST",
content="""# Decision: GraphQL vs REST
## Context
User asked about API architecture choice.
## Decision
Chose GraphQL for new features, maintain REST for legacy.
## Observations
- [decision] GraphQL for flexibility and performance #api
- [requirement] Mobile app needs efficient data loading #mobile
- [fact] REST API has 50K existing clients #legacy
## Relations
- implements [[API Modernization Plan]]
- affects [[Mobile Development]]
""",
folder="decisions",
project="main"
)
- Important Discoveries
- Action Items and Plans
- Connected Topics
Recording Patterns
Conversation summary:
await write_note(
title=f"Conversation: {topic} - {date}",
content=f"""# Conversation: {topic}
## Summary
{brief_summary}
## Key Points
{key_points}
## Observations
{categorized_observations}
## Relations
{relevant_relations}
""",
folder="conversations",
tags=["conversation", topic_tags],
project="main"
)
Decision record:
await write_note(
title=f"Decision: {decision_title}",
content=f"""# Decision: {decision_title}
## Context
{why_decision_needed}
## Decision
{what_was_decided}
## Observations
{categorized_observations}
## Rationale
{reasoning}
## Relations
{related_entities}
""",
folder="decisions",
entity_type="decision",
project="main"
)
Building on Past Conversations
Reference previous discussions:
# Search for related past conversations
past = await search_notes(
query="API authentication",
types=["conversation", "decision"],
project="main"
)
# Build context
context = await build_context(
url=f"memory://{past['results'][0]['permalink']}",
depth=2,
timeframe="30d",
project="main"
)
# Reference in new conversation
# "Building on our previous discussion about JWT authentication..."
# Link new note to previous
await write_note(
title="Refresh Token Implementation",
content="""# Refresh Token Implementation
## Relations
- builds_on [[Conversation: API Authentication]]
- implements [[JWT Authentication Decision]]
""",
folder="implementation",
project="main"
)
Best Practices
1. Project Discovery
Always start with discovery:
# First action in conversation
projects = await list_memory_projects()
# Ask user which to use
# Store for session
# Use consistently
2. Rich Knowledge Graphs
Every note should have:
- Clear, descriptive title
- 3-5 observations minimum
- 2-3 relations minimum
- Appropriate categories and tags
Good structure:
---
title: Clear Descriptive Title
tags: [relevant, tags]
type: note
---
# Title
## Context
Brief background
## Observations
- [category] Specific fact #tag1 #tag2
- [category] Another fact #tag3
- [category] Third fact #tag4
## Relations
- relation_type [[Related Entity 1]]
- relation_type [[Related Entity 2]]
3. Search Before Creating
Always search first to avoid duplicates:
# Before writing new note
existing = await search_notes(
query="topic name",
project="main"
)
if existing["total"] > 0:
# Update existing
await edit_note(
identifier=existing["results"][0]["permalink"],
operation="append",
content=new_information,
project="main"
)
else:
# Create new
await write_note(...)
4. Exact Entity Titles in Relations
Use exact titles when creating relations:
# Search for exact title
results = await search_notes(query="Authentication System", project="main")
exact_title = results["results"][0]["title"]
# Use in relation
content = f"## Relations\n- relates_to [[{exact_title}]]"
5. Meaningful Categories and Relations
Use semantic categories:
[decision]
for choices made[fact]
for objective information[technique]
for methods[requirement]
for needs[insight]
for realizations
Use specific relation types:
implements
for implementationrequires
for dependenciespart_of
for hierarchyextends
for enhancementcontrasts_with
for alternatives
Not generic:
- Avoid overusing
relates_to
- Be specific about relationships
6. Progressive Elaboration
Build knowledge over time:
# Session 1: Create foundation
await write_note(
title="Topic",
content="Basic structure with initial observations",
folder="notes",
project="main"
)
# Session 2: Add details
await edit_note(
identifier="Topic",
operation="append",
content="Additional observations",
project="main"
)
# Session 3: Add relations
await edit_note(
identifier="Topic",
operation="append",
content="Relations to related topics",
project="main"
)
7. Consistent Organization
Folder structure:
specs/
- Specificationsdecisions/
- Decision recordsmeetings/
- Meeting notesconversations/
- AI conversationsimplementations/
- Code/implementationsdocs/
- Documentation
File naming:
- Use descriptive titles
- Consistent format
- Avoid special characters
Error Handling
Missing Project Parameter
Error: Tool called without project parameter
Solution:
try:
results = await search_notes(query="test")
except:
# Show available projects
projects = await list_memory_projects()
# Ask user which to use
# Retry with project
results = await search_notes(query="test", project="main")
Entity Not Found
Error: Note doesn’t exist
Solution:
try:
note = await read_note("Nonexistent Note", project="main")
except:
# Search for similar
results = await search_notes(query="Note", project="main")
# Suggest alternatives
# Show similar results to user
Forward References
Not an error: Forward references resolve automatically when targets are created. No action needed.
Sync Status Issues
Error: Data not found, sync in progress
Solution:
# Check sync status
status = await sync_status(project="main")
if status["sync_in_progress"]:
# Inform user: "Knowledge base is syncing, please wait..."
# Or proceed with available data
else:
# Sync complete, proceed normally
results = await search_notes(query="topic", project="main")
Tool Reference
Content Management
write_note(title, content, folder, tags, entity_type, project)
- Create or update markdown notes
- Returns: Entity with permalink
read_note(identifier, page, page_size, project)
- Read notes with knowledge graph context
- Returns: Entity with content, observations, relations
edit_note(identifier, operation, content, find_text, section, expected_replacements, project)
- Edit notes incrementally
- Operations: append, prepend, find_replace, replace_section
- Returns: Updated entity
move_note(identifier, destination_path, project)
- Move notes to new locations
- Returns: Updated entity with new path
delete_note(identifier, project)
- Delete notes from knowledge base
- Returns: Deletion confirmation
read_content(path, project)
- Read raw file content
- Returns: Raw file content (text or base64)
view_note(identifier, page, page_size, project)
- View notes as formatted artifacts
- Returns: Formatted markdown for display
Knowledge Graph Navigation
build_context(url, depth, timeframe, max_related, page, page_size, project)
- Navigate knowledge graph
- Returns: Root entity, related entities, paths
recent_activity(type, depth, timeframe, project)
- Get recent changes
- Returns: Recently updated entities
list_directory(dir_name, depth, file_name_glob, project)
- Browse directory contents
- Returns: Files and subdirectories
Search & Discovery
search_notes(query, page, page_size, search_type, types, entity_types, after_date, project)
- Search across knowledge base
- Returns: Matching entities with scores
Project Management
list_memory_projects()
- List all available projects
- Returns: Projects with metadata
create_memory_project(project_name, project_path, set_default)
- Create new project
- Returns: Created project details
delete_project(project_name)
- Delete project from configuration
- Returns: Deletion confirmation
sync_status(project)
- Check synchronization status
- Returns: Sync progress and status
Visualization
canvas(nodes, edges, title, folder, project)
- Create Obsidian canvas
- Returns: Created canvas file