Class: Legion::MCP::Client::Connection
- Inherits:
-
Object
- Object
- Legion::MCP::Client::Connection
- Includes:
- Logging::Helper
- Defined in:
- lib/legion/mcp/client/connection.rb
Overview
rubocop:disable Metrics/ClassLength
Constant Summary collapse
- TOOL_CACHE_TTL =
seconds
300
Instance Attribute Summary collapse
-
#config ⇒ Object
readonly
Returns the value of attribute config.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#transport_type ⇒ Object
readonly
Returns the value of attribute transport_type.
Instance Method Summary collapse
- #call_tool(name:, arguments: {}, context: {}) ⇒ Object
- #connect ⇒ Object
- #connected? ⇒ Boolean
- #disconnect ⇒ Object
-
#initialize(name:, transport:, **config) ⇒ Connection
constructor
A new instance of Connection.
- #tools(force_refresh: false) ⇒ Object
Constructor Details
#initialize(name:, transport:, **config) ⇒ Connection
Returns a new instance of Connection.
16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/legion/mcp/client/connection.rb', line 16 def initialize(name:, transport:, **config) @name = name @transport_type = transport.to_sym @config = config @tools_cache = nil @tools_cached_at = nil @connected = false @mcp_client = nil @mcp_transport = nil @mutex = Mutex.new end |
Instance Attribute Details
#config ⇒ Object (readonly)
Returns the value of attribute config.
12 13 14 |
# File 'lib/legion/mcp/client/connection.rb', line 12 def config @config end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
12 13 14 |
# File 'lib/legion/mcp/client/connection.rb', line 12 def name @name end |
#transport_type ⇒ Object (readonly)
Returns the value of attribute transport_type.
12 13 14 |
# File 'lib/legion/mcp/client/connection.rb', line 12 def transport_type @transport_type end |
Instance Method Details
#call_tool(name:, arguments: {}, context: {}) ⇒ Object
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/legion/mcp/client/connection.rb', line 88 def call_tool(name:, arguments: {}, context: {}) connect unless connected? exchange_id = TracingContext.generate_exchange_id log.info("[mcp] client.tool_call.start #{Utils.format_fields( connection: @name, transport: @transport_type, tool_name: name, exchange_id: exchange_id, trace_id: context[:trace_id], arguments: Utils.summarize_params(arguments) )}") start_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC) result = execute_tool_call(name: name, arguments: arguments, context: context) elapsed = ((::Process.clock_gettime(::Process::CLOCK_MONOTONIC) - start_time) * 1000).round(1) log.info("[mcp] client.tool_call.complete #{Utils.format_fields( connection: @name, transport: @transport_type, tool_name: name, exchange_id: exchange_id, duration_ms: elapsed, result: Utils.summarize_result(result) )}") emit_client_audit(tool_name: name, arguments: arguments, result: result, context: context, exchange_id: exchange_id, duration_ms: elapsed) result rescue StandardError => e handle_exception(e, level: :warn, operation: 'legion.mcp.client.connection.call_tool') raise end |
#connect ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/legion/mcp/client/connection.rb', line 32 def connect @mutex.synchronize do return if @connected log.info("[mcp] client.connect.start #{Utils.format_fields(connection: @name, transport: @transport_type, config: @config.slice(:url, :command))}") case @transport_type when :stdio connect_stdio when :http, :streamable_http connect_http else raise ArgumentError, "Unknown transport: #{@transport_type}" end verify_connection! @connected = true log.info("[mcp] client.connect.complete #{Utils.format_fields(connection: @name, transport: @transport_type)}") end rescue StandardError => e @connected = false handle_exception(e, level: :error, operation: 'legion.mcp.client.connection.connect') raise end |
#connected? ⇒ Boolean
28 29 30 |
# File 'lib/legion/mcp/client/connection.rb', line 28 def connected? @connected end |
#disconnect ⇒ Object
58 59 60 61 62 63 64 65 66 67 |
# File 'lib/legion/mcp/client/connection.rb', line 58 def disconnect log.debug("[mcp][client] action=disconnect connection=#{@name}") @mutex.synchronize do @mcp_transport&.close if @mcp_transport.respond_to?(:close) @connected = false @mcp_client = nil @mcp_transport = nil @tools_cache = nil end end |
#tools(force_refresh: false) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/legion/mcp/client/connection.rb', line 69 def tools(force_refresh: false) @mutex.synchronize do if !force_refresh && @tools_cache && @tools_cached_at && (Time.now - @tools_cached_at) < TOOL_CACHE_TTL log.info("[mcp] client.tools.cache_hit #{Utils.format_fields(connection: @name, transport: @transport_type, count: @tools_cache.size)}") return @tools_cache end log.info("[mcp] client.tools.fetch.start #{Utils.format_fields(connection: @name, transport: @transport_type, force_refresh: force_refresh)}") @tools_cache = fetch_tools @tools_cached_at = Time.now log.info("[mcp] client.tools.fetch.complete #{Utils.format_fields(connection: @name, transport: @transport_type, count: @tools_cache.size)}") @tools_cache end end |