Class: ActionMCP::Server::BaseSession
- Inherits:
-
Object
- Object
- ActionMCP::Server::BaseSession
show all
- Defined in:
- lib/action_mcp/server/base_session.rb
Overview
Base session object that mimics ActiveRecord Session with common functionality
Defined Under Namespace
Classes: MessageCollection, SubscriptionCollection
Instance Attribute Summary collapse
Instance Method Summary
collapse
Constructor Details
#initialize(attributes = {}, store = nil) ⇒ BaseSession
Returns a new instance of BaseSession.
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
# File 'lib/action_mcp/server/base_session.rb', line 14
def initialize(attributes = {}, store = nil)
@store = store
@messages = Concurrent::Array.new
@subscriptions = Concurrent::Array.new
@message_counter = Concurrent::AtomicFixnum.new(0)
@new_record = true
@consents = {}
@session_data = {}
attributes.each do |key, value|
send("#{key}=", value) if respond_to?("#{key}=")
end
end
|
Instance Attribute Details
#client_capabilities ⇒ Object
Returns the value of attribute client_capabilities.
7
8
9
|
# File 'lib/action_mcp/server/base_session.rb', line 7
def client_capabilities
@client_capabilities
end
|
#client_info ⇒ Object
Returns the value of attribute client_info.
7
8
9
|
# File 'lib/action_mcp/server/base_session.rb', line 7
def client_info
@client_info
end
|
#consents ⇒ Object
Returns the value of attribute consents.
7
8
9
|
# File 'lib/action_mcp/server/base_session.rb', line 7
def consents
@consents
end
|
#created_at ⇒ Object
Returns the value of attribute created_at.
7
8
9
|
# File 'lib/action_mcp/server/base_session.rb', line 7
def created_at
@created_at
end
|
#ended_at ⇒ Object
Returns the value of attribute ended_at.
7
8
9
|
# File 'lib/action_mcp/server/base_session.rb', line 7
def ended_at
@ended_at
end
|
#id ⇒ Object
Returns the value of attribute id.
7
8
9
|
# File 'lib/action_mcp/server/base_session.rb', line 7
def id
@id
end
|
#initialized ⇒ Object
Returns the value of attribute initialized.
7
8
9
|
# File 'lib/action_mcp/server/base_session.rb', line 7
def initialized
@initialized
end
|
#last_event_id ⇒ Object
Returns the value of attribute last_event_id.
7
8
9
|
# File 'lib/action_mcp/server/base_session.rb', line 7
def last_event_id
@last_event_id
end
|
#messages_count ⇒ Object
Returns the value of attribute messages_count.
7
8
9
|
# File 'lib/action_mcp/server/base_session.rb', line 7
def messages_count
@messages_count
end
|
#prompt_registry ⇒ Object
Returns the value of attribute prompt_registry.
7
8
9
|
# File 'lib/action_mcp/server/base_session.rb', line 7
def prompt_registry
@prompt_registry
end
|
#protocol_version ⇒ Object
Returns the value of attribute protocol_version.
7
8
9
|
# File 'lib/action_mcp/server/base_session.rb', line 7
def protocol_version
@protocol_version
end
|
#resource_registry ⇒ Object
Returns the value of attribute resource_registry.
7
8
9
|
# File 'lib/action_mcp/server/base_session.rb', line 7
def resource_registry
@resource_registry
end
|
#role ⇒ Object
Returns the value of attribute role.
7
8
9
|
# File 'lib/action_mcp/server/base_session.rb', line 7
def role
@role
end
|
#server_capabilities ⇒ Object
Returns the value of attribute server_capabilities.
7
8
9
|
# File 'lib/action_mcp/server/base_session.rb', line 7
def server_capabilities
@server_capabilities
end
|
#server_info ⇒ Object
Returns the value of attribute server_info.
7
8
9
|
# File 'lib/action_mcp/server/base_session.rb', line 7
def server_info
@server_info
end
|
#session_data ⇒ Object
Returns the value of attribute session_data.
7
8
9
|
# File 'lib/action_mcp/server/base_session.rb', line 7
def session_data
@session_data
end
|
#status ⇒ Object
Returns the value of attribute status.
7
8
9
|
# File 'lib/action_mcp/server/base_session.rb', line 7
def status
@status
end
|
Returns the value of attribute tool_registry.
7
8
9
|
# File 'lib/action_mcp/server/base_session.rb', line 7
def tool_registry
@tool_registry
end
|
#updated_at ⇒ Object
Returns the value of attribute updated_at.
7
8
9
|
# File 'lib/action_mcp/server/base_session.rb', line 7
def updated_at
@updated_at
end
|
Instance Method Details
#begin_initialization! ⇒ Object
73
74
75
76
77
78
|
# File 'lib/action_mcp/server/base_session.rb', line 73
def begin_initialization!
return false unless status == "pre_initialize" && !initialized?
self.status = "initializing"
save
end
|
#cancel_in_flight_request(request_id) ⇒ Object
111
112
113
114
115
116
117
118
119
120
|
# File 'lib/action_mcp/server/base_session.rb', line 111
def cancel_in_flight_request(request_id)
return if request_id.nil?
request = received_requests_with_id(request_id).find do |message|
!message[:request_acknowledged] && !message[:request_cancelled]
end
return if request && message_payload(request)[:method] == JsonRpcHandlerBase::Methods::INITIALIZE
request&.tap { |message| message[:request_cancelled] = true }
end
|
#client_request_for_progress(progress_token) ⇒ Object
122
123
124
125
126
127
128
129
|
# File 'lib/action_mcp/server/base_session.rb', line 122
def client_request_for_progress(progress_token)
return if progress_token.nil?
issued_client_requests.find do |request|
message_payload(request).dig(:params, :_meta, :progressToken) == progress_token &&
client_request_accepts_progress?(request)
end
end
|
#client_request_for_task(task_id) ⇒ Object
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
# File 'lib/action_mcp/server/base_session.rb', line 131
def client_request_for_task(task_id)
return unless task_id.is_a?(String) && task_id.present?
response = @messages.reverse_each.find do |message|
message[:direction] == role &&
message_payload(message).dig(:result, :task, :taskId) == task_id
end
return unless response
response_id = message_payload(response)[:id]
issued_client_requests.find do |request|
payload = message_payload(request)
payload[:id] == response_id && payload.dig(:params, :task).is_a?(Hash)
end
end
|
#close! ⇒ Object
88
89
90
91
92
|
# File 'lib/action_mcp/server/base_session.rb', line 88
def close!
self.status = "closed"
self.ended_at = Time.current
save
end
|
#consent_granted_for?(key) ⇒ Boolean
Consent management methods
294
295
296
297
298
|
# File 'lib/action_mcp/server/base_session.rb', line 294
def consent_granted_for?(key)
consents_hash = consents.is_a?(String) ? JSON.parse(consents) : consents
consents_hash ||= {}
consents_hash[key] == true
end
|
#destroy ⇒ Object
61
62
63
|
# File 'lib/action_mcp/server/base_session.rb', line 61
def destroy
@store&.delete_session(id)
end
|
#grant_consent(key) ⇒ Object
300
301
302
303
304
305
306
|
# File 'lib/action_mcp/server/base_session.rb', line 300
def grant_consent(key)
consents_hash = consents.is_a?(String) ? JSON.parse(consents) : consents
consents_hash ||= {}
consents_hash[key] = true
self.consents = consents_hash
save!
end
|
#initialize! ⇒ Object
80
81
82
83
84
85
86
|
# File 'lib/action_mcp/server/base_session.rb', line 80
def initialize!
return false unless status == "initializing" && !initialized?
self.initialized = true
self.status = "initialized"
save
end
|
#initialized? ⇒ Boolean
69
70
71
|
# File 'lib/action_mcp/server/base_session.rb', line 69
def initialized?
initialized
end
|
#messages ⇒ Object
103
104
105
|
# File 'lib/action_mcp/server/base_session.rb', line 103
def messages
MessageCollection.new(@messages)
end
|
#new_record? ⇒ Boolean
ActiveRecord-like interface
31
32
33
|
# File 'lib/action_mcp/server/base_session.rb', line 31
def new_record?
@new_record
end
|
#persisted? ⇒ Boolean
35
36
37
|
# File 'lib/action_mcp/server/base_session.rb', line 35
def persisted?
!@new_record
end
|
#read(data) ⇒ Object
99
100
101
|
# File 'lib/action_mcp/server/base_session.rb', line 99
def read(data)
record_message(data, role)
end
|
#register_prompt(prompt_class_or_name) ⇒ Object
223
224
225
226
227
228
229
230
231
232
233
234
|
# File 'lib/action_mcp/server/base_session.rb', line 223
def register_prompt(prompt_class_or_name)
prompt_name = normalize_name(prompt_class_or_name, :prompt)
return false unless prompt_exists?(prompt_name)
self.prompt_registry ||= []
unless self.prompt_registry.include?(prompt_name)
self.prompt_registry << prompt_name
save!
send_prompts_list_changed_notification
end
true
end
|
#register_resource_template(template_class_or_name) ⇒ Object
246
247
248
249
250
251
252
253
254
255
256
257
|
# File 'lib/action_mcp/server/base_session.rb', line 246
def register_resource_template(template_class_or_name)
template_name = normalize_name(template_class_or_name, :resource_template)
return false unless resource_template_exists?(template_name)
self.resource_registry ||= []
unless self.resource_registry.include?(template_name)
self.resource_registry << template_name
save!
send_resources_list_changed_notification
end
true
end
|
Registry management methods
200
201
202
203
204
205
206
207
208
209
210
211
|
# File 'lib/action_mcp/server/base_session.rb', line 200
def register_tool(tool_class_or_name)
tool_name = normalize_name(tool_class_or_name, :tool)
return false unless tool_exists?(tool_name)
self.tool_registry ||= []
unless self.tool_registry.include?(tool_name)
self.tool_registry << tool_name
save!
send_tools_list_changed_notification
end
true
end
|
#registered_prompts ⇒ Object
277
278
279
280
281
282
283
|
# File 'lib/action_mcp/server/base_session.rb', line 277
def registered_prompts
(self.prompt_registry || []).filter_map do |prompt_name|
ActionMCP::PromptsRegistry.find(prompt_name)
rescue StandardError
nil
end
end
|
#registered_resource_templates ⇒ Object
285
286
287
288
289
290
291
|
# File 'lib/action_mcp/server/base_session.rb', line 285
def registered_resource_templates
(self.resource_registry || []).filter_map do |template_name|
ActionMCP::ResourceTemplatesRegistry.find(template_name)
rescue StandardError
nil
end
end
|
269
270
271
272
273
274
275
|
# File 'lib/action_mcp/server/base_session.rb', line 269
def registered_tools
(self.tool_registry || []).filter_map do |tool_name|
ActionMCP::ToolsRegistry.find(tool_name)
rescue StandardError
nil
end
end
|
#reload ⇒ Object
65
66
67
|
# File 'lib/action_mcp/server/base_session.rb', line 65
def reload
self
end
|
#resource_subscribe(uri) ⇒ Object
174
175
176
177
178
|
# File 'lib/action_mcp/server/base_session.rb', line 174
def resource_subscribe(uri)
return if @subscriptions.any? { |s| s[:uri] == uri }
@subscriptions << { uri: uri, created_at: Time.current }
end
|
#resource_subscribed?(uri) ⇒ Boolean
184
185
186
|
# File 'lib/action_mcp/server/base_session.rb', line 184
def resource_subscribed?(uri)
@subscriptions.any? { |subscription| subscription[:uri] == uri }
end
|
#resource_unsubscribe(uri) ⇒ Object
180
181
182
|
# File 'lib/action_mcp/server/base_session.rb', line 180
def resource_unsubscribe(uri)
@subscriptions.delete_if { |s| s[:uri] == uri }
end
|
#revoke_consent(key) ⇒ Object
308
309
310
311
312
313
314
|
# File 'lib/action_mcp/server/base_session.rb', line 308
def revoke_consent(key)
consents_hash = consents.is_a?(String) ? JSON.parse(consents) : consents
consents_hash ||= {}
consents_hash.delete(key)
self.consents = consents_hash
save!
end
|
#save ⇒ Object
39
40
41
42
43
44
|
# File 'lib/action_mcp/server/base_session.rb', line 39
def save
self.updated_at = Time.current
@store&.save_session(self)
@new_record = false
true
end
|
#save! ⇒ Object
46
47
48
|
# File 'lib/action_mcp/server/base_session.rb', line 46
def save!
save
end
|
#send_progress_notification(progressToken:, progress:, total: nil, message: nil) ⇒ Object
189
190
191
192
193
194
195
196
197
|
# File 'lib/action_mcp/server/base_session.rb', line 189
def send_progress_notification(progressToken:, progress:, total: nil, message: nil)
handler = ActionMCP::Server::TransportHandler.new(self)
handler.send_progress_notification(
progressToken: progressToken,
progress: progress,
total: total,
message: message
)
end
|
#server_capabilities_payload ⇒ Object
148
149
150
151
152
153
154
155
156
157
158
|
# File 'lib/action_mcp/server/base_session.rb', line 148
def server_capabilities_payload
payload = {
protocolVersion: ActionMCP::LATEST_VERSION,
serverInfo: server_info,
capabilities: capabilities_for_protocol(server_capabilities)
}
instructions = ActionMCP.configuration.instructions
payload[:instructions] = instructions if instructions
payload
end
|
#set_protocol_version(version) ⇒ Object
160
161
162
163
|
# File 'lib/action_mcp/server/base_session.rb', line 160
def set_protocol_version(version)
self.protocol_version = version
save
end
|
#store_client_capabilities(capabilities) ⇒ Object
169
170
171
|
# File 'lib/action_mcp/server/base_session.rb', line 169
def store_client_capabilities(capabilities)
self.client_capabilities = capabilities
end
|
#store_client_info(info) ⇒ Object
165
166
167
|
# File 'lib/action_mcp/server/base_session.rb', line 165
def store_client_info(info)
self.client_info = info
end
|
#subscriptions ⇒ Object
107
108
109
|
# File 'lib/action_mcp/server/base_session.rb', line 107
def subscriptions
SubscriptionCollection.new(@subscriptions)
end
|
#unregister_prompt(prompt_class_or_name) ⇒ Object
236
237
238
239
240
241
242
243
244
|
# File 'lib/action_mcp/server/base_session.rb', line 236
def unregister_prompt(prompt_class_or_name)
prompt_name = normalize_name(prompt_class_or_name, :prompt)
self.prompt_registry ||= []
return unless self.prompt_registry.delete(prompt_name)
save!
send_prompts_list_changed_notification
end
|
#unregister_resource_template(template_class_or_name) ⇒ Object
259
260
261
262
263
264
265
266
267
|
# File 'lib/action_mcp/server/base_session.rb', line 259
def unregister_resource_template(template_class_or_name)
template_name = normalize_name(template_class_or_name, :resource_template)
self.resource_registry ||= []
return unless self.resource_registry.delete(template_name)
save!
send_resources_list_changed_notification
end
|
213
214
215
216
217
218
219
220
221
|
# File 'lib/action_mcp/server/base_session.rb', line 213
def unregister_tool(tool_class_or_name)
tool_name = normalize_name(tool_class_or_name, :tool)
self.tool_registry ||= []
return unless self.tool_registry.delete(tool_name)
save!
send_tools_list_changed_notification
end
|
#update(attributes) ⇒ Object
50
51
52
53
54
55
|
# File 'lib/action_mcp/server/base_session.rb', line 50
def update(attributes)
attributes.each do |key, value|
send("#{key}=", value) if respond_to?("#{key}=")
end
save
end
|
#update!(attributes) ⇒ Object
57
58
59
|
# File 'lib/action_mcp/server/base_session.rb', line 57
def update!(attributes)
update(attributes)
end
|
#write(data) ⇒ Object
95
96
97
|
# File 'lib/action_mcp/server/base_session.rb', line 95
def write(data)
record_message(data, writer_role)
end
|