Class: RubynCode::MCP::Client
- Inherits:
-
Object
- Object
- RubynCode::MCP::Client
- Defined in:
- lib/rubyn_code/mcp/client.rb
Overview
High-level MCP client that manages the connection lifecycle, tool discovery, and tool invocation for a single MCP server.
Defined Under Namespace
Classes: ClientError
Constant Summary collapse
- INITIALIZE_TIMEOUT =
10
Instance Attribute Summary collapse
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#transport ⇒ Object
readonly
Returns the value of attribute transport.
Class Method Summary collapse
-
.from_config(server_config) ⇒ Client
Factory method that creates a Client with the appropriate transport based on the server configuration.
Instance Method Summary collapse
-
#call_tool(tool_name, arguments = {}) ⇒ Hash
Invokes a tool on the MCP server.
-
#connect! ⇒ void
Starts the transport, performs the MCP initialize handshake, and discovers available tools.
-
#connected? ⇒ Boolean
Returns whether the client is connected and the transport is alive.
-
#disconnect! ⇒ void
Gracefully disconnects from the MCP server.
-
#get_prompt(name, arguments = {}) ⇒ Hash
Fetches a prompt, expanding its template with the given arguments.
-
#initialize(name:, transport:) ⇒ Client
constructor
A new instance of Client.
-
#prompts ⇒ Array<Hash>
Returns the prompts advertised by the server (empty unless the server declared the ‘prompts` capability).
-
#read_resource(uri) ⇒ Hash
Reads a single resource by URI.
-
#resources ⇒ Array<Hash>
Returns the resources advertised by the server (empty unless the server declared the ‘resources` capability).
-
#supports_prompts? ⇒ Boolean
Whether the server advertised the prompts capability.
-
#supports_resources? ⇒ Boolean
Whether the server advertised the resources capability.
-
#tools ⇒ Array<Hash>
Returns the list of tool definitions from the MCP server.
Constructor Details
#initialize(name:, transport:) ⇒ Client
Returns a new instance of Client.
19 20 21 22 23 24 |
# File 'lib/rubyn_code/mcp/client.rb', line 19 def initialize(name:, transport:) @name = name @transport = transport @tools_cache = nil @initialized = false end |
Instance Attribute Details
#name ⇒ Object (readonly)
Returns the value of attribute name.
15 16 17 |
# File 'lib/rubyn_code/mcp/client.rb', line 15 def name @name end |
#transport ⇒ Object (readonly)
Returns the value of attribute transport.
15 16 17 |
# File 'lib/rubyn_code/mcp/client.rb', line 15 def transport @transport end |
Class Method Details
.from_config(server_config) ⇒ Client
Factory method that creates a Client with the appropriate transport based on the server configuration.
Configs with a :url key use SSETransport; all others use StdioTransport.
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/rubyn_code/mcp/client.rb', line 146 def from_config(server_config) name = server_config[:name] transport = if server_config[:url] SSETransport.new( url: server_config[:url], timeout: server_config[:timeout] || SSETransport::DEFAULT_TIMEOUT ) else StdioTransport.new( command: server_config[:command], args: server_config[:args] || [], env: server_config[:env] || {}, timeout: server_config[:timeout] || StdioTransport::DEFAULT_TIMEOUT ) end new(name: name, transport: transport) end |
Instance Method Details
#call_tool(tool_name, arguments = {}) ⇒ Hash
Invokes a tool on the MCP server.
54 55 56 57 58 59 60 61 |
# File 'lib/rubyn_code/mcp/client.rb', line 54 def call_tool(tool_name, arguments = {}) ensure_connected! @transport.send_request('tools/call', { name: tool_name, arguments: arguments }) end |
#connect! ⇒ void
This method returns an undefined value.
Starts the transport, performs the MCP initialize handshake, and discovers available tools.
31 32 33 34 35 36 37 38 |
# File 'lib/rubyn_code/mcp/client.rb', line 31 def connect! @transport.start! perform_initialize @initialized = true rescue StandardError => e @transport.stop! raise ClientError, "Failed to connect to MCP server '#{@name}': #{e.}" end |
#connected? ⇒ Boolean
Returns whether the client is connected and the transport is alive.
134 135 136 |
# File 'lib/rubyn_code/mcp/client.rb', line 134 def connected? @initialized && @transport.alive? end |
#disconnect! ⇒ void
This method returns an undefined value.
Gracefully disconnects from the MCP server.
123 124 125 126 127 128 129 |
# File 'lib/rubyn_code/mcp/client.rb', line 123 def disconnect! @transport.stop! @initialized = false @tools = nil @resources = nil @prompts = nil end |
#get_prompt(name, arguments = {}) ⇒ Hash
Fetches a prompt, expanding its template with the given arguments.
105 106 107 108 |
# File 'lib/rubyn_code/mcp/client.rb', line 105 def get_prompt(name, arguments = {}) ensure_connected! @transport.send_request('prompts/get', { name: name, arguments: arguments }) end |
#prompts ⇒ Array<Hash>
Returns the prompts advertised by the server (empty unless the server declared the ‘prompts` capability). Each entry has “name” and optionally “description”/“arguments”.
91 92 93 94 95 96 97 98 |
# File 'lib/rubyn_code/mcp/client.rb', line 91 def prompts return [] unless supports_prompts? @prompts ||= @transport.send_request('prompts/list')&.fetch('prompts', []) || [] rescue StandardError => e RubynCode::Debug.warn("MCP '#{@name}' prompts/list failed: #{e.}") [] end |
#read_resource(uri) ⇒ Hash
Reads a single resource by URI.
81 82 83 84 |
# File 'lib/rubyn_code/mcp/client.rb', line 81 def read_resource(uri) ensure_connected! @transport.send_request('resources/read', { uri: uri }) end |
#resources ⇒ Array<Hash>
Returns the resources advertised by the server (empty unless the server declared the ‘resources` capability). Each entry is a Hash with “uri”, “name”, and optionally “description”/“mimeType”.
68 69 70 71 72 73 74 75 |
# File 'lib/rubyn_code/mcp/client.rb', line 68 def resources return [] unless supports_resources? @resources ||= @transport.send_request('resources/list')&.fetch('resources', []) || [] rescue StandardError => e RubynCode::Debug.warn("MCP '#{@name}' resources/list failed: #{e.}") [] end |
#supports_prompts? ⇒ Boolean
Returns whether the server advertised the prompts capability.
116 117 118 |
# File 'lib/rubyn_code/mcp/client.rb', line 116 def supports_prompts? @server_capabilities.is_a?(Hash) && @server_capabilities.key?('prompts') end |
#supports_resources? ⇒ Boolean
Returns whether the server advertised the resources capability.
111 112 113 |
# File 'lib/rubyn_code/mcp/client.rb', line 111 def supports_resources? @server_capabilities.is_a?(Hash) && @server_capabilities.key?('resources') end |
#tools ⇒ Array<Hash>
Returns the list of tool definitions from the MCP server. Each tool is a Hash with “name”, “description”, and “inputSchema” keys.
44 45 46 |
# File 'lib/rubyn_code/mcp/client.rb', line 44 def tools @tools ||= discover_tools end |