Class: AdminSuite::Mcp::Tools::ListRecords

Inherits:
MCP::Tool
  • Object
show all
Defined in:
lib/admin_suite/mcp/tools/list_records.rb

Class Method Summary collapse

Class Method Details

.build_query(config, filters, **params) ⇒ Object



39
40
41
42
43
44
45
# File 'lib/admin_suite/mcp/tools/list_records.rb', line 39

def self.build_query(config, filters, **params)
  AdminSuite::Query.new(
    resource_config: config,
    params: (filters || {}).merge(params.except(:q), search: params[:q]).compact,
    max_page_size: AdminSuite.config.mcp.max_page_size
  )
end

.call(resource:, server_context:, q: nil, filters: {}, sort: nil, direction: nil, page: 1, per_page: nil) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/admin_suite/mcp/tools/list_records.rb', line 22

def self.call(resource:, server_context:, q: nil, filters: {}, sort: nil, direction: nil, page: 1, per_page: nil)
  AdminSuite::Mcp.instrument(tool: "list_records", resource: resource, actor: server_context[:actor], request: server_context[:request], filters: filters, q: q) do
    allowed = false
    config = Authorization.authorize_resource!(name: resource, actor: server_context[:actor], action: :read, request: server_context[:request])
    next [Authorization.denied_response, nil, false] unless config

    allowed = true
    query = build_query(config, filters, q:, sort:, direction:, per_page:)
    payload = response_payload(resource, config, query, page)
    response = ::MCP::Tool::Response.new([{ type: "text", text: Serializer.dump(payload) }])
    [response, payload[:rows].size, true]
  rescue StandardError => e
    Rails.logger&.warn("AdminSuite MCP list_records failed: #{e.class}: #{e.message}")
    [Authorization.error_response("list_records failed"), nil, allowed]
  end
end

.paginated(query, page) ⇒ Object



57
58
59
60
61
62
63
# File 'lib/admin_suite/mcp/tools/list_records.rb', line 57

def self.paginated(query, page)
  offset = (page - 1) * query.per_page
  scope = query.scope
  return scope.offset(offset).limit(query.per_page) if scope.respond_to?(:offset)

  Array(scope).drop(offset).first(query.per_page)
end

.response_payload(resource, config, query, page) ⇒ Object



47
48
49
50
51
52
53
54
55
# File 'lib/admin_suite/mcp/tools/list_records.rb', line 47

def self.response_payload(resource, config, query, page)
  applied_page = page.to_i.clamp(1..)
  {
    resource: resource,
    page: applied_page,
    applied_per_page: query.per_page,
    rows: paginated(query, applied_page).map { |record| Serializer.index_row(record, config) }
  }
end