Class: MCP::Client
- Inherits:
-
Object
- Object
- MCP::Client
- Defined in:
- lib/mcp/client.rb,
lib/mcp/client/http.rb,
lib/mcp/client/tool.rb,
lib/mcp/client/oauth.rb,
lib/mcp/client/stdio.rb,
lib/mcp/client/oauth/flow.rb,
lib/mcp/client/oauth/pkce.rb,
lib/mcp/client/oauth/provider.rb,
lib/mcp/client/oauth/discovery.rb,
lib/mcp/client/paginated_result.rb,
lib/mcp/client/oauth/in_memory_storage.rb,
lib/mcp/client/oauth/storage_backed_provider.rb,
lib/mcp/client/oauth/client_credentials_provider.rb
Defined Under Namespace
Modules: OAuth Classes: HTTP, ListPromptsResult, ListResourceTemplatesResult, ListResourcesResult, ListToolsResult, RequestHandlerError, ServerError, SessionExpiredError, Stdio, Tool, ValidationError
Instance Attribute Summary collapse
-
#transport ⇒ Object
readonly
The user may want to access additional transport-specific methods/attributes So keeping it public.
Instance Method Summary collapse
-
#call_tool(name: nil, tool: nil, arguments: nil, progress_token: nil, meta: nil) ⇒ Hash
Calls a tool via the transport layer and returns the full response from the server.
-
#complete(ref:, argument:, context: nil, meta: nil) ⇒ Hash
Requests completion suggestions from the server for a prompt argument or resource template URI.
-
#connect(client_info: nil, protocol_version: nil, capabilities: {}) ⇒ Hash?
Performs the MCP ‘initialize` handshake by delegating to the transport (e.g. `MCP::Client::HTTP`, `MCP::Client::Stdio`).
-
#connected? ⇒ Boolean
Returns true once ‘connect` has completed the handshake on the underlying transport.
-
#get_prompt(name:, meta: nil) ⇒ Hash
Gets a prompt from the server by name and returns its details.
-
#initialize(transport:) ⇒ Client
constructor
Initializes a new MCP::Client instance.
-
#list_prompts(cursor: nil, meta: nil) ⇒ MCP::Client::ListPromptsResult
Returns a single page of prompts from the server.
-
#list_resource_templates(cursor: nil, meta: nil) ⇒ MCP::Client::ListResourceTemplatesResult
Returns a single page of resource templates from the server.
-
#list_resources(cursor: nil, meta: nil) ⇒ MCP::Client::ListResourcesResult
Returns a single page of resources from the server.
-
#list_tools(cursor: nil, meta: nil) ⇒ MCP::Client::ListToolsResult
Returns a single page of tools from the server.
-
#ping(meta: nil) ⇒ Hash
Sends a ‘ping` request to the server to verify the connection is alive.
-
#prompts ⇒ Array<Hash>
Returns every prompt available on the server.
-
#read_resource(uri:, meta: nil) ⇒ Array<Hash>
Reads a resource from the server by URI and returns the contents.
-
#resource_templates ⇒ Array<Hash>
Returns every resource template available on the server.
-
#resources ⇒ Array<Hash>
Returns every resource available on the server.
-
#server_info ⇒ Object
The server’s ‘InitializeResult` (protocol version, capabilities, server info, instructions), as reported by the transport after a successful `connect`.
-
#tools ⇒ Array<MCP::Client::Tool>
Returns every tool available on the server.
Constructor Details
#initialize(transport:) ⇒ Client
Initializes a new MCP::Client instance.
55 56 57 |
# File 'lib/mcp/client.rb', line 55 def initialize(transport:) @transport = transport end |
Instance Attribute Details
#transport ⇒ Object (readonly)
The user may want to access additional transport-specific methods/attributes So keeping it public
61 62 63 |
# File 'lib/mcp/client.rb', line 61 def transport @transport end |
Instance Method Details
#call_tool(name: nil, tool: nil, arguments: nil, progress_token: nil, meta: nil) ⇒ Hash
The exact requirements for ‘arguments` are determined by the transport layer in use. Consult the documentation for your transport (e.g., MCP::Client::HTTP) for details.
Calls a tool via the transport layer and returns the full response from the server.
271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
# File 'lib/mcp/client.rb', line 271 def call_tool(name: nil, tool: nil, arguments: nil, progress_token: nil, meta: nil) tool_name = name || tool&.name raise ArgumentError, "Either `name:` or `tool:` must be provided." unless tool_name params = { name: tool_name, arguments: arguments } = ? .dup : {} if progress_token .delete("progressToken") [:progressToken] = progress_token end params[:_meta] = unless .empty? request(method: "tools/call", params: params) end |
#complete(ref:, argument:, context: nil, meta: nil) ⇒ Hash
Requests completion suggestions from the server for a prompt argument or resource template URI.
319 320 321 322 323 324 325 326 |
# File 'lib/mcp/client.rb', line 319 def complete(ref:, argument:, context: nil, meta: nil) params = { ref: ref, argument: argument } params[:context] = context if context response = request(method: "completion/complete", params: params, meta: ) response.dig("result", "completion") || { "values" => [], "hasMore" => false } end |
#connect(client_info: nil, protocol_version: nil, capabilities: {}) ⇒ Hash?
Performs the MCP ‘initialize` handshake by delegating to the transport (e.g. `MCP::Client::HTTP`, `MCP::Client::Stdio`). Returns the server’s ‘InitializeResult`.
When the transport does not respond to ‘:connect`, this is a no-op and returns `nil`.
modelcontextprotocol.io/specification/2025-11-25/basic/lifecycle#initialization
84 85 86 87 88 89 90 91 92 |
# File 'lib/mcp/client.rb', line 84 def connect(client_info: nil, protocol_version: nil, capabilities: {}) return unless transport.respond_to?(:connect) transport.connect( client_info: client_info, protocol_version: protocol_version, capabilities: capabilities, ) end |
#connected? ⇒ Boolean
Returns true once ‘connect` has completed the handshake on the underlying transport. Transports that do not expose connection state are assumed connected and return `true`.
97 98 99 100 101 |
# File 'lib/mcp/client.rb', line 97 def connected? return transport.connected? if transport.respond_to?(:connected?) true end |
#get_prompt(name:, meta: nil) ⇒ Hash
Gets a prompt from the server by name and returns its details.
304 305 306 307 308 |
# File 'lib/mcp/client.rb', line 304 def get_prompt(name:, meta: nil) response = request(method: "prompts/get", params: { name: name }, meta: ) response.fetch("result", {}) end |
#list_prompts(cursor: nil, meta: nil) ⇒ MCP::Client::ListPromptsResult
Returns a single page of prompts from the server.
223 224 225 226 227 228 229 230 231 232 233 |
# File 'lib/mcp/client.rb', line 223 def list_prompts(cursor: nil, meta: nil) params = cursor ? { cursor: cursor } : nil response = request(method: "prompts/list", params: params, meta: ) result = response["result"] || {} ListPromptsResult.new( prompts: result["prompts"] || [], next_cursor: result["nextCursor"], meta: result["_meta"], ) end |
#list_resource_templates(cursor: nil, meta: nil) ⇒ MCP::Client::ListResourceTemplatesResult
Returns a single page of resource templates from the server.
192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/mcp/client.rb', line 192 def list_resource_templates(cursor: nil, meta: nil) params = cursor ? { cursor: cursor } : nil response = request(method: "resources/templates/list", params: params, meta: ) result = response["result"] || {} ListResourceTemplatesResult.new( resource_templates: result["resourceTemplates"] || [], next_cursor: result["nextCursor"], meta: result["_meta"], ) end |
#list_resources(cursor: nil, meta: nil) ⇒ MCP::Client::ListResourcesResult
Returns a single page of resources from the server.
161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/mcp/client.rb', line 161 def list_resources(cursor: nil, meta: nil) params = cursor ? { cursor: cursor } : nil response = request(method: "resources/list", params: params, meta: ) result = response["result"] || {} ListResourcesResult.new( resources: result["resources"] || [], next_cursor: result["nextCursor"], meta: result["_meta"], ) end |
#list_tools(cursor: nil, meta: nil) ⇒ MCP::Client::ListToolsResult
Returns a single page of tools from the server.
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/mcp/client.rb', line 119 def list_tools(cursor: nil, meta: nil) params = cursor ? { cursor: cursor } : nil response = request(method: "tools/list", params: params, meta: ) result = response["result"] || {} tools = (result["tools"] || []).map do |tool| Tool.new( name: tool["name"], description: tool["description"], input_schema: tool["inputSchema"], output_schema: tool["outputSchema"], ) end ListToolsResult.new(tools: tools, next_cursor: result["nextCursor"], meta: result["_meta"]) end |
#ping(meta: nil) ⇒ Hash
Sends a ‘ping` request to the server to verify the connection is alive. Per the MCP spec, the server responds with an empty result.
339 340 341 342 343 344 |
# File 'lib/mcp/client.rb', line 339 def ping(meta: nil) result = request(method: Methods::PING, meta: )["result"] raise ValidationError, "Response validation failed: missing or invalid `result`" unless result.is_a?(Hash) result end |
#prompts ⇒ Array<Hash>
Returns every prompt available on the server. Iterates through all pages automatically when the server paginates, so the full collection is returned regardless of the server’s ‘page_size` setting. Use #list_prompts when you need fine-grained cursor control.
Each call will make a new request - the result is not cached.
242 243 244 245 |
# File 'lib/mcp/client.rb', line 242 def prompts # TODO: consider renaming to `list_all_prompts`. fetch_all_pages { |cursor| list_prompts(cursor: cursor) }.flat_map(&:prompts) end |
#read_resource(uri:, meta: nil) ⇒ Array<Hash>
Reads a resource from the server by URI and returns the contents.
292 293 294 295 296 |
# File 'lib/mcp/client.rb', line 292 def read_resource(uri:, meta: nil) response = request(method: "resources/read", params: { uri: uri }, meta: ) response.dig("result", "contents") || [] end |
#resource_templates ⇒ Array<Hash>
Returns every resource template available on the server. Iterates through all pages automatically when the server paginates, so the full collection is returned regardless of the server’s ‘page_size` setting. Use #list_resource_templates when you need fine-grained cursor control.
Each call will make a new request - the result is not cached.
211 212 213 214 |
# File 'lib/mcp/client.rb', line 211 def resource_templates # TODO: consider renaming to `list_all_resource_templates`. fetch_all_pages { |cursor| list_resource_templates(cursor: cursor) }.flat_map(&:resource_templates) end |
#resources ⇒ Array<Hash>
Returns every resource available on the server. Iterates through all pages automatically when the server paginates, so the full collection is returned regardless of the server’s ‘page_size` setting. Use #list_resources when you need fine-grained cursor control.
Each call will make a new request - the result is not cached.
180 181 182 183 |
# File 'lib/mcp/client.rb', line 180 def resources # TODO: consider renaming to `list_all_resources`. fetch_all_pages { |cursor| list_resources(cursor: cursor) }.flat_map(&:resources) end |
#server_info ⇒ Object
The server’s ‘InitializeResult` (protocol version, capabilities, server info, instructions), as reported by the transport after a successful `connect`. Returns `nil` before `connect`, after `close`, or when the transport does not expose a cached handshake result.
67 68 69 |
# File 'lib/mcp/client.rb', line 67 def server_info transport.server_info if transport.respond_to?(:server_info) end |
#tools ⇒ Array<MCP::Client::Tool>
Returns every tool available on the server. Iterates through all pages automatically when the server paginates, so the full collection is returned regardless of the server’s ‘page_size` setting. Use #list_tools when you need fine-grained cursor control.
Each call will make a new request - the result is not cached.
149 150 151 152 |
# File 'lib/mcp/client.rb', line 149 def tools # TODO: consider renaming to `list_all_tools`. fetch_all_pages { |cursor| list_tools(cursor: cursor) }.flat_map(&:tools) end |