basic-memory 0.17.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. basic_memory/__init__.py +7 -0
  2. basic_memory/alembic/alembic.ini +119 -0
  3. basic_memory/alembic/env.py +185 -0
  4. basic_memory/alembic/migrations.py +24 -0
  5. basic_memory/alembic/script.py.mako +26 -0
  6. basic_memory/alembic/versions/314f1ea54dc4_add_postgres_full_text_search_support_.py +131 -0
  7. basic_memory/alembic/versions/3dae7c7b1564_initial_schema.py +93 -0
  8. basic_memory/alembic/versions/502b60eaa905_remove_required_from_entity_permalink.py +51 -0
  9. basic_memory/alembic/versions/5fe1ab1ccebe_add_projects_table.py +120 -0
  10. basic_memory/alembic/versions/647e7a75e2cd_project_constraint_fix.py +112 -0
  11. basic_memory/alembic/versions/9d9c1cb7d8f5_add_mtime_and_size_columns_to_entity_.py +49 -0
  12. basic_memory/alembic/versions/a1b2c3d4e5f6_fix_project_foreign_keys.py +49 -0
  13. basic_memory/alembic/versions/a2b3c4d5e6f7_add_search_index_entity_cascade.py +56 -0
  14. basic_memory/alembic/versions/b3c3938bacdb_relation_to_name_unique_index.py +44 -0
  15. basic_memory/alembic/versions/cc7172b46608_update_search_index_schema.py +113 -0
  16. basic_memory/alembic/versions/e7e1f4367280_add_scan_watermark_tracking_to_project.py +37 -0
  17. basic_memory/alembic/versions/f8a9b2c3d4e5_add_pg_trgm_for_fuzzy_link_resolution.py +239 -0
  18. basic_memory/api/__init__.py +5 -0
  19. basic_memory/api/app.py +131 -0
  20. basic_memory/api/routers/__init__.py +11 -0
  21. basic_memory/api/routers/directory_router.py +84 -0
  22. basic_memory/api/routers/importer_router.py +152 -0
  23. basic_memory/api/routers/knowledge_router.py +318 -0
  24. basic_memory/api/routers/management_router.py +80 -0
  25. basic_memory/api/routers/memory_router.py +90 -0
  26. basic_memory/api/routers/project_router.py +448 -0
  27. basic_memory/api/routers/prompt_router.py +260 -0
  28. basic_memory/api/routers/resource_router.py +249 -0
  29. basic_memory/api/routers/search_router.py +36 -0
  30. basic_memory/api/routers/utils.py +169 -0
  31. basic_memory/api/template_loader.py +292 -0
  32. basic_memory/api/v2/__init__.py +35 -0
  33. basic_memory/api/v2/routers/__init__.py +21 -0
  34. basic_memory/api/v2/routers/directory_router.py +93 -0
  35. basic_memory/api/v2/routers/importer_router.py +182 -0
  36. basic_memory/api/v2/routers/knowledge_router.py +413 -0
  37. basic_memory/api/v2/routers/memory_router.py +130 -0
  38. basic_memory/api/v2/routers/project_router.py +342 -0
  39. basic_memory/api/v2/routers/prompt_router.py +270 -0
  40. basic_memory/api/v2/routers/resource_router.py +286 -0
  41. basic_memory/api/v2/routers/search_router.py +73 -0
  42. basic_memory/cli/__init__.py +1 -0
  43. basic_memory/cli/app.py +84 -0
  44. basic_memory/cli/auth.py +277 -0
  45. basic_memory/cli/commands/__init__.py +18 -0
  46. basic_memory/cli/commands/cloud/__init__.py +6 -0
  47. basic_memory/cli/commands/cloud/api_client.py +112 -0
  48. basic_memory/cli/commands/cloud/bisync_commands.py +110 -0
  49. basic_memory/cli/commands/cloud/cloud_utils.py +101 -0
  50. basic_memory/cli/commands/cloud/core_commands.py +195 -0
  51. basic_memory/cli/commands/cloud/rclone_commands.py +371 -0
  52. basic_memory/cli/commands/cloud/rclone_config.py +110 -0
  53. basic_memory/cli/commands/cloud/rclone_installer.py +263 -0
  54. basic_memory/cli/commands/cloud/upload.py +233 -0
  55. basic_memory/cli/commands/cloud/upload_command.py +124 -0
  56. basic_memory/cli/commands/command_utils.py +77 -0
  57. basic_memory/cli/commands/db.py +44 -0
  58. basic_memory/cli/commands/format.py +198 -0
  59. basic_memory/cli/commands/import_chatgpt.py +84 -0
  60. basic_memory/cli/commands/import_claude_conversations.py +87 -0
  61. basic_memory/cli/commands/import_claude_projects.py +86 -0
  62. basic_memory/cli/commands/import_memory_json.py +87 -0
  63. basic_memory/cli/commands/mcp.py +76 -0
  64. basic_memory/cli/commands/project.py +889 -0
  65. basic_memory/cli/commands/status.py +174 -0
  66. basic_memory/cli/commands/telemetry.py +81 -0
  67. basic_memory/cli/commands/tool.py +341 -0
  68. basic_memory/cli/main.py +28 -0
  69. basic_memory/config.py +616 -0
  70. basic_memory/db.py +394 -0
  71. basic_memory/deps.py +705 -0
  72. basic_memory/file_utils.py +478 -0
  73. basic_memory/ignore_utils.py +297 -0
  74. basic_memory/importers/__init__.py +27 -0
  75. basic_memory/importers/base.py +79 -0
  76. basic_memory/importers/chatgpt_importer.py +232 -0
  77. basic_memory/importers/claude_conversations_importer.py +180 -0
  78. basic_memory/importers/claude_projects_importer.py +148 -0
  79. basic_memory/importers/memory_json_importer.py +108 -0
  80. basic_memory/importers/utils.py +61 -0
  81. basic_memory/markdown/__init__.py +21 -0
  82. basic_memory/markdown/entity_parser.py +279 -0
  83. basic_memory/markdown/markdown_processor.py +160 -0
  84. basic_memory/markdown/plugins.py +242 -0
  85. basic_memory/markdown/schemas.py +70 -0
  86. basic_memory/markdown/utils.py +117 -0
  87. basic_memory/mcp/__init__.py +1 -0
  88. basic_memory/mcp/async_client.py +139 -0
  89. basic_memory/mcp/project_context.py +141 -0
  90. basic_memory/mcp/prompts/__init__.py +19 -0
  91. basic_memory/mcp/prompts/ai_assistant_guide.py +70 -0
  92. basic_memory/mcp/prompts/continue_conversation.py +62 -0
  93. basic_memory/mcp/prompts/recent_activity.py +188 -0
  94. basic_memory/mcp/prompts/search.py +57 -0
  95. basic_memory/mcp/prompts/utils.py +162 -0
  96. basic_memory/mcp/resources/ai_assistant_guide.md +283 -0
  97. basic_memory/mcp/resources/project_info.py +71 -0
  98. basic_memory/mcp/server.py +81 -0
  99. basic_memory/mcp/tools/__init__.py +48 -0
  100. basic_memory/mcp/tools/build_context.py +120 -0
  101. basic_memory/mcp/tools/canvas.py +152 -0
  102. basic_memory/mcp/tools/chatgpt_tools.py +190 -0
  103. basic_memory/mcp/tools/delete_note.py +242 -0
  104. basic_memory/mcp/tools/edit_note.py +324 -0
  105. basic_memory/mcp/tools/list_directory.py +168 -0
  106. basic_memory/mcp/tools/move_note.py +551 -0
  107. basic_memory/mcp/tools/project_management.py +201 -0
  108. basic_memory/mcp/tools/read_content.py +281 -0
  109. basic_memory/mcp/tools/read_note.py +267 -0
  110. basic_memory/mcp/tools/recent_activity.py +534 -0
  111. basic_memory/mcp/tools/search.py +385 -0
  112. basic_memory/mcp/tools/utils.py +540 -0
  113. basic_memory/mcp/tools/view_note.py +78 -0
  114. basic_memory/mcp/tools/write_note.py +230 -0
  115. basic_memory/models/__init__.py +15 -0
  116. basic_memory/models/base.py +10 -0
  117. basic_memory/models/knowledge.py +226 -0
  118. basic_memory/models/project.py +87 -0
  119. basic_memory/models/search.py +85 -0
  120. basic_memory/repository/__init__.py +11 -0
  121. basic_memory/repository/entity_repository.py +503 -0
  122. basic_memory/repository/observation_repository.py +73 -0
  123. basic_memory/repository/postgres_search_repository.py +379 -0
  124. basic_memory/repository/project_info_repository.py +10 -0
  125. basic_memory/repository/project_repository.py +128 -0
  126. basic_memory/repository/relation_repository.py +146 -0
  127. basic_memory/repository/repository.py +385 -0
  128. basic_memory/repository/search_index_row.py +95 -0
  129. basic_memory/repository/search_repository.py +94 -0
  130. basic_memory/repository/search_repository_base.py +241 -0
  131. basic_memory/repository/sqlite_search_repository.py +439 -0
  132. basic_memory/schemas/__init__.py +86 -0
  133. basic_memory/schemas/base.py +297 -0
  134. basic_memory/schemas/cloud.py +50 -0
  135. basic_memory/schemas/delete.py +37 -0
  136. basic_memory/schemas/directory.py +30 -0
  137. basic_memory/schemas/importer.py +35 -0
  138. basic_memory/schemas/memory.py +285 -0
  139. basic_memory/schemas/project_info.py +212 -0
  140. basic_memory/schemas/prompt.py +90 -0
  141. basic_memory/schemas/request.py +112 -0
  142. basic_memory/schemas/response.py +229 -0
  143. basic_memory/schemas/search.py +117 -0
  144. basic_memory/schemas/sync_report.py +72 -0
  145. basic_memory/schemas/v2/__init__.py +27 -0
  146. basic_memory/schemas/v2/entity.py +129 -0
  147. basic_memory/schemas/v2/resource.py +46 -0
  148. basic_memory/services/__init__.py +8 -0
  149. basic_memory/services/context_service.py +601 -0
  150. basic_memory/services/directory_service.py +308 -0
  151. basic_memory/services/entity_service.py +864 -0
  152. basic_memory/services/exceptions.py +37 -0
  153. basic_memory/services/file_service.py +541 -0
  154. basic_memory/services/initialization.py +216 -0
  155. basic_memory/services/link_resolver.py +121 -0
  156. basic_memory/services/project_service.py +880 -0
  157. basic_memory/services/search_service.py +404 -0
  158. basic_memory/services/service.py +15 -0
  159. basic_memory/sync/__init__.py +6 -0
  160. basic_memory/sync/background_sync.py +26 -0
  161. basic_memory/sync/sync_service.py +1259 -0
  162. basic_memory/sync/watch_service.py +510 -0
  163. basic_memory/telemetry.py +249 -0
  164. basic_memory/templates/prompts/continue_conversation.hbs +110 -0
  165. basic_memory/templates/prompts/search.hbs +101 -0
  166. basic_memory/utils.py +468 -0
  167. basic_memory-0.17.1.dist-info/METADATA +617 -0
  168. basic_memory-0.17.1.dist-info/RECORD +171 -0
  169. basic_memory-0.17.1.dist-info/WHEEL +4 -0
  170. basic_memory-0.17.1.dist-info/entry_points.txt +3 -0
  171. basic_memory-0.17.1.dist-info/licenses/LICENSE +661 -0
@@ -0,0 +1,188 @@
1
+ """Recent activity prompts for Basic Memory MCP server.
2
+
3
+ These prompts help users see what has changed in their knowledge base recently.
4
+ """
5
+
6
+ from typing import Annotated, Optional
7
+
8
+ from loguru import logger
9
+ from pydantic import Field
10
+
11
+ from basic_memory.mcp.prompts.utils import format_prompt_context, PromptContext, PromptContextItem
12
+ from basic_memory.mcp.server import mcp
13
+ from basic_memory.mcp.tools.recent_activity import recent_activity
14
+ from basic_memory.schemas.base import TimeFrame
15
+ from basic_memory.schemas.memory import GraphContext, ProjectActivitySummary
16
+ from basic_memory.schemas.search import SearchItemType
17
+
18
+
19
+ @mcp.prompt(
20
+ name="recent_activity",
21
+ description="Get recent activity from a specific project or across all projects",
22
+ )
23
+ async def recent_activity_prompt(
24
+ timeframe: Annotated[
25
+ TimeFrame,
26
+ Field(description="How far back to look for activity (e.g. '1d', '1 week')"),
27
+ ] = "7d",
28
+ project: Annotated[
29
+ Optional[str],
30
+ Field(
31
+ description="Specific project to get activity from (None for discovery across all projects)"
32
+ ),
33
+ ] = None,
34
+ ) -> str:
35
+ """Get recent activity from a specific project or across all projects.
36
+
37
+ This prompt helps you see what's changed recently in the knowledge base.
38
+ In discovery mode (project=None), it shows activity across all projects.
39
+ In project-specific mode, it shows detailed activity for one project.
40
+
41
+ Args:
42
+ timeframe: How far back to look for activity (e.g. '1d', '1 week')
43
+ project: Specific project to get activity from (None for discovery across all projects)
44
+
45
+ Returns:
46
+ Formatted summary of recent activity
47
+ """
48
+ logger.info(f"Getting recent activity, timeframe: {timeframe}, project: {project}")
49
+
50
+ recent = await recent_activity.fn(
51
+ project=project, timeframe=timeframe, type=[SearchItemType.ENTITY]
52
+ )
53
+
54
+ # Extract primary results from the hierarchical structure
55
+ primary_results = []
56
+ related_results = []
57
+
58
+ if isinstance(recent, ProjectActivitySummary):
59
+ # Discovery mode - extract results from all projects
60
+ for _, project_activity in recent.projects.items():
61
+ if project_activity.activity.results:
62
+ # Take up to 2 primary results per project
63
+ for item in project_activity.activity.results[:2]:
64
+ primary_results.append(item.primary_result)
65
+ # Add up to 1 related result per primary item
66
+ if item.related_results:
67
+ related_results.extend(item.related_results[:1])
68
+
69
+ # Limit total results for readability
70
+ primary_results = primary_results[:8]
71
+ related_results = related_results[:6]
72
+
73
+ elif isinstance(recent, GraphContext):
74
+ # Project-specific mode - use existing logic
75
+ if recent.results:
76
+ # Take up to 5 primary results
77
+ for item in recent.results[:5]:
78
+ primary_results.append(item.primary_result)
79
+ # Add up to 2 related results per primary item
80
+ if item.related_results:
81
+ related_results.extend(item.related_results[:2])
82
+
83
+ # Set topic based on mode
84
+ if project:
85
+ topic = f"Recent Activity in {project} ({timeframe})"
86
+ else:
87
+ topic = f"Recent Activity Across All Projects ({timeframe})"
88
+
89
+ prompt_context = format_prompt_context(
90
+ PromptContext(
91
+ topic=topic,
92
+ timeframe=timeframe,
93
+ results=[
94
+ PromptContextItem(
95
+ primary_results=primary_results,
96
+ related_results=related_results[:10], # Limit total related results
97
+ )
98
+ ],
99
+ )
100
+ )
101
+
102
+ # Add mode-specific suggestions
103
+ first_title = "Recent Topic"
104
+ if primary_results and len(primary_results) > 0:
105
+ first_title = primary_results[0].title
106
+
107
+ if project:
108
+ # Project-specific suggestions
109
+ capture_suggestions = f"""
110
+ ## Opportunity to Capture Activity Summary
111
+
112
+ Consider creating a summary note of recent activity in {project}:
113
+
114
+ ```python
115
+ await write_note(
116
+ "{project}",
117
+ title="Activity Summary {timeframe}",
118
+ content='''
119
+ # Activity Summary for {project} ({timeframe})
120
+
121
+ ## Overview
122
+ [Summary of key changes and developments in this project over this period]
123
+
124
+ ## Key Updates
125
+ [List main updates and their significance within this project]
126
+
127
+ ## Observations
128
+ - [trend] [Observation about patterns in recent activity]
129
+ - [insight] [Connection between different activities]
130
+
131
+ ## Relations
132
+ - summarizes [[{first_title}]]
133
+ - relates_to [[{project} Overview]]
134
+ ''',
135
+ folder="summaries"
136
+ )
137
+ ```
138
+
139
+ Summarizing periodic activity helps create high-level insights and connections within the project.
140
+ """
141
+ else:
142
+ # Discovery mode suggestions
143
+ project_count = len(recent.projects) if isinstance(recent, ProjectActivitySummary) else 0
144
+ most_active = (
145
+ getattr(recent.summary, "most_active_project", "Unknown")
146
+ if isinstance(recent, ProjectActivitySummary)
147
+ else "Unknown"
148
+ )
149
+
150
+ capture_suggestions = f"""
151
+ ## Cross-Project Activity Discovery
152
+
153
+ Found activity across {project_count} projects. Most active: **{most_active}**
154
+
155
+ Consider creating a cross-project summary:
156
+
157
+ ```python
158
+ await write_note(
159
+ "{most_active if most_active != "Unknown" else "main"}",
160
+ title="Cross-Project Activity Summary {timeframe}",
161
+ content='''
162
+ # Cross-Project Activity Summary ({timeframe})
163
+
164
+ ## Overview
165
+ Activity found across {project_count} projects, with {most_active} showing the most activity.
166
+
167
+ ## Key Developments
168
+ [Summarize important changes across all projects]
169
+
170
+ ## Project Insights
171
+ [Note patterns or connections between projects]
172
+
173
+ ## Observations
174
+ - [trend] [Cross-project patterns observed]
175
+ - [insight] [Connections between different project activities]
176
+
177
+ ## Relations
178
+ - summarizes [[{first_title}]]
179
+ - relates_to [[Project Portfolio Overview]]
180
+ ''',
181
+ folder="summaries"
182
+ )
183
+ ```
184
+
185
+ Cross-project summaries help identify broader trends and project interconnections.
186
+ """
187
+
188
+ return prompt_context + capture_suggestions
@@ -0,0 +1,57 @@
1
+ """Search prompts for Basic Memory MCP server.
2
+
3
+ These prompts help users search and explore their knowledge base.
4
+ """
5
+
6
+ from typing import Annotated, Optional
7
+
8
+ from loguru import logger
9
+ from pydantic import Field
10
+
11
+ from basic_memory.config import get_project_config
12
+ from basic_memory.mcp.async_client import get_client
13
+ from basic_memory.mcp.server import mcp
14
+ from basic_memory.mcp.tools.utils import call_post
15
+ from basic_memory.schemas.base import TimeFrame
16
+ from basic_memory.schemas.prompt import SearchPromptRequest
17
+
18
+
19
+ @mcp.prompt(
20
+ name="search_knowledge_base",
21
+ description="Search across all content in basic-memory",
22
+ )
23
+ async def search_prompt(
24
+ query: str,
25
+ timeframe: Annotated[
26
+ Optional[TimeFrame],
27
+ Field(description="How far back to search (e.g. '1d', '1 week')"),
28
+ ] = None,
29
+ ) -> str:
30
+ """Search across all content in basic-memory.
31
+
32
+ This prompt helps search for content in the knowledge base and
33
+ provides helpful context about the results.
34
+
35
+ Args:
36
+ query: The search text to look for
37
+ timeframe: Optional timeframe to limit results (e.g. '1d', '1 week')
38
+
39
+ Returns:
40
+ Formatted search results with context
41
+ """
42
+ logger.info(f"Searching knowledge base, query: {query}, timeframe: {timeframe}")
43
+
44
+ async with get_client() as client:
45
+ # Create request model
46
+ request = SearchPromptRequest(query=query, timeframe=timeframe)
47
+
48
+ project_url = get_project_config().project_url
49
+
50
+ # Call the prompt API endpoint
51
+ response = await call_post(
52
+ client, f"{project_url}/prompt/search", json=request.model_dump(exclude_none=True)
53
+ )
54
+
55
+ # Extract the rendered prompt from the response
56
+ result = response.json()
57
+ return result["prompt"]
@@ -0,0 +1,162 @@
1
+ """Utility functions for formatting prompt responses.
2
+
3
+ These utilities help format data from various tools into consistent,
4
+ user-friendly markdown summaries.
5
+ """
6
+
7
+ from dataclasses import dataclass
8
+ from textwrap import dedent
9
+ from typing import List
10
+
11
+ from basic_memory.schemas.base import TimeFrame
12
+ from basic_memory.schemas.memory import (
13
+ normalize_memory_url,
14
+ EntitySummary,
15
+ RelationSummary,
16
+ ObservationSummary,
17
+ )
18
+
19
+
20
+ @dataclass
21
+ class PromptContextItem:
22
+ primary_results: List[EntitySummary]
23
+ related_results: List[EntitySummary | RelationSummary | ObservationSummary]
24
+
25
+
26
+ @dataclass
27
+ class PromptContext:
28
+ timeframe: TimeFrame
29
+ topic: str
30
+ results: List[PromptContextItem]
31
+
32
+
33
+ def format_prompt_context(context: PromptContext) -> str:
34
+ """Format continuation context into a helpful summary.
35
+ Returns:
36
+ Formatted continuation summary
37
+ """
38
+ if not context.results: # pragma: no cover
39
+ return dedent(f"""
40
+ # Continuing conversation on: {context.topic}
41
+
42
+ This is a memory retrieval session.
43
+ The supplied query did not return any information specifically on this topic.
44
+
45
+ ## Opportunity to Capture New Knowledge!
46
+
47
+ This is an excellent chance to start documenting this topic:
48
+
49
+ ```python
50
+ await write_note(
51
+ title="{context.topic}",
52
+ content=f'''
53
+ # {context.topic}
54
+
55
+ ## Overview
56
+ [Summary of what we know about {context.topic}]
57
+
58
+ ## Key Points
59
+ [Main aspects or components of {context.topic}]
60
+
61
+ ## Observations
62
+ - [category] [First important observation about {context.topic}]
63
+ - [category] [Second observation about {context.topic}]
64
+
65
+ ## Relations
66
+ - relates_to [[Related Topic]]
67
+ - part_of [[Broader Context]]
68
+ '''
69
+ )
70
+ ```
71
+
72
+ ## Other Options
73
+
74
+ Please use the available basic-memory tools to gather relevant context before responding.
75
+ You can also:
76
+ - Try a different search term
77
+ - Check recent activity with `recent_activity(timeframe="1w")`
78
+ """)
79
+
80
+ # Start building our summary with header - add knowledge capture emphasis
81
+ summary = dedent(f"""
82
+ # Continuing conversation on: {context.topic}
83
+
84
+ This is a memory retrieval session.
85
+
86
+ Please use the available basic-memory tools to gather relevant context before responding.
87
+ Start by executing one of the suggested commands below to retrieve content.
88
+
89
+ Here's what I found from previous conversations:
90
+
91
+ > **Knowledge Capture Recommendation:** As you continue this conversation, actively look for opportunities to record new information, decisions, or insights that emerge. Use `write_note()` to document important context.
92
+ """)
93
+
94
+ # Track what we've added to avoid duplicates
95
+ added_permalinks = set()
96
+ sections = []
97
+
98
+ # Process each context
99
+ for context in context.results: # pyright: ignore
100
+ for primary in context.primary_results: # pyright: ignore
101
+ if primary.permalink not in added_permalinks:
102
+ primary_permalink = primary.permalink
103
+
104
+ added_permalinks.add(primary_permalink)
105
+
106
+ # Use permalink if available, otherwise use file_path
107
+ if primary_permalink:
108
+ memory_url = normalize_memory_url(primary_permalink)
109
+ read_command = f'read_note("{primary_permalink}")'
110
+ else:
111
+ memory_url = f"file://{primary.file_path}"
112
+ read_command = f'read_file("{primary.file_path}")'
113
+
114
+ section = dedent(f"""
115
+ --- {memory_url}
116
+
117
+ ## {primary.title}
118
+ - **Type**: {primary.type}
119
+ """)
120
+
121
+ # Add creation date
122
+ section += f"- **Created**: {primary.created_at.strftime('%Y-%m-%d %H:%M')}\n"
123
+
124
+ # Add content snippet
125
+ if hasattr(primary, "content") and primary.content: # pyright: ignore
126
+ content = primary.content or "" # pyright: ignore
127
+ if content:
128
+ section += f"\n**Excerpt**:\n{content}\n"
129
+
130
+ section += dedent(f"""
131
+
132
+ You can read this document with: `{read_command}`
133
+ """)
134
+ sections.append(section)
135
+
136
+ if context.related_results: # pyright: ignore
137
+ section += dedent( # pyright: ignore
138
+ """
139
+ ## Related Context
140
+ """
141
+ )
142
+
143
+ for related in context.related_results: # pyright: ignore
144
+ section_content = dedent(f"""
145
+ - type: **{related.type}**
146
+ - title: {related.title}
147
+ """)
148
+ if related.permalink: # pragma: no cover
149
+ section_content += (
150
+ f'You can view this document with: `read_note("{related.permalink}")`'
151
+ )
152
+ else: # pragma: no cover
153
+ section_content += (
154
+ f'You can view this file with: `read_file("{related.file_path}")`'
155
+ )
156
+
157
+ section += section_content
158
+ sections.append(section)
159
+
160
+ # Add all sections
161
+ summary += "\n".join(sections)
162
+ return summary
@@ -0,0 +1,283 @@
1
+ # AI Assistant Guide for Basic Memory
2
+
3
+ Quick reference for using Basic Memory tools effectively through MCP.
4
+
5
+ **For comprehensive coverage**: See the [Extended AI Assistant Guide](https://github.com/basicmachines-co/basic-memory/blob/main/docs/ai-assistant-guide-extended.md) with detailed examples, advanced patterns, and self-contained sections.
6
+
7
+ ## Overview
8
+
9
+ Basic Memory creates a semantic knowledge graph from markdown files. Focus on building rich connections between notes.
10
+
11
+ - **Local-First**: Plain text files on user's computer
12
+ - **Persistent**: Knowledge survives across sessions
13
+ - **Semantic**: Observations and relations create a knowledge graph
14
+
15
+ **Your role**: You're helping humans build enduring knowledge they'll own forever. The semantic graph (observations, relations, context) helps you provide better assistance by understanding connections and maintaining continuity. Think: lasting insights worth keeping, not disposable chat logs.
16
+
17
+ ## Project Management
18
+
19
+ All tools require explicit project specification.
20
+
21
+ **Three-tier resolution:**
22
+ 1. CLI constraint: `--project name` (highest priority)
23
+ 2. Explicit parameter: `project="name"` in tool calls
24
+ 3. Default mode: `default_project_mode=true` in config (fallback)
25
+
26
+ ### Quick Setup Check
27
+
28
+ ```python
29
+ # Discover projects
30
+ projects = await list_memory_projects()
31
+
32
+ # Check if default_project_mode enabled
33
+ # If yes: project parameter optional
34
+ # If no: project parameter required
35
+ ```
36
+
37
+ ### Default Project Mode
38
+
39
+ When `default_project_mode=true`:
40
+ ```python
41
+ # These are equivalent:
42
+ await write_note("Note", "Content", "folder")
43
+ await write_note("Note", "Content", "folder", project="main")
44
+ ```
45
+
46
+ When `default_project_mode=false` (default):
47
+ ```python
48
+ # Project required:
49
+ await write_note("Note", "Content", "folder", project="main") # ✓
50
+ await write_note("Note", "Content", "folder") # ✗ Error
51
+ ```
52
+
53
+ ## Core Tools
54
+
55
+ ### Writing Knowledge
56
+
57
+ ```python
58
+ await write_note(
59
+ title="Topic",
60
+ content="# Topic\n## Observations\n- [category] fact\n## Relations\n- relates_to [[Other]]",
61
+ folder="notes",
62
+ project="main" # Required unless default_project_mode=true
63
+ )
64
+ ```
65
+
66
+ ### Reading Knowledge
67
+
68
+ ```python
69
+ # By identifier
70
+ content = await read_note("Topic", project="main")
71
+
72
+ # By memory:// URL
73
+ content = await read_note("memory://folder/topic", project="main")
74
+ ```
75
+
76
+ ### Searching
77
+
78
+ ```python
79
+ results = await search_notes(
80
+ query="authentication",
81
+ project="main",
82
+ page_size=10
83
+ )
84
+ ```
85
+
86
+ ### Building Context
87
+
88
+ ```python
89
+ context = await build_context(
90
+ url="memory://specs/auth",
91
+ project="main",
92
+ depth=2,
93
+ timeframe="1 week"
94
+ )
95
+ ```
96
+
97
+ ## Knowledge Graph Essentials
98
+
99
+ ### Observations
100
+
101
+ Categorized facts with optional tags:
102
+ ```markdown
103
+ - [decision] Use JWT for authentication #security
104
+ - [technique] Hash passwords with bcrypt #best-practice
105
+ - [requirement] Support OAuth 2.0 providers
106
+ ```
107
+
108
+ ### Relations
109
+
110
+ Directional links between entities:
111
+ ```markdown
112
+ - implements [[Authentication Spec]]
113
+ - requires [[User Database]]
114
+ - extends [[Base Security Model]]
115
+ ```
116
+
117
+ **Common relation types:** `relates_to`, `implements`, `requires`, `extends`, `part_of`, `contrasts_with`
118
+
119
+ ### Forward References
120
+
121
+ Reference entities that don't exist yet:
122
+ ```python
123
+ # Create note with forward reference
124
+ await write_note(
125
+ title="Login Flow",
126
+ content="## Relations\n- requires [[OAuth Provider]]", # Doesn't exist yet
127
+ folder="auth",
128
+ project="main"
129
+ )
130
+
131
+ # Later, create referenced entity
132
+ await write_note(
133
+ title="OAuth Provider",
134
+ content="# OAuth Provider\n...",
135
+ folder="auth",
136
+ project="main"
137
+ )
138
+ # → Relation automatically resolved
139
+ ```
140
+
141
+ ## Best Practices
142
+
143
+ ### 1. Project Management
144
+
145
+ **Single-project users:**
146
+ - Enable `default_project_mode=true`
147
+ - Simpler tool calls
148
+
149
+ **Multi-project users:**
150
+ - Keep `default_project_mode=false`
151
+ - Always specify project explicitly
152
+
153
+ **Discovery:**
154
+ ```python
155
+ # Start with discovery
156
+ projects = await list_memory_projects()
157
+
158
+ # Cross-project activity (no project param = all projects)
159
+ activity = await recent_activity()
160
+
161
+ # Or specific project
162
+ activity = await recent_activity(project="main")
163
+ ```
164
+
165
+ ### 2. Building Rich Graphs
166
+
167
+ **Always include:**
168
+ - 3-5 observations per note
169
+ - 2-3 relations per note
170
+ - Meaningful categories and relation types
171
+
172
+ **Search before creating:**
173
+ ```python
174
+ # Find existing entities to reference
175
+ results = await search_notes(query="authentication", project="main")
176
+ # Use exact titles in [[WikiLinks]]
177
+ ```
178
+
179
+ ### 3. Writing Effective Notes
180
+
181
+ **Structure:**
182
+ ```markdown
183
+ # Title
184
+
185
+ ## Context
186
+ Background information
187
+
188
+ ## Observations
189
+ - [category] Fact with #tags
190
+ - [category] Another fact
191
+
192
+ ## Relations
193
+ - relation_type [[Exact Entity Title]]
194
+ ```
195
+
196
+ **Categories:** `[idea]`, `[decision]`, `[fact]`, `[technique]`, `[requirement]`
197
+
198
+ ### 4. Error Handling
199
+
200
+ **Missing project:**
201
+ ```python
202
+ try:
203
+ await search_notes(query="test") # Missing project parameter - will error
204
+ except:
205
+ # Show available projects
206
+ projects = await list_memory_projects()
207
+ # Then retry with project
208
+ results = await search_notes(query="test", project=projects[0].name)
209
+ ```
210
+
211
+ **Forward references:**
212
+ ```python
213
+ # Check response for unresolved relations
214
+ response = await write_note(
215
+ title="New Topic",
216
+ content="## Relations\n- relates_to [[Future Topic]]",
217
+ folder="notes",
218
+ project="main"
219
+ )
220
+ # Forward refs will resolve when target created
221
+ ```
222
+
223
+ ### 5. Recording Context
224
+
225
+ **Ask permission:**
226
+ > "Would you like me to save our discussion about [topic] to Basic Memory?"
227
+
228
+ **Confirm when done:**
229
+ > "I've saved our discussion to Basic Memory."
230
+
231
+ **What to record:**
232
+ - Decisions and rationales
233
+ - Important discoveries
234
+ - Action items and plans
235
+ - Connected topics
236
+
237
+ ## Common Patterns
238
+
239
+ ### Capture Decision
240
+
241
+ ```python
242
+ await write_note(
243
+ title="DB Choice",
244
+ content="""# DB Choice\n## Decision\nUse PostgreSQL\n## Observations\n- [requirement] ACID compliance #reliability\n- [decision] PostgreSQL over MySQL\n## Relations\n- implements [[Data Architecture]]""",
245
+ folder="decisions",
246
+ project="main"
247
+ )
248
+ ```
249
+
250
+ ### Link Topics & Build Context
251
+
252
+ ```python
253
+ # Link bidirectionally
254
+ await write_note(title="API Auth", content="## Relations\n- part_of [[API Design]]", folder="api", project="main")
255
+ await edit_note(identifier="API Design", operation="append", content="\n- includes [[API Auth]]", project="main")
256
+
257
+ # Search and build context
258
+ results = await search_notes(query="authentication", project="main")
259
+ context = await build_context(url=f"memory://{results[0].permalink}", project="main", depth=2)
260
+ ```
261
+
262
+ ## Tool Quick Reference
263
+
264
+ | Tool | Purpose | Key Params |
265
+ |------|---------|------------|
266
+ | `write_note` | Create/update | title, content, folder, project |
267
+ | `read_note` | Read content | identifier, project |
268
+ | `edit_note` | Modify existing | identifier, operation, content, project |
269
+ | `search_notes` | Find notes | query, project |
270
+ | `build_context` | Graph traversal | url, depth, project |
271
+ | `recent_activity` | Recent changes | timeframe, project |
272
+ | `list_memory_projects` | Show projects | (none) |
273
+
274
+ ## memory:// URL Format
275
+
276
+ - `memory://title` - By title
277
+ - `memory://folder/title` - By folder + title
278
+ - `memory://permalink` - By permalink
279
+ - `memory://folder/*` - All in folder
280
+
281
+ For full documentation: https://docs.basicmemory.com
282
+
283
+ Built with ♥️ by Basic Machines