Class: Otto::MCP::Registry

Inherits:
Object
  • Object
show all
Defined in:
lib/otto/mcp/registry.rb

Overview

Registry for managing MCP resources and tools

Instance Method Summary collapse

Constructor Details

#initializeRegistry

Returns a new instance of Registry.



12
13
14
15
# File 'lib/otto/mcp/registry.rb', line 12

def initialize
  @resources = {}
  @tools     = {}
end

Instance Method Details

#call_tool(name, arguments, env) ⇒ Object

Raises:



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/otto/mcp/registry.rb', line 75

def call_tool(name, arguments, env)
  tool = @tools[name]
  raise ToolNotFoundError, "Tool not found: #{name}" unless tool

  handler = tool[:handler]
  if handler.respond_to?(:call)
    result = handler.call(arguments, env)
  elsif handler.is_a?(String) && handler.include?('.')
    klass_method = handler.split('.')
    klass_name   = klass_method[0..-2].join('::')
    method_name  = klass_method.last

    klass  = Otto::Security::ConstantResolver.safe_const_get(klass_name)
    result = klass.public_send(method_name, arguments, env)
  else
    raise "Invalid tool handler: #{handler}"
  end

  {
    content: [{
      type: 'text',
      text: result.to_s,
    }],
  }
end

#list_resourcesObject



36
37
38
39
40
41
42
43
44
45
# File 'lib/otto/mcp/registry.rb', line 36

def list_resources
  @resources.values.map do |resource|
    {
      uri: resource[:uri],
      name: resource[:name],
      description: resource[:description],
      mimeType: resource[:mimeType],
    }
  end
end

#list_toolsObject



47
48
49
50
51
52
53
54
55
# File 'lib/otto/mcp/registry.rb', line 47

def list_tools
  @tools.values.map do |tool|
    {
      name: tool[:name],
      description: tool[:description],
      inputSchema: tool[:inputSchema],
    }
  end
end

#read_resource(uri) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/otto/mcp/registry.rb', line 57

def read_resource(uri)
  resource = @resources[uri]
  return nil unless resource

  # A handler that blows up propagates: it is an execution fault
  # (-32603/500), not a missing resource (-32001/404). Returning nil
  # here previously made the two indistinguishable to the protocol,
  # which owns the logging (Protocol#handle_resources_read).
  content = resource[:handler].call
  {
    contents: [{
      uri: uri,
      mimeType: resource[:mimeType],
      text: content.to_s,
    }],
  }
end

#register_resource(uri, name, description, mime_type, handler) ⇒ Object



17
18
19
20
21
22
23
24
25
# File 'lib/otto/mcp/registry.rb', line 17

def register_resource(uri, name, description, mime_type, handler)
  @resources[uri] = {
    uri: uri,
    name: name,
    description: description,
    mimeType: mime_type,
    handler: handler,
  }
end

#register_tool(name, description, input_schema, handler) ⇒ Object



27
28
29
30
31
32
33
34
# File 'lib/otto/mcp/registry.rb', line 27

def register_tool(name, description, input_schema, handler)
  @tools[name] = {
    name: name,
    description: description,
    inputSchema: input_schema,
    handler: handler,
  }
end