Class: ActionMCP::ResourceTemplatesRegistry

Inherits:
RegistryBase show all
Defined in:
lib/action_mcp/resource_templates_registry.rb

Overview

Registry for managing resource templates.

Class Method Summary collapse

Methods inherited from RegistryBase

clear!, find, items, non_abstract, re_register, register, size, unregister

Class Method Details

.extract_parameters(uri, template) ⇒ Object

Extract parameter values from a URI based on a template



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/action_mcp/resource_templates_registry.rb', line 107

def extract_parameters(uri, template)
  return {} unless uri_matches_template?(uri, template)

  uri_data = parse_uri(uri)
  template_data = parse_uri_template(template.uri_template)

  uri_segments = uri_data[:path].split("/")
  template_segments = template_data[:path].split("/")

  # Extract parameters
  params = {}
  template_segments.each_with_index do |template_segment, index|
    next unless template_segment.start_with?("{") && template_segment.end_with?("}")

    # Extract parameter name without braces
    param_name = template_segment[1...-1].to_sym
    params[param_name] = uri_segments[index]
  end

  params
end

.find_template_for_uri(uri) ⇒ Object

Find the most specific template for a given URI. Uses registry-backed source (not ResourceTemplate.registered_templates class array).



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/action_mcp/resource_templates_registry.rb', line 27

def find_template_for_uri(uri)
  parse_result = parse_uri(uri)
  return nil unless parse_result

  schema = parse_result[:schema]
  path = parse_result[:path]
  path_segments = path.split("/")

  matching_templates = resource_templates.values.select do |template|
    next unless template.uri_template

    # Parse the template
    template_data = parse_uri_template(template.uri_template)
    next unless template_data && template_data[:schema] == schema

    # Split template into segments and check if structure matches
    template_segments = template_data[:path].split("/")
    next unless template_segments.length == path_segments.length

    # Check if each segment matches (either static match or a parameter)
    segments_match = true

    template_segments.each_with_index do |template_segment, index|
      path_segment = path_segments[index]

      if template_segment.start_with?("{") && template_segment.end_with?("}")
        # This is a parameter segment, it matches any value
        next
      elsif template_segment != path_segment
        # Static segment doesn't match
        segments_match = false
        break
      end
    end

    segments_match
  end

  # If multiple templates match, select the most specific one
  # (the one with the most static segments)
  if matching_templates.size > 1
    matching_templates.max_by do |template|
      template_data = parse_uri_template(template.uri_template)
      template_segments = template_data[:path].split("/")

      # Count static segments (not parameters)
      template_segments.count { |segment| !segment.start_with?("{") }
    end
  elsif matching_templates.size == 1
    matching_templates.first
  end
end

.get_resource_template(template_name) ⇒ ActionMCP::ResourceTemplate

Retrieves a resource template by name.

Parameters:

  • template_name (String)

    The name of the resource template to retrieve.

Returns:

Raises:



17
18
19
# File 'lib/action_mcp/resource_templates_registry.rb', line 17

def get_resource_template(template_name)
  find(template_name)
end

.item_klassObject



21
22
23
# File 'lib/action_mcp/resource_templates_registry.rb', line 21

def item_klass
  ResourceTemplate
end

.uri_matches_template?(uri, template) ⇒ Boolean

Check if a URI matches a specific template

Returns:

  • (Boolean)


81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/action_mcp/resource_templates_registry.rb', line 81

def uri_matches_template?(uri, template)
  uri_data = parse_uri(uri)
  template_data = parse_uri_template(template.uri_template)

  return false unless uri_data && template_data && uri_data[:schema] == template_data[:schema]

  uri_segments = uri_data[:path].split("/")
  template_segments = template_data[:path].split("/")

  return false unless uri_segments.length == template_segments.length

  # Check each segment
  template_segments.each_with_index do |template_segment, index|
    uri_segment = uri_segments[index]

    # If template segment is a parameter, it matches anything
    next if template_segment.start_with?("{") && template_segment.end_with?("}")

    # Otherwise, segments must match exactly
    return false if template_segment != uri_segment
  end

  true
end