Class: SwarmSDK::Tools::McpToolStub
- Defined in:
- lib/swarm_sdk/tools/mcp_tool_stub.rb
Overview
Lazy-loading wrapper for MCP tools
Creates minimal tool stub without calling tools/list. Schema is fetched on-demand when LLM needs it.
Boot Optimization
When MCP server tools are pre-specified in configuration:
- Boot time: Create stubs instantly (no RPC)
- First LLM request: Fetch schema lazily (~100ms one-time cost)
- Subsequent requests: Use cached schema (instant)
Thread Safety
Schema loading is protected by Async::Semaphore with double-check pattern to ensure only one fiber fetches the schema even under concurrent access.
Instance Attribute Summary collapse
-
#client ⇒ Object
readonly
Returns the value of attribute client.
-
#description ⇒ String
readonly
Get tool description.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#server_name ⇒ Object
readonly
Returns the value of attribute server_name.
Instance Method Summary collapse
-
#execute(**params) ⇒ String, Hash
Execute the MCP tool.
-
#initialize(client:, name:, server_name: nil, description: nil, schema: nil) ⇒ McpToolStub
constructor
Create a new MCP tool stub.
-
#params_schema ⇒ Hash?
Get parameter schema (lazy-loaded on first access).
Methods inherited from Base
removable, removable?, #removable?
Constructor Details
#initialize(client:, name:, server_name: nil, description: nil, schema: nil) ⇒ McpToolStub
Create a new MCP tool stub
65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/swarm_sdk/tools/mcp_tool_stub.rb', line 65 def initialize(client:, name:, server_name: nil, description: nil, schema: nil) super() @client = client @name = name @mcp_name = name @server_name = server_name || "unknown" @description = description || "MCP tool: #{name}" @input_schema = schema @schema_loaded = !schema.nil? @schema_mutex = Async::Semaphore.new(1) # Thread-safe schema loading end |
Instance Attribute Details
#client ⇒ Object (readonly)
Returns the value of attribute client.
36 37 38 |
# File 'lib/swarm_sdk/tools/mcp_tool_stub.rb', line 36 def client @client end |
#description ⇒ String (readonly)
Get tool description
80 81 82 |
# File 'lib/swarm_sdk/tools/mcp_tool_stub.rb', line 80 def description @description end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
36 37 38 |
# File 'lib/swarm_sdk/tools/mcp_tool_stub.rb', line 36 def name @name end |
#server_name ⇒ Object (readonly)
Returns the value of attribute server_name.
36 37 38 |
# File 'lib/swarm_sdk/tools/mcp_tool_stub.rb', line 36 def server_name @server_name end |
Instance Method Details
#execute(**params) ⇒ String, Hash
Execute the MCP tool
Calls the MCP server's tools/call endpoint with the provided parameters. Schema is NOT required for execution - the server validates parameters.
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/swarm_sdk/tools/mcp_tool_stub.rb', line 103 def execute(**params) # Use client.call_tool (client has internal coordinator) result = @client.call_tool( name: @mcp_name, arguments: params, ) # client.call_tool returns the result content directly result rescue RubyLLM::MCP::Errors::TimeoutError => e raise MCPTimeoutError, format_mcp_error( "MCP request timed out", original_message: e., request_id: e.request_id, ) rescue RubyLLM::MCP::Errors::TransportError => e raise MCPTransportError, format_mcp_error( "MCP transport error", original_message: e., code: e.code, ) rescue RubyLLM::MCP::Errors::BaseError => e raise MCPError, format_mcp_error( "MCP error", original_message: e., ) end |
#params_schema ⇒ Hash?
Get parameter schema (lazy-loaded on first access)
This method is called by RubyLLM when building tool schemas for LLM requests. On first access, it triggers a tools/list RPC to fetch the schema.
88 89 90 91 |
# File 'lib/swarm_sdk/tools/mcp_tool_stub.rb', line 88 def params_schema ensure_schema_loaded! @input_schema end |