Module: ClaudeMemory::MCP::ToolHelpers

Included in:
Tools
Defined in:
lib/claude_memory/mcp/tool_helpers.rb

Overview

Shared utility methods for MCP tool implementations Reduces duplication across tool methods

Instance Method Summary collapse

Instance Method Details

#collect_undistilled_items(limit:, min_length: 200) ⇒ Array<Hash>

Collect undistilled content items from both stores (or legacy store)

Parameters:

  • limit (Integer)

    Maximum items to return

  • min_length (Integer) (defaults to: 200)

    Minimum byte_len to include

Returns:

  • (Array<Hash>)

    Undistilled items sorted by recency



91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/claude_memory/mcp/tool_helpers.rb', line 91

def collect_undistilled_items(limit:, min_length: 200)
  if @manager
    stores = []
    stores << @manager.project_store if @manager.project_exists?
    stores << @manager.global_store if @manager.global_exists?
    items = stores.flat_map { |s| s.undistilled_content_items(limit: limit, min_length: min_length) }
    items.sort_by { |i| i[:occurred_at] || "" }.reverse.first(limit)
  elsif @legacy_store
    @legacy_store.undistilled_content_items(limit: limit, min_length: min_length)
  else
    []
  end
end

#database_not_found_error(error) ⇒ Hash

Standard error response when database is not accessible

Parameters:

  • error (Exception)

    The caught database error

Returns:

  • (Hash)

    Formatted error response with recommendations



11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/claude_memory/mcp/tool_helpers.rb', line 11

def database_not_found_error(error)
  {
    error: "Database not found or not accessible",
    message: "ClaudeMemory may not be initialized. Run memory.check_setup for detailed status.",
    details: error.message,
    recommendations: [
      "Run memory.check_setup to diagnose the issue",
      "If not initialized, run: claude-memory init",
      "For help: claude-memory doctor"
    ]
  }
end

#extract_intent(args) ⇒ String?

Extract optional intent parameter for query disambiguation

Parameters:

  • args (Hash)

    Tool arguments

Returns:

  • (String, nil)

    Intent string or nil if not provided/blank



82
83
84
85
# File 'lib/claude_memory/mcp/tool_helpers.rb', line 82

def extract_intent(args)
  intent = args["intent"]
  (intent.nil? || intent.to_s.strip.empty?) ? nil : intent.to_s.strip
end

#extract_limit(args, default: 10) ⇒ Integer

Get default limit from arguments

Parameters:

  • args (Hash)

    Tool arguments

  • default (Integer) (defaults to: 10)

    Default limit if not specified

Returns:

  • (Integer)

    Limit value



75
76
77
# File 'lib/claude_memory/mcp/tool_helpers.rb', line 75

def extract_limit(args, default: 10)
  args["limit"] || default
end

#extract_scope(args, default: "all") ⇒ String

Get default scope from arguments

Parameters:

  • args (Hash)

    Tool arguments

  • default (String) (defaults to: "all")

    Default scope if not specified

Returns:

  • (String)

    Scope value



67
68
69
# File 'lib/claude_memory/mcp/tool_helpers.rb', line 67

def extract_scope(args, default: "all")
  args["scope"] || default
end

#find_store_for_content_item(content_item_id) ⇒ Store::SQLiteStore?

Find the store containing a given content item

Parameters:

  • content_item_id (Integer)

    Content item ID to locate

Returns:



108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/claude_memory/mcp/tool_helpers.rb', line 108

def find_store_for_content_item(content_item_id)
  if @manager
    if @manager.project_store&.content_items&.where(id: content_item_id)&.any?
      @manager.project_store
    elsif @manager.global_store&.content_items&.where(id: content_item_id)&.any?
      @manager.global_store
    end
  elsif @legacy_store
    if @legacy_store.content_items.where(id: content_item_id).any?
      @legacy_store
    end
  end
end

#format_fact(fact) ⇒ Hash

Format a fact hash for API response

Parameters:

  • fact (Hash)

    Fact record from database

Returns:

  • (Hash)

    Formatted fact with standard fields



27
28
29
30
31
32
33
34
35
36
# File 'lib/claude_memory/mcp/tool_helpers.rb', line 27

def format_fact(fact)
  {
    id: fact[:id],
    subject: fact[:subject_name],
    predicate: fact[:predicate],
    object: fact[:object_literal],
    status: fact[:status],
    scope: fact[:scope]
  }
end

#format_receipt(receipt) ⇒ Hash

Format a receipt hash for API response

Parameters:

  • receipt (Hash)

    Provenance record from database

Returns:

  • (Hash)

    Formatted receipt with quote and strength



41
42
43
44
45
46
# File 'lib/claude_memory/mcp/tool_helpers.rb', line 41

def format_receipt(receipt)
  {
    quote: receipt[:quote],
    strength: receipt[:strength]
  }
end

#format_result(result) ⇒ Hash

Format a result with fact and receipts

Parameters:

  • result (Hash)

    Result hash with :fact and :receipts keys

Returns:

  • (Hash)

    Formatted result with source



51
52
53
54
55
56
57
58
59
60
61
# File 'lib/claude_memory/mcp/tool_helpers.rb', line 51

def format_result(result)
  {
    id: result[:fact][:id],
    subject: result[:fact][:subject_name],
    predicate: result[:fact][:predicate],
    object: result[:fact][:object_literal],
    scope: result[:fact][:scope],
    source: result[:source],
    receipts: result[:receipts].map { |r| format_receipt(r) }
  }
end