basic-memory 0.14.0b1__py3-none-any.whl → 0.14.2__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.

Potentially problematic release.


This version of basic-memory might be problematic. Click here for more details.

basic_memory/__init__.py CHANGED
@@ -1,7 +1,7 @@
1
1
  """basic-memory - Local-first knowledge management combining Zettelkasten with knowledge graphs"""
2
2
 
3
3
  # Package version - updated by release automation
4
- __version__ = "0.14.0b1"
4
+ __version__ = "0.14.2"
5
5
 
6
6
  # API version for FastAPI - independent of package version
7
7
  __api_version__ = "v0"
@@ -38,7 +38,9 @@ def entity_model_from_markdown(
38
38
  # Update basic fields
39
39
  model.title = markdown.frontmatter.title
40
40
  model.entity_type = markdown.frontmatter.type
41
- model.permalink = markdown.frontmatter.permalink
41
+ # Only update permalink if it exists in frontmatter, otherwise preserve existing
42
+ if markdown.frontmatter.permalink is not None:
43
+ model.permalink = markdown.frontmatter.permalink
42
44
  model.file_path = str(file_path)
43
45
  model.content_type = "text/markdown"
44
46
  model.created_at = markdown.created
@@ -1,7 +1,7 @@
1
1
  """OAuth authentication provider for Basic Memory MCP server."""
2
2
 
3
3
  import secrets
4
- from datetime import datetime, timedelta
4
+ from datetime import datetime, timedelta, timezone
5
5
  from typing import Dict, Optional
6
6
 
7
7
  import jwt
@@ -92,7 +92,7 @@ class BasicMemoryOAuthProvider(
92
92
  self.authorization_codes[auth_code] = BasicMemoryAuthorizationCode(
93
93
  code=auth_code,
94
94
  scopes=params.scopes or [],
95
- expires_at=(datetime.utcnow() + timedelta(minutes=10)).timestamp(),
95
+ expires_at=(datetime.now(timezone.utc) + timedelta(minutes=10)).timestamp(),
96
96
  client_id=client.client_id,
97
97
  code_challenge=params.code_challenge,
98
98
  redirect_uri=params.redirect_uri,
@@ -119,7 +119,7 @@ class BasicMemoryOAuthProvider(
119
119
 
120
120
  if code and code.client_id == client.client_id:
121
121
  # Check if expired
122
- if datetime.utcnow().timestamp() > code.expires_at:
122
+ if datetime.now(timezone.utc).timestamp() > code.expires_at:
123
123
  del self.authorization_codes[authorization_code]
124
124
  return None
125
125
  return code
@@ -135,7 +135,7 @@ class BasicMemoryOAuthProvider(
135
135
  refresh_token = secrets.token_urlsafe(32)
136
136
 
137
137
  # Store tokens
138
- expires_at = (datetime.utcnow() + timedelta(hours=1)).timestamp()
138
+ expires_at = (datetime.now(timezone.utc) + timedelta(hours=1)).timestamp()
139
139
 
140
140
  self.access_tokens[access_token] = BasicMemoryAccessToken(
141
141
  token=access_token,
@@ -187,7 +187,7 @@ class BasicMemoryOAuthProvider(
187
187
  new_refresh_token = secrets.token_urlsafe(32)
188
188
 
189
189
  # Store new tokens
190
- expires_at = (datetime.utcnow() + timedelta(hours=1)).timestamp()
190
+ expires_at = (datetime.now(timezone.utc) + timedelta(hours=1)).timestamp()
191
191
 
192
192
  self.access_tokens[new_access_token] = BasicMemoryAccessToken(
193
193
  token=new_access_token,
@@ -220,7 +220,7 @@ class BasicMemoryOAuthProvider(
220
220
 
221
221
  if access_token:
222
222
  # Check if expired
223
- if access_token.expires_at and datetime.utcnow().timestamp() > access_token.expires_at:
223
+ if access_token.expires_at and datetime.now(timezone.utc).timestamp() > access_token.expires_at:
224
224
  logger.debug("Token found in memory but expired, removing")
225
225
  del self.access_tokens[token]
226
226
  return None
@@ -262,8 +262,8 @@ class BasicMemoryOAuthProvider(
262
262
  "iss": self.issuer_url,
263
263
  "sub": client_id,
264
264
  "aud": "basic-memory",
265
- "exp": datetime.utcnow() + timedelta(hours=1),
266
- "iat": datetime.utcnow(),
265
+ "exp": datetime.now(timezone.utc) + timedelta(hours=1),
266
+ "iat": datetime.now(timezone.utc),
267
267
  "scopes": scopes,
268
268
  }
269
269
 
@@ -3,7 +3,7 @@
3
3
  import os
4
4
  import secrets
5
5
  from dataclasses import dataclass
6
- from datetime import datetime, timedelta
6
+ from datetime import datetime, timedelta, timezone
7
7
  from typing import Optional, Dict, Any
8
8
 
9
9
  import httpx
@@ -123,7 +123,7 @@ class SupabaseOAuthProvider(
123
123
  self.pending_auth_codes[state] = SupabaseAuthorizationCode(
124
124
  code=state,
125
125
  scopes=params.scopes or [],
126
- expires_at=(datetime.utcnow() + timedelta(minutes=10)).timestamp(),
126
+ expires_at=(datetime.now(timezone.utc) + timedelta(minutes=10)).timestamp(),
127
127
  client_id=client.client_id,
128
128
  code_challenge=params.code_challenge,
129
129
  redirect_uri=params.redirect_uri,
@@ -218,7 +218,7 @@ class SupabaseOAuthProvider(
218
218
 
219
219
  if code and code.client_id == client.client_id:
220
220
  # Check expiration
221
- if datetime.utcnow().timestamp() > code.expires_at:
221
+ if datetime.now(timezone.utc).timestamp() > code.expires_at:
222
222
  del self.pending_auth_codes[authorization_code]
223
223
  return None
224
224
  return code
@@ -453,8 +453,8 @@ class SupabaseOAuthProvider(
453
453
  "email": email,
454
454
  "scopes": scopes,
455
455
  "supabase_token": supabase_access_token[:10] + "...", # Reference only
456
- "exp": datetime.utcnow() + timedelta(hours=1),
457
- "iat": datetime.utcnow(),
456
+ "exp": datetime.now(timezone.utc) + timedelta(hours=1),
457
+ "iat": datetime.now(timezone.utc),
458
458
  }
459
459
 
460
460
  # Use Supabase JWT secret if available
@@ -20,24 +20,24 @@ from basic_memory.mcp.tools.edit_note import edit_note
20
20
  from basic_memory.mcp.tools.move_note import move_note
21
21
  from basic_memory.mcp.tools.sync_status import sync_status
22
22
  from basic_memory.mcp.tools.project_management import (
23
- list_projects,
23
+ list_memory_projects,
24
24
  switch_project,
25
25
  get_current_project,
26
26
  set_default_project,
27
- create_project,
27
+ create_memory_project,
28
28
  delete_project,
29
29
  )
30
30
 
31
31
  __all__ = [
32
32
  "build_context",
33
33
  "canvas",
34
- "create_project",
34
+ "create_memory_project",
35
35
  "delete_note",
36
36
  "delete_project",
37
37
  "edit_note",
38
38
  "get_current_project",
39
39
  "list_directory",
40
- "list_projects",
40
+ "list_memory_projects",
41
41
  "move_note",
42
42
  "read_content",
43
43
  "read_note",
@@ -5,6 +5,7 @@ and manage project context during conversations.
5
5
  """
6
6
 
7
7
  from textwrap import dedent
8
+ from typing import Optional
8
9
 
9
10
  from fastmcp import Context
10
11
  from loguru import logger
@@ -19,7 +20,9 @@ from basic_memory.utils import generate_permalink
19
20
 
20
21
 
21
22
  @mcp.tool("list_memory_projects")
22
- async def list_projects(ctx: Context | None = None) -> str:
23
+ async def list_memory_projects(
24
+ ctx: Context | None = None, _compatibility: Optional[str] = None
25
+ ) -> str:
23
26
  """List all available projects with their status.
24
27
 
25
28
  Shows all Basic Memory projects that are available, indicating which one
@@ -29,7 +32,7 @@ async def list_projects(ctx: Context | None = None) -> str:
29
32
  Formatted list of projects with status indicators
30
33
 
31
34
  Example:
32
- list_projects()
35
+ list_memory_projects()
33
36
  """
34
37
  if ctx: # pragma: no cover
35
38
  await ctx.info("Listing all available projects")
@@ -144,13 +147,13 @@ async def switch_project(project_name: str, ctx: Context | None = None) -> str:
144
147
  Your session remains on the previous project.
145
148
 
146
149
  ## Troubleshooting:
147
- 1. **Check available projects**: Use `list_projects()` to see valid project names
150
+ 1. **Check available projects**: Use `list_memory_projects()` to see valid project names
148
151
  2. **Verify spelling**: Ensure the project name is spelled correctly
149
152
  3. **Check permissions**: Verify you have access to the requested project
150
153
  4. **Try again**: The error might be temporary
151
154
 
152
155
  ## Available options:
153
- - See all projects: `list_projects()`
156
+ - See all projects: `list_memory_projects()`
154
157
  - Stay on current project: `get_current_project()`
155
158
  - Try different project: `switch_project("correct-project-name")`
156
159
 
@@ -159,7 +162,9 @@ async def switch_project(project_name: str, ctx: Context | None = None) -> str:
159
162
 
160
163
 
161
164
  @mcp.tool()
162
- async def get_current_project(ctx: Context | None = None) -> str:
165
+ async def get_current_project(
166
+ ctx: Context | None = None, _compatibility: Optional[str] = None
167
+ ) -> str:
163
168
  """Show the currently active project and basic stats.
164
169
 
165
170
  Displays which project is currently active and provides basic information
@@ -231,7 +236,7 @@ async def set_default_project(project_name: str, ctx: Context | None = None) ->
231
236
 
232
237
 
233
238
  @mcp.tool("create_memory_project")
234
- async def create_project(
239
+ async def create_memory_project(
235
240
  project_name: str, project_path: str, set_default: bool = False, ctx: Context | None = None
236
241
  ) -> str:
237
242
  """Create a new Basic Memory project.
@@ -248,8 +253,8 @@ async def create_project(
248
253
  Confirmation message with project details
249
254
 
250
255
  Example:
251
- create_project("my-research", "~/Documents/research")
252
- create_project("work-notes", "/home/user/work", set_default=True)
256
+ create_memory_project("my-research", "~/Documents/research")
257
+ create_memory_project("work-notes", "/home/user/work", set_default=True)
253
258
  """
254
259
  if ctx: # pragma: no cover
255
260
  await ctx.info(f"Creating project: {project_name} at {project_path}")
@@ -45,13 +45,18 @@ def _format_search_error_response(error_message: str, query: str, search_type: s
45
45
  - Boolean OR: `meeting OR discussion`
46
46
  - Boolean NOT: `project NOT archived`
47
47
  - Grouped: `(project OR planning) AND notes`
48
+ - Exact phrases: `"weekly standup meeting"`
49
+ - Content-specific: `tag:example` or `category:observation`
48
50
 
49
51
  ## Try again with:
50
52
  ```
51
- search_notes("INSERT_CLEAN_QUERY_HERE")
53
+ search_notes("{clean_query}")
52
54
  ```
53
55
 
54
- Replace INSERT_CLEAN_QUERY_HERE with your simplified search terms.
56
+ ## Alternative search strategies:
57
+ - Break into simpler terms: `search_notes("{" ".join(clean_query.split()[:2])}")`
58
+ - Try different search types: `search_notes("{clean_query}", search_type="title")`
59
+ - Use filtering: `search_notes("{clean_query}", types=["entity"])`
55
60
  """).strip()
56
61
 
57
62
  # Project not found errors (check before general "not found")
@@ -85,24 +90,39 @@ def _format_search_error_response(error_message: str, query: str, search_type: s
85
90
 
86
91
  No content found matching '{query}' in the current project.
87
92
 
88
- ## Suggestions to try:
93
+ ## Search strategy suggestions:
89
94
  1. **Broaden your search**: Try fewer or more general terms
90
95
  - Instead of: `{query}`
91
96
  - Try: `{simplified_query}`
92
97
 
93
- 2. **Check spelling**: Verify terms are spelled correctly
94
- 3. **Try different search types**:
95
- - Text search: `search_notes("{query}", search_type="text")`
96
- - Title search: `search_notes("{query}", search_type="title")`
97
- - Permalink search: `search_notes("{query}", search_type="permalink")`
98
-
99
- 4. **Use boolean operators**:
100
- - Try OR search for broader results
101
-
102
- ## Check what content exists:
103
- - Recent activity: `recent_activity(timeframe="7d")`
104
- - List files: `list_directory("/")`
105
- - Browse by folder: `list_directory("/notes")` or `list_directory("/docs")`
98
+ 2. **Check spelling and try variations**:
99
+ - Verify terms are spelled correctly
100
+ - Try synonyms or related terms
101
+
102
+ 3. **Use different search approaches**:
103
+ - **Text search**: `search_notes("{query}", search_type="text")` (searches full content)
104
+ - **Title search**: `search_notes("{query}", search_type="title")` (searches only titles)
105
+ - **Permalink search**: `search_notes("{query}", search_type="permalink")` (searches file paths)
106
+
107
+ 4. **Try boolean operators for broader results**:
108
+ - OR search: `search_notes("{" OR ".join(query.split()[:3])}")`
109
+ - Remove restrictive terms: Focus on the most important keywords
110
+
111
+ 5. **Use filtering to narrow scope**:
112
+ - By content type: `search_notes("{query}", types=["entity"])`
113
+ - By recent content: `search_notes("{query}", after_date="1 week")`
114
+ - By entity type: `search_notes("{query}", entity_types=["observation"])`
115
+
116
+ 6. **Try advanced search patterns**:
117
+ - Tag search: `search_notes("tag:your-tag")`
118
+ - Category search: `search_notes("category:observation")`
119
+ - Pattern matching: `search_notes("*{query}*", search_type="permalink")`
120
+
121
+ ## Explore what content exists:
122
+ - **Recent activity**: `recent_activity(timeframe="7d")` - See what's been updated recently
123
+ - **List directories**: `list_directory("/")` - Browse all content
124
+ - **Browse by folder**: `list_directory("/notes")` or `list_directory("/docs")`
125
+ - **Check project**: `get_current_project()` - Verify you're in the right project
106
126
  """).strip()
107
127
 
108
128
  # Server/API errors
@@ -151,25 +171,36 @@ You don't have permission to search in the current project: {error_message}
151
171
 
152
172
  Error searching for '{query}': {error_message}
153
173
 
154
- ## General troubleshooting:
155
- 1. **Check your query**: Ensure it uses valid search syntax
156
- 2. **Try simpler terms**: Use basic words without special characters
174
+ ## Troubleshooting steps:
175
+ 1. **Simplify your query**: Try basic words without special characters
176
+ 2. **Check search syntax**: Ensure boolean operators are correctly formatted
157
177
  3. **Verify project access**: Make sure you can access the current project
158
- 4. **Check recent activity**: `recent_activity(timeframe="7d")` to see if content exists
159
-
160
- ## Alternative approaches:
161
- - Browse files: `list_directory("/")`
162
- - Try different search type: `search_notes("{query}", search_type="title")`
163
- - Search with filters: `search_notes("{query}", types=["entity"])`
164
-
165
- ## Need help?
166
- - View recent changes: `recent_activity()`
167
- - List projects: `list_projects()`
168
- - Check current project: `get_current_project()`"""
178
+ 4. **Test with simple search**: Try `search_notes("test")` to verify search is working
179
+
180
+ ## Alternative search approaches:
181
+ - **Different search types**:
182
+ - Title only: `search_notes("{query}", search_type="title")`
183
+ - Permalink patterns: `search_notes("{query}*", search_type="permalink")`
184
+ - **With filters**: `search_notes("{query}", types=["entity"])`
185
+ - **Recent content**: `search_notes("{query}", after_date="1 week")`
186
+ - **Boolean variations**: `search_notes("{" OR ".join(query.split()[:2])}")`
187
+
188
+ ## Explore your content:
189
+ - **Browse files**: `list_directory("/")` - See all available content
190
+ - **Recent activity**: `recent_activity(timeframe="7d")` - Check what's been updated
191
+ - **Project info**: `get_current_project()` - Verify current project
192
+ - **All projects**: `list_projects()` - Switch to different project if needed
193
+
194
+ ## Search syntax reference:
195
+ - **Basic**: `keyword` or `multiple words`
196
+ - **Boolean**: `term1 AND term2`, `term1 OR term2`, `term1 NOT term2`
197
+ - **Phrases**: `"exact phrase"`
198
+ - **Grouping**: `(term1 OR term2) AND term3`
199
+ - **Patterns**: `tag:example`, `category:observation`"""
169
200
 
170
201
 
171
202
  @mcp.tool(
172
- description="Search across all content in the knowledge base.",
203
+ description="Search across all content in the knowledge base with advanced syntax support.",
173
204
  )
174
205
  async def search_notes(
175
206
  query: str,
@@ -181,24 +212,60 @@ async def search_notes(
181
212
  after_date: Optional[str] = None,
182
213
  project: Optional[str] = None,
183
214
  ) -> SearchResponse | str:
184
- """Search across all content in the knowledge base.
215
+ """Search across all content in the knowledge base with comprehensive syntax support.
185
216
 
186
217
  This tool searches the knowledge base using full-text search, pattern matching,
187
218
  or exact permalink lookup. It supports filtering by content type, entity type,
188
- and date.
219
+ and date, with advanced boolean and phrase search capabilities.
220
+
221
+ ## Search Syntax Examples
222
+
223
+ ### Basic Searches
224
+ - `search_notes("keyword")` - Find any content containing "keyword"
225
+ - `search_notes("exact phrase")` - Search for exact phrase match
226
+
227
+ ### Advanced Boolean Searches
228
+ - `search_notes("term1 term2")` - Find content with both terms (implicit AND)
229
+ - `search_notes("term1 AND term2")` - Explicit AND search (both terms required)
230
+ - `search_notes("term1 OR term2")` - Either term can be present
231
+ - `search_notes("term1 NOT term2")` - Include term1 but exclude term2
232
+ - `search_notes("(project OR planning) AND notes")` - Grouped boolean logic
233
+
234
+ ### Content-Specific Searches
235
+ - `search_notes("tag:example")` - Search within specific tags (if supported by content)
236
+ - `search_notes("category:observation")` - Filter by observation categories
237
+ - `search_notes("author:username")` - Find content by author (if metadata available)
238
+
239
+ ### Search Type Examples
240
+ - `search_notes("Meeting", search_type="title")` - Search only in titles
241
+ - `search_notes("docs/meeting-*", search_type="permalink")` - Pattern match permalinks
242
+ - `search_notes("keyword", search_type="text")` - Full-text search (default)
243
+
244
+ ### Filtering Options
245
+ - `search_notes("query", types=["entity"])` - Search only entities
246
+ - `search_notes("query", types=["note", "person"])` - Multiple content types
247
+ - `search_notes("query", entity_types=["observation"])` - Filter by entity type
248
+ - `search_notes("query", after_date="2024-01-01")` - Recent content only
249
+ - `search_notes("query", after_date="1 week")` - Relative date filtering
250
+
251
+ ### Advanced Pattern Examples
252
+ - `search_notes("project AND (meeting OR discussion)")` - Complex boolean logic
253
+ - `search_notes("\"exact phrase\" AND keyword")` - Combine phrase and keyword search
254
+ - `search_notes("bug NOT fixed")` - Exclude resolved issues
255
+ - `search_notes("docs/2024-*", search_type="permalink")` - Year-based permalink search
189
256
 
190
257
  Args:
191
- query: The search query string
258
+ query: The search query string (supports boolean operators, phrases, patterns)
192
259
  page: The page number of results to return (default 1)
193
260
  page_size: The number of results to return per page (default 10)
194
261
  search_type: Type of search to perform, one of: "text", "title", "permalink" (default: "text")
195
262
  types: Optional list of note types to search (e.g., ["note", "person"])
196
263
  entity_types: Optional list of entity types to filter by (e.g., ["entity", "observation"])
197
- after_date: Optional date filter for recent content (e.g., "1 week", "2d")
264
+ after_date: Optional date filter for recent content (e.g., "1 week", "2d", "2024-01-01")
198
265
  project: Optional project name to search in. If not provided, uses current active project.
199
266
 
200
267
  Returns:
201
- SearchResponse with results and pagination info
268
+ SearchResponse with results and pagination info, or helpful error guidance if search fails
202
269
 
203
270
  Examples:
204
271
  # Basic text search
@@ -216,16 +283,19 @@ async def search_notes(
216
283
  # Boolean search with grouping
217
284
  results = await search_notes("(project OR planning) AND notes")
218
285
 
286
+ # Exact phrase search
287
+ results = await search_notes("\"weekly standup meeting\"")
288
+
219
289
  # Search with type filter
220
290
  results = await search_notes(
221
291
  query="meeting notes",
222
292
  types=["entity"],
223
293
  )
224
294
 
225
- # Search with entity type filter, e.g., note vs
295
+ # Search with entity type filter
226
296
  results = await search_notes(
227
297
  query="meeting notes",
228
- types=["entity"],
298
+ entity_types=["observation"],
229
299
  )
230
300
 
231
301
  # Search for recent content
@@ -242,6 +312,13 @@ async def search_notes(
242
312
 
243
313
  # Search in specific project
244
314
  results = await search_notes("meeting notes", project="work-project")
315
+
316
+ # Complex search with multiple filters
317
+ results = await search_notes(
318
+ query="(bug OR issue) AND NOT resolved",
319
+ types=["entity"],
320
+ after_date="2024-01-01"
321
+ )
245
322
  """
246
323
  # Create a SearchQuery object based on the parameters
247
324
  search_query = SearchQuery()
@@ -131,7 +131,7 @@ class EntityResponse(SQLAlchemyModel):
131
131
  }
132
132
  """
133
133
 
134
- permalink: Permalink
134
+ permalink: Optional[Permalink]
135
135
  title: str
136
136
  file_path: str
137
137
  entity_type: EntityType
basic_memory/utils.py CHANGED
@@ -173,6 +173,8 @@ def setup_logging(
173
173
  "httpx": logging.WARNING,
174
174
  # File watching logs
175
175
  "watchfiles.main": logging.WARNING,
176
+ # SQLAlchemy deprecation warnings
177
+ "sqlalchemy": logging.WARNING,
176
178
  }
177
179
 
178
180
  # Set log levels for noisy loggers
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: basic-memory
3
- Version: 0.14.0b1
3
+ Version: 0.14.2
4
4
  Summary: Local-first knowledge management combining Zettelkasten with knowledge graphs
5
5
  Project-URL: Homepage, https://github.com/basicmachines-co/basic-memory
6
6
  Project-URL: Repository, https://github.com/basicmachines-co/basic-memory
@@ -13,7 +13,7 @@ Requires-Dist: aiosqlite>=0.20.0
13
13
  Requires-Dist: alembic>=1.14.1
14
14
  Requires-Dist: dateparser>=1.2.0
15
15
  Requires-Dist: fastapi[standard]>=0.115.8
16
- Requires-Dist: fastmcp>=2.3.4
16
+ Requires-Dist: fastmcp<2.10.0,>=2.3.4
17
17
  Requires-Dist: greenlet>=3.1.1
18
18
  Requires-Dist: icecream>=2.1.3
19
19
  Requires-Dist: loguru>=0.7.3
@@ -71,6 +71,10 @@ https://github.com/user-attachments/assets/a55d8238-8dd0-454a-be4c-8860dbbd0ddc
71
71
  # Install with uv (recommended)
72
72
  uv tool install basic-memory
73
73
 
74
+ # or with Homebrew
75
+ brew tap basicmachines-co/basic-memory
76
+ brew install basic-memory
77
+
74
78
  # Configure Claude Desktop (edit ~/Library/Application Support/Claude/claude_desktop_config.json)
75
79
  # Add this to your config:
76
80
  {
@@ -104,6 +108,13 @@ npx -y @smithery/cli install @basicmachines-co/basic-memory --client claude
104
108
 
105
109
  This installs and configures Basic Memory without requiring manual edits to the Claude Desktop configuration file. Note: The Smithery installation uses their hosted MCP server, while your data remains stored locally as Markdown files.
106
110
 
111
+ ### Add to Cursor
112
+
113
+ Once you have installed Basic Memory revisit this page for the 1-click installer for Cursor:
114
+
115
+ [![Install MCP Server](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/install-mcp?name=basic-memory&config=eyJjb21tYW5kIjoiL1VzZXJzL2RyZXcvLmxvY2FsL2Jpbi91dnggYmFzaWMtbWVtb3J5IG1jcCJ9)
116
+
117
+
107
118
  ### Glama.ai
108
119
 
109
120
  <a href="https://glama.ai/mcp/servers/o90kttu9ym">
@@ -252,7 +263,7 @@ title: <Entity title>
252
263
  type: <The type of Entity> (e.g. note)
253
264
  permalink: <a uri slug>
254
265
 
255
- - <optional metadata> (such as tags)
266
+ - <optional metadata> (such as tags)
256
267
  ```
257
268
 
258
269
  ### Observations
@@ -1,9 +1,9 @@
1
- basic_memory/__init__.py,sha256=DPlOFFx4PSC_e78q8BXXJTJMjPtdv3jAI7UszpA20Dk,258
1
+ basic_memory/__init__.py,sha256=yUZJCrnWSVfSXfN_chOSAkkW-Kge2Dj3Co6TixwmN9s,256
2
2
  basic_memory/config.py,sha256=YX6pP8aOMlIx9NoCeKLS0b5cgOnegbWhX2ijJzimLQg,11828
3
3
  basic_memory/db.py,sha256=bFuJHj_PGEhaj5ZgRItIUSW0ujAFCGgYKO7nZsjbYD0,7582
4
4
  basic_memory/deps.py,sha256=zXOhqXCoSVIa1iIcO8U6uUiofJn5eT4ycwJkH9I2kX4,12102
5
5
  basic_memory/file_utils.py,sha256=eaxTKLLEbTIy_Mb_Iv_Dmt4IXAJSrZGVi-Knrpyci3E,6700
6
- basic_memory/utils.py,sha256=BL6DDRiMF1gNcDr_guRAYflooSrSlDniJh96ApdzuDY,7555
6
+ basic_memory/utils.py,sha256=yG-HHoSqw6RUD9yU0PkrLdhDAi99r6tmE8fWTvBxrgc,7636
7
7
  basic_memory/alembic/alembic.ini,sha256=IEZsnF8CbbZnkwBr67LzKKNobHuzTaQNUvM8Psop5xc,3733
8
8
  basic_memory/alembic/env.py,sha256=gECjMcc--Hhacy3od1WNIAFyHzv6MUi7F_eQG7k3bRQ,2812
9
9
  basic_memory/alembic/migrations.py,sha256=lriHPXDdBLSNXEW3QTpU0SJKuVd1V-8NrVkpN3qfsUQ,718
@@ -55,14 +55,14 @@ basic_memory/markdown/entity_parser.py,sha256=Gw0RdzWGRcy63RcLP2J2Dcm9g404x0GXir
55
55
  basic_memory/markdown/markdown_processor.py,sha256=S5ny69zu2dlqO7tWJoLrpLSzg8emQIDq7Du7olpJUsk,4968
56
56
  basic_memory/markdown/plugins.py,sha256=gtIzKRjoZsyvBqLpVNnrmzl_cbTZ5ZGn8kcuXxQjRko,6639
57
57
  basic_memory/markdown/schemas.py,sha256=eyxYCr1hVyWmImcle0asE5It_DD6ARkqaBZYu1KK5n4,1896
58
- basic_memory/markdown/utils.py,sha256=wr7KnDMThgnztkOoqSG_ANPhwNBoPkyjYP1sA1Wnxe4,3270
58
+ basic_memory/markdown/utils.py,sha256=G3V_DQbmDj6idsCy6kT-GhVqiV4JPB5gfWKG5wK_SuQ,3410
59
59
  basic_memory/mcp/__init__.py,sha256=dsDOhKqjYeIbCULbHIxfcItTbqudEuEg1Np86eq0GEQ,35
60
60
  basic_memory/mcp/async_client.py,sha256=Eo345wANiBRSM4u3j_Vd6Ax4YtMg7qbWd9PIoFfj61I,236
61
- basic_memory/mcp/auth_provider.py,sha256=CTydkEBvxh_fg_Z0hxKjTT8nHJoFhxrwp5hTQuToiIU,9977
61
+ basic_memory/mcp/auth_provider.py,sha256=NnnxpOUMI1sZhKkzHh4Hhoufo4FuiKByx34TdfPoBX8,10050
62
62
  basic_memory/mcp/external_auth_provider.py,sha256=Z1GDbr6P4C-flZVHMWkIqAu30kcfeHv2iSp0EYbFuxo,11483
63
63
  basic_memory/mcp/project_session.py,sha256=KfObBqUFUKNGlcApCfQcsqMYsmtWs72OdIcQ79ZSWhk,4142
64
64
  basic_memory/mcp/server.py,sha256=T8utX0fTA12rAC_TjtWgsfB1z-Q6pdTWJH4HISw73vg,3764
65
- basic_memory/mcp/supabase_auth_provider.py,sha256=MLHfSHjdx2Q5jr_Ljx0qZBaOwp7CkPdk_ybR_LQ7Mvw,16472
65
+ basic_memory/mcp/supabase_auth_provider.py,sha256=R_E4jzXSDOyPomoHiIqPVjx-VUhPqJSIUbg84mE2YaQ,16518
66
66
  basic_memory/mcp/prompts/__init__.py,sha256=UvaIw5KA8PaXj3Wz1Dr-VjlkEq6T5D8AGtYFVwaHqnA,683
67
67
  basic_memory/mcp/prompts/ai_assistant_guide.py,sha256=8TI5xObiRVcwv6w9by1xQHlX0whvyE7-LGsiqDMRTFg,821
68
68
  basic_memory/mcp/prompts/continue_conversation.py,sha256=rsmlC2V7e7G6DAK0K825vFsPKgsRQ702HFzn6lkHaDM,1998
@@ -72,18 +72,18 @@ basic_memory/mcp/prompts/sync_status.py,sha256=0F6YowgqIbAFmGE3vFFJ-D-q1SrTqzGLK
72
72
  basic_memory/mcp/prompts/utils.py,sha256=VacrbqwYtySpIlYIrKHo5s6jtoTMscYJqrFRH3zpC6Q,5431
73
73
  basic_memory/mcp/resources/ai_assistant_guide.md,sha256=qnYWDkYlb-JmKuOoZ5llmRas_t4dWDXB_i8LE277Lgs,14777
74
74
  basic_memory/mcp/resources/project_info.py,sha256=LcUkTx4iXBfU6Lp4TVch78OqLopbOy4ljyKnfr4VXso,1906
75
- basic_memory/mcp/tools/__init__.py,sha256=lCCOC0jElvL2v53WI_dxRs4qABq4Eo-YGm6j2XeZ6AQ,1591
75
+ basic_memory/mcp/tools/__init__.py,sha256=hyt3HdUuw7djZForr24Qpw8EnOMQaDCm0_BTs-CaX-Y,1619
76
76
  basic_memory/mcp/tools/build_context.py,sha256=ckKAt3uPXz5hzT_e68PuZuK8_tquo2OOai4uM_yxl44,4611
77
77
  basic_memory/mcp/tools/canvas.py,sha256=22F9G9gfPb-l8i1B5ra4Ja_h9zYY83rPY9mDA5C5gkY,3738
78
78
  basic_memory/mcp/tools/delete_note.py,sha256=tSyRc_VgBmLyVeenClwX1Sk--LKcGahAMzTX2mK2XIs,7346
79
79
  basic_memory/mcp/tools/edit_note.py,sha256=q4x-f7-j_l-wzm17-AVFT1_WGCo0Cq4lI3seYSe21aY,13570
80
80
  basic_memory/mcp/tools/list_directory.py,sha256=-FxDsCru5YD02M4qkQDAurEJWyRaC7YI4YR6zg0atR8,5236
81
81
  basic_memory/mcp/tools/move_note.py,sha256=jAsCFXrcWXPoBWlWcW8y3Tli5MkKwCQK-n6IwUZoOK8,17357
82
- basic_memory/mcp/tools/project_management.py,sha256=sZQbak0jIQ6k03Syz6X6Zsy-C9z8KdPnEQcpJLCxPwM,12779
82
+ basic_memory/mcp/tools/project_management.py,sha256=zaxzbWUSn2iahca4L44EO8hKMWV-rXqDMXcRce6qhg8,12944
83
83
  basic_memory/mcp/tools/read_content.py,sha256=4FTw13B8UjVVhR78NJB9HKeJb_nA6-BGT1WdGtekN5Q,8596
84
84
  basic_memory/mcp/tools/read_note.py,sha256=V08NdBqWY8Y0Q4zuwK--zN3VK7fmuCH1mOYZKwL1IT4,7614
85
85
  basic_memory/mcp/tools/recent_activity.py,sha256=XVjNJAJnmxvzx9_Ls1A-QOd2yTR7pJlSTTuRxSivmN4,4833
86
- basic_memory/mcp/tools/search.py,sha256=22sLHed6z53mH9NQqBv37Xi4d6AtOTyrUvKs2Mycijk,11296
86
+ basic_memory/mcp/tools/search.py,sha256=hRmwBXRoxEUOtUOi9WG80NfLluHOG5XpSOArMJumt8o,15883
87
87
  basic_memory/mcp/tools/sync_status.py,sha256=mt0DdcaAlyiKW4NK4gy6psajSqcez0bOm_4MzG1NOdg,10486
88
88
  basic_memory/mcp/tools/utils.py,sha256=qVAEkR4naCLrqIo_7xXFubqGGxypouz-DB4_svTvARY,20892
89
89
  basic_memory/mcp/tools/view_note.py,sha256=ddNXxyETsdA5SYflIaQVj_Cbd7I7CLVs3atRRDMbGmg,2499
@@ -110,7 +110,7 @@ basic_memory/schemas/memory.py,sha256=rLSpU6VT_spnLEiVeYp9lI7FH5IvdbZt19VXFuO-vt
110
110
  basic_memory/schemas/project_info.py,sha256=fcNjUpe25_5uMmKy142ib3p5qEakzs1WJPLkgol5zyw,7047
111
111
  basic_memory/schemas/prompt.py,sha256=SpIVfZprQT8E5uP40j3CpBc2nHKflwOo3iZD7BFPIHE,3648
112
112
  basic_memory/schemas/request.py,sha256=Mv5EvrLZlFIiPr8dOjo_4QXvkseYhQI7cd_X2zDsxQM,3760
113
- basic_memory/schemas/response.py,sha256=lVYR31DTtSeFRddGWX_wQWnQgyiwX0LEpNJ4f4lKpTM,6440
113
+ basic_memory/schemas/response.py,sha256=XupGYKKr5I2D7Qg9HCSD_c-0A-C1BPA8FNIvHK6Gars,6450
114
114
  basic_memory/schemas/search.py,sha256=ywMsDGAQK2sO2TT5lc-da_k67OKW1x1TenXormHHWv4,3657
115
115
  basic_memory/services/__init__.py,sha256=XGt8WX3fX_0K9L37Msy8HF8nlMZYIG3uQ6mUX6_iJtg,259
116
116
  basic_memory/services/context_service.py,sha256=4ReLAF5qifA9ayOePGsVKusw1TWj8oBzRECjrsFiKPI,14462
@@ -131,8 +131,8 @@ basic_memory/sync/sync_service.py,sha256=AxC5J1YTcPWTmA0HdzvOZBthi4-_LZ44kNF0KQo
131
131
  basic_memory/sync/watch_service.py,sha256=JAumrHUjV1lF9NtEK32jgg0myWBfLXotNXxONeIV9SM,15316
132
132
  basic_memory/templates/prompts/continue_conversation.hbs,sha256=trrDHSXA5S0JCbInMoUJL04xvCGRB_ku1RHNQHtl6ZI,3076
133
133
  basic_memory/templates/prompts/search.hbs,sha256=H1cCIsHKp4VC1GrH2KeUB8pGe5vXFPqb2VPotypmeCA,3098
134
- basic_memory-0.14.0b1.dist-info/METADATA,sha256=J0wpc3nuaEntf0KMuMgnNhQZC4L0ap2g5ST8c07QLO0,17226
135
- basic_memory-0.14.0b1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
136
- basic_memory-0.14.0b1.dist-info/entry_points.txt,sha256=wvE2mRF6-Pg4weIYcfQ-86NOLZD4WJg7F7TIsRVFLb8,90
137
- basic_memory-0.14.0b1.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
138
- basic_memory-0.14.0b1.dist-info/RECORD,,
134
+ basic_memory-0.14.2.dist-info/METADATA,sha256=h7tyu5dCVDkJYGeV4XPL2RbK7hL3CrKM9n5UlrUapWc,17639
135
+ basic_memory-0.14.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
136
+ basic_memory-0.14.2.dist-info/entry_points.txt,sha256=wvE2mRF6-Pg4weIYcfQ-86NOLZD4WJg7F7TIsRVFLb8,90
137
+ basic_memory-0.14.2.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
138
+ basic_memory-0.14.2.dist-info/RECORD,,