Class: LittleGhost::MCP::Toolset
- Inherits:
-
Object
- Object
- LittleGhost::MCP::Toolset
- Extended by:
- Support::ClassAttributes
- Defined in:
- lib/little_ghost/mcp/toolset.rb
Overview
Connects one MCP server to an Agent as a reusable Tool provider. Each Agent
run gets its own connection. map_tool chooses and configures the generated
Tool classes; map_result converts results that need application-specific
handling.
class HelpCenterTools < LittleGhost::MCP::Toolset
connection url: "https://mcp.example/rpc", timeout: 20
end
class CustomerSupportAgent < LittleGhost::Agent
tools HelpCenterTools
end
Defined Under Namespace
Classes: CallbackFailure
Constant Summary collapse
- CONNECTION_OPTIONS =
:nodoc:
%i[url headers timeout signer allow_insecure_http max_response_bytes].freeze
- UNSET =
:nodoc:
Object.new.freeze
Class Method Summary collapse
-
.connection(value = UNSET, &resolver) ⇒ Object
Declares a static connection Hash or a block called with the current Tool::Binding.
-
.map_result(&mapping) ⇒ Object
Maps each immutable MCP::Result.
-
.map_tool(&mapping) ⇒ Object
Maps each generated Tool class.
-
.on_error(&callback) ⇒ Object
Observes an expected discovery failure caught by optional true.
-
.optional(value = UNSET) ⇒ Object
Makes expected provider and protocol discovery failures produce no tools.
-
.tools(binding) ⇒ Object
Generates Tool classes for an Agent's current binding.
Methods included from Support::ClassAttributes
Class Method Details
.connection(value = UNSET, &resolver) ⇒ Object
Declares a static connection Hash or a block called with the current
Tool::Binding. The Hash requires url and may include
headers, timeout, signer, allow_insecure_http, and
max_response_bytes.
:call-seq:
connection() -> Hash, Proc, nil
connection(values) -> Hash
connection { |binding| ... } -> Proc
48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/little_ghost/mcp/toolset.rb', line 48 def connection(value = UNSET, &resolver) return connection_value if value.equal?(UNSET) && !resolver raise ArgumentError, "provide a connection or a block, not both" unless value.equal?(UNSET) || !resolver configured = resolver || value unless configured.is_a?(Hash) || configured.respond_to?(:call) raise ArgumentError, "connection must be a hash or callable" end self.connection_value = configured.is_a?(Hash) ? normalize_connection(configured) : configured end |
.map_result(&mapping) ⇒ Object
Maps each immutable MCP::Result. The block receives call: and
binding: keywords and returns any Ruby value or Tool::Result.
:call-seq:
map_result() -> Proc, nil
map_result { |result, call:, binding:| ... } -> Proc
80 81 82 83 84 |
# File 'lib/little_ghost/mcp/toolset.rb', line 80 def map_result(&mapping) return result_mapping_value unless mapping self.result_mapping_value = mapping end |
.map_tool(&mapping) ⇒ Object
Maps each generated Tool class. The block receives definition: and
binding: keywords. Return the configured Tool class, or nil to omit
it. Changing Tool#tool_name does not change the operation name sent to
the MCP server.
:call-seq:
map_tool() -> Proc, nil
map_tool { |tool_class, definition:, binding:| ... } -> Proc
68 69 70 71 72 |
# File 'lib/little_ghost/mcp/toolset.rb', line 68 def map_tool(&mapping) return tool_mapping_value unless mapping self.tool_mapping_value = mapping end |
.on_error(&callback) ⇒ Object
Observes an expected discovery failure caught by optional true. Exceptions raised by this callback propagate.
:call-seq:
on_error() -> Proc, nil
on_error { |error, binding:| ... } -> Proc
105 106 107 108 109 |
# File 'lib/little_ghost/mcp/toolset.rb', line 105 def on_error(&callback) return error_callback_value unless callback self.error_callback_value = callback end |
.optional(value = UNSET) ⇒ Object
Makes expected provider and protocol discovery failures produce no tools. Configuration, cancellation, deadline, and callback failures still propagate.
:call-seq:
optional() -> true or false
optional(value) -> true or false
93 94 95 96 97 |
# File 'lib/little_ghost/mcp/toolset.rb', line 93 def optional(value = UNSET) return optional_value if value.equal?(UNSET) self.optional_value = !!value end |
.tools(binding) ⇒ Object
Generates Tool classes for an Agent's current binding.
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/little_ghost/mcp/toolset.rb', line 112 def tools(binding) = resolved_connection(binding) context = binding.run.context if binding.run&.respond_to?(:context) mapper = tool_mapping_value result_mapper = result_mapping_value = connection_with_wrapped_signer() Instrumentation.instrument(:mcp_discovery, toolset: toolset_name) do |telemetry| client = Client.new( transport: HTTPTransport.new(**), name: toolset_name, tool_mapper: mapper && lambda do |tool_class, definition:, binding:| invoke_application_callback do mapper.call(tool_class, definition:, binding:) end end, result_mapper: result_mapper && lambda do |result, call:, binding:| result_mapper.call(result, call:, binding:) end ) discovered = client.tools(context:, binding:) telemetry[:outcome] = :success telemetry[:tool_count] = discovered.length discovered end rescue CallbackFailure => error raise error.original rescue ProviderError, ProtocolError, ToolError => error raise unless optional_value error_callback_value&.call(error, binding:) [] end |