Class: DebugMcp::Tools::RailsRecentEvents
- Inherits:
-
MCP::Tool
- Object
- MCP::Tool
- DebugMcp::Tools::RailsRecentEvents
- Defined in:
- lib/debug_mcp/tools/rails_recent_events.rb
Overview
Read recent Rails internal events (SQL, render, cache, job enqueue, request lifecycle) from the in-process Notifications buffer, independent of trigger_request.
IMPORTANT semantics, surfaced in every response so the model does not mistake “empty” for “nothing happened”:
-
forward-only: only events fired AFTER the subscriber was installed are visible. The first call installs the subscriber, so it usually returns little or nothing — that is not evidence that no SQL/jobs ran.
-
paused-only: the target must be paused at a debugger prompt (we send commands over the debug socket).
-
NOT read-only: installing the subscriber subscribes to ActiveSupport::Notifications inside the target — an in-process instrumentation side effect (no application data is written).
Constant Summary collapse
- DEFAULT_LIMIT =
50- MAX_LIMIT =
500- KIND_MATCHERS =
{ "sql" => ->(name) { name == "sql.active_record" }, "render" => ->(name) { name.start_with?("render_") }, "cache" => ->(name) { name.start_with?("cache_") }, "job" => ->(name) { name == "enqueue.active_job" }, "request" => ->(name) { name.end_with?(".action_controller") }, }.freeze
Class Method Summary collapse
Class Method Details
.call(kinds: nil, limit: nil, after_seq: nil, include_debug_eval: false, session_id: nil, server_context:) ⇒ Object
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/debug_mcp/tools/rails_recent_events.rb', line 82 def call(kinds: nil, limit: nil, after_seq: nil, include_debug_eval: false, session_id: nil, server_context:) client = server_context[:session_manager].client(session_id) client.auto_repause! RailsHelper.require_rails!(client) # Reads and install both send commands over the debug socket and both # take the buffer/Notifications mutex, which fails in trap context. if RailsHelper.trap_context?(client) return text_response("Rails recent events: unavailable in trap context.\n\n" \ "#{RailsHelper::TRAP_CONTEXT_HINT}") end installed = NotificationsSubscriber.install(client) unless installed return text_response("Rails recent events: could not install the Notifications subscriber " \ "in the target process.\n\n#{RailsHelper::TRAP_CONTEXT_HINT}") end limit = resolve_limit(limit) events = fetch_events(client, after_seq: after_seq, limit: limit) events = filter_by_kinds(events, kinds) = NotificationsSubscriber.(client) # `installed` is the result of the install we just performed — the only # trustworthy signal here. metadata[:installed] can be missing if the # metadata round-trip itself returned no parseable object. text_response(build_output(events, , kinds, include_debug_eval, limit, installed)) rescue DebugMcp::Error => e text_response("Error: #{e.}") end |