actionmcp 0.60.2 → 0.71.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +46 -59
  3. data/app/controllers/action_mcp/application_controller.rb +95 -28
  4. data/app/controllers/action_mcp/oauth/metadata_controller.rb +13 -13
  5. data/app/controllers/action_mcp/oauth/registration_controller.rb +206 -0
  6. data/app/models/action_mcp/oauth_client.rb +157 -0
  7. data/app/models/action_mcp/oauth_token.rb +141 -0
  8. data/app/models/action_mcp/session/message.rb +12 -12
  9. data/app/models/action_mcp/session/resource.rb +2 -2
  10. data/app/models/action_mcp/session/sse_event.rb +2 -2
  11. data/app/models/action_mcp/session/subscription.rb +2 -2
  12. data/app/models/action_mcp/session.rb +68 -43
  13. data/config/routes.rb +1 -0
  14. data/db/migrate/20250708105124_create_action_mcp_oauth_clients.rb +42 -0
  15. data/db/migrate/20250708105226_create_action_mcp_oauth_tokens.rb +37 -0
  16. data/lib/action_mcp/capability.rb +2 -0
  17. data/lib/action_mcp/client/json_rpc_handler.rb +9 -9
  18. data/lib/action_mcp/client/jwt_client_provider.rb +134 -0
  19. data/lib/action_mcp/configuration.rb +90 -11
  20. data/lib/action_mcp/engine.rb +26 -1
  21. data/lib/action_mcp/filtered_logger.rb +32 -0
  22. data/lib/action_mcp/oauth/active_record_storage.rb +183 -0
  23. data/lib/action_mcp/oauth/memory_storage.rb +23 -1
  24. data/lib/action_mcp/oauth/middleware.rb +33 -0
  25. data/lib/action_mcp/oauth/provider.rb +49 -13
  26. data/lib/action_mcp/oauth.rb +12 -0
  27. data/lib/action_mcp/prompt.rb +14 -0
  28. data/lib/action_mcp/registry_base.rb +25 -4
  29. data/lib/action_mcp/resource_response.rb +110 -0
  30. data/lib/action_mcp/resource_template.rb +30 -2
  31. data/lib/action_mcp/server/capabilities.rb +3 -14
  32. data/lib/action_mcp/server/memory_session.rb +0 -1
  33. data/lib/action_mcp/server/prompts.rb +8 -1
  34. data/lib/action_mcp/server/resources.rb +9 -6
  35. data/lib/action_mcp/server/tools.rb +41 -20
  36. data/lib/action_mcp/server.rb +6 -3
  37. data/lib/action_mcp/sse_listener.rb +0 -7
  38. data/lib/action_mcp/test_helper.rb +5 -0
  39. data/lib/action_mcp/tool.rb +108 -4
  40. data/lib/action_mcp/tools_registry.rb +3 -0
  41. data/lib/action_mcp/version.rb +1 -1
  42. data/lib/generators/action_mcp/install/templates/mcp.yml +16 -16
  43. data/lib/tasks/action_mcp_tasks.rake +238 -0
  44. metadata +11 -1
@@ -124,4 +124,242 @@ namespace :action_mcp do
124
124
  task list: %i[list_tools list_prompts list_resources list_profiles] do
125
125
  # This task lists all tools, prompts, resources and profiles
126
126
  end
127
+
128
+ # bin/rails action_mcp:info
129
+ # bin/rails action_mcp:info[test]
130
+ desc "Display ActionMCP configuration for current or specified environment"
131
+ task :info, [ :env ] => :environment do |_t, args|
132
+ env = args[:env] || Rails.env
133
+
134
+ # Load configuration for the specified environment
135
+ original_env = Rails.env
136
+ Rails.env = env.to_s
137
+
138
+ # Reload configuration to get the environment-specific settings
139
+ config = ActionMCP::Configuration.new
140
+ config.load_profiles
141
+
142
+ puts "\e[35mActionMCP Configuration (#{env})\e[0m"
143
+ puts "\e[35m#{'=' * (25 + env.length)}\e[0m"
144
+
145
+ # Basic Information
146
+ puts "\n\e[36mBasic Information:\e[0m"
147
+ puts " Name: #{config.name}"
148
+ puts " Version: #{config.version}"
149
+ puts " Protocol Version: #{config.protocol_version}"
150
+ puts " Active Profile: #{config.active_profile}"
151
+
152
+ # Session Storage
153
+ puts "\n\e[36mSession Storage:\e[0m"
154
+ puts " Session Store Type: #{config.session_store_type}"
155
+ puts " Client Session Store: #{config.client_session_store_type || 'default'}"
156
+ puts " Server Session Store: #{config.server_session_store_type || 'default'}"
157
+
158
+ # Transport Configuration
159
+ puts "\n\e[36mTransport Configuration:\e[0m"
160
+ puts " SSE Heartbeat Interval: #{config.sse_heartbeat_interval}s"
161
+ puts " Post Response Preference: #{config.post_response_preference}"
162
+ puts " SSE Event Retention Period: #{config.sse_event_retention_period}"
163
+ puts " Max Stored SSE Events: #{config.max_stored_sse_events}"
164
+
165
+ # Pub/Sub Adapter
166
+ puts "\n\e[36mPub/Sub Adapter:\e[0m"
167
+ puts " Adapter: #{config.adapter || 'not configured'}"
168
+ if config.adapter
169
+ puts " Polling Interval: #{config.polling_interval}" if config.polling_interval
170
+ puts " Min Threads: #{config.min_threads}" if config.min_threads
171
+ puts " Max Threads: #{config.max_threads}" if config.max_threads
172
+ puts " Max Queue: #{config.max_queue}" if config.max_queue
173
+ end
174
+
175
+ # Authentication
176
+ puts "\n\e[36mAuthentication:\e[0m"
177
+ puts " Methods: #{config.authentication_methods.join(', ')}"
178
+ if config.oauth_config && config.oauth_config.any?
179
+ puts " OAuth Provider: #{config.oauth_config['provider']}"
180
+ puts " OAuth Scopes: #{config.oauth_config['scopes_supported']&.join(', ')}"
181
+ end
182
+
183
+ # Logging
184
+ puts "\n\e[36mLogging:\e[0m"
185
+ puts " Logging Enabled: #{config.logging_enabled}"
186
+ puts " Logging Level: #{config.logging_level}"
187
+
188
+ # Gateway
189
+ puts "\n\e[36mGateway:\e[0m"
190
+ puts " Gateway Class: #{config.gateway_class}"
191
+
192
+ # Capabilities
193
+ puts "\n\e[36mEnabled Capabilities:\e[0m"
194
+ capabilities = config.capabilities
195
+ if capabilities.any?
196
+ capabilities.each do |cap_name, cap_config|
197
+ puts " #{cap_name}: #{cap_config.inspect}"
198
+ end
199
+ else
200
+ puts " None"
201
+ end
202
+
203
+ # Available Profiles
204
+ puts "\n\e[36mAvailable Profiles:\e[0m"
205
+ config.profiles.each_key do |profile_name|
206
+ puts " - #{profile_name}"
207
+ end
208
+
209
+ # Restore original environment
210
+ Rails.env = original_env
211
+
212
+ puts "\n"
213
+ end
214
+
215
+ # bin/rails action_mcp:stats
216
+ desc "Display ActionMCP session and database statistics"
217
+ task stats: :environment do
218
+ puts "\e[35mActionMCP Statistics\e[0m"
219
+ puts "\e[35m===================\e[0m"
220
+
221
+ # Debug database connection
222
+ puts "\n\e[36mDatabase Debug:\e[0m"
223
+ puts " Rails Environment: #{Rails.env}"
224
+ puts " Rails Root: #{Rails.root}"
225
+ puts " Database Config: #{ActionMCP::ApplicationRecord.connection_db_config.configuration_hash.inspect}"
226
+ if ActionMCP::ApplicationRecord.connection.adapter_name.downcase.include?("sqlite")
227
+ db_path = ActionMCP::ApplicationRecord.connection_db_config.database
228
+ puts " Database Path: #{db_path}"
229
+ puts " Database Exists?: #{File.exist?(db_path)}" if db_path
230
+ end
231
+
232
+ # Session Statistics
233
+ puts "\n\e[36mSession Statistics:\e[0m"
234
+
235
+ begin
236
+ total_sessions = ActionMCP::Session.count
237
+ puts " Total Sessions: #{total_sessions}"
238
+
239
+ if total_sessions > 0
240
+ # Sessions by status
241
+ sessions_by_status = ActionMCP::Session.group(:status).count
242
+ puts " Sessions by Status:"
243
+ sessions_by_status.each do |status, count|
244
+ puts " #{status}: #{count}"
245
+ end
246
+
247
+ # Sessions by protocol version
248
+ sessions_by_protocol = ActionMCP::Session.group(:protocol_version).count
249
+ puts " Sessions by Protocol Version:"
250
+ sessions_by_protocol.each do |version, count|
251
+ puts " #{version}: #{count}"
252
+ end
253
+
254
+ # Active sessions (initialized and not ended)
255
+ active_sessions = ActionMCP::Session.where(status: "initialized", ended_at: nil).count
256
+ puts " Active Sessions: #{active_sessions}"
257
+
258
+ # Recent activity
259
+ recent_sessions = ActionMCP::Session.where("created_at > ?", 1.hour.ago).count
260
+ puts " Sessions Created (Last Hour): #{recent_sessions}"
261
+
262
+ # Session with most messages
263
+ if ActionMCP::Session.maximum(:messages_count)
264
+ busiest_session = ActionMCP::Session.order(messages_count: :desc).first
265
+ puts " Most Active Session: #{busiest_session.id} (#{busiest_session.messages_count} messages)"
266
+ end
267
+
268
+ # Average messages per session
269
+ avg_messages = ActionMCP::Session.average(:messages_count).to_f.round(2)
270
+ puts " Average Messages per Session: #{avg_messages}"
271
+ end
272
+ rescue StandardError => e
273
+ puts " Error accessing session data: #{e.message}"
274
+ puts " (Session store might be using volatile storage)"
275
+ end
276
+
277
+ # Message Statistics (if messages table exists)
278
+ puts "\n\e[36mMessage Statistics:\e[0m"
279
+
280
+ begin
281
+ if ActionMCP::ApplicationRecord.connection.table_exists?("action_mcp_session_messages")
282
+ total_messages = ActionMCP::Session::Message.count
283
+ puts " Total Messages: #{total_messages}"
284
+
285
+ if total_messages > 0
286
+ # Messages by direction
287
+ messages_by_direction = ActionMCP::Session::Message.group(:direction).count
288
+ puts " Messages by Direction:"
289
+ messages_by_direction.each do |direction, count|
290
+ puts " #{direction}: #{count}"
291
+ end
292
+
293
+ # Messages by type
294
+ messages_by_type = ActionMCP::Session::Message.group(:message_type).count.sort_by { |_type, count| -count }.first(10)
295
+ puts " Top Message Types:"
296
+ messages_by_type.each do |type, count|
297
+ puts " #{type}: #{count}"
298
+ end
299
+
300
+ # Recent messages
301
+ recent_messages = ActionMCP::Session::Message.where("created_at > ?", 1.hour.ago).count
302
+ puts " Messages (Last Hour): #{recent_messages}"
303
+ end
304
+ else
305
+ puts " Message table not found"
306
+ end
307
+ rescue StandardError => e
308
+ puts " Error accessing message data: #{e.message}"
309
+ end
310
+
311
+ # SSE Event Statistics (if table exists)
312
+ puts "\n\e[36mSSE Event Statistics:\e[0m"
313
+
314
+ begin
315
+ if ActionMCP::ApplicationRecord.connection.table_exists?("action_mcp_sse_events")
316
+ total_events = ActionMCP::Session::SSEEvent.count
317
+ puts " Total SSE Events: #{total_events}"
318
+
319
+ if total_events > 0
320
+ # Recent events
321
+ recent_events = ActionMCP::Session::SSEEvent.where("created_at > ?", 1.hour.ago).count
322
+ puts " SSE Events (Last Hour): #{recent_events}"
323
+
324
+ # Events by session
325
+ events_by_session = ActionMCP::Session::SSEEvent.joins(:session)
326
+ .group("action_mcp_sessions.id")
327
+ .count
328
+ .sort_by { |_session_id, count| -count }
329
+ .first(5)
330
+ puts " Top Sessions by SSE Events:"
331
+ events_by_session.each do |session_id, count|
332
+ puts " #{session_id}: #{count} events"
333
+ end
334
+ end
335
+ else
336
+ puts " SSE Events table not found"
337
+ end
338
+ rescue StandardError => e
339
+ puts " Error accessing SSE event data: #{e.message}"
340
+ end
341
+
342
+ # Storage Information
343
+ puts "\n\e[36mStorage Information:\e[0m"
344
+ puts " Session Store Type: #{ActionMCP.configuration.session_store_type}"
345
+ puts " Database Adapter: #{ActionMCP::ApplicationRecord.connection.adapter_name}"
346
+
347
+ # Database size (if SQLite)
348
+ begin
349
+ if ActionMCP::ApplicationRecord.connection.adapter_name.downcase.include?("sqlite")
350
+ db_config = Rails.application.config.database_configuration[Rails.env]
351
+ if db_config && db_config["database"]
352
+ db_file = db_config["database"]
353
+ if File.exist?(db_file)
354
+ size_mb = (File.size(db_file) / 1024.0 / 1024.0).round(2)
355
+ puts " Database Size: #{size_mb} MB"
356
+ end
357
+ end
358
+ end
359
+ rescue StandardError => e
360
+ puts " Could not determine database size: #{e.message}"
361
+ end
362
+
363
+ puts "\n"
364
+ end
127
365
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: actionmcp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.60.2
4
+ version: 0.71.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Abdelkader Boudih
@@ -206,8 +206,11 @@ files:
206
206
  - app/controllers/action_mcp/application_controller.rb
207
207
  - app/controllers/action_mcp/oauth/endpoints_controller.rb
208
208
  - app/controllers/action_mcp/oauth/metadata_controller.rb
209
+ - app/controllers/action_mcp/oauth/registration_controller.rb
209
210
  - app/models/action_mcp.rb
210
211
  - app/models/action_mcp/application_record.rb
212
+ - app/models/action_mcp/oauth_client.rb
213
+ - app/models/action_mcp/oauth_token.rb
211
214
  - app/models/action_mcp/session.rb
212
215
  - app/models/action_mcp/session/message.rb
213
216
  - app/models/action_mcp/session/resource.rb
@@ -218,6 +221,8 @@ files:
218
221
  - config/routes.rb
219
222
  - db/migrate/20250512154359_consolidated_migration.rb
220
223
  - db/migrate/20250608112101_add_oauth_to_sessions.rb
224
+ - db/migrate/20250708105124_create_action_mcp_oauth_clients.rb
225
+ - db/migrate/20250708105226_create_action_mcp_oauth_tokens.rb
221
226
  - exe/actionmcp_cli
222
227
  - lib/action_mcp.rb
223
228
  - lib/action_mcp/base_response.rb
@@ -231,6 +236,7 @@ files:
231
236
  - lib/action_mcp/client/collection.rb
232
237
  - lib/action_mcp/client/elicitation.rb
233
238
  - lib/action_mcp/client/json_rpc_handler.rb
239
+ - lib/action_mcp/client/jwt_client_provider.rb
234
240
  - lib/action_mcp/client/logging.rb
235
241
  - lib/action_mcp/client/messaging.rb
236
242
  - lib/action_mcp/client/oauth_client_provider.rb
@@ -262,6 +268,7 @@ files:
262
268
  - lib/action_mcp/current.rb
263
269
  - lib/action_mcp/current_helpers.rb
264
270
  - lib/action_mcp/engine.rb
271
+ - lib/action_mcp/filtered_logger.rb
265
272
  - lib/action_mcp/gateway.rb
266
273
  - lib/action_mcp/gem_version.rb
267
274
  - lib/action_mcp/instrumentation/controller_runtime.rb
@@ -272,6 +279,8 @@ files:
272
279
  - lib/action_mcp/jwt_decoder.rb
273
280
  - lib/action_mcp/log_subscriber.rb
274
281
  - lib/action_mcp/logging.rb
282
+ - lib/action_mcp/oauth.rb
283
+ - lib/action_mcp/oauth/active_record_storage.rb
275
284
  - lib/action_mcp/oauth/error.rb
276
285
  - lib/action_mcp/oauth/memory_storage.rb
277
286
  - lib/action_mcp/oauth/middleware.rb
@@ -284,6 +293,7 @@ files:
284
293
  - lib/action_mcp/renderable.rb
285
294
  - lib/action_mcp/resource.rb
286
295
  - lib/action_mcp/resource_callbacks.rb
296
+ - lib/action_mcp/resource_response.rb
287
297
  - lib/action_mcp/resource_template.rb
288
298
  - lib/action_mcp/resource_templates_registry.rb
289
299
  - lib/action_mcp/server.rb