mnemo-mcp 2.2.2b1__tar.gz → 2.2.2b2__tar.gz
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.
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/PKG-INFO +1 -1
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/pyproject.toml +1 -1
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/graph.py +1 -1
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/server.py +16 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/sync/delta.py +45 -23
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/.gitignore +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/LICENSE +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/README.md +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/__init__.py +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/__main__.py +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/alembic/README +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/alembic/env.py +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/alembic/script.py.mako +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/alembic/versions/baseline_001_existing_schema.py +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/alembic/versions/mem_001_context_types.py +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/alembic/versions/mem_002_compression.py +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/alembic/versions/mem_003_temporal.py +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/alembic.ini +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/capture.py +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/compression.py +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/config.py +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/credential_state.py +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/db.py +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/docs/__init__.py +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/docs/config.md +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/docs/memory.md +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/embedder.py +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/llm.py +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/py.typed +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/relay_schema.py +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/relay_setup.py +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/reranker.py +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/setup_tool.py +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/sync/__init__.py +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/sync/base.py +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/sync/bundle.py +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/sync/gdrive.py +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/sync/s3.py +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/temporal/__init__.py +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/temporal/extract.py +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/temporal/queries.py +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/temporal/resolve.py +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/temporal/store.py +0 -0
- {mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/token_store.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mnemo-mcp
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.2b2
|
|
4
4
|
Summary: Open-source MCP Server for persistent AI memory with embedded sync
|
|
5
5
|
Project-URL: Homepage, https://github.com/n24q02m/mnemo-mcp
|
|
6
6
|
Project-URL: Repository, https://github.com/n24q02m/mnemo-mcp.git
|
|
@@ -305,7 +305,7 @@ def create_relations(
|
|
|
305
305
|
|
|
306
306
|
def link_memory_entities(conn, memory_id: str, entity_ids: list[str]) -> None:
|
|
307
307
|
"""Link a memory to entities."""
|
|
308
|
-
if not entity_ids:
|
|
308
|
+
if not memory_id or not memory_id.strip() or not entity_ids:
|
|
309
309
|
return
|
|
310
310
|
|
|
311
311
|
try:
|
|
@@ -2146,6 +2146,14 @@ def save_summary(summary: str) -> str:
|
|
|
2146
2146
|
- Use when a conversation is concluding or shifting topics to persist key takeaways.
|
|
2147
2147
|
- Parameters: 'summary' (the consolidated text to save).
|
|
2148
2148
|
"""
|
|
2149
|
+
if not summary or not summary.strip():
|
|
2150
|
+
return _json(
|
|
2151
|
+
{
|
|
2152
|
+
"error": "Summary cannot be empty",
|
|
2153
|
+
"suggestion": "Provide a concise summary of the conversation to save as memory.",
|
|
2154
|
+
}
|
|
2155
|
+
)
|
|
2156
|
+
|
|
2149
2157
|
return (
|
|
2150
2158
|
f"Save this conversation summary as a memory:\n\n{summary}\n\n"
|
|
2151
2159
|
"Use the memory tool with action='add', category='context', "
|
|
@@ -2161,6 +2169,14 @@ def recall_context(topic: str) -> str:
|
|
|
2161
2169
|
- Use when starting a new task or answering a question to retrieve prior context.
|
|
2162
2170
|
- Parameters: 'topic' (the specific subject or keywords to search for).
|
|
2163
2171
|
"""
|
|
2172
|
+
if not topic or not topic.strip():
|
|
2173
|
+
return _json(
|
|
2174
|
+
{
|
|
2175
|
+
"error": "Topic cannot be empty",
|
|
2176
|
+
"suggestion": "Provide a specific topic or keyword to search for in your memories.",
|
|
2177
|
+
}
|
|
2178
|
+
)
|
|
2179
|
+
|
|
2164
2180
|
return (
|
|
2165
2181
|
f"Search your memories for relevant context about: {topic}\n\n"
|
|
2166
2182
|
"Use the memory tool with action='search' and this query. "
|
|
@@ -269,46 +269,50 @@ def _apply_kg_sections(db: MemoryDB, payload: dict[str, bytes]) -> dict:
|
|
|
269
269
|
cursor = db._conn.cursor()
|
|
270
270
|
|
|
271
271
|
ents_raw = payload.get("memories_entities.jsonl", b"").decode("utf-8")
|
|
272
|
+
entities_list = []
|
|
272
273
|
for line in ents_raw.splitlines():
|
|
273
274
|
line = line.strip()
|
|
274
275
|
if not line:
|
|
275
276
|
continue
|
|
276
277
|
try:
|
|
277
278
|
ent = json.loads(line)
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
cursor.execute(
|
|
282
|
-
"INSERT OR IGNORE INTO memory_entities "
|
|
283
|
-
"(id, name, entity_type, created_at, updated_at) "
|
|
284
|
-
"VALUES (?, ?, ?, ?, ?)",
|
|
279
|
+
if not isinstance(ent, dict):
|
|
280
|
+
continue
|
|
281
|
+
entities_list.append(
|
|
285
282
|
(
|
|
286
283
|
ent.get("id"),
|
|
287
284
|
ent.get("name"),
|
|
288
285
|
ent.get("entity_type"),
|
|
289
286
|
ent.get("created_at"),
|
|
290
287
|
ent.get("updated_at"),
|
|
291
|
-
)
|
|
288
|
+
)
|
|
289
|
+
)
|
|
290
|
+
except (json.JSONDecodeError, AttributeError):
|
|
291
|
+
continue
|
|
292
|
+
|
|
293
|
+
if entities_list:
|
|
294
|
+
try:
|
|
295
|
+
cursor.executemany(
|
|
296
|
+
"INSERT OR IGNORE INTO memory_entities "
|
|
297
|
+
"(id, name, entity_type, created_at, updated_at) "
|
|
298
|
+
"VALUES (?, ?, ?, ?, ?)",
|
|
299
|
+
entities_list,
|
|
292
300
|
)
|
|
293
301
|
counts["entities_applied"] += cursor.rowcount or 0
|
|
294
302
|
except Exception as e:
|
|
295
|
-
logger.debug(f"apply_bundle:
|
|
303
|
+
logger.debug(f"apply_bundle: entities skipped ({e})")
|
|
296
304
|
|
|
297
305
|
edges_raw = payload.get("memories_edges.jsonl", b"").decode("utf-8")
|
|
306
|
+
edges_list = []
|
|
298
307
|
for line in edges_raw.splitlines():
|
|
299
308
|
line = line.strip()
|
|
300
309
|
if not line:
|
|
301
310
|
continue
|
|
302
311
|
try:
|
|
303
312
|
edge = json.loads(line)
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
cursor.execute(
|
|
308
|
-
"INSERT OR IGNORE INTO memory_edges "
|
|
309
|
-
"(id, source_id, target_id, relation_type, created_at, "
|
|
310
|
-
" memory_id, valid_from, valid_to) "
|
|
311
|
-
"VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
|
|
313
|
+
if not isinstance(edge, dict):
|
|
314
|
+
continue
|
|
315
|
+
edges_list.append(
|
|
312
316
|
(
|
|
313
317
|
edge.get("id"),
|
|
314
318
|
edge.get("source_id"),
|
|
@@ -318,30 +322,48 @@ def _apply_kg_sections(db: MemoryDB, payload: dict[str, bytes]) -> dict:
|
|
|
318
322
|
edge.get("memory_id"),
|
|
319
323
|
edge.get("valid_from"),
|
|
320
324
|
edge.get("valid_to"),
|
|
321
|
-
)
|
|
325
|
+
)
|
|
326
|
+
)
|
|
327
|
+
except (json.JSONDecodeError, AttributeError):
|
|
328
|
+
continue
|
|
329
|
+
|
|
330
|
+
if edges_list:
|
|
331
|
+
try:
|
|
332
|
+
cursor.executemany(
|
|
333
|
+
"INSERT OR IGNORE INTO memory_edges "
|
|
334
|
+
"(id, source_id, target_id, relation_type, created_at, "
|
|
335
|
+
" memory_id, valid_from, valid_to) "
|
|
336
|
+
"VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
|
|
337
|
+
edges_list,
|
|
322
338
|
)
|
|
323
339
|
counts["edges_applied"] += cursor.rowcount or 0
|
|
324
340
|
except Exception as e:
|
|
325
|
-
logger.debug(f"apply_bundle:
|
|
341
|
+
logger.debug(f"apply_bundle: edges skipped ({e})")
|
|
326
342
|
|
|
327
343
|
links_raw = payload.get("memories_entity_links.jsonl", b"").decode("utf-8")
|
|
344
|
+
links_list = []
|
|
328
345
|
for line in links_raw.splitlines():
|
|
329
346
|
line = line.strip()
|
|
330
347
|
if not line:
|
|
331
348
|
continue
|
|
332
349
|
try:
|
|
333
350
|
link = json.loads(line)
|
|
334
|
-
|
|
351
|
+
if not isinstance(link, dict):
|
|
352
|
+
continue
|
|
353
|
+
links_list.append((link.get("memory_id"), link.get("entity_id")))
|
|
354
|
+
except (json.JSONDecodeError, AttributeError):
|
|
335
355
|
continue
|
|
356
|
+
|
|
357
|
+
if links_list:
|
|
336
358
|
try:
|
|
337
|
-
cursor.
|
|
359
|
+
cursor.executemany(
|
|
338
360
|
"INSERT OR IGNORE INTO memory_entity_links "
|
|
339
361
|
"(memory_id, entity_id) VALUES (?, ?)",
|
|
340
|
-
|
|
362
|
+
links_list,
|
|
341
363
|
)
|
|
342
364
|
counts["links_applied"] += cursor.rowcount or 0
|
|
343
365
|
except Exception as e:
|
|
344
|
-
logger.debug(f"apply_bundle:
|
|
366
|
+
logger.debug(f"apply_bundle: links skipped ({e})")
|
|
345
367
|
|
|
346
368
|
db._conn.commit()
|
|
347
369
|
return counts
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/alembic/versions/mem_001_context_types.py
RENAMED
|
File without changes
|
{mnemo_mcp-2.2.2b1 → mnemo_mcp-2.2.2b2}/src/mnemo_mcp/alembic/versions/mem_002_compression.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|