Class: RailsVitals::MCP::Tools::ExplainQuery
- Defined in:
- lib/rails_vitals/mcp/tools/explain_query.rb
Constant Summary collapse
- TOOL_NAME =
"railsvitals_explain_query"- DESCRIPTION =
<<~DESC.strip Runs EXPLAIN ANALYZE on a SELECT query and returns the execution plan summary: total cost, actual execution time, rows examined, detected warnings (Seq Scan, Sort without index, large Nested Loop), and deterministic fix suggestions with migration hints. Only SELECT statements are accepted — any SQL containing DML keywords (INSERT, UPDATE, DELETE, DROP, TRUNCATE, ALTER) is rejected, including CTEs. Use this to investigate a specific slow query from railsvitals_get_slow_queries. When presenting results, always lead with the interpretation field as a plain-English verdict. Then highlight each warning by name and explain what it means for this specific query (table name, rows scanned). For each suggestion, show the body explanation first, then the migration snippet in a code block, then the generator command if present. Avoid listing raw numbers without context — translate total_cost and rows_examined into plain language (e.g. "scanned 50,000 rows to return 3" instead of "rows_examined: 50000"). DESC
- INPUT_SCHEMA =
{ type: "object", required: [ "sql" ], properties: { sql: { type: "string", description: "The SELECT query to explain. Must not contain INSERT, UPDATE, DELETE, DROP, TRUNCATE, or ALTER — including inside CTEs." } } }.freeze
- DML_PATTERN =
/\b(INSERT|UPDATE|DELETE|DROP|TRUNCATE|ALTER|CREATE)\b/i.freeze
Instance Method Summary collapse
Methods inherited from Base
Instance Method Details
#call(params) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/rails_vitals/mcp/tools/explain_query.rb', line 36 def call(params) sql = params[:sql] || params["sql"] return missing_sql_response if sql.nil? || sql.strip.empty? return rejected_sql_response(sql) if dml_present?(sql) result = Analyzers::ExplainAnalyzer.analyze(sql.strip) return error_response(result.error) if result.error { sql: result.sql, total_cost: result.total_cost, actual_time_ms: result.actual_time_ms, rows_examined: result.rows_examined, warnings: serialize_warnings(result.warnings), suggestions: serialize_suggestions(result.suggestions), interpretation: result.interpretation } end |