Class: ActionMCP::Client::Base

Inherits:
Object
  • Object
show all
Includes:
Elicitation, Messaging, Prompts, Resources, Roots, Tools
Defined in:
lib/action_mcp/client/base.rb

Overview

Base client class containing common MCP functionality

Direct Known Subclasses

StreamableClient

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Elicitation

#process_elicitation_request, #send_elicitation_response

Methods included from Roots

#roots_list_changed_notification

Methods included from Resources

#list_resource_templates, #list_resources, #read_resource, #subscribe_resource, #unsubscribe_resource

Methods included from Prompts

#get_prompt, #list_prompts

Methods included from Tools

#call_tool, #list_tools

Methods included from Messaging

#send_jsonrpc_error, #send_jsonrpc_notification, #send_jsonrpc_request, #send_jsonrpc_response

Constructor Details

#initialize(transport:, logger: ActionMCP.logger, protocol_version: nil, **options) ⇒ Base

Returns a new instance of Base.



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/action_mcp/client/base.rb', line 25

def initialize(transport:, logger: ActionMCP.logger, protocol_version: nil, **options)
  @logger = logger
  @transport = transport
  @session = nil # Session will be created/loaded based on server response
  @session_id = options[:session_id] # Optional session ID for resumption
  @protocol_version = protocol_version || ActionMCP::DEFAULT_PROTOCOL_VERSION
  @server_capabilities = nil
  @connection_error = nil
  @initialized = false

  # Resource objects
  @catalog = Catalog.new([], self)
  # Resource template objects
  @blueprint = Blueprint.new([], self)
  # Prompt objects
  @prompt_book = PromptBook.new([], self)
  # Tool objects
  @toolbox = Toolbox.new([], self)

  setup_transport_callbacks
end

Instance Attribute Details

#blueprintObject (readonly)

Returns the value of attribute blueprint.



17
18
19
# File 'lib/action_mcp/client/base.rb', line 17

def blueprint
  @blueprint
end

#catalogObject (readonly)

Returns the value of attribute catalog.



17
18
19
# File 'lib/action_mcp/client/base.rb', line 17

def catalog
  @catalog
end

#connection_errorObject (readonly)

Returns the value of attribute connection_error.



17
18
19
# File 'lib/action_mcp/client/base.rb', line 17

def connection_error
  @connection_error
end

#loggerObject (readonly)

Returns the value of attribute logger.



17
18
19
# File 'lib/action_mcp/client/base.rb', line 17

def logger
  @logger
end

#prompt_bookObject (readonly)

Returns the value of attribute prompt_book.



17
18
19
# File 'lib/action_mcp/client/base.rb', line 17

def prompt_book
  @prompt_book
end

#serverObject

Returns the value of attribute server.



17
18
19
# File 'lib/action_mcp/client/base.rb', line 17

def server
  @server
end

#server_capabilitiesObject (readonly)

Returns the value of attribute server_capabilities.



17
18
19
# File 'lib/action_mcp/client/base.rb', line 17

def server_capabilities
  @server_capabilities
end

#sessionObject (readonly)

Returns the value of attribute session.



17
18
19
# File 'lib/action_mcp/client/base.rb', line 17

def session
  @session
end

#toolboxObject (readonly)

Returns the value of attribute toolbox.



17
18
19
# File 'lib/action_mcp/client/base.rb', line 17

def toolbox
  @toolbox
end

#transportObject (readonly)

Returns the value of attribute transport.



17
18
19
# File 'lib/action_mcp/client/base.rb', line 17

def transport
  @transport
end

Instance Method Details

#connectObject

Connect to the MCP server



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/action_mcp/client/base.rb', line 48

def connect
  return true if connected?

  begin
    log_debug("Connecting to MCP server via #{transport.class.name}...")
    @connection_error = nil

    success = @transport.connect
    unless success
      log_error("Failed to establish transport connection")
      return false
    end

    log_debug("Connected to MCP server")
    true
  rescue StandardError => e
    @connection_error = e.message
    log_error("Failed to connect to MCP server: #{e.message}")
    false
  end
end

#disconnectObject

Disconnect from the MCP server



71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/action_mcp/client/base.rb', line 71

def disconnect
  return true unless connected?

  begin
    @transport.disconnect
    log_debug("Disconnected from MCP server")
    true
  rescue StandardError => e
    log_error("Error disconnecting from MCP server: #{e.message}")
    false
  end
end

#initialized?Boolean

Returns:

  • (Boolean)


118
119
120
# File 'lib/action_mcp/client/base.rb', line 118

def initialized?
  @initialized && @session&.initialized?
end

#inspectObject



122
123
124
125
# File 'lib/action_mcp/client/base.rb', line 122

def inspect
  session_info = @session ? "session: #{@session.id}" : "session: none"
  "#<#{self.class.name} transport: #{transport.class.name}, server: #{server}, client_name: #{client_info[:name]}, client_version: #{client_info[:version]}, capabilities: #{client_capabilities}, connected: #{connected?}, initialized: #{initialized?}, #{session_info}>"
end

#write_message(payload) ⇒ Object

Send a request to the MCP server



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/action_mcp/client/base.rb', line 85

def write_message(payload)
  unless ready?
    log_error("Cannot send request - transport not ready")
    return false
  end

  begin
    # Only write to session if it exists (after initialization)
    session&.write(payload)
    data = payload.to_json unless payload.is_a?(String)
    @transport.send_message(data)
    true
  rescue StandardError => e
    log_error("Failed to send request: #{e.message}")
    false
  end
end