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
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.
-
#request_header(name) ⇒ String?
deprecated
Deprecated.
Will be removed in 0.7. Use the per-request invocation's Invocation#request_header instead.
-
#request_headers? ⇒ Boolean
deprecated
Deprecated.
Will be removed in 0.7. Use the per-request invocation's Invocation#request_headers? instead.
-
#request_param(name) ⇒ String?
deprecated
Deprecated.
Will be removed in 0.7. Use the per-request invocation's Invocation#request_param instead.
-
#request_params? ⇒ Boolean
deprecated
Deprecated.
Will be removed in 0.7. Use the per-request invocation's Invocation#request_params? instead.
-
#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.
-
#update_request_context(**attributes) ⇒ RequestContext
deprecated
Deprecated.
Will be removed in 0.7. Use the per-request invocation's Invocation#update_request_context instead.
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
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 |
#request_header(name) ⇒ String?
Will be removed in 0.7. Use the per-request invocation's Invocation#request_header instead.
Returns The header value or nil if not found.
166 167 168 169 |
# File 'lib/vector_mcp/session.rb', line 166 def request_header(name) deprecated_request_api(:request_header) @request_context.header(name) end |
#request_headers? ⇒ Boolean
Will be removed in 0.7. Use the per-request invocation's Invocation#request_headers? instead.
Returns True if the request context has headers.
149 150 151 152 |
# File 'lib/vector_mcp/session.rb', line 149 def request_headers? deprecated_request_api(:request_headers?) @request_context.headers? end |
#request_param(name) ⇒ String?
Will be removed in 0.7. Use the per-request invocation's Invocation#request_param instead.
Returns The parameter value or nil if not found.
175 176 177 178 |
# File 'lib/vector_mcp/session.rb', line 175 def request_param(name) deprecated_request_api(:request_param) @request_context.param(name) end |
#request_params? ⇒ Boolean
Will be removed in 0.7. Use the per-request invocation's Invocation#request_params? instead.
Returns True if the request context has parameters.
157 158 159 160 |
# File 'lib/vector_mcp/session.rb', line 157 def request_params? deprecated_request_api(:request_params?) @request_context.params? 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.
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
# File 'lib/vector_mcp/session.rb', line 197 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 |
#update_request_context(**attributes) ⇒ RequestContext
Will be removed in 0.7. Use the per-request invocation's Invocation#update_request_context instead.
Updates the request context with new data.
141 142 143 144 |
# File 'lib/vector_mcp/session.rb', line 141 def update_request_context(**attributes) deprecated_request_api(:update_request_context) @request_context = @request_context.merge(attributes) end |