Class: Legion::MCP::ToolAdapter
- Inherits:
-
MCP::Tool
- Object
- MCP::Tool
- Legion::MCP::ToolAdapter
- Extended by:
- Logging::Helper
- Defined in:
- lib/legion/mcp/tool_adapter.rb
Overview
rubocop:disable Metrics/ClassLength
Constant Summary collapse
- MCP_NAME_PATTERN =
/[^a-zA-Z0-9_-]/
Class Method Summary collapse
- .from_legion_tool(tool_class) ⇒ Object
-
.from_registry_entry(entry) ⇒ Object
Builds an MCP tool from a Settings::Extensions registry entry hash.
- .sanitize_tool_name(name) ⇒ Object
Class Method Details
.from_legion_tool(tool_class) ⇒ Object
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/legion/mcp/tool_adapter.rb', line 15 def from_legion_tool(tool_class) safe_name = sanitize_tool_name(tool_class.tool_name) log.debug("[mcp][adapter] action=from_legion_tool tool=#{safe_name}") Class.new(::MCP::Tool) do tool_name safe_name description tool_class.description input_schema(tool_class.input_schema || { properties: {} }) define_singleton_method(:legion_tool_class) { tool_class } define_singleton_method(:call) do |**params| result = tool_class.call(**params) if result.is_a?(Hash) && result[:content] content = result[:content].map do |c| { type: c[:type] || 'text', text: c[:text] || '' } end ::MCP::Tool::Response.new(content, error: result[:error] || false) else text = result.is_a?(String) ? result : Legion::JSON.dump(result) error = result.is_a?(Hash) ? !!result[:error] : false ::MCP::Tool::Response.new([{ type: 'text', text: text }], error: error) end rescue StandardError => e Legion::MCP::ToolAdapter.handle_exception(e, level: :warn, operation: 'legion.mcp.tool_adapter.from_legion_tool') ::MCP::Tool::Response.new([{ type: 'text', text: Legion::JSON.dump({ error: e. }) }], error: true) end end end |
.from_registry_entry(entry) ⇒ Object
Builds an MCP tool from a Settings::Extensions registry entry hash. If the entry contains a loaded tool_class, delegates to from_legion_tool. Otherwise builds a thin adapter from the metadata alone.
48 49 50 51 52 53 54 55 56 |
# File 'lib/legion/mcp/tool_adapter.rb', line 48 def from_registry_entry(entry) tool_class = entry[:tool_class] dispatch = entry[:dispatch_type] log.debug("[mcp][adapter] action=from_registry_entry name=#{entry[:name]} " \ "dispatch_type=#{dispatch} has_class=#{!tool_class.nil?}") return from_legion_tool(tool_class) if tool_class.is_a?(Class) && tool_class.respond_to?(:tool_name) (entry) end |
.sanitize_tool_name(name) ⇒ Object
11 12 13 |
# File 'lib/legion/mcp/tool_adapter.rb', line 11 def sanitize_tool_name(name) name.to_s.gsub(MCP_NAME_PATTERN, '_').slice(0, 64) end |