Module: RosettAi::Mcp::Governance
- Defined in:
- lib/rosett_ai/mcp/governance.rb
Overview
Centralized MCP tool, resource, and prompt registration.
Always loaded before plugins. Registers all built-in tools, resources, and prompts with the MCP server instance.
Constant Summary collapse
- TOOL_CLASSES =
[ Tools::ValidateTool, Tools::CompileTool, Tools::BehaviourListTool, Tools::BehaviourShowTool, Tools::BehaviourDisplayTool, Tools::BehaviourManageTool, Tools::DesignListTool, Tools::DesignShowTool, Tools::ConfigStatusTool, Tools::ConfigCompileTool, Tools::AdoptTool, Tools::ComplyTool, Tools::DoctorTool, Tools::EnginesTool, Tools::HooksStatusTool, Tools::LicenseStatusTool, Tools::ProjectTool, Tools::ProvenanceTool, Tools::ProvenanceWriteTool, Tools::ToolingTool, Tools::WorkflowTool, Tools::WorkflowExecuteTool, Tools::DocumentationStatusTool, Tools::InitTool, Tools::BackupTool, Tools::ContentTool, Tools::RetrofitTool ].freeze
- RESOURCE_CLASSES =
[ Resources::BehaviourResource, Resources::DesignResource, Resources::ProvenanceResource, Resources::ConfigResource ].freeze
- PROMPT_CLASSES =
[ Prompts::ValidationPrompt, Prompts::CompilationPrompt, Prompts::CompliancePrompt, Prompts::DiagnosticsPrompt ].freeze
- KEYWORD_PARAM_TYPES =
[:keyreq, :key].freeze
Class Method Summary collapse
- .build_kwargs(tool, args) ⇒ Object
- .find_resource_for_uri(resources, uri) ⇒ Object
- .register(server) ⇒ Object
- .register_prompts(server) ⇒ Object
- .register_resources(server) ⇒ Object
- .register_tool(server, klass) ⇒ Object
- .register_tools(server) ⇒ Object
- .resource_matches_uri?(resource, uri) ⇒ Boolean
Class Method Details
.build_kwargs(tool, args) ⇒ Object
127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/rosett_ai/mcp/governance.rb', line 127 def build_kwargs(tool, args) return {} unless args.is_a?(Hash) method_params = tool.method(:call).parameters param_names = method_params.filter_map { |type, name| name if KEYWORD_PARAM_TYPES.include?(type) } args.each_with_object({}) do |(key, value), kwargs| sym = key.to_sym kwargs[sym] = value if param_names.include?(sym) end end |
.find_resource_for_uri(resources, uri) ⇒ Object
117 118 119 |
# File 'lib/rosett_ai/mcp/governance.rb', line 117 def find_resource_for_uri(resources, uri) resources.find { |r| resource_matches_uri?(r, uri) } end |
.register(server) ⇒ Object
65 66 67 68 69 |
# File 'lib/rosett_ai/mcp/governance.rb', line 65 def register(server) register_tools(server) register_resources(server) register_prompts(server) end |
.register_prompts(server) ⇒ Object
89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/rosett_ai/mcp/governance.rb', line 89 def register_prompts(server) PROMPT_CLASSES.each do |klass| prompt = klass.new server.define_prompt( name: klass::PROMPT_NAME, description: klass::DESCRIPTION ) do |args| kwargs = (args || {}).transform_keys(&:to_sym) prompt.call(**kwargs) end end end |
.register_resources(server) ⇒ Object
77 78 79 80 81 82 83 84 85 86 |
# File 'lib/rosett_ai/mcp/governance.rb', line 77 def register_resources(server) resources = RESOURCE_CLASSES.map(&:new) server.resources_list_handler { resources.flat_map(&:list) } server.resources_read_handler do |uri:| resource_name = uri.split('/').last resource_class = find_resource_for_uri(resources, uri) result = resource_class&.read(resource_name) result&.fetch(:content, '') end end |
.register_tool(server, klass) ⇒ Object
104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/rosett_ai/mcp/governance.rb', line 104 def register_tool(server, klass) server.define_tool( name: klass::TOOL_NAME, description: klass::DESCRIPTION, annotations: klass::ANNOTATIONS ) do |args| tool = klass.new kwargs = build_kwargs(tool, args) result = kwargs.empty? ? tool.call : tool.call(**kwargs) JSON.generate(result) end end |
.register_tools(server) ⇒ Object
72 73 74 |
# File 'lib/rosett_ai/mcp/governance.rb', line 72 def register_tools(server) TOOL_CLASSES.each { |klass| register_tool(server, klass) } end |
.resource_matches_uri?(resource, uri) ⇒ Boolean
121 122 123 |
# File 'lib/rosett_ai/mcp/governance.rb', line 121 def resource_matches_uri?(resource, uri) resource.list.any? { |entry| entry[:uri] == uri } end |