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
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) ⇒ Hash
Calls a tool via the transport layer and returns the full response from the server.
-
#complete(ref:, argument:, context: 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:) ⇒ 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) ⇒ MCP::Client::ListPromptsResult
Returns a single page of prompts from the server.
-
#list_resource_templates(cursor: nil) ⇒ MCP::Client::ListResourceTemplatesResult
Returns a single page of resource templates from the server.
-
#list_resources(cursor: nil) ⇒ MCP::Client::ListResourcesResult
Returns a single page of resources from the server.
-
#list_tools(cursor: nil) ⇒ MCP::Client::ListToolsResult
Returns a single page of tools from the server.
-
#ping ⇒ 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:) ⇒ 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) ⇒ 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.
259 260 261 262 263 264 265 266 267 268 269 |
# File 'lib/mcp/client.rb', line 259 def call_tool(name: nil, tool: nil, arguments: nil, progress_token: nil) tool_name = name || tool&.name raise ArgumentError, "Either `name:` or `tool:` must be provided." unless tool_name params = { name: tool_name, arguments: arguments } if progress_token params[:_meta] = { progressToken: progress_token } end request(method: "tools/call", params: params) end |
#complete(ref:, argument:, context: nil) ⇒ Hash
Requests completion suggestions from the server for a prompt argument or resource template URI.
298 299 300 301 302 303 304 305 |
# File 'lib/mcp/client.rb', line 298 def complete(ref:, argument:, context: nil) params = { ref: ref, argument: argument } params[:context] = context if context response = request(method: "completion/complete", params: params) 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:) ⇒ Hash
Gets a prompt from the server by name and returns its details.
285 286 287 288 289 |
# File 'lib/mcp/client.rb', line 285 def get_prompt(name:) response = request(method: "prompts/get", params: { name: name }) response.fetch("result", {}) end |
#list_prompts(cursor: nil) ⇒ MCP::Client::ListPromptsResult
Returns a single page of prompts from the server.
215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/mcp/client.rb', line 215 def list_prompts(cursor: nil) params = cursor ? { cursor: cursor } : nil response = request(method: "prompts/list", params: params) result = response["result"] || {} ListPromptsResult.new( prompts: result["prompts"] || [], next_cursor: result["nextCursor"], meta: result["_meta"], ) end |
#list_resource_templates(cursor: nil) ⇒ MCP::Client::ListResourceTemplatesResult
Returns a single page of resource templates from the server.
186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/mcp/client.rb', line 186 def list_resource_templates(cursor: nil) params = cursor ? { cursor: cursor } : nil response = request(method: "resources/templates/list", params: params) result = response["result"] || {} ListResourceTemplatesResult.new( resource_templates: result["resourceTemplates"] || [], next_cursor: result["nextCursor"], meta: result["_meta"], ) end |
#list_resources(cursor: nil) ⇒ MCP::Client::ListResourcesResult
Returns a single page of resources from the server.
157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/mcp/client.rb', line 157 def list_resources(cursor: nil) params = cursor ? { cursor: cursor } : nil response = request(method: "resources/list", params: params) result = response["result"] || {} ListResourcesResult.new( resources: result["resources"] || [], next_cursor: result["nextCursor"], meta: result["_meta"], ) end |
#list_tools(cursor: nil) ⇒ MCP::Client::ListToolsResult
Returns a single page of tools from the server.
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/mcp/client.rb', line 117 def list_tools(cursor: nil) params = cursor ? { cursor: cursor } : nil response = request(method: "tools/list", params: params) 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 ⇒ 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.
318 319 320 321 322 323 |
# File 'lib/mcp/client.rb', line 318 def ping result = request(method: Methods::PING)["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.
234 235 236 237 |
# File 'lib/mcp/client.rb', line 234 def prompts # TODO: consider renaming to `list_all_prompts`. fetch_all_pages { |cursor| list_prompts(cursor: cursor) }.flat_map(&:prompts) end |
#read_resource(uri:) ⇒ Array<Hash>
Reads a resource from the server by URI and returns the contents.
275 276 277 278 279 |
# File 'lib/mcp/client.rb', line 275 def read_resource(uri:) response = request(method: "resources/read", params: { uri: uri }) 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.
205 206 207 208 |
# File 'lib/mcp/client.rb', line 205 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.
176 177 178 179 |
# File 'lib/mcp/client.rb', line 176 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.
147 148 149 150 |
# File 'lib/mcp/client.rb', line 147 def tools # TODO: consider renaming to `list_all_tools`. fetch_all_pages { |cursor| list_tools(cursor: cursor) }.flat_map(&:tools) end |