Class: RailsAiContext::CLI::ToolRunner
- Inherits:
-
Object
- Object
- RailsAiContext::CLI::ToolRunner
- Defined in:
- lib/rails_ai_context/cli/tool_runner.rb
Overview
Runs MCP tools from the command line without requiring an MCP client. Reads tool schemas at runtime — no hardcoded parameter lists.
Usage:
runner = ToolRunner.new("schema", ["--table", "users", "--detail", "full"])
puts runner.run
runner = ToolRunner.new("schema", { table: "users", detail: "full" })
puts runner.run
Defined Under Namespace
Classes: InvalidArgumentError, ToolNotFoundError
Instance Attribute Summary collapse
-
#json_mode ⇒ Object
readonly
Returns the value of attribute json_mode.
-
#raw_args ⇒ Object
readonly
Returns the value of attribute raw_args.
-
#tool_class ⇒ Object
readonly
Returns the value of attribute tool_class.
Class Method Summary collapse
-
.available_tools ⇒ Object
Filtered tool list respecting skip_tools config.
-
.short_name(tool_name) ⇒ Object
Derive short name: rails_get_schema → schema, rails_analyze_feature → analyze_feature.
-
.tool_help(tool_class) ⇒ Object
Generate help for a specific tool from its input_schema.
-
.tool_list ⇒ Object
List all available tools with short names and descriptions.
Instance Method Summary collapse
-
#initialize(tool_name, raw_args, json_mode: false) ⇒ ToolRunner
constructor
A new instance of ToolRunner.
- #run ⇒ Object
Constructor Details
#initialize(tool_name, raw_args, json_mode: false) ⇒ ToolRunner
Returns a new instance of ToolRunner.
20 21 22 23 24 |
# File 'lib/rails_ai_context/cli/tool_runner.rb', line 20 def initialize(tool_name, raw_args, json_mode: false) @tool_class = resolve_tool(tool_name) @raw_args = raw_args @json_mode = json_mode end |
Instance Attribute Details
#json_mode ⇒ Object (readonly)
Returns the value of attribute json_mode.
18 19 20 |
# File 'lib/rails_ai_context/cli/tool_runner.rb', line 18 def json_mode @json_mode end |
#raw_args ⇒ Object (readonly)
Returns the value of attribute raw_args.
18 19 20 |
# File 'lib/rails_ai_context/cli/tool_runner.rb', line 18 def raw_args @raw_args end |
#tool_class ⇒ Object (readonly)
Returns the value of attribute tool_class.
18 19 20 |
# File 'lib/rails_ai_context/cli/tool_runner.rb', line 18 def tool_class @tool_class end |
Class Method Details
.available_tools ⇒ Object
Filtered tool list respecting skip_tools config.
49 50 51 52 53 54 55 |
# File 'lib/rails_ai_context/cli/tool_runner.rb', line 49 def self.available_tools skip = RailsAiContext.configuration.skip_tools tools = Server.builtin_tools tools += RailsAiContext.configuration.custom_tools return tools if skip.empty? tools.reject { |t| skip.include?(t.tool_name) } end |
.short_name(tool_name) ⇒ Object
Derive short name: rails_get_schema → schema, rails_analyze_feature → analyze_feature
90 91 92 |
# File 'lib/rails_ai_context/cli/tool_runner.rb', line 90 def self.short_name(tool_name) tool_name.sub(/\Arails_get_/, "").sub(/\Arails_/, "") end |
.tool_help(tool_class) ⇒ Object
Generate help for a specific tool from its input_schema.
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/rails_ai_context/cli/tool_runner.rb', line 58 def self.tool_help(tool_class) schema = tool_class.input_schema_value&.schema || {} properties = schema[:properties] || {} required = schema[:required] || [] lines = [ "#{tool_class.tool_name} — #{tool_class.description_value}", "", "Usage:", " rails 'ai:tool[#{short_name(tool_class.tool_name)}]' #{properties.keys.map { |k| "#{k}=VALUE" }.join(' ')}", " rails-ai-context tool #{short_name(tool_class.tool_name)} #{properties.keys.map { |k| "--#{k.to_s.tr('_', '-')} VALUE" }.join(' ')}", "" ] if properties.any? lines << "Options:" properties.each do |name, prop| flag = "--#{name.to_s.tr('_', '-')}" type_hint = prop[:type] || "string" type_hint = "#{type_hint} (#{prop[:enum].join('/')})" if prop[:enum] req = required.include?(name.to_s) ? " [required]" : "" desc = prop[:description] || "" lines << " #{flag.ljust(24)} #{desc} (#{type_hint})#{req}" end else lines << " No parameters." end lines.join("\n") end |
.tool_list ⇒ Object
List all available tools with short names and descriptions.
35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/rails_ai_context/cli/tool_runner.rb', line 35 def self.tool_list lines = [ "Available tools:", "" ] available_tools.each do |tool| short = short_name(tool.tool_name) desc = tool.description_value.to_s[0..79] lines << " #{short.ljust(24)} #{desc}" end lines << "" lines << "Usage: rails 'ai:tool[NAME]' param=value" lines << " rails-ai-context tool NAME --param value" lines.join("\n") end |
Instance Method Details
#run ⇒ Object
26 27 28 29 30 31 32 |
# File 'lib/rails_ai_context/cli/tool_runner.rb', line 26 def run kwargs = build_kwargs schema = tool_schema validate_kwargs!(kwargs, schema) response = tool_class.call(**kwargs) extract_output(response) end |