@danielsimonjr/memory-mcp 12.2.3 → 12.7.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.
@@ -2,7 +2,7 @@
2
2
  * MCP Tool Definitions
3
3
  *
4
4
  * Extracted from MCPServer.ts to reduce file size and improve maintainability.
5
- * Contains all 106 tool schemas for the Knowledge Graph MCP Server.
5
+ * Contains all 241 tool schemas for the Knowledge Graph MCP Server.
6
6
  *
7
7
  * @module server/toolDefinitions
8
8
  */
@@ -476,7 +476,7 @@ export const toolDefinitions = [
476
476
  // Phase 11 Sprint 2: Hybrid Search
477
477
  {
478
478
  name: 'hybrid_search',
479
- description: 'Search using combined semantic, lexical, and metadata signals. Provides better recall than single-signal search by fusing multiple relevance signals.',
479
+ description: 'Search using combined semantic, lexical, and metadata signals. Provides better recall than single-signal search by fusing multiple relevance signals. v3 additive options: graphWeight adds a graph-connectivity (PageRank) channel, expandNeighbors appends one-hop neighbors of top results, explain annotates results with evidence paths from query anchors, lookFor ranks expansion neighbors by a free-text connection description.',
480
480
  inputSchema: {
481
481
  type: 'object',
482
482
  properties: {
@@ -531,6 +531,27 @@ export const toolDefinitions = [
531
531
  additionalProperties: false,
532
532
  },
533
533
  limit: { type: 'number', description: 'Maximum results to return (default: 10)' },
534
+ graphWeight: {
535
+ type: 'number',
536
+ description: 'Weight for the graph-connectivity channel (normalized PageRank). 0/omitted = channel disabled (default)',
537
+ },
538
+ expandNeighbors: {
539
+ type: 'object',
540
+ description: 'One-hop neighbor expansion: neighbors of the top-K results are appended with a damped score and re-sorted',
541
+ properties: {
542
+ topK: { type: 'number', description: 'Number of top-ranked results to expand from (default: 10)' },
543
+ damping: { type: 'number', description: "Damping factor applied to the parent's combined score (default: 0.3)" },
544
+ },
545
+ additionalProperties: false,
546
+ },
547
+ explain: {
548
+ type: 'boolean',
549
+ description: 'Annotate each result with evidencePaths — graph paths connecting query anchor matches to the result (default: false)',
550
+ },
551
+ lookFor: {
552
+ type: 'string',
553
+ description: 'Free-text description of the desired connection; expansion neighbors are ranked by similarity to it (lookForScore)',
554
+ },
534
555
  },
535
556
  required: ['query'],
536
557
  additionalProperties: false,
@@ -1846,9 +1867,30 @@ export const toolDefinitions = [
1846
1867
  additionalProperties: false,
1847
1868
  },
1848
1869
  },
1849
- // Phase 13: Config tool
1850
- // TODO: set_project_scope requires server state management (activeProjectId on MCPServer)
1851
- // Skipped in this pass implement when MCPServer exposes mutable server state to handlers.
1870
+ // Phase 13 (v12.3.2 backport): Active project scope. Mutable per-server state stored in a
1871
+ // WeakMap keyed on ManagerContext (see toolHandlers.ts projectScopeMap). Handlers that
1872
+ // want to apply the active scope may call getActiveProjectScope(ctx).
1873
+ {
1874
+ name: 'set_project_scope',
1875
+ description: 'Set the active project scope for this server session. New entities passed without an explicit projectId may be auto-stamped with this value by scope-aware handlers; pass an empty string to clear the scope. Returns { projectId } where projectId is the new active scope (null when cleared).',
1876
+ inputSchema: {
1877
+ type: 'object',
1878
+ properties: {
1879
+ projectId: { type: 'string', description: 'Project ID to scope to. Empty string clears the active scope.' },
1880
+ },
1881
+ required: ['projectId'],
1882
+ additionalProperties: false,
1883
+ },
1884
+ },
1885
+ {
1886
+ name: 'get_project_scope',
1887
+ description: 'Returns the active project scope for this server session (set via set_project_scope). Returns { projectId } where projectId is null when no scope is active.',
1888
+ inputSchema: {
1889
+ type: 'object',
1890
+ properties: {},
1891
+ additionalProperties: false,
1892
+ },
1893
+ },
1852
1894
  // ==================== SESSION & WORKING MEMORY TOOLS ====================
1853
1895
  {
1854
1896
  name: 'session_start',
@@ -2605,6 +2647,958 @@ export const toolDefinitions = [
2605
2647
  additionalProperties: false,
2606
2648
  },
2607
2649
  },
2650
+ // ==================== v2.1.0 TOOL AFFORDANCE TOOLS ====================
2651
+ {
2652
+ name: 'record_tool_outcome',
2653
+ description: 'v2.1.0 — Record a single tool-call outcome directly via ToolAffordanceManager (bypasses ToolCallObserver). Creates the record on first call; appends to rolling window on subsequent. Throws "conflict" on concurrent writer mismatch.',
2654
+ inputSchema: {
2655
+ type: 'object',
2656
+ properties: {
2657
+ toolName: { type: 'string' },
2658
+ outcome: { type: 'string', enum: ['success', 'failure', 'partial'] },
2659
+ errorMessage: { type: 'string', description: 'Required when outcome is failure or partial (ranked in commonFailureModes).' },
2660
+ durationMs: { type: 'number', minimum: 0, description: 'Wall-clock duration. Optional.' },
2661
+ },
2662
+ required: ['toolName', 'outcome'],
2663
+ additionalProperties: false,
2664
+ },
2665
+ },
2666
+ {
2667
+ name: 'get_tool_affordance_stats',
2668
+ description: 'v2.1.0 — Flat rolling stats for a tool: success_rate, total_calls, common_failure_modes, avg_duration_ms.',
2669
+ inputSchema: {
2670
+ type: 'object',
2671
+ properties: { toolName: { type: 'string' } },
2672
+ required: ['toolName'],
2673
+ additionalProperties: false,
2674
+ },
2675
+ },
2676
+ {
2677
+ name: 'suggest_tool',
2678
+ description: 'v2.1.0 — Suggest tools matching a task hint, ranked by successRate × recency factor (1.0 at ≤1d, linearly decays to 0.1 at ≥30d).',
2679
+ inputSchema: {
2680
+ type: 'object',
2681
+ properties: {
2682
+ taskHint: { type: 'string', description: 'Substring matched against toolName.' },
2683
+ limit: { type: 'number', minimum: 1, description: 'Max candidates. Default 5.' },
2684
+ minScore: { type: 'number', minimum: 0, maximum: 1, description: 'Default 0.' },
2685
+ },
2686
+ required: ['taskHint'],
2687
+ additionalProperties: false,
2688
+ },
2689
+ },
2690
+ {
2691
+ name: 'list_tool_affordances',
2692
+ description: 'v2.1.0 — All recorded ToolAffordanceRecords.',
2693
+ inputSchema: { type: 'object', properties: {}, additionalProperties: false },
2694
+ },
2695
+ {
2696
+ name: 'remove_tool_affordance',
2697
+ description: 'v2.1.0 — Drop a tool-affordance record by toolName.',
2698
+ inputSchema: {
2699
+ type: 'object',
2700
+ properties: { toolName: { type: 'string' } },
2701
+ required: ['toolName'],
2702
+ additionalProperties: false,
2703
+ },
2704
+ },
2705
+ {
2706
+ name: 'observe_tool_start',
2707
+ description: 'v2.1.0 — Begin observing a tool call. Returns a callId the caller threads through observe_tool_complete / observe_tool_error / observe_tool_partial / observe_tool_cancel. Emits toolCall:start on the observer EventEmitter.',
2708
+ inputSchema: {
2709
+ type: 'object',
2710
+ properties: {
2711
+ toolName: { type: 'string' },
2712
+ args: { type: 'object', additionalProperties: true, description: 'Optional structured args for telemetry.' },
2713
+ },
2714
+ required: ['toolName'],
2715
+ additionalProperties: false,
2716
+ },
2717
+ },
2718
+ {
2719
+ name: 'observe_tool_complete',
2720
+ description: 'v2.1.0 — Record successful completion. Computes durationMs from observe_tool_start. No-op on unknown callId.',
2721
+ inputSchema: {
2722
+ type: 'object',
2723
+ properties: {
2724
+ callId: { type: 'string' },
2725
+ result: { type: 'string', description: 'Optional summary string for telemetry.' },
2726
+ },
2727
+ required: ['callId'],
2728
+ additionalProperties: false,
2729
+ },
2730
+ },
2731
+ {
2732
+ name: 'observe_tool_error',
2733
+ description: 'v2.1.0 — Record failure with an error message. No-op on unknown callId.',
2734
+ inputSchema: {
2735
+ type: 'object',
2736
+ properties: {
2737
+ callId: { type: 'string' },
2738
+ errorMessage: { type: 'string' },
2739
+ },
2740
+ required: ['callId', 'errorMessage'],
2741
+ additionalProperties: false,
2742
+ },
2743
+ },
2744
+ {
2745
+ name: 'observe_tool_partial',
2746
+ description: 'v2.1.0 — Record a partial result (tool returned a usable but incomplete result). No-op on unknown callId.',
2747
+ inputSchema: {
2748
+ type: 'object',
2749
+ properties: {
2750
+ callId: { type: 'string' },
2751
+ reason: { type: 'string' },
2752
+ },
2753
+ required: ['callId', 'reason'],
2754
+ additionalProperties: false,
2755
+ },
2756
+ },
2757
+ {
2758
+ name: 'observe_tool_cancel',
2759
+ description: 'v2.1.0 — Drop an in-flight observation without recording (e.g. user cancelled). No-op on unknown callId.',
2760
+ inputSchema: {
2761
+ type: 'object',
2762
+ properties: { callId: { type: 'string' } },
2763
+ required: ['callId'],
2764
+ additionalProperties: false,
2765
+ },
2766
+ },
2767
+ {
2768
+ name: 'tool_observer_in_flight_count',
2769
+ description: 'v2.1.0 — Diagnostic: number of in-flight (started but not yet completed) tool-call observations.',
2770
+ inputSchema: { type: 'object', properties: {}, additionalProperties: false },
2771
+ },
2772
+ // ==================== v2.1.0 HEURISTIC GUIDELINES TOOLS ====================
2773
+ {
2774
+ name: 'add_heuristic',
2775
+ description: 'v2.1.0 — Register a new condition→action heuristic. Storage-backed; default confidence 0.5. Pass an explicit content-addressed id (e.g. h_<sha256(condition|action)>) for caller-managed idempotency.',
2776
+ inputSchema: {
2777
+ type: 'object',
2778
+ properties: {
2779
+ condition: { type: 'string', description: 'Natural-language condition that triggers the action.' },
2780
+ action: { type: 'string', description: 'Recommended action when the condition matches.' },
2781
+ priority: { type: 'number', description: 'Tie-breaker when multiple match (higher wins).' },
2782
+ initialConfidence: { type: 'number', minimum: 0, maximum: 1, description: 'Default 0.5.' },
2783
+ importance: { type: 'number', minimum: 0, maximum: 10 },
2784
+ agentId: { type: 'string' },
2785
+ id: { type: 'string', description: 'Optional explicit id for idempotent registration.' },
2786
+ },
2787
+ required: ['condition', 'action'],
2788
+ additionalProperties: false,
2789
+ },
2790
+ },
2791
+ {
2792
+ name: 'get_heuristic',
2793
+ description: 'v2.1.0 — Sync lookup by HeuristicId.',
2794
+ inputSchema: {
2795
+ type: 'object',
2796
+ properties: { id: { type: 'string' } },
2797
+ required: ['id'],
2798
+ additionalProperties: false,
2799
+ },
2800
+ },
2801
+ {
2802
+ name: 'list_heuristics',
2803
+ description: 'v2.1.0 — All registered heuristics.',
2804
+ inputSchema: { type: 'object', properties: {}, additionalProperties: false },
2805
+ },
2806
+ {
2807
+ name: 'heuristic_count',
2808
+ description: 'v2.1.0 — Count of stored heuristics.',
2809
+ inputSchema: { type: 'object', properties: {}, additionalProperties: false },
2810
+ },
2811
+ {
2812
+ name: 'match_heuristics',
2813
+ description: 'v2.1.0 — Find heuristics whose condition matches input via Jaccard token-overlap × confidence; sorted descending, then by priority.',
2814
+ inputSchema: {
2815
+ type: 'object',
2816
+ properties: {
2817
+ input: { type: 'string', description: 'Text to match against heuristic conditions.' },
2818
+ limit: { type: 'number', minimum: 1, description: 'Max matches returned. Default 10.' },
2819
+ minScore: { type: 'number', minimum: 0, maximum: 1, description: 'Minimum score. Default 0.1.' },
2820
+ },
2821
+ required: ['input'],
2822
+ additionalProperties: false,
2823
+ },
2824
+ },
2825
+ {
2826
+ name: 'reinforce_heuristic',
2827
+ description: 'v2.1.0 — Record a successful application: bumps support; raises confidence asymptotically (new = old + (1-old)*0.1). OCC-protected — surfaces "conflict" when concurrent writer collides.',
2828
+ inputSchema: {
2829
+ type: 'object',
2830
+ properties: { id: { type: 'string' } },
2831
+ required: ['id'],
2832
+ additionalProperties: false,
2833
+ },
2834
+ },
2835
+ {
2836
+ name: 'record_heuristic_contradiction',
2837
+ description: 'v2.1.0 — Record a counter-example: bumps contradictions; lowers confidence (new = old - old*0.2). OCC-protected.',
2838
+ inputSchema: {
2839
+ type: 'object',
2840
+ properties: { id: { type: 'string' } },
2841
+ required: ['id'],
2842
+ additionalProperties: false,
2843
+ },
2844
+ },
2845
+ {
2846
+ name: 'detect_heuristic_conflicts',
2847
+ description: 'v2.1.0 — Pair-wise overlap/contradiction detection across stored heuristics. Surfaces overlap (same condition tokens, different actions) and contradiction (opposing actions on overlapping conditions; negation prefixes such as "do not" / "never" / "avoid").',
2848
+ inputSchema: { type: 'object', properties: {}, additionalProperties: false },
2849
+ },
2850
+ {
2851
+ name: 'remove_heuristic',
2852
+ description: 'v2.1.0 — Drop a heuristic by id.',
2853
+ inputSchema: {
2854
+ type: 'object',
2855
+ properties: { id: { type: 'string' } },
2856
+ required: ['id'],
2857
+ additionalProperties: false,
2858
+ },
2859
+ },
2860
+ {
2861
+ name: 'clear_heuristics',
2862
+ description: 'v2.1.0 — Drop every heuristic (across all entities of type "heuristic").',
2863
+ inputSchema: { type: 'object', properties: {}, additionalProperties: false },
2864
+ },
2865
+ // ==================== v2.1.0 PROJECT CONTEXT TOOLS ====================
2866
+ {
2867
+ name: 'upsert_project_context',
2868
+ description: 'v2.1.0 — Merge structured project knowledge into the ProjectContextRecord for `projectId`. Array fields (facts/conventions/commands/glossary) append + dedup; scalars overwrite. One record per projectId.',
2869
+ inputSchema: {
2870
+ type: 'object',
2871
+ properties: {
2872
+ projectId: { type: 'string', description: 'Project identifier (unique key).' },
2873
+ facts: { type: 'array', items: { type: 'string' } },
2874
+ conventions: { type: 'array', items: { type: 'string' } },
2875
+ commands: {
2876
+ type: 'array',
2877
+ items: {
2878
+ type: 'object',
2879
+ properties: {
2880
+ name: { type: 'string' },
2881
+ command: { type: 'string' },
2882
+ purpose: { type: 'string' },
2883
+ },
2884
+ required: ['name', 'command', 'purpose'],
2885
+ },
2886
+ },
2887
+ glossary: {
2888
+ type: 'array',
2889
+ items: {
2890
+ type: 'object',
2891
+ properties: {
2892
+ term: { type: 'string' },
2893
+ definition: { type: 'string' },
2894
+ },
2895
+ required: ['term', 'definition'],
2896
+ },
2897
+ },
2898
+ },
2899
+ required: ['projectId'],
2900
+ additionalProperties: false,
2901
+ },
2902
+ },
2903
+ {
2904
+ name: 'get_project_context',
2905
+ description: 'v2.1.0 — Sync lookup of the ProjectContextRecord for projectId.',
2906
+ inputSchema: {
2907
+ type: 'object',
2908
+ properties: { projectId: { type: 'string' } },
2909
+ required: ['projectId'],
2910
+ additionalProperties: false,
2911
+ },
2912
+ },
2913
+ {
2914
+ name: 'append_project_fact',
2915
+ description: 'v2.1.0 — Append one fact to a project context (auto-creates the record on first call; dedups).',
2916
+ inputSchema: {
2917
+ type: 'object',
2918
+ properties: { projectId: { type: 'string' }, fact: { type: 'string' } },
2919
+ required: ['projectId', 'fact'],
2920
+ additionalProperties: false,
2921
+ },
2922
+ },
2923
+ {
2924
+ name: 'append_project_convention',
2925
+ description: 'v2.1.0 — Append one convention to a project context (auto-creates; dedups).',
2926
+ inputSchema: {
2927
+ type: 'object',
2928
+ properties: { projectId: { type: 'string' }, convention: { type: 'string' } },
2929
+ required: ['projectId', 'convention'],
2930
+ additionalProperties: false,
2931
+ },
2932
+ },
2933
+ {
2934
+ name: 'append_project_command',
2935
+ description: 'v2.1.0 — Append a documented project command (dedup by name).',
2936
+ inputSchema: {
2937
+ type: 'object',
2938
+ properties: {
2939
+ projectId: { type: 'string' },
2940
+ name: { type: 'string', description: 'Short command name (e.g. "test").' },
2941
+ command: { type: 'string', description: 'The command line (e.g. "npm test").' },
2942
+ purpose: { type: 'string', description: 'What the command does.' },
2943
+ },
2944
+ required: ['projectId', 'name', 'command', 'purpose'],
2945
+ additionalProperties: false,
2946
+ },
2947
+ },
2948
+ {
2949
+ name: 'append_project_glossary_term',
2950
+ description: 'v2.1.0 — Append a glossary term (dedup by term).',
2951
+ inputSchema: {
2952
+ type: 'object',
2953
+ properties: {
2954
+ projectId: { type: 'string' },
2955
+ term: { type: 'string' },
2956
+ definition: { type: 'string' },
2957
+ },
2958
+ required: ['projectId', 'term', 'definition'],
2959
+ additionalProperties: false,
2960
+ },
2961
+ },
2962
+ {
2963
+ name: 'remove_project_fact',
2964
+ description: 'v2.1.0 — Remove a single fact. Returns true if found.',
2965
+ inputSchema: {
2966
+ type: 'object',
2967
+ properties: { projectId: { type: 'string' }, fact: { type: 'string' } },
2968
+ required: ['projectId', 'fact'],
2969
+ additionalProperties: false,
2970
+ },
2971
+ },
2972
+ {
2973
+ name: 'remove_project_convention',
2974
+ description: 'v2.1.0 — Remove a single convention. Returns true if found.',
2975
+ inputSchema: {
2976
+ type: 'object',
2977
+ properties: { projectId: { type: 'string' }, convention: { type: 'string' } },
2978
+ required: ['projectId', 'convention'],
2979
+ additionalProperties: false,
2980
+ },
2981
+ },
2982
+ {
2983
+ name: 'remove_project_command',
2984
+ description: 'v2.1.0 — Remove a command by name. Returns true if found.',
2985
+ inputSchema: {
2986
+ type: 'object',
2987
+ properties: { projectId: { type: 'string' }, commandName: { type: 'string' } },
2988
+ required: ['projectId', 'commandName'],
2989
+ additionalProperties: false,
2990
+ },
2991
+ },
2992
+ {
2993
+ name: 'remove_project_glossary_term',
2994
+ description: 'v2.1.0 — Remove a glossary entry by term. Returns true if found.',
2995
+ inputSchema: {
2996
+ type: 'object',
2997
+ properties: { projectId: { type: 'string' }, term: { type: 'string' } },
2998
+ required: ['projectId', 'term'],
2999
+ additionalProperties: false,
3000
+ },
3001
+ },
3002
+ {
3003
+ name: 'clear_project_context',
3004
+ description: 'v2.1.0 — Wipe the four arrays (facts/conventions/commands/glossary) for projectId; keeps the entity.',
3005
+ inputSchema: {
3006
+ type: 'object',
3007
+ properties: { projectId: { type: 'string' } },
3008
+ required: ['projectId'],
3009
+ additionalProperties: false,
3010
+ },
3011
+ },
3012
+ {
3013
+ name: 'format_project_context_for_llm',
3014
+ description: 'v2.1.0 — Render the ProjectContextRecord as a prose summary suitable for the wakeUp L0 layer or a system prompt. Honors budgetChars with ellipsis truncation.',
3015
+ inputSchema: {
3016
+ type: 'object',
3017
+ properties: {
3018
+ projectId: { type: 'string' },
3019
+ budgetChars: { type: 'number', minimum: 1, description: 'Character cap for the rendered prose.' },
3020
+ },
3021
+ required: ['projectId'],
3022
+ additionalProperties: false,
3023
+ },
3024
+ },
3025
+ // ==================== v2.1.0 DECISION RATIONALE TOOLS ====================
3026
+ {
3027
+ name: 'propose_decision',
3028
+ description: 'v2.1.0 — Propose a new architecture-decision-record (ADR-equivalent). Creates a "proposed" DecisionRecord. Default importance 8.',
3029
+ inputSchema: {
3030
+ type: 'object',
3031
+ properties: {
3032
+ context: { type: 'string', description: 'Problem-space description (the question the decision answers)' },
3033
+ decision: { type: 'string', description: 'The chosen path' },
3034
+ alternatives: { type: 'array', items: { type: 'string' }, description: 'Considered-but-not-chosen options. Default [].' },
3035
+ consequences: { type: 'array', items: { type: 'string' }, description: 'Anticipated downstream effects. Default [].' },
3036
+ relatedFiles: { type: 'array', items: { type: 'string' }, description: 'Optional paths to related ADRs / code.' },
3037
+ supersedes: { type: 'string', description: 'Optional backward link to the decision being replaced (DecisionId).' },
3038
+ sourceSessionId: { type: 'string' },
3039
+ sourceProjectId: { type: 'string' },
3040
+ importance: { type: 'number', minimum: 0, maximum: 10, description: 'Entity-level importance. Default 8.' },
3041
+ agentId: { type: 'string', description: 'Owning agent.' },
3042
+ },
3043
+ required: ['context', 'decision'],
3044
+ additionalProperties: false,
3045
+ },
3046
+ },
3047
+ {
3048
+ name: 'accept_decision',
3049
+ description: 'v2.1.0 — Transition a proposed decision to accepted. Returns one of: accepted | already-accepted | not-found | illegal-transition | conflict | vanished-mid-update.',
3050
+ inputSchema: {
3051
+ type: 'object',
3052
+ properties: { id: { type: 'string', description: 'DecisionId' } },
3053
+ required: ['id'],
3054
+ additionalProperties: false,
3055
+ },
3056
+ },
3057
+ {
3058
+ name: 'reject_decision',
3059
+ description: 'v2.1.0 — Transition a proposed decision to rejected with a reason. Returns rejected | already-rejected | not-found | illegal-transition | conflict | vanished-mid-update.',
3060
+ inputSchema: {
3061
+ type: 'object',
3062
+ properties: {
3063
+ id: { type: 'string', description: 'DecisionId' },
3064
+ reason: { type: 'string', description: 'Why the decision is being rejected.' },
3065
+ },
3066
+ required: ['id', 'reason'],
3067
+ additionalProperties: false,
3068
+ },
3069
+ },
3070
+ {
3071
+ name: 'supersede_decision',
3072
+ description: 'v2.1.0 — Mark an accepted decision as superseded by another. illegal-transition when target is not accepted. not-found when target or replacement is missing.',
3073
+ inputSchema: {
3074
+ type: 'object',
3075
+ properties: {
3076
+ id: { type: 'string', description: 'Decision being superseded' },
3077
+ by: { type: 'string', description: 'DecisionId of the replacement' },
3078
+ },
3079
+ required: ['id', 'by'],
3080
+ additionalProperties: false,
3081
+ },
3082
+ },
3083
+ {
3084
+ name: 'find_decisions_by_context',
3085
+ description: 'v2.1.0 — Substring search across context, decision, and consequences fields.',
3086
+ inputSchema: {
3087
+ type: 'object',
3088
+ properties: { query: { type: 'string', description: 'Substring to search for' } },
3089
+ required: ['query'],
3090
+ additionalProperties: false,
3091
+ },
3092
+ },
3093
+ {
3094
+ name: 'get_decision_chain',
3095
+ description: 'v2.1.0 — Walk the supersedes link backward from the supplied id to the original proposal. Returns chain oldest-first; cycle-protected.',
3096
+ inputSchema: {
3097
+ type: 'object',
3098
+ properties: { id: { type: 'string', description: 'Any DecisionId in the chain' } },
3099
+ required: ['id'],
3100
+ additionalProperties: false,
3101
+ },
3102
+ },
3103
+ {
3104
+ name: 'list_decisions',
3105
+ description: 'v2.1.0 — List decisions, optionally filtered by status / sourceSessionId / sourceProjectId.',
3106
+ inputSchema: {
3107
+ type: 'object',
3108
+ properties: {
3109
+ status: { type: 'string', enum: ['proposed', 'accepted', 'superseded', 'rejected'] },
3110
+ sourceSessionId: { type: 'string' },
3111
+ sourceProjectId: { type: 'string' },
3112
+ limit: { type: 'number', minimum: 1 },
3113
+ },
3114
+ additionalProperties: false,
3115
+ },
3116
+ },
3117
+ {
3118
+ name: 'get_decision',
3119
+ description: 'v2.1.0 — Sync lookup by DecisionId.',
3120
+ inputSchema: {
3121
+ type: 'object',
3122
+ properties: { id: { type: 'string', description: 'DecisionId' } },
3123
+ required: ['id'],
3124
+ additionalProperties: false,
3125
+ },
3126
+ },
3127
+ {
3128
+ name: 'export_decision_as_adr_markdown',
3129
+ description: 'v2.1.0 — Render a stored decision as ADR-format markdown (# title, Status, Context, Decision, Consequences bullet list, Alternatives bullet list, optional Supersedes link).',
3130
+ inputSchema: {
3131
+ type: 'object',
3132
+ properties: { id: { type: 'string', description: 'DecisionId' } },
3133
+ required: ['id'],
3134
+ additionalProperties: false,
3135
+ },
3136
+ },
3137
+ {
3138
+ name: 'parse_adr_markdown',
3139
+ description: 'v2.1.0 — Parse a hand-written or previously-exported ADR markdown into a DecisionInput shape (static; no persistence). Returns null when required Context or Decision sections are missing.',
3140
+ inputSchema: {
3141
+ type: 'object',
3142
+ properties: { text: { type: 'string', description: 'Raw ADR markdown text' } },
3143
+ required: ['text'],
3144
+ additionalProperties: false,
3145
+ },
3146
+ },
3147
+ // ==================== v2.1.0 do_not_remember (Exclusion) TOOLS ====================
3148
+ {
3149
+ name: 'add_exclusion_rule',
3150
+ description: 'v2.1.0 — Add a content-pattern exclusion rule (do_not_remember). Hard-deletes existing matches (per `scope`) and write-blocks future ones when consulted by upstream callers. v1 substring-only.',
3151
+ inputSchema: {
3152
+ type: 'object',
3153
+ properties: {
3154
+ pattern: { type: 'string', description: 'Substring to match (case-insensitive).' },
3155
+ scope: {
3156
+ type: 'string',
3157
+ enum: ['future-only', 'past-only', 'both'],
3158
+ description: 'When the rule applies. Default: both.',
3159
+ },
3160
+ entityType: { type: 'string', description: 'Optional restriction by entityType.' },
3161
+ reason: { type: 'string', description: 'Free-text justification (e.g. "GDPR request 2026-05-15").' },
3162
+ },
3163
+ required: ['pattern'],
3164
+ additionalProperties: false,
3165
+ },
3166
+ },
3167
+ {
3168
+ name: 'list_exclusion_rules',
3169
+ description: 'v2.1.0 — Return every registered ExclusionRule.',
3170
+ inputSchema: { type: 'object', properties: {}, additionalProperties: false },
3171
+ },
3172
+ {
3173
+ name: 'remove_exclusion_rule',
3174
+ description: 'v2.1.0 — Drop an exclusion rule by id. Does NOT restore previously deleted memories — the contract is "user said forget".',
3175
+ inputSchema: {
3176
+ type: 'object',
3177
+ properties: { id: { type: 'string', description: 'Rule id (exclusion-...)' } },
3178
+ required: ['id'],
3179
+ additionalProperties: false,
3180
+ },
3181
+ },
3182
+ {
3183
+ name: 'check_exclusion',
3184
+ description: 'v2.1.0 — Check whether content would be blocked by any active forward-blocking rule. Returns {blocked, ruleId?, reason?}. Past-only rules are skipped.',
3185
+ inputSchema: {
3186
+ type: 'object',
3187
+ properties: {
3188
+ content: { type: 'string', description: 'Content to test.' },
3189
+ entityType: { type: 'string', description: 'Optional entityType — narrows entityType-scoped rules.' },
3190
+ },
3191
+ required: ['content'],
3192
+ additionalProperties: false,
3193
+ },
3194
+ },
3195
+ {
3196
+ name: 'find_matching_memories_for_rule',
3197
+ description: 'v2.1.0 — Dry-run preview: return entities whose observations would match the candidate exclusion pattern. Does NOT persist the rule.',
3198
+ inputSchema: {
3199
+ type: 'object',
3200
+ properties: {
3201
+ pattern: { type: 'string', description: 'Candidate substring pattern.' },
3202
+ entityType: { type: 'string', description: 'Optional entityType restriction.' },
3203
+ },
3204
+ required: ['pattern'],
3205
+ additionalProperties: false,
3206
+ },
3207
+ },
3208
+ // ==================== v2.1.0 OBSERVATION DEDUP TOOLS ====================
3209
+ {
3210
+ name: 'find_duplicate_observations',
3211
+ description: 'v2.1.0 — Find verbatim duplicate observation strings across distinct entities (SHA-256 exact tier). Complementary to MemoryEngine.checkDuplicate (turn-level) and CompressionManager.findDuplicates (whole-entity). Report-only.',
3212
+ inputSchema: {
3213
+ type: 'object',
3214
+ properties: {
3215
+ entityType: {
3216
+ oneOf: [
3217
+ { type: 'string', description: 'Single entityType to include' },
3218
+ { type: 'array', items: { type: 'string' }, description: 'Multiple entityTypes to include' },
3219
+ ],
3220
+ description: 'Optional entityType filter (single or array). Omit to scan all.',
3221
+ },
3222
+ projectId: { type: 'string', description: 'Restrict to entities with this projectId.' },
3223
+ sessionId: { type: 'string', description: 'Restrict to entities with this sessionId.' },
3224
+ minOccurrences: { type: 'number', minimum: 2, description: 'Minimum occurrences to count as a group. Default 2.' },
3225
+ maxGroups: { type: 'number', minimum: 1, description: 'Cap on groups returned. Default 100.' },
3226
+ },
3227
+ additionalProperties: false,
3228
+ },
3229
+ },
3230
+ {
3231
+ name: 'find_jaccard_duplicate_observations',
3232
+ description: 'v2.1.0 — Find near-duplicate observation strings across distinct entities via token-Jaccard similarity with union-find grouping. More expensive than the exact tier (O(o²)); opt-in for higher recall.',
3233
+ inputSchema: {
3234
+ type: 'object',
3235
+ properties: {
3236
+ entityType: {
3237
+ oneOf: [
3238
+ { type: 'string' },
3239
+ { type: 'array', items: { type: 'string' } },
3240
+ ],
3241
+ },
3242
+ projectId: { type: 'string' },
3243
+ sessionId: { type: 'string' },
3244
+ minOccurrences: { type: 'number', minimum: 2 },
3245
+ maxGroups: { type: 'number', minimum: 1 },
3246
+ },
3247
+ additionalProperties: false,
3248
+ },
3249
+ },
3250
+ // ==================== v2.1.0 SPELL CORRECTION TOOLS ====================
3251
+ {
3252
+ name: 'spell_suggest',
3253
+ description: 'v2.1.0 — Suggest close matches for a (potentially misspelled) query over the vocabulary of entity names + tag values. Two-stage: bigram-Jaccard pre-filter (NGramIndex) + Levenshtein re-rank.',
3254
+ inputSchema: {
3255
+ type: 'object',
3256
+ properties: {
3257
+ query: { type: 'string', description: 'The (potentially misspelled) query string' },
3258
+ limit: { type: 'number', minimum: 1, description: 'Maximum corrections to return. Default 5.' },
3259
+ minScore: { type: 'number', minimum: 0, maximum: 1, description: 'Minimum final similarity score (1 - distance/maxLen). Default 0.4.' },
3260
+ maxDistance: { type: 'number', minimum: 0, description: 'Maximum Levenshtein edit distance to allow. Default 3.' },
3261
+ },
3262
+ required: ['query'],
3263
+ additionalProperties: false,
3264
+ },
3265
+ },
3266
+ {
3267
+ name: 'spell_rebuild_vocabulary',
3268
+ description: 'v2.1.0 — Force a rebuild of the SpellChecker vocabulary + n-gram index. Call after bulk entity churn; the lazy cache is otherwise correct for low-churn graphs.',
3269
+ inputSchema: {
3270
+ type: 'object',
3271
+ properties: {},
3272
+ additionalProperties: false,
3273
+ },
3274
+ },
3275
+ {
3276
+ name: 'spell_vocabulary_size',
3277
+ description: 'v2.1.0 — Return the count of unique terms in the SpellChecker vocabulary (entity names + tag values by default). Mostly diagnostic.',
3278
+ inputSchema: {
3279
+ type: 'object',
3280
+ properties: {},
3281
+ additionalProperties: false,
3282
+ },
3283
+ },
3284
+ // ==================== v12.5.0 ENGINEERING / DIAGNOSTIC TOOLS ====================
3285
+ // Parallel surface to the memoryjs CLI engineering commands (`memory diag`,
3286
+ // `memory check`, `memory reindex`, etc.). Useful when the MCP server is up
3287
+ // but the graph state is suspect.
3288
+ {
3289
+ name: 'diag',
3290
+ description: 'v12.5.0 — Runtime + storage diagnostic snapshot: node version, platform, storage path/type/size, entity + relation counts, ISO timestamp. Good first call when something feels off.',
3291
+ inputSchema: { type: 'object', properties: {}, additionalProperties: false },
3292
+ },
3293
+ {
3294
+ name: 'health',
3295
+ description: 'v12.5.0 — Fast integrity checks: storage:loadGraph, entities:distinct-names, relations:no-orphans, hierarchy:no-cycles-no-missing-parents. Returns per-check duration; ok=false when any check fails.',
3296
+ inputSchema: { type: 'object', properties: {}, additionalProperties: false },
3297
+ },
3298
+ {
3299
+ name: 'check_graph',
3300
+ description: 'v12.5.0 — Detect orphan relations (from/to references a missing entity), missing parents (entity.parentId references a missing entity), and hierarchy cycles. Reports findings. With apply=true, deletes orphan relations and clears missing parentIds; cycles are always reported but never auto-repaired (no safe default for which edge to break).',
3301
+ inputSchema: {
3302
+ type: 'object',
3303
+ properties: {
3304
+ apply: { type: 'boolean', description: 'When true, repair orphan relations + missing parentIds. Default false (dry-run).' },
3305
+ },
3306
+ additionalProperties: false,
3307
+ },
3308
+ },
3309
+ {
3310
+ name: 'reindex',
3311
+ description: 'v12.5.0 — Rebuild search-side indexes that may have drifted (TF-IDF/BM25 ranked + spell-checker vocabulary). Pass ranked=false or spell=false to scope. Returns per-target ok flag + durationMs.',
3312
+ inputSchema: {
3313
+ type: 'object',
3314
+ properties: {
3315
+ ranked: { type: 'boolean', description: 'Rebuild the ranked-search (TF-IDF/BM25) index (default true)' },
3316
+ spell: { type: 'boolean', description: 'Rebuild the spell-checker vocabulary (default true)' },
3317
+ },
3318
+ additionalProperties: false,
3319
+ },
3320
+ },
3321
+ {
3322
+ name: 'cache_stats',
3323
+ description: 'v12.5.0 — Per-tier snapshot of the global search caches (basic / ranked / boolean / fuzzy) showing hits / misses / size / hitRate. Process-local — every fresh server process starts at zero.',
3324
+ inputSchema: { type: 'object', properties: {}, additionalProperties: false },
3325
+ },
3326
+ {
3327
+ name: 'cache_clear',
3328
+ description: 'v12.5.0 — Bust all four global search caches. Idempotent; safe after manual graph edits to drop stale results.',
3329
+ inputSchema: { type: 'object', properties: {}, additionalProperties: false },
3330
+ },
3331
+ {
3332
+ name: 'graph_size',
3333
+ description: 'v12.5.0 — Graph + storage footprint: entity / relation / observation counts, distinct tag count, avg observations per entity, on-disk byte size + JSONL line count.',
3334
+ inputSchema: { type: 'object', properties: {}, additionalProperties: false },
3335
+ },
3336
+ {
3337
+ name: 'inspect_entity',
3338
+ description: 'v12.5.0 — Verbose snapshot of one entity: observations (resolved via ObservationManager so the column-store sidecar is consulted), outgoing + incoming relations, tags, importance, timestamps, parentId, immediate children, full ancestors. Errors when entity not found.',
3339
+ inputSchema: {
3340
+ type: 'object',
3341
+ properties: {
3342
+ name: { type: 'string', description: 'Entity name to inspect' },
3343
+ },
3344
+ required: ['name'],
3345
+ additionalProperties: false,
3346
+ },
3347
+ },
3348
+ {
3349
+ name: 'hierarchy_tree',
3350
+ description: 'v12.5.0 — Hierarchy tree as nested JSON. With an explicit root, returns just that subtree; without, returns all root entities. Useful for visualising parent/child structure.',
3351
+ inputSchema: {
3352
+ type: 'object',
3353
+ properties: {
3354
+ root: { type: 'string', description: 'Root entity name. Omit to return all root entities.' },
3355
+ },
3356
+ additionalProperties: false,
3357
+ },
3358
+ },
3359
+ {
3360
+ name: 'entity_neighbors',
3361
+ description: 'v12.5.0 — Incoming + outgoing relations for one entity, plus in/out degree counts. Lighter than inspect_entity when you only need the graph-topology view.',
3362
+ inputSchema: {
3363
+ type: 'object',
3364
+ properties: {
3365
+ name: { type: 'string', description: 'Entity name' },
3366
+ },
3367
+ required: ['name'],
3368
+ additionalProperties: false,
3369
+ },
3370
+ },
3371
+ // ==================== EVENT MEMORY TOOLS (memoryjs v3.0.0) ====================
3372
+ {
3373
+ name: 'record_event',
3374
+ description: 'Record an n-ary event: the action becomes a first-class event hub entity with role-typed relations (actor_of/targeted/occurred_in/participant_in). Missing endpoints auto-create as concept stubs. Optional flowKey groups events into a named flow.',
3375
+ inputSchema: {
3376
+ type: 'object',
3377
+ properties: {
3378
+ action: { type: 'string', description: 'The verb — what happened (e.g. "deployed", "approved")' },
3379
+ actor: { type: 'string', description: 'Entity name of who performed the action' },
3380
+ target: { type: 'string', description: 'Entity name the action was performed on' },
3381
+ context: { type: 'string', description: 'Entity name of where/within-what the event occurred' },
3382
+ participants: { type: 'array', items: { type: 'string' }, description: 'Additional participant entity names' },
3383
+ occurredAt: { type: 'string', description: 'ISO 8601 timestamp of when the event occurred' },
3384
+ flowKey: { type: 'string', description: 'Flow key grouping related events (case-insensitive)' },
3385
+ detail: { type: 'array', items: { type: 'string' }, description: 'Free-text detail observations attached to the event' },
3386
+ importance: { type: 'number', description: 'Importance score for the event entity' },
3387
+ },
3388
+ required: ['action', 'actor'],
3389
+ additionalProperties: false,
3390
+ },
3391
+ },
3392
+ {
3393
+ name: 'get_event',
3394
+ description: 'Load one recorded event by its entity name, joining the event hub with its role-typed relation endpoints (actor, target, context, participants).',
3395
+ inputSchema: {
3396
+ type: 'object',
3397
+ properties: {
3398
+ name: { type: 'string', description: 'Event entity name (as returned by record_event / query_events)' },
3399
+ },
3400
+ required: ['name'],
3401
+ additionalProperties: false,
3402
+ },
3403
+ },
3404
+ {
3405
+ name: 'query_events',
3406
+ description: 'Query recorded events by any combination of actor, target, action, flowKey, and inclusive time range. Results are chronologically ordered (occurredAt, falling back to createdAt). Uses relation/type indexes — never a full-graph scan.',
3407
+ inputSchema: {
3408
+ type: 'object',
3409
+ properties: {
3410
+ actor: { type: 'string', description: 'Filter by actor entity name' },
3411
+ target: { type: 'string', description: 'Filter by target entity name' },
3412
+ action: { type: 'string', description: 'Filter by action verb' },
3413
+ flowKey: { type: 'string', description: 'Filter by flow key' },
3414
+ timeRange: {
3415
+ type: 'object',
3416
+ properties: {
3417
+ start: { type: 'string', description: 'Inclusive lower bound (ISO 8601)' },
3418
+ end: { type: 'string', description: 'Inclusive upper bound (ISO 8601)' },
3419
+ },
3420
+ additionalProperties: false,
3421
+ description: 'Inclusive time range; either bound may be omitted',
3422
+ },
3423
+ limit: { type: 'number', description: 'Max events to return' },
3424
+ },
3425
+ additionalProperties: false,
3426
+ },
3427
+ },
3428
+ {
3429
+ name: 'get_event_flow',
3430
+ description: 'All events sharing a flow key (flow:<key> tag), chronologically ordered — the full timeline of a named flow (e.g. a release, an incident).',
3431
+ inputSchema: {
3432
+ type: 'object',
3433
+ properties: {
3434
+ flowKey: { type: 'string', description: 'Flow key (case-insensitive)' },
3435
+ },
3436
+ required: ['flowKey'],
3437
+ additionalProperties: false,
3438
+ },
3439
+ },
3440
+ {
3441
+ name: 'who_did_what',
3442
+ description: 'Convenience join answering "who did what (to target / in context / within time range)?" over recorded events. Returns actor + action + event tuples; events without a resolvable actor are omitted.',
3443
+ inputSchema: {
3444
+ type: 'object',
3445
+ properties: {
3446
+ target: { type: 'string', description: 'Filter by target entity name' },
3447
+ context: { type: 'string', description: 'Filter by context entity name' },
3448
+ timeRange: {
3449
+ type: 'object',
3450
+ properties: {
3451
+ start: { type: 'string', description: 'Inclusive lower bound (ISO 8601)' },
3452
+ end: { type: 'string', description: 'Inclusive upper bound (ISO 8601)' },
3453
+ },
3454
+ additionalProperties: false,
3455
+ description: 'Inclusive time range; either bound may be omitted',
3456
+ },
3457
+ limit: { type: 'number', description: 'Max entries to return' },
3458
+ },
3459
+ additionalProperties: false,
3460
+ },
3461
+ },
3462
+ // ==================== RECONSTRUCTIVE MEMORY TOOLS (memoryjs v3.0.0) ====================
3463
+ {
3464
+ name: 'ingest_dialogue',
3465
+ description: 'Distill raw dialogue turns into the Cue–Tag–Content associative memory graph (MRAgent-style "memory is reconstructed, not retrieved"). Episodic/semantic/topic layers are also persisted into the live knowledge graph. Multiple calls accumulate.',
3466
+ inputSchema: {
3467
+ type: 'object',
3468
+ properties: {
3469
+ turns: {
3470
+ type: 'array',
3471
+ items: {
3472
+ type: 'object',
3473
+ properties: {
3474
+ id: { type: 'string', description: 'Unique turn id' },
3475
+ speaker: { type: 'string', description: 'Speaker name' },
3476
+ text: { type: 'string', description: 'Turn text' },
3477
+ timestamp: { type: 'string', description: 'ISO 8601 timestamp' },
3478
+ },
3479
+ required: ['id', 'text'],
3480
+ additionalProperties: false,
3481
+ },
3482
+ description: 'Dialogue turns to distill and ingest',
3483
+ },
3484
+ },
3485
+ required: ['turns'],
3486
+ additionalProperties: false,
3487
+ },
3488
+ },
3489
+ {
3490
+ name: 'reconstruct_memory',
3491
+ description: 'Answer a query via active multi-step traversal of the reconstructive (Cue–Tag–Content) memory graph. Returns accumulated evidence, the step-by-step trajectory, and whether the loop stopped early on a satisfied condition vs. budget.',
3492
+ inputSchema: {
3493
+ type: 'object',
3494
+ properties: {
3495
+ query: { type: 'string', description: 'Query to reconstruct an answer for' },
3496
+ maxSteps: { type: 'number', description: 'Max reasoning turns (default 8)' },
3497
+ perStepBudget: { type: 'number', description: 'Max content nodes routed per step (default 10)' },
3498
+ evidenceTarget: { type: 'number', description: 'Stop once this many distinct evidence items accumulate (default 12)' },
3499
+ },
3500
+ required: ['query'],
3501
+ additionalProperties: false,
3502
+ },
3503
+ },
3504
+ {
3505
+ name: 'reconstructive_memory_stats',
3506
+ description: 'Size statistics of the reconstructive (Cue–Tag–Content) memory graph: cue / tag / content node counts and edge counts.',
3507
+ inputSchema: { type: 'object', properties: {}, additionalProperties: false },
3508
+ },
3509
+ // ==================== RELATION CONSOLIDATION TOOLS (memoryjs v3.0.0) ====================
3510
+ {
3511
+ name: 'analyze_relation_duplicates',
3512
+ description: 'Dry-run the three-tier relation janitor: tier 1 finds trivial relationType spelling variants (WorksAt/works-at/works_at) and redundant bidirectional mirrors; tier 2 (when an embedding provider is configured) finds semantically equivalent same-pair relations. Report-only — never mutates the graph.',
3513
+ inputSchema: { type: 'object', properties: {}, additionalProperties: false },
3514
+ },
3515
+ {
3516
+ name: 'consolidate_relations',
3517
+ description: 'Run relation-duplicate analysis and — when apply=true — merge tier 1+2 duplicate groups (delete variants, create the canonical survivor with summed confirmationCount). apply=false (default) is identical to analyze_relation_duplicates.',
3518
+ inputSchema: {
3519
+ type: 'object',
3520
+ properties: {
3521
+ apply: { type: 'boolean', description: 'Apply tier 1+2 merges (default false = dry-run)' },
3522
+ },
3523
+ additionalProperties: false,
3524
+ },
3525
+ },
3526
+ // ==================== AGENT REFLECTION TOOLS (memoryjs v3.0.0) ====================
3527
+ {
3528
+ name: 'create_reflection',
3529
+ description: 'Persist an agent reflection — a generalized lesson distilled from experience, backed by evidence entities. Deduplicated by evidence hash; scoped to session, project, or global.',
3530
+ inputSchema: {
3531
+ type: 'object',
3532
+ properties: {
3533
+ scope: { type: 'string', enum: ['session', 'project', 'global'], description: 'Generalization scope of the reflection' },
3534
+ summary: { type: 'string', description: 'The reflection text (non-empty)' },
3535
+ evidence: { type: 'array', items: { type: 'string' }, description: 'Entity names backing this reflection (non-empty)' },
3536
+ generalizationConfidence: { type: 'number', description: 'Confidence in [0.0, 1.0] that the lesson generalizes' },
3537
+ keyInsights: { type: 'array', items: { type: 'string' }, description: 'Top pattern strings (max 5)' },
3538
+ experienceType: { type: 'string', description: 'Experience type label (e.g. "success", "failure")' },
3539
+ sourceSessionId: { type: 'string', description: 'Session the reflection was distilled from' },
3540
+ sourceProjectId: { type: 'string', description: 'Project the reflection was distilled from' },
3541
+ importance: { type: 'number', description: 'Importance score for the reflection entity' },
3542
+ agentId: { type: 'string', description: 'Agent that authored the reflection' },
3543
+ },
3544
+ required: ['scope', 'summary', 'evidence', 'generalizationConfidence'],
3545
+ additionalProperties: false,
3546
+ },
3547
+ },
3548
+ {
3549
+ name: 'list_reflections',
3550
+ description: 'List stored agent reflections, filterable by scope, source session/project, and minimum generalization confidence. Archived reflections are excluded unless includeArchived is set.',
3551
+ inputSchema: {
3552
+ type: 'object',
3553
+ properties: {
3554
+ scope: { type: 'string', enum: ['session', 'project', 'global'], description: 'Filter by scope' },
3555
+ sourceSessionId: { type: 'string', description: 'Filter by source session' },
3556
+ sourceProjectId: { type: 'string', description: 'Filter by source project' },
3557
+ minConfidence: { type: 'number', description: 'Minimum generalization_confidence (inclusive)' },
3558
+ includeArchived: { type: 'boolean', description: 'Include archived reflections (default false)' },
3559
+ limit: { type: 'number', description: 'Max reflections to return' },
3560
+ },
3561
+ additionalProperties: false,
3562
+ },
3563
+ },
3564
+ {
3565
+ name: 'get_relevant_reflections',
3566
+ description: 'Reflections relevant to a session: matches by sourceSessionId, plus evidence overlap with the supplied session entity names. Use at session start to surface applicable past lessons.',
3567
+ inputSchema: {
3568
+ type: 'object',
3569
+ properties: {
3570
+ sessionId: { type: 'string', description: 'Session to find relevant reflections for' },
3571
+ sessionEntityNames: { type: 'array', items: { type: 'string' }, description: 'Entity names from the session for evidence-overlap matching' },
3572
+ minConfidence: { type: 'number', description: 'Minimum generalization_confidence (inclusive)' },
3573
+ limit: { type: 'number', description: 'Max reflections to return (default 10)' },
3574
+ },
3575
+ required: ['sessionId'],
3576
+ additionalProperties: false,
3577
+ },
3578
+ },
3579
+ {
3580
+ name: 'archive_reflection',
3581
+ description: 'Archive a reflection by id so it no longer appears in default listings or relevance matches (soft delete — the record is retained).',
3582
+ inputSchema: {
3583
+ type: 'object',
3584
+ properties: {
3585
+ id: { type: 'string', description: 'Reflection id to archive' },
3586
+ },
3587
+ required: ['id'],
3588
+ additionalProperties: false,
3589
+ },
3590
+ },
3591
+ // ==================== RECONSTRUCTIVE MEMORY PERSISTENCE TOOLS (memoryjs v3.0.0) ====================
3592
+ {
3593
+ name: 'save_reconstructive_memory',
3594
+ description: 'Serialize the in-memory Cue–Tag–Content reconstructive graph to a JSON sidecar next to the storage file (<basename>-reconstructive.json). The CTC graph is process-local; save before shutdown to survive restarts.',
3595
+ inputSchema: { type: 'object', properties: {}, additionalProperties: false },
3596
+ },
3597
+ {
3598
+ name: 'load_reconstructive_memory',
3599
+ description: 'Restore the Cue–Tag–Content reconstructive graph from the <basename>-reconstructive.json sidecar written by save_reconstructive_memory, replacing the current in-memory graph. Errors if no sidecar exists.',
3600
+ inputSchema: { type: 'object', properties: {}, additionalProperties: false },
3601
+ },
2608
3602
  ];
2609
3603
  // Tool categories are documented in CLAUDE.md for reference:
2610
3604
  // - Entity Operations: create_entities, delete_entities, read_graph, open_nodes