Class: RobotLab::MCP::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/robot_lab/mcp/client.rb

Overview

MCP client for communicating with Model Context Protocol servers

Uses actionmcp gem for MCP protocol implementation. Supports multiple transport types: StdIO, SSE, WebSocket, HTTP.

Examples:

client = Client.new(name: "neon", transport: { type: "ws", url: "ws://..." })
client.connect
tools = client.list_tools
result = client.call_tool("createBranch", { project_id: "abc" })

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(server_or_config, poller: nil) ⇒ Client

Creates a new MCP Client instance.

Parameters:

  • server_or_config (Server, Hash)

    the server or configuration hash

  • poller (MCP::ConnectionPoller, nil) (defaults to: nil)

    optional shared IO.select poller for multiplexing multiple stdio transports (opt-in, default nil = per-client blocking)

Raises:

  • (ArgumentError)

    if config is invalid



29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/robot_lab/mcp/client.rb', line 29

def initialize(server_or_config, poller: nil)
  @server = case server_or_config
            when Server
              server_or_config
            when Hash
              Server.new(**server_or_config.transform_keys(&:to_sym))
            else
              raise ArgumentError, "Invalid server config"
            end
  @connected  = false
  @transport  = nil
  @request_id = 0
  @poller     = poller
end

Instance Attribute Details

#connectedBoolean (readonly)

Returns whether currently connected.

Returns:

  • (Boolean)

    whether currently connected



21
# File 'lib/robot_lab/mcp/client.rb', line 21

attr_reader :server, :connected, :transport

#serverServer (readonly)

Returns the MCP server configuration.

Returns:

  • (Server)

    the MCP server configuration



21
22
23
# File 'lib/robot_lab/mcp/client.rb', line 21

def server
  @server
end

#transportObject (readonly)

Returns the value of attribute transport.



21
22
23
# File 'lib/robot_lab/mcp/client.rb', line 21

def transport
  @transport
end

Instance Method Details

#call_tool(name, arguments = {}) ⇒ Object

Call a tool on the server

Parameters:

  • name (String)

    Tool name

  • arguments (Hash) (defaults to: {})

    Tool arguments

Returns:

  • (Object)

    Tool result



96
97
98
99
100
101
102
103
# File 'lib/robot_lab/mcp/client.rb', line 96

def call_tool(name, arguments = {})
  ensure_connected!
  response = request(
    method: "tools/call",
    params: { name: name, arguments: arguments }
  )
  response[:content] || response
end

#connectself

Connect to the MCP server

Returns:

  • (self)


48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/robot_lab/mcp/client.rb', line 48

def connect
  return self if @connected

  @transport = create_transport
  @transport.connect if @transport.respond_to?(:connect)
  @connected = true

  # Register with shared poller after the transport is connected
  @poller.register(self) if @poller

  self
rescue StandardError => e
  RobotLab.config.logger.warn("MCP connection failed for #{@server.name}: #{e.message}")
  @connected = false
  self
end

#connected?Boolean

Checks if the client is connected to the server.

Returns:

  • (Boolean)


151
152
153
# File 'lib/robot_lab/mcp/client.rb', line 151

def connected?
  @connected
end

#disconnectself

Disconnect from the server

Returns:

  • (self)


69
70
71
72
73
74
75
76
77
78
# File 'lib/robot_lab/mcp/client.rb', line 69

def disconnect
  return self unless @connected

  @poller.unregister(self) if @poller
  @transport.close if @transport.respond_to?(:close)
  @connected = false
  @transport = nil

  self
end

#get_prompt(name, arguments = {}) ⇒ Hash

Get a prompt

Parameters:

  • name (String)

    Prompt name

  • arguments (Hash) (defaults to: {})

    Prompt arguments

Returns:

  • (Hash)


142
143
144
145
146
# File 'lib/robot_lab/mcp/client.rb', line 142

def get_prompt(name, arguments = {})
  ensure_connected!
  response = request(method: "prompts/get", params: { name: name, arguments: arguments })
  response
end

#list_promptsArray<Hash>

List available prompts

Returns:

  • (Array<Hash>)


130
131
132
133
134
# File 'lib/robot_lab/mcp/client.rb', line 130

def list_prompts
  ensure_connected!
  response = request(method: "prompts/list")
  response[:prompts] || []
end

#list_resourcesArray<Hash>

List available resources

Returns:

  • (Array<Hash>)


109
110
111
112
113
# File 'lib/robot_lab/mcp/client.rb', line 109

def list_resources
  ensure_connected!
  response = request(method: "resources/list")
  response[:resources] || []
end

#list_toolsArray<Hash>

List available tools from the server

Returns:

  • (Array<Hash>)

    Tool definitions



84
85
86
87
88
# File 'lib/robot_lab/mcp/client.rb', line 84

def list_tools
  ensure_connected!
  response = request(method: "tools/list")
  response[:tools] || []
end

#read_resource(uri) ⇒ Object

Read a resource

Parameters:

  • uri (String)

    Resource URI

Returns:

  • (Object)


120
121
122
123
124
# File 'lib/robot_lab/mcp/client.rb', line 120

def read_resource(uri)
  ensure_connected!
  response = request(method: "resources/read", params: { uri: uri })
  response[:contents] || response
end

#to_hHash

Converts the client to a hash representation.

Returns:

  • (Hash)


158
159
160
161
162
163
# File 'lib/robot_lab/mcp/client.rb', line 158

def to_h
  {
    server: @server.to_h,
    connected: @connected
  }
end