get-claudia 1.55.21 → 1.57.0

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 (38) hide show
  1. package/CHANGELOG.md +79 -0
  2. package/bin/index.js +213 -5
  3. package/bin/manifest-lib.js +245 -0
  4. package/memory-daemon/claudia_memory/daemon/health.py +1 -1
  5. package/memory-daemon/claudia_memory/daemon/scheduler.py +1 -1
  6. package/memory-daemon/claudia_memory/mcp/server.py +132 -123
  7. package/memory-daemon/claudia_memory/services/consolidate.py +1 -1
  8. package/memory-daemon/claudia_memory/services/remember.py +1 -1
  9. package/package.json +6 -2
  10. package/template-v2/.claude/hooks/__pycache__/post-tool-capture.cpython-313.pyc +0 -0
  11. package/template-v2/.claude/hooks/__pycache__/session-health-check.cpython-313.pyc +0 -0
  12. package/template-v2/.claude/hooks/__pycache__/user-prompt-capture.cpython-313.pyc +0 -0
  13. package/template-v2/.claude/hooks/hooks.json +11 -11
  14. package/template-v2/.claude/hooks/post-tool-capture.py +110 -10
  15. package/template-v2/.claude/hooks/pre-compact.py +4 -4
  16. package/template-v2/.claude/hooks/pre-compact.sh +1 -1
  17. package/template-v2/.claude/hooks/session-health-check.py +52 -4
  18. package/template-v2/.claude/hooks/session-summary.py +399 -0
  19. package/template-v2/.claude/hooks/user-prompt-capture.py +123 -0
  20. package/template-v2/.claude/manifest.json +73 -0
  21. package/template-v2/.claude/rules/claudia-principles.md +2 -2
  22. package/template-v2/.claude/rules/memory-availability.md +3 -3
  23. package/template-v2/.claude/rules/memory-commitment.md +92 -0
  24. package/template-v2/.claude/settings.local.json +26 -0
  25. package/template-v2/.claude/skills/capture-meeting/SKILL.md +6 -6
  26. package/template-v2/.claude/skills/capture-meeting/evals/basic.yaml +1 -1
  27. package/template-v2/.claude/skills/deep-context/SKILL.md +7 -7
  28. package/template-v2/.claude/skills/meditate/SKILL.md +10 -10
  29. package/template-v2/.claude/skills/meditate/evals/basic.yaml +1 -1
  30. package/template-v2/.claude/skills/meeting-prep/SKILL.md +3 -3
  31. package/template-v2/.claude/skills/memory-health/SKILL.md +1 -1
  32. package/template-v2/.claude/skills/memory-manager.md +85 -85
  33. package/template-v2/.claude/skills/morning-brief/SKILL.md +10 -10
  34. package/template-v2/.claude/skills/research/SKILL.md +2 -2
  35. package/template-v2/.claude/skills/skill-index.json +1 -1
  36. package/template-v2/CLAUDE.md +6 -6
  37. package/template-v2/.claude/hooks/__pycache__/pre-compact.cpython-313.pyc +0 -0
  38. package/template-v2/gitignore +0 -35
@@ -158,17 +158,17 @@ def _guard_response_size(text: str, tool_name: str) -> str:
158
158
  # They return a CallToolResult directly.
159
159
 
160
160
 
161
- @_handler("memory.temporal", "memory.upcoming", "memory.since", "memory.timeline", "memory.morning_context")
161
+ @_handler("memory_temporal", "memory_upcoming", "memory_since", "memory_timeline", "memory_morning_context")
162
162
  async def _handle_temporal(arguments, db, config, logger, **ctx):
163
163
  # Determine operation from merged tool or backward-compat alias
164
- name = ctx.get("tool_name", "memory.temporal")
165
- if name == "memory.upcoming":
164
+ name = ctx.get("tool_name", "memory_temporal")
165
+ if name == "memory_upcoming":
166
166
  op = "upcoming"
167
- elif name == "memory.since":
167
+ elif name == "memory_since":
168
168
  op = "since"
169
- elif name == "memory.timeline":
169
+ elif name == "memory_timeline":
170
170
  op = "timeline"
171
- elif name == "memory.morning_context":
171
+ elif name == "memory_morning_context":
172
172
  op = "morning"
173
173
  else:
174
174
  op = arguments.get("operation", "upcoming")
@@ -240,18 +240,18 @@ async def _handle_temporal(arguments, db, config, logger, **ctx):
240
240
  )
241
241
 
242
242
 
243
- @_handler("memory.graph", "memory.project_network", "memory.find_path", "memory.network_hubs", "memory.dormant_relationships", "memory.reconnections")
243
+ @_handler("memory_graph", "memory_project_network", "memory_find_path", "memory_network_hubs", "memory_dormant_relationships", "memory_reconnections")
244
244
  async def _handle_graph(arguments, db, config, logger, **ctx):
245
- name = ctx.get("tool_name", "memory.graph")
246
- if name == "memory.project_network":
245
+ name = ctx.get("tool_name", "memory_graph")
246
+ if name == "memory_project_network":
247
247
  op = "network"
248
- elif name == "memory.find_path":
248
+ elif name == "memory_find_path":
249
249
  op = "path"
250
- elif name == "memory.network_hubs":
250
+ elif name == "memory_network_hubs":
251
251
  op = "hubs"
252
- elif name == "memory.dormant_relationships":
252
+ elif name == "memory_dormant_relationships":
253
253
  op = "dormant"
254
- elif name == "memory.reconnections":
254
+ elif name == "memory_reconnections":
255
255
  op = "reconnect"
256
256
  else:
257
257
  op = arguments.get("operation", "network")
@@ -347,18 +347,18 @@ async def _handle_graph(arguments, db, config, logger, **ctx):
347
347
  )
348
348
 
349
349
 
350
- @_handler("memory.entities", "memory.entity", "memory.search_entities", "memory.merge_entities", "memory.delete_entity", "memory.entity_overview")
350
+ @_handler("memory_entities", "memory_entity", "memory_search_entities", "memory_merge_entities", "memory_delete_entity", "memory_entity_overview")
351
351
  async def _handle_entities(arguments, db, config, logger, **ctx):
352
- name = ctx.get("tool_name", "memory.entities")
353
- if name == "memory.entity":
352
+ name = ctx.get("tool_name", "memory_entities")
353
+ if name == "memory_entity":
354
354
  op = "create"
355
- elif name == "memory.search_entities":
355
+ elif name == "memory_search_entities":
356
356
  op = "search"
357
- elif name == "memory.merge_entities":
357
+ elif name == "memory_merge_entities":
358
358
  op = "merge"
359
- elif name == "memory.delete_entity":
359
+ elif name == "memory_delete_entity":
360
360
  op = "delete"
361
- elif name == "memory.entity_overview":
361
+ elif name == "memory_entity_overview":
362
362
  op = "overview"
363
363
  else:
364
364
  op = arguments.get("operation", "search")
@@ -438,16 +438,16 @@ async def _handle_entities(arguments, db, config, logger, **ctx):
438
438
  )
439
439
 
440
440
 
441
- @_handler("memory.vault", "memory.sync_vault", "memory.vault_status", "memory.generate_canvas", "memory.import_vault_edits")
441
+ @_handler("memory_vault", "memory_sync_vault", "memory_vault_status", "memory_generate_canvas", "memory_import_vault_edits")
442
442
  async def _handle_vault(arguments, db, config, logger, **ctx):
443
- name = ctx.get("tool_name", "memory.vault")
444
- if name == "memory.sync_vault":
443
+ name = ctx.get("tool_name", "memory_vault")
444
+ if name == "memory_sync_vault":
445
445
  op = "sync"
446
- elif name == "memory.vault_status":
446
+ elif name == "memory_vault_status":
447
447
  op = "status"
448
- elif name == "memory.generate_canvas":
448
+ elif name == "memory_generate_canvas":
449
449
  op = "canvas"
450
- elif name == "memory.import_vault_edits":
450
+ elif name == "memory_import_vault_edits":
451
451
  op = "import"
452
452
  else:
453
453
  op = arguments.get("operation", "status")
@@ -522,14 +522,14 @@ async def _handle_vault(arguments, db, config, logger, **ctx):
522
522
  )
523
523
 
524
524
 
525
- @_handler("memory.modify", "memory.correct", "memory.invalidate", "memory.invalidate_relationship")
525
+ @_handler("memory_modify", "memory_correct", "memory_invalidate", "memory_invalidate_relationship")
526
526
  async def _handle_modify(arguments, db, config, logger, **ctx):
527
- name = ctx.get("tool_name", "memory.modify")
528
- if name == "memory.correct":
527
+ name = ctx.get("tool_name", "memory_modify")
528
+ if name == "memory_correct":
529
529
  op = "correct"
530
- elif name == "memory.invalidate":
530
+ elif name == "memory_invalidate":
531
531
  op = "invalidate"
532
- elif name == "memory.invalidate_relationship":
532
+ elif name == "memory_invalidate_relationship":
533
533
  op = "invalidate_relationship"
534
534
  else:
535
535
  op = arguments.get("operation", "correct")
@@ -570,14 +570,14 @@ async def _handle_modify(arguments, db, config, logger, **ctx):
570
570
  )
571
571
 
572
572
 
573
- @_handler("memory.session", "memory.buffer_turn", "memory.session_context", "memory.unsummarized")
573
+ @_handler("memory_session", "memory_buffer_turn", "memory_session_context", "memory_unsummarized")
574
574
  async def _handle_session(arguments, db, config, logger, **ctx):
575
- name = ctx.get("tool_name", "memory.session")
576
- if name == "memory.buffer_turn":
575
+ name = ctx.get("tool_name", "memory_session")
576
+ if name == "memory_buffer_turn":
577
577
  op = "buffer"
578
- elif name == "memory.session_context":
578
+ elif name == "memory_session_context":
579
579
  op = "context"
580
- elif name == "memory.unsummarized":
580
+ elif name == "memory_unsummarized":
581
581
  op = "unsummarized"
582
582
  else:
583
583
  op = arguments.get("operation", "context")
@@ -614,14 +614,14 @@ async def _handle_session(arguments, db, config, logger, **ctx):
614
614
  )
615
615
 
616
616
 
617
- @_handler("memory.document", "memory.file", "memory.documents", "memory.purge")
617
+ @_handler("memory_document", "memory_file", "memory_documents", "memory_purge")
618
618
  async def _handle_document(arguments, db, config, logger, **ctx):
619
- name = ctx.get("tool_name", "memory.document")
620
- if name == "memory.file":
619
+ name = ctx.get("tool_name", "memory_document")
620
+ if name == "memory_file":
621
621
  op = "store"
622
- elif name == "memory.documents":
622
+ elif name == "memory_documents":
623
623
  op = "search"
624
- elif name == "memory.purge":
624
+ elif name == "memory_purge":
625
625
  op = "purge"
626
626
  else:
627
627
  op = arguments.get("operation", "search")
@@ -667,12 +667,12 @@ async def _handle_document(arguments, db, config, logger, **ctx):
667
667
  )
668
668
 
669
669
 
670
- @_handler("memory.provenance", "memory.trace", "memory.audit_history")
670
+ @_handler("memory_provenance", "memory_trace", "memory_audit_history")
671
671
  async def _handle_provenance(arguments, db, config, logger, **ctx):
672
- name = ctx.get("tool_name", "memory.provenance")
673
- if name == "memory.trace":
672
+ name = ctx.get("tool_name", "memory_provenance")
673
+ if name == "memory_trace":
674
674
  op = "trace"
675
- elif name == "memory.audit_history":
675
+ elif name == "memory_audit_history":
676
676
  op = "audit"
677
677
  else:
678
678
  op = arguments.get("operation", "trace")
@@ -739,11 +739,11 @@ async def _handle_provenance(arguments, db, config, logger, **ctx):
739
739
  )
740
740
 
741
741
 
742
- @_handler("memory.remember")
742
+ @_handler("memory_remember")
743
743
  async def _handle_remember(arguments, db, config, logger, **ctx):
744
744
  _coerce_arg(arguments, "about")
745
745
  memory_id = remember_fact(
746
- content=_require(arguments, "content", "memory.remember"),
746
+ content=_require(arguments, "content", "memory_remember"),
747
747
  memory_type=arguments.get("type", "fact"),
748
748
  about_entities=arguments.get("about"),
749
749
  importance=arguments.get("importance", 1.0),
@@ -774,7 +774,7 @@ async def _handle_remember(arguments, db, config, logger, **ctx):
774
774
  )
775
775
 
776
776
 
777
- @_handler("memory.recall")
777
+ @_handler("memory_recall")
778
778
  async def _handle_recall(arguments, db, config, logger, **ctx):
779
779
  _coerce_arg(arguments, "types")
780
780
  _coerce_arg(arguments, "ids")
@@ -802,7 +802,7 @@ async def _handle_recall(arguments, db, config, logger, **ctx):
802
802
  ]
803
803
  }
804
804
  )
805
- response_text = _guard_response_size(response_text, "memory.recall")
805
+ response_text = _guard_response_size(response_text, "memory_recall")
806
806
  return CallToolResult(
807
807
  content=[TextContent(type="text", text=response_text)]
808
808
  )
@@ -844,7 +844,7 @@ async def _handle_recall(arguments, db, config, logger, **ctx):
844
844
  ]
845
845
  }
846
846
  )
847
- response_text = _guard_response_size(response_text, "memory.recall")
847
+ response_text = _guard_response_size(response_text, "memory_recall")
848
848
  return CallToolResult(
849
849
  content=[TextContent(type="text", text=response_text)]
850
850
  )
@@ -869,17 +869,17 @@ async def _handle_recall(arguments, db, config, logger, **ctx):
869
869
  ]
870
870
  }
871
871
  )
872
- response_text = _guard_response_size(response_text, "memory.recall")
872
+ response_text = _guard_response_size(response_text, "memory_recall")
873
873
  return CallToolResult(
874
874
  content=[TextContent(type="text", text=response_text)]
875
875
  )
876
876
 
877
877
 
878
- @_handler("memory.about")
878
+ @_handler("memory_about")
879
879
  async def _handle_about(arguments, db, config, logger, **ctx):
880
880
  _coerce_int(arguments, "limit")
881
881
  result = recall_about(
882
- entity_name=_require(arguments, "entity", "memory.about"),
882
+ entity_name=_require(arguments, "entity", "memory_about"),
883
883
  limit=arguments.get("limit", 20),
884
884
  include_historical=arguments.get("include_historical", False),
885
885
  )
@@ -901,18 +901,18 @@ async def _handle_about(arguments, db, config, logger, **ctx):
901
901
  ]
902
902
 
903
903
  response_text = json.dumps(result)
904
- response_text = _guard_response_size(response_text, "memory.about")
904
+ response_text = _guard_response_size(response_text, "memory_about")
905
905
  return CallToolResult(
906
906
  content=[TextContent(type="text", text=response_text)]
907
907
  )
908
908
 
909
909
 
910
- @_handler("memory.relate")
910
+ @_handler("memory_relate")
911
911
  async def _handle_relate(arguments, db, config, logger, **ctx):
912
912
  relationship_id = relate_entities(
913
- source=_require(arguments, "source", "memory.relate"),
914
- target=_require(arguments, "target", "memory.relate"),
915
- relationship=_require(arguments, "relationship", "memory.relate"),
913
+ source=_require(arguments, "source", "memory_relate"),
914
+ target=_require(arguments, "target", "memory_relate"),
915
+ relationship=_require(arguments, "relationship", "memory_relate"),
916
916
  strength=arguments.get("strength", 1.0),
917
917
  valid_at=arguments.get("valid_at"),
918
918
  supersedes=arguments.get("supersedes", False),
@@ -929,7 +929,7 @@ async def _handle_relate(arguments, db, config, logger, **ctx):
929
929
  )
930
930
 
931
931
 
932
- @_handler("memory.consolidate")
932
+ @_handler("memory_consolidate")
933
933
  async def _handle_consolidate(arguments, db, config, logger, **ctx):
934
934
  result = run_full_consolidation()
935
935
  return CallToolResult(
@@ -942,7 +942,7 @@ async def _handle_consolidate(arguments, db, config, logger, **ctx):
942
942
  )
943
943
 
944
944
 
945
- @_handler("memory.end_session")
945
+ @_handler("memory_end_session")
946
946
  async def _handle_end_session(arguments, db, config, logger, **ctx):
947
947
  _coerce_int(arguments, "episode_id")
948
948
  # Coerce all array fields (LLMs may send JSON strings)
@@ -970,7 +970,7 @@ async def _handle_end_session(arguments, db, config, logger, **ctx):
970
970
 
971
971
  result = end_session(
972
972
  episode_id=episode_id,
973
- narrative=_require(arguments, "narrative", "memory.end_session"),
973
+ narrative=_require(arguments, "narrative", "memory_end_session"),
974
974
  facts=arguments.get("facts"),
975
975
  commitments=arguments.get("commitments"),
976
976
  entities=arguments.get("entities"),
@@ -1003,7 +1003,7 @@ async def _handle_end_session(arguments, db, config, logger, **ctx):
1003
1003
  )
1004
1004
 
1005
1005
 
1006
- @_handler("memory.reflections")
1006
+ @_handler("memory_reflections")
1007
1007
  async def _handle_reflections(arguments, db, config, logger, **ctx):
1008
1008
  _coerce_int(arguments, "limit")
1009
1009
  _coerce_int(arguments, "reflection_id")
@@ -1097,7 +1097,7 @@ async def _handle_reflections(arguments, db, config, logger, **ctx):
1097
1097
  )
1098
1098
 
1099
1099
 
1100
- @_handler("memory.batch")
1100
+ @_handler("memory_batch")
1101
1101
  async def _handle_batch(arguments, db, config, logger, **ctx):
1102
1102
  _coerce_arg(arguments, "operations")
1103
1103
  operations = arguments.get("operations", [])
@@ -1225,11 +1225,11 @@ async def _handle_ingest(arguments, db, config, logger, **ctx):
1225
1225
  )
1226
1226
 
1227
1227
 
1228
- @_handler("memory.multi_recall")
1228
+ @_handler("memory_multi_recall")
1229
1229
  async def _handle_multi_recall(arguments, db, config, logger, **ctx):
1230
1230
  """Execute multiple recall queries in a single call and return deduplicated results.
1231
1231
 
1232
- This is the compound equivalent of calling memory.recall N times sequentially.
1232
+ This is the compound equivalent of calling memory_recall N times sequentially.
1233
1233
  Saves N-1 model round trips and deduplicates overlapping results server-side.
1234
1234
  """
1235
1235
  _coerce_arg(arguments, "queries")
@@ -1309,11 +1309,11 @@ async def _handle_multi_recall(arguments, db, config, logger, **ctx):
1309
1309
  }
1310
1310
  text = json.dumps(response)
1311
1311
  return CallToolResult(
1312
- content=[TextContent(type="text", text=_guard_response_size(text, "memory.multi_recall"))]
1312
+ content=[TextContent(type="text", text=_guard_response_size(text, "memory_multi_recall"))]
1313
1313
  )
1314
1314
 
1315
1315
 
1316
- @_handler("memory.deep_context")
1316
+ @_handler("memory_deep_context")
1317
1317
  async def _handle_deep_context(arguments, db, config, logger, **ctx):
1318
1318
  """Server-side deep context assembly. Replaces 6-8 sequential MCP calls with one.
1319
1319
 
@@ -1321,7 +1321,7 @@ async def _handle_deep_context(arguments, db, config, logger, **ctx):
1321
1321
  temporal sweep + episode search. Deduplicates by memory ID across all steps.
1322
1322
  Returns a structured JSON object ready for synthesis.
1323
1323
  """
1324
- target = _require(arguments, "target", "memory.deep_context")
1324
+ target = _require(arguments, "target", "memory_deep_context")
1325
1325
  entity_limit = arguments.get("entity_limit", 50)
1326
1326
  recall_limit = arguments.get("recall_limit", 50)
1327
1327
  connected_limit = arguments.get("connected_limit", 10)
@@ -1488,11 +1488,11 @@ async def _handle_deep_context(arguments, db, config, logger, **ctx):
1488
1488
 
1489
1489
  text = json.dumps(result)
1490
1490
  return CallToolResult(
1491
- content=[TextContent(type="text", text=_guard_response_size(text, "memory.deep_context"))]
1491
+ content=[TextContent(type="text", text=_guard_response_size(text, "memory_deep_context"))]
1492
1492
  )
1493
1493
 
1494
1494
 
1495
- @_handler("memory.briefing")
1495
+ @_handler("memory_briefing")
1496
1496
  async def _handle_briefing(arguments, db, config, logger, **ctx):
1497
1497
  briefing_text = _build_briefing()
1498
1498
  return CallToolResult(
@@ -1505,7 +1505,7 @@ async def _handle_briefing(arguments, db, config, logger, **ctx):
1505
1505
  )
1506
1506
 
1507
1507
 
1508
- @_handler("memory.summary")
1508
+ @_handler("memory_summary")
1509
1509
  async def _handle_summary(arguments, db, config, logger, **ctx):
1510
1510
  _coerce_int(arguments, "top_facts_limit")
1511
1511
  entity_names = arguments.get("entities", [])
@@ -1601,7 +1601,7 @@ async def _handle_summary(arguments, db, config, logger, **ctx):
1601
1601
  )
1602
1602
 
1603
1603
 
1604
- @_handler("memory.system_health")
1604
+ @_handler("memory_system_health")
1605
1605
  async def _handle_system_health(arguments, db, config, logger, **ctx):
1606
1606
  import urllib.request, urllib.error
1607
1607
  report = None
@@ -1626,7 +1626,7 @@ async def _handle_system_health(arguments, db, config, logger, **ctx):
1626
1626
  )
1627
1627
 
1628
1628
 
1629
- @_handler("memory.backup")
1629
+ @_handler("memory_backup")
1630
1630
  async def _handle_backup(arguments, db, config, logger, **ctx):
1631
1631
  import urllib.request, urllib.error
1632
1632
  result = None
@@ -1650,11 +1650,11 @@ async def _handle_backup(arguments, db, config, logger, **ctx):
1650
1650
  )
1651
1651
 
1652
1652
 
1653
- @_handler("memory.project_health")
1653
+ @_handler("memory_project_health")
1654
1654
  async def _handle_project_health(arguments, db, config, logger, **ctx):
1655
1655
  _coerce_int(arguments, "days_ahead")
1656
1656
  from ..services.recall import project_relationship_health
1657
- entity = _require(arguments, "entity", "memory.project_health")
1657
+ entity = _require(arguments, "entity", "memory_project_health")
1658
1658
  days_ahead = arguments.get("days_ahead", 30)
1659
1659
  result = project_relationship_health(entity, days_ahead)
1660
1660
  return CallToolResult(
@@ -1662,13 +1662,13 @@ async def _handle_project_health(arguments, db, config, logger, **ctx):
1662
1662
  )
1663
1663
 
1664
1664
 
1665
- @_handler("memory.lifecycle")
1665
+ @_handler("memory_lifecycle")
1666
1666
  async def _handle_lifecycle(arguments, db, config, logger, **ctx):
1667
- op = _require(arguments, "operation", "memory.lifecycle")
1667
+ op = _require(arguments, "operation", "memory_lifecycle")
1668
1668
 
1669
1669
  if op == "set":
1670
- fact_id = _require(arguments, "fact_id", "memory.lifecycle")
1671
- tier = _require(arguments, "tier", "memory.lifecycle")
1670
+ fact_id = _require(arguments, "fact_id", "memory_lifecycle")
1671
+ tier = _require(arguments, "tier", "memory_lifecycle")
1672
1672
  reason = arguments.get("reason", "manual")
1673
1673
  if tier == "sacred":
1674
1674
  db.execute(
@@ -1690,7 +1690,7 @@ async def _handle_lifecycle(arguments, db, config, logger, **ctx):
1690
1690
  )
1691
1691
 
1692
1692
  elif op == "protect":
1693
- entity_name = _require(arguments, "entity", "memory.lifecycle")
1693
+ entity_name = _require(arguments, "entity", "memory_lifecycle")
1694
1694
  reason = arguments.get("reason", "user-designated")
1695
1695
  canonical = entity_name.strip().lower()
1696
1696
  row = db.execute(
@@ -1709,7 +1709,7 @@ async def _handle_lifecycle(arguments, db, config, logger, **ctx):
1709
1709
  )
1710
1710
 
1711
1711
  elif op == "archive":
1712
- fact_id = _require(arguments, "fact_id", "memory.lifecycle")
1712
+ fact_id = _require(arguments, "fact_id", "memory_lifecycle")
1713
1713
  db.execute(
1714
1714
  "UPDATE memories SET lifecycle_tier = 'archived', archived_at = datetime('now'), updated_at = datetime('now') WHERE fact_id = ?",
1715
1715
  (fact_id,),
@@ -1719,7 +1719,7 @@ async def _handle_lifecycle(arguments, db, config, logger, **ctx):
1719
1719
  )
1720
1720
 
1721
1721
  elif op == "restore":
1722
- fact_id = _require(arguments, "fact_id", "memory.lifecycle")
1722
+ fact_id = _require(arguments, "fact_id", "memory_lifecycle")
1723
1723
  db.execute(
1724
1724
  "UPDATE memories SET lifecycle_tier = 'active', archived_at = NULL, updated_at = datetime('now') WHERE fact_id = ?",
1725
1725
  (fact_id,),
@@ -1758,12 +1758,12 @@ async def _handle_lifecycle(arguments, db, config, logger, **ctx):
1758
1758
  )
1759
1759
 
1760
1760
 
1761
- @_handler("memory.context")
1761
+ @_handler("memory_context")
1762
1762
  async def _handle_context(arguments, db, config, logger, **ctx):
1763
1763
  from ..services.context_builder import build_context
1764
1764
  _coerce_int(arguments, "token_budget")
1765
1765
  result = build_context(
1766
- query=_require(arguments, "query", "memory.context"),
1766
+ query=_require(arguments, "query", "memory_context"),
1767
1767
  token_budget=arguments.get("token_budget", 8000),
1768
1768
  include_sacred=arguments.get("include_sacred", True),
1769
1769
  entity=arguments.get("entity"),
@@ -1773,9 +1773,9 @@ async def _handle_context(arguments, db, config, logger, **ctx):
1773
1773
  )
1774
1774
 
1775
1775
 
1776
- @_handler("memory.checkpoint")
1776
+ @_handler("memory_checkpoint")
1777
1777
  async def _handle_checkpoint(arguments, db, config, logger, **ctx):
1778
- op = _require(arguments, "operation", "memory.checkpoint")
1778
+ op = _require(arguments, "operation", "memory_checkpoint")
1779
1779
 
1780
1780
  if op == "save":
1781
1781
  name = arguments.get("name", "manual")
@@ -1819,12 +1819,12 @@ async def _handle_checkpoint(arguments, db, config, logger, **ctx):
1819
1819
  )
1820
1820
 
1821
1821
 
1822
- @_handler("memory.rollback")
1822
+ @_handler("memory_rollback")
1823
1823
  async def _handle_rollback(arguments, db, config, logger, **ctx):
1824
- op = _require(arguments, "operation", "memory.rollback")
1824
+ op = _require(arguments, "operation", "memory_rollback")
1825
1825
 
1826
1826
  if op == "set":
1827
- ts = _require(arguments, "timestamp", "memory.rollback")
1827
+ ts = _require(arguments, "timestamp", "memory_rollback")
1828
1828
  db.execute(
1829
1829
  "INSERT INTO _meta (key, value, updated_at) VALUES ('view_as_of', ?, datetime('now')) ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = datetime('now')",
1830
1830
  (ts,),
@@ -1855,6 +1855,15 @@ async def _handle_rollback(arguments, db, config, logger, **ctx):
1855
1855
  )
1856
1856
 
1857
1857
 
1858
+ # ── Backward compatibility: accept dot-notation names during transition ──
1859
+ # Users who haven't updated skills/hooks may still call memory.recall instead
1860
+ # of memory_recall. Register aliases so both work. list_tools() only advertises
1861
+ # underscore names; these aliases only affect call_tool() dispatch.
1862
+ # TODO: Remove after v1.58.0 (2 release cycles)
1863
+ _DOT_ALIASES = {k.replace("_", ".", 1): v for k, v in _TOOL_HANDLERS.items()
1864
+ if k.startswith("memory_")}
1865
+ _TOOL_HANDLERS.update(_DOT_ALIASES)
1866
+
1858
1867
  # Initialize the MCP server
1859
1868
  server = Server("claudia-memory")
1860
1869
 
@@ -1864,7 +1873,7 @@ async def list_tools() -> ListToolsResult:
1864
1873
  """List all available memory tools"""
1865
1874
  tools = [
1866
1875
  Tool(
1867
- name="memory.remember",
1876
+ name="memory_remember",
1868
1877
  title="Store a Memory",
1869
1878
  description="Store information in Claudia's memory. Use for facts, preferences, observations, or learnings about people, projects, or the user.",
1870
1879
  annotations=ToolAnnotations(destructiveHint=False),
@@ -1920,7 +1929,7 @@ async def list_tools() -> ListToolsResult:
1920
1929
  },
1921
1930
  ),
1922
1931
  Tool(
1923
- name="memory.recall",
1932
+ name="memory_recall",
1924
1933
  title="Search Memory",
1925
1934
  description=(
1926
1935
  "Search Claudia's memory for relevant information. Uses hybrid vector + full-text "
@@ -1967,7 +1976,7 @@ async def list_tools() -> ListToolsResult:
1967
1976
  },
1968
1977
  ),
1969
1978
  Tool(
1970
- name="memory.about",
1979
+ name="memory_about",
1971
1980
  title="Get Entity Context",
1972
1981
  description="Get all context about a specific person, project, or entity. Returns memories, relationships, and metadata.",
1973
1982
  annotations=ToolAnnotations(readOnlyHint=True),
@@ -1993,7 +2002,7 @@ async def list_tools() -> ListToolsResult:
1993
2002
  },
1994
2003
  ),
1995
2004
  Tool(
1996
- name="memory.relate",
2005
+ name="memory_relate",
1997
2006
  title="Create Relationship",
1998
2007
  description="Create or strengthen a relationship between two entities (people, projects, etc.)",
1999
2008
  annotations=ToolAnnotations(destructiveHint=False),
@@ -2041,7 +2050,7 @@ async def list_tools() -> ListToolsResult:
2041
2050
  },
2042
2051
  ),
2043
2052
  Tool(
2044
- name="memory.consolidate",
2053
+ name="memory_consolidate",
2045
2054
  title="Run Consolidation",
2046
2055
  description="Manually trigger memory consolidation (decay, merging, pattern detection). Usually runs automatically at 3 AM.",
2047
2056
  annotations=ToolAnnotations(destructiveHint=False),
@@ -2051,7 +2060,7 @@ async def list_tools() -> ListToolsResult:
2051
2060
  },
2052
2061
  ),
2053
2062
  Tool(
2054
- name="memory.end_session",
2063
+ name="memory_end_session",
2055
2064
  title="End Session",
2056
2065
  description=(
2057
2066
  "Finalize a session with a narrative summary and structured extractions. "
@@ -2222,7 +2231,7 @@ async def list_tools() -> ListToolsResult:
2222
2231
  },
2223
2232
  ),
2224
2233
  Tool(
2225
- name="memory.reflections",
2234
+ name="memory_reflections",
2226
2235
  title="Manage Reflections",
2227
2236
  description=(
2228
2237
  "Get or search persistent reflections (observations, patterns, learnings, questions) "
@@ -2273,14 +2282,14 @@ async def list_tools() -> ListToolsResult:
2273
2282
  },
2274
2283
  ),
2275
2284
  Tool(
2276
- name="memory.batch",
2285
+ name="memory_batch",
2277
2286
  title="Batch Memory Operations",
2278
2287
  description=(
2279
2288
  "Execute multiple memory operations in a single call. Use this for mid-session "
2280
2289
  "entity creation when processing a new person, meeting transcript, or topic that "
2281
2290
  "requires entity creation, multiple memories, and relationships. Much more efficient "
2282
- "than calling memory.entity, memory.remember, and memory.relate separately. "
2283
- "For end-of-session summaries, use memory.end_session instead."
2291
+ "than calling memory_entity, memory_remember, and memory_relate separately. "
2292
+ "For end-of-session summaries, use memory_end_session instead."
2284
2293
  ),
2285
2294
  annotations=ToolAnnotations(destructiveHint=False),
2286
2295
  inputSchema={
@@ -2381,11 +2390,11 @@ async def list_tools() -> ListToolsResult:
2381
2390
  },
2382
2391
  ),
2383
2392
  Tool(
2384
- name="memory.multi_recall",
2393
+ name="memory_multi_recall",
2385
2394
  title="Multi-Query Recall",
2386
2395
  description=(
2387
2396
  "Execute multiple recall queries in a single call. Returns deduplicated results "
2388
- "grouped by query. Use instead of calling memory.recall repeatedly when you need "
2397
+ "grouped by query. Use instead of calling memory_recall repeatedly when you need "
2389
2398
  "to search across several dimensions (e.g., different topics, entity types, or "
2390
2399
  "time-sensitive items). Saves round trips and deduplicates overlapping results "
2391
2400
  "server-side. Each query can specify its own limit, types filter, and entity filter."
@@ -2417,7 +2426,7 @@ async def list_tools() -> ListToolsResult:
2417
2426
  },
2418
2427
  ),
2419
2428
  Tool(
2420
- name="memory.deep_context",
2429
+ name="memory_deep_context",
2421
2430
  title="Deep Context Assembly",
2422
2431
  description=(
2423
2432
  "Full-context deep analysis in a single call. Executes the complete deep-context "
@@ -2425,7 +2434,7 @@ async def list_tools() -> ListToolsResult:
2425
2434
  "temporal sweep (observations/learnings/commitments), and episode search. "
2426
2435
  "Deduplicates by memory ID across all steps. Returns structured JSON ready for "
2427
2436
  "synthesis. Use for meeting prep, relationship deep dives, or strategic analysis. "
2428
- "Replaces 6-8 sequential memory.about/memory.recall calls with one compound call."
2437
+ "Replaces 6-8 sequential memory_about/memory_recall calls with one compound call."
2429
2438
  ),
2430
2439
  annotations=ToolAnnotations(readOnlyHint=True),
2431
2440
  inputSchema={
@@ -2470,13 +2479,13 @@ async def list_tools() -> ListToolsResult:
2470
2479
  },
2471
2480
  ),
2472
2481
  Tool(
2473
- name="memory.briefing",
2482
+ name="memory_briefing",
2474
2483
  title="Compact Briefing",
2475
2484
  description=(
2476
2485
  "Compact session briefing (~500 tokens). Returns aggregate counts and highlights: "
2477
2486
  "active commitments, cooling relationships, unread messages, top prediction, "
2478
2487
  "recent activity. Call at session start instead of loading full context. "
2479
- "Use memory.recall or memory.about to drill into specifics during conversation."
2488
+ "Use memory_recall or memory_about to drill into specifics during conversation."
2480
2489
  ),
2481
2490
  annotations=ToolAnnotations(readOnlyHint=True),
2482
2491
  inputSchema={
@@ -2521,12 +2530,12 @@ async def list_tools() -> ListToolsResult:
2521
2530
  },
2522
2531
  ),
2523
2532
  Tool(
2524
- name="memory.summary",
2533
+ name="memory_summary",
2525
2534
  title="Entity Summaries",
2526
2535
  description=(
2527
2536
  "Get a lightweight summary for one or more entities. Returns name, type, "
2528
2537
  "importance, memory count, relationship count, last mentioned date, and "
2529
- "top facts. Cheaper than memory.about for quick overviews."
2538
+ "top facts. Cheaper than memory_about for quick overviews."
2530
2539
  ),
2531
2540
  annotations=ToolAnnotations(readOnlyHint=True),
2532
2541
  inputSchema={
@@ -2547,7 +2556,7 @@ async def list_tools() -> ListToolsResult:
2547
2556
  },
2548
2557
  ),
2549
2558
  Tool(
2550
- name="memory.system_health",
2559
+ name="memory_system_health",
2551
2560
  title="System Health Check",
2552
2561
  description=(
2553
2562
  "Get comprehensive system health: schema version, component status, "
@@ -2561,7 +2570,7 @@ async def list_tools() -> ListToolsResult:
2561
2570
  },
2562
2571
  ),
2563
2572
  Tool(
2564
- name="memory.backup",
2573
+ name="memory_backup",
2565
2574
  title="Trigger Database Backup",
2566
2575
  description=(
2567
2576
  "Trigger an immediate backup of the memory database. Returns the path "
@@ -2574,7 +2583,7 @@ async def list_tools() -> ListToolsResult:
2574
2583
  },
2575
2584
  ),
2576
2585
  Tool(
2577
- name="memory.project_health",
2586
+ name="memory_project_health",
2578
2587
  title="Project Health Check",
2579
2588
  description=(
2580
2589
  "Project when a relationship will go dormant based on contact velocity. "
@@ -2601,7 +2610,7 @@ async def list_tools() -> ListToolsResult:
2601
2610
  ),
2602
2611
  # ── Merged tools (8 composite tools with operation parameter) ──
2603
2612
  Tool(
2604
- name="memory.temporal",
2613
+ name="memory_temporal",
2605
2614
  title="Temporal Queries",
2606
2615
  description=(
2607
2616
  "Time-based memory queries: upcoming deadlines, recent changes, entity timelines, "
@@ -2645,7 +2654,7 @@ async def list_tools() -> ListToolsResult:
2645
2654
  },
2646
2655
  ),
2647
2656
  Tool(
2648
- name="memory.graph",
2657
+ name="memory_graph",
2649
2658
  title="Relationship Graph",
2650
2659
  description=(
2651
2660
  "Explore the entity relationship graph: project networks, connection paths, "
@@ -2710,7 +2719,7 @@ async def list_tools() -> ListToolsResult:
2710
2719
  },
2711
2720
  ),
2712
2721
  Tool(
2713
- name="memory.entities",
2722
+ name="memory_entities",
2714
2723
  title="Entity Management",
2715
2724
  description=(
2716
2725
  "Create, search, merge, delete, or overview entities (people, projects, orgs). "
@@ -2795,7 +2804,7 @@ async def list_tools() -> ListToolsResult:
2795
2804
  },
2796
2805
  ),
2797
2806
  Tool(
2798
- name="memory.vault",
2807
+ name="memory_vault",
2799
2808
  title="Obsidian Vault",
2800
2809
  description=(
2801
2810
  "Manage the Obsidian vault integration: sync memory to vault, check status, "
@@ -2831,7 +2840,7 @@ async def list_tools() -> ListToolsResult:
2831
2840
  },
2832
2841
  ),
2833
2842
  Tool(
2834
- name="memory.modify",
2843
+ name="memory_modify",
2835
2844
  title="Modify Memories & Relationships",
2836
2845
  description=(
2837
2846
  "Correct, invalidate, or end relationships. "
@@ -2877,7 +2886,7 @@ async def list_tools() -> ListToolsResult:
2877
2886
  },
2878
2887
  ),
2879
2888
  Tool(
2880
- name="memory.session",
2889
+ name="memory_session",
2881
2890
  title="Session Lifecycle",
2882
2891
  description=(
2883
2892
  "Session management: buffer turns, load context, or check unsummarized sessions. "
@@ -2920,7 +2929,7 @@ async def list_tools() -> ListToolsResult:
2920
2929
  },
2921
2930
  ),
2922
2931
  Tool(
2923
- name="memory.document",
2932
+ name="memory_document",
2924
2933
  title="Document Storage",
2925
2934
  description=(
2926
2935
  "Store or search documents (transcripts, emails, files). "
@@ -2986,7 +2995,7 @@ async def list_tools() -> ListToolsResult:
2986
2995
  },
2987
2996
  ),
2988
2997
  Tool(
2989
- name="memory.provenance",
2998
+ name="memory_provenance",
2990
2999
  title="Provenance & Audit",
2991
3000
  description=(
2992
3001
  "Trace memory origins, get full audit trails, or verify hash chain integrity. "
@@ -3022,7 +3031,7 @@ async def list_tools() -> ListToolsResult:
3022
3031
  ),
3023
3032
  # ── Lifecycle / Sacred memory tools ──
3024
3033
  Tool(
3025
- name="memory.lifecycle",
3034
+ name="memory_lifecycle",
3026
3035
  title="Memory Lifecycle",
3027
3036
  description="Manage memory lifecycle tiers (sacred/active/cooling/archived) and entity close-circle status.",
3028
3037
  inputSchema={
@@ -3058,7 +3067,7 @@ async def list_tools() -> ListToolsResult:
3058
3067
  },
3059
3068
  ),
3060
3069
  Tool(
3061
- name="memory.context",
3070
+ name="memory_context",
3062
3071
  title="Build Context Window",
3063
3072
  description="Build a token-budgeted context window with sacred facts always included. Uses the Context Relevance Engine (CRE).",
3064
3073
  inputSchema={
@@ -3085,7 +3094,7 @@ async def list_tools() -> ListToolsResult:
3085
3094
  },
3086
3095
  ),
3087
3096
  Tool(
3088
- name="memory.checkpoint",
3097
+ name="memory_checkpoint",
3089
3098
  title="Database Checkpoints",
3090
3099
  description="Save, list, or restore database checkpoints (labeled backups).",
3091
3100
  inputSchema={
@@ -3105,7 +3114,7 @@ async def list_tools() -> ListToolsResult:
3105
3114
  },
3106
3115
  ),
3107
3116
  Tool(
3108
- name="memory.rollback",
3117
+ name="memory_rollback",
3109
3118
  title="Temporal Rollback",
3110
3119
  description="Set a temporal view filter so recall only returns memories created before a given timestamp. Non-destructive.",
3111
3120
  inputSchema={
@@ -3507,7 +3516,7 @@ def _build_session_context(token_budget: str = "normal") -> str:
3507
3516
  unsummarized = get_unsummarized_turns()
3508
3517
  if unsummarized:
3509
3518
  sections.append(f"## Unsummarized Sessions ({len(unsummarized)})\n")
3510
- sections.append("**Action needed:** Generate retroactive summaries using `memory.end_session` for each.\n")
3519
+ sections.append("**Action needed:** Generate retroactive summaries using `memory_end_session` for each.\n")
3511
3520
  for session in unsummarized:
3512
3521
  ep_id = session.get("episode_id", "?")
3513
3522
  turn_count = session.get("turn_count", 0)