Class: DebugMcp::Tools::RailsMailDeliveries

Inherits:
MCP::Tool
  • Object
show all
Defined in:
lib/debug_mcp/tools/rails_mail_deliveries.rb

Overview

Read ActionMailer::Base.deliveries from the running process.

Observability caveat (surfaced in every response): deliveries is only populated when delivery_method is :test. With :smtp / :letter_opener / etc. the array is usually empty, so an empty result is NOT proof that no mail was sent — it may simply not be observable this way.

PII: recipients, subject and body can contain personal data or secrets, and Rails’ filter_parameters does NOT apply to this path. Bodies are truncated to a preview by default; attachment CONTENT is never returned (only name and content type).

Constant Summary collapse

DEFAULT_LIMIT =
20
MAX_LIMIT =
200
DEFAULT_PREVIEW_CHARS =
500
MAX_PREVIEW_CHARS =
5000
MAX_BODY_CHARS =

Hard ceiling applied even when include_body is true, so a multi-megabyte body can never cross the line-oriented debug socket as one JSON line.

50_000

Class Method Summary collapse

Class Method Details

.call(limit: nil, include_body: false, body_preview_chars: nil, session_id: nil, server_context:) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/debug_mcp/tools/rails_mail_deliveries.rb', line 67

def call(limit: nil, include_body: false, body_preview_chars: nil, session_id: nil, server_context:)
  client = server_context[:session_manager].client(session_id)
  client.auto_repause!
  RailsHelper.require_rails!(client)

  # The probe iterates Mail objects and puts a JSON line; both need a
  # normal (non-trap) paused context.
  if RailsHelper.trap_context?(client)
    return text_response("Rails mail deliveries: unavailable in trap context.\n\n" \
                         "#{RailsHelper::TRAP_CONTEXT_HINT}")
  end

  data = fetch_deliveries(
    client,
    limit: resolve_limit(limit),
    include_body: include_body ? true : false,
    preview_chars: resolve_preview(body_preview_chars),
  )

  if data.nil? || data.empty? || data[:error]
    msg = data && data[:error] ? "Error: #{data[:error]}" : "Rails mail deliveries: unavailable."
    msg += "\n\n#{RailsHelper::TRAP_CONTEXT_HINT}" if RailsHelper.trap_context?(client)
    return text_response(msg)
  end

  text_response(format_output(data))
rescue DebugMcp::Error => e
  text_response("Error: #{e.message}")
end