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



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

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



26
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
# File 'lib/action_mcp/resource_templates_registry.rb', line 26

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 = ResourceTemplate.registered_templates.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)


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

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