Class: Boxcars::MCP::ToolBoxcar

Inherits:
Boxcar
  • Object
show all
Defined in:
lib/boxcars/mcp/tool_boxcar.rb

Overview

Wraps an MCP tool as a standard Boxcar so it can be used in Trains.

Constant Summary

Constants inherited from Boxcar

Boxcar::SCHEMA_KEY_ALIASES, Boxcar::TYPE_ALIASES

Instance Attribute Summary collapse

Attributes inherited from Boxcar

#description, #name, #parameters, #return_direct

Instance Method Summary collapse

Methods inherited from Boxcar

#apply, assi, #conduct, #conduct_result, hist, #output_keys, #run, #run_result, #schema, syst, #tool_call_name, #tool_definition, #tool_spec, user, #validate_inputs, #validate_outputs

Constructor Details

#initialize(mcp_client:, tool_name:, tool_description: nil, input_schema: {}, name_prefix: nil, **kwargs) ⇒ ToolBoxcar

Returns a new instance of ToolBoxcar.

Parameters:

  • mcp_client (Object)

    MCP client that responds to ‘call_tool`.

  • tool_name (String, Symbol)

    Name of the remote MCP tool.

  • tool_description (String, nil) (defaults to: nil)

    Human-readable tool description.

  • input_schema (Hash) (defaults to: {})

    MCP input schema for the tool.

  • name_prefix (String, nil) (defaults to: nil)

    Optional prefix for local boxcar naming.

  • kwargs (Hash)

    Standard Boxcar options.



17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/boxcars/mcp/tool_boxcar.rb', line 17

def initialize(mcp_client:, tool_name:, tool_description: nil, input_schema: {}, name_prefix: nil, **kwargs)
  @mcp_client = mcp_client
  @tool_name = tool_name.to_s
  @tool_description = tool_description.to_s.strip
  @tool_description = "MCP tool #{@tool_name}" if @tool_description.empty?
  @input_schema = deep_stringify(input_schema || {})

  kwargs[:name] ||= [name_prefix, @tool_name].compact.join(": ")
  kwargs[:description] ||= @tool_description
  kwargs[:parameters] ||= mcp_schema_to_parameters(@input_schema)
  super(**kwargs)
end

Instance Attribute Details

#input_schemaObject (readonly)

Returns the value of attribute input_schema.



9
10
11
# File 'lib/boxcars/mcp/tool_boxcar.rb', line 9

def input_schema
  @input_schema
end

#mcp_clientObject (readonly)

Returns the value of attribute mcp_client.



9
10
11
# File 'lib/boxcars/mcp/tool_boxcar.rb', line 9

def mcp_client
  @mcp_client
end

#tool_descriptionObject (readonly)

Returns the value of attribute tool_description.



9
10
11
# File 'lib/boxcars/mcp/tool_boxcar.rb', line 9

def tool_description
  @tool_description
end

#tool_nameObject (readonly)

Returns the value of attribute tool_name.



9
10
11
# File 'lib/boxcars/mcp/tool_boxcar.rb', line 9

def tool_name
  @tool_name
end

Instance Method Details

#call(inputs:) ⇒ Hash

Execute one MCP tool call.

Parameters:

  • inputs (Hash)

    Tool arguments to forward to MCP.

Returns:

  • (Hash)

    ‘{ answer: Boxcars::Result }`.



33
34
35
36
37
# File 'lib/boxcars/mcp/tool_boxcar.rb', line 33

def call(inputs:)
  payload = mcp_client.call_tool(name: tool_name, arguments: stringify_keys(inputs))
  result = mcp_payload_to_result(payload)
  { answer: result }
end

#input_keysArray<Symbol>

Returns Tool parameter names accepted by this boxcar.

Returns:

  • (Array<Symbol>)

    Tool parameter names accepted by this boxcar.



40
41
42
# File 'lib/boxcars/mcp/tool_boxcar.rb', line 40

def input_keys
  parameters.keys
end

#parameters_json_schemaHash

Prefer the MCP-provided schema over the legacy parameter map.

Returns:

  • (Hash)

    JSON Schema compatible input schema.



46
47
48
49
50
51
52
53
# File 'lib/boxcars/mcp/tool_boxcar.rb', line 46

def parameters_json_schema
  schema = deep_stringify(input_schema)
  return super if schema.empty?

  schema["type"] ||= "object"
  schema["properties"] ||= {}
  schema
end