Class: VectorMCP::Session
- Inherits:
-
Object
- Object
- VectorMCP::Session
- Defined in:
- lib/vector_mcp/session.rb
Overview
Represents the state of a single client-server connection session in MCP. It tracks initialization status, and negotiated capabilities between the client and server.
Instance Attribute Summary collapse
-
#client_capabilities ⇒ Hash?
readonly
Capabilities supported by the client, received during initialization.
-
#client_info ⇒ Hash?
readonly
Information about the client, received during initialization.
-
#created_at ⇒ Object
readonly
Returns the value of attribute created_at.
-
#data ⇒ Object
For user-defined session-specific storage and resolved auth context.
-
#id ⇒ Object
readonly
Returns the value of attribute id.
-
#last_accessed_at ⇒ Object
readonly
Returns the value of attribute last_accessed_at.
-
#metadata ⇒ Object
readonly
Returns the value of attribute metadata.
-
#protocol_version ⇒ String
readonly
The MCP protocol version used by the server.
-
#request_context ⇒ RequestContext
readonly
The request context for this session.
-
#security_context ⇒ Object
For user-defined session-specific storage and resolved auth context.
-
#server ⇒ Object
readonly
Returns the value of attribute server.
-
#server_capabilities ⇒ Hash
readonly
Capabilities supported by the server.
-
#server_info ⇒ Hash
readonly
Information about the server.
-
#transport ⇒ Object
readonly
Returns the value of attribute transport.
Instance Method Summary collapse
-
#age ⇒ Float
Seconds since the session was created.
-
#expired?(timeout) ⇒ Boolean
True when the session has been idle longer than the timeout.
-
#initialize(server, transport = nil, id: SecureRandom.uuid, request_context: nil) ⇒ Session
constructor
Initializes a new session.
-
#initialize!(params) ⇒ Hash
Marks the session as initialized using parameters from the client's
initializerequest. -
#initialized? ⇒ Boolean
Checks if the session has been successfully initialized.
-
#sample(request_params, timeout: nil) ⇒ VectorMCP::Sampling::Result
Initiates an MCP sampling request to the client associated with this session.
-
#touch! ⇒ void
Records activity on this session, deferring expiry.
Constructor Details
#initialize(server, transport = nil, id: SecureRandom.uuid, request_context: nil) ⇒ Session
Initializes a new session.
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/vector_mcp/session.rb', line 30 def initialize(server, transport = nil, id: SecureRandom.uuid, request_context: nil) @server = server @transport = transport # Store the transport for sending requests @id = id @initialized_state = :pending # :pending, :succeeded, :failed @client_info = nil @client_capabilities = nil @data = {} # Initialize user data hash @security_context = Security::SessionContext.anonymous @created_at = Time.now @last_accessed_at = @created_at @metadata = {} # Transport-owned lifecycle/connection state @logger = server.logger # Initialize request context @request_context = case request_context when RequestContext request_context when Hash RequestContext.new(**request_context) else RequestContext.new end end |
Instance Attribute Details
#client_capabilities ⇒ Hash? (readonly)
Capabilities supported by the client, received during initialization.
19 20 21 |
# File 'lib/vector_mcp/session.rb', line 19 def client_capabilities @client_capabilities end |
#client_info ⇒ Hash? (readonly)
Information about the client, received during initialization.
19 20 21 |
# File 'lib/vector_mcp/session.rb', line 19 def client_info @client_info end |
#created_at ⇒ Object (readonly)
Returns the value of attribute created_at.
20 21 22 |
# File 'lib/vector_mcp/session.rb', line 20 def created_at @created_at end |
#data ⇒ Object
For user-defined session-specific storage and resolved auth context
22 23 24 |
# File 'lib/vector_mcp/session.rb', line 22 def data @data end |
#id ⇒ Object (readonly)
Returns the value of attribute id.
20 21 22 |
# File 'lib/vector_mcp/session.rb', line 20 def id @id end |
#last_accessed_at ⇒ Object (readonly)
Returns the value of attribute last_accessed_at.
20 21 22 |
# File 'lib/vector_mcp/session.rb', line 20 def last_accessed_at @last_accessed_at end |
#metadata ⇒ Object (readonly)
Returns the value of attribute metadata.
20 21 22 |
# File 'lib/vector_mcp/session.rb', line 20 def @metadata end |
#protocol_version ⇒ String (readonly)
The MCP protocol version used by the server.
19 20 21 |
# File 'lib/vector_mcp/session.rb', line 19 def protocol_version @protocol_version end |
#request_context ⇒ RequestContext (readonly)
The request context for this session.
19 20 21 |
# File 'lib/vector_mcp/session.rb', line 19 def request_context @request_context end |
#security_context ⇒ Object
For user-defined session-specific storage and resolved auth context
22 23 24 |
# File 'lib/vector_mcp/session.rb', line 22 def security_context @security_context end |
#server ⇒ Object (readonly)
Returns the value of attribute server.
20 21 22 |
# File 'lib/vector_mcp/session.rb', line 20 def server @server end |
#server_capabilities ⇒ Hash (readonly)
Capabilities supported by the server.
19 20 21 |
# File 'lib/vector_mcp/session.rb', line 19 def server_capabilities @server_capabilities end |
#server_info ⇒ Hash (readonly)
Information about the server.
19 20 21 |
# File 'lib/vector_mcp/session.rb', line 19 def server_info @server_info end |
#transport ⇒ Object (readonly)
Returns the value of attribute transport.
20 21 22 |
# File 'lib/vector_mcp/session.rb', line 20 def transport @transport end |
Instance Method Details
#age ⇒ Float
Returns Seconds since the session was created.
112 113 114 |
# File 'lib/vector_mcp/session.rb', line 112 def age Time.now - @created_at end |
#expired?(timeout) ⇒ Boolean
Returns True when the session has been idle longer than the timeout.
107 108 109 |
# File 'lib/vector_mcp/session.rb', line 107 def expired?(timeout) Time.now - @last_accessed_at > timeout end |
#initialize!(params) ⇒ Hash
Marks the session as initialized using parameters from the client's initialize request.
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/vector_mcp/session.rb', line 60 def initialize!(params) raise InitializationError, "Session already initialized or initialization attempt in progress." unless @initialized_state == :pending # TODO: More robust validation of params against MCP spec for initialize request params["protocolVersion"] client_capabilities_raw = params["capabilities"] client_info_raw = params["clientInfo"] # For now, we mostly care about clientInfo and capabilities for the session object. # Protocol version matching is more of a server/transport concern at a lower level if strict checks are needed. @client_info = client_info_raw.transform_keys(&:to_sym) if client_info_raw.is_a?(Hash) @client_capabilities = client_capabilities_raw.transform_keys(&:to_sym) if client_capabilities_raw.is_a?(Hash) @initialized_state = :succeeded @logger.info("[Session #{@id}] Initialized successfully. Client: #{@client_info&.dig(:name)}") { protocolVersion: @server.protocol_version, serverInfo: @server.server_info, capabilities: @server.server_capabilities } rescue StandardError => e @initialized_state = :failed @logger.error("[Session #{@id}] Initialization failed: #{e.}") # Re-raise as an InitializationError if it's not already one of our ProtocolErrors raise e if e.is_a?(ProtocolError) raise InitializationError, "Initialization processing error: #{e.}", details: { original_error: e.to_s } end |
#initialized? ⇒ Boolean
Checks if the session has been successfully initialized.
93 94 95 |
# File 'lib/vector_mcp/session.rb', line 93 def initialized? @initialized_state == :succeeded end |
#sample(request_params, timeout: nil) ⇒ VectorMCP::Sampling::Result
Initiates an MCP sampling request to the client associated with this session. This is a blocking call that waits for the client's response.
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/vector_mcp/session.rb', line 139 def sample(request_params, timeout: nil) validate_sampling_preconditions # Create middleware context for sampling context = VectorMCP::Middleware::Context.new( operation_type: :sampling, operation_name: "createMessage", params: request_params, session: self, server: @server, metadata: { start_time: Time.now, timeout: timeout } ) # Execute before_sampling_request hooks context = @server.middleware_manager.execute_hooks(:before_sampling_request, context) raise context.error if context.error? begin sampling_req_obj = VectorMCP::Sampling::Request.new(request_params) @logger.debug("[Session #{@id}] Sending sampling/createMessage request to client.") result = send_sampling_request(sampling_req_obj, timeout) # Set result in context context.result = result # Execute after_sampling_response hooks context = @server.middleware_manager.execute_hooks(:after_sampling_response, context) context.result rescue StandardError => e # Set error in context and execute error hooks context.error = e context = @server.middleware_manager.execute_hooks(:on_sampling_error, context) # Re-raise unless middleware handled the error raise e unless context.result context.result end end |
#touch! ⇒ void
This method returns an undefined value.
Records activity on this session, deferring expiry.
101 102 103 |
# File 'lib/vector_mcp/session.rb', line 101 def touch! @last_accessed_at = Time.now end |