-
-
Notifications
You must be signed in to change notification settings - Fork 20
Feat/additional tools #85
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Signed-off-by: Tommy Nguyen <tuannvm@hotmail.com>
Signed-off-by: Tommy Nguyen <tuannvm@hotmail.com>
Caution Review failedThe pull request is closed. WalkthroughAdds an explain_query MCP tool and documentation, implements TrinoHandlers.ExplainQuery and Client.ExplainQuery, updates tool registrations to optionally apply OAuth middleware, and formats explain results as indented JSON text. No public API breaking changes detected. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant MCP as MCP Server
participant H as TrinoHandlers
participant M as OAuthMiddleware (optional)
participant C as TrinoClient
participant DB as Trino
rect rgb(240,248,255)
note over User,MCP: explain_query flow
User->>MCP: callTool(explain_query, {query, format?})
MCP->>H: invoke handler
alt OAuth enabled
H->>M: apply middleware -> handler
M->>H: authenticated call
end
H->>C: ExplainQuery(query, format?)
C->>DB: EXPLAIN [TYPE <FORMAT>] <query>
DB-->>C: plan rows
C-->>H: []map[string]interface{}
H-->>MCP: CallToolResult{text: JSON(plan)}
MCP-->>User: result
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. 📜 Recent review detailsConfiguration used: CodeRabbit UI 💡 Knowledge Base configuration:
You can enable these sources in your CodeRabbit configuration. 📒 Files selected for processing (3)
✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
internal/trino/client.go (1)
131-136
: Log a warning when write queries are allowed (per guidelines).When TRINO_ALLOW_WRITE_QUERIES=true (c.config.AllowWriteQueries), the client must log a warning before executing non-read-only queries. This is currently missing.
Apply this diff to add the warning while avoiding duplicate isReadOnly checks:
- // SQL injection protection: only allow read-only queries unless explicitly allowed in config - if !c.config.AllowWriteQueries && !isReadOnlyQuery(query) { + // SQL injection protection: only allow read-only queries unless explicitly allowed in config + isRO := isReadOnlyQuery(query) + if !c.config.AllowWriteQueries && !isRO { return nil, fmt.Errorf("security restriction: only SELECT, SHOW, DESCRIBE, and EXPLAIN queries are allowed. " + "Set TRINO_ALLOW_WRITE_QUERIES=true to enable write operations (at your own risk)") } + if c.config.AllowWriteQueries && !isRO { + log.Printf("WARNING: executing non-read-only query with TRINO_ALLOW_WRITE_QUERIES=true. Proceed with caution.") + }
🧹 Nitpick comments (4)
internal/trino/client.go (1)
300-322
: Optional hardening: quote identifiers in SHOW STATS table reference.Currently table identifiers are interpolated directly. While we restrict to read-only statements, defensive quoting of identifiers (catalog/schema/table parts) avoids malformed identifiers or accidental token injection.
Consider a helper like:
- Split the fully-qualified name into parts, escape embedded double quotes by doubling them, wrap each with ".
Example inside this method:
- For 3 parts: SHOW STATS FOR "cat"."sch"."tbl"
- For 2 parts: SHOW STATS FOR "cat".<parts[0]>."<parts[1]>"
- For 1 part: SHOW STATS FOR "cat"."sch"."tbl"
I can draft a small quoteIdent helper if you want to proceed.
README.md (1)
586-675
: Doc-response shape likely does not match actual server output for EXPLAIN.Handlers/client return raw rows/columns from Trino (marshaled JSON), typically a single text column "Query Plan" for EXPLAIN/EXPLAIN (TYPE DISTRIBUTED). The documented response under explain_query shows a structured execution_plan array with stages/operations, which the code does not produce.
Please either:
- Update the docs to reflect the actual raw EXPLAIN output (e.g., {"columns":["Query Plan"], "data":[["Fragment 0 ...\n..."]]}), or
- Enhance the handler to parse Trino’s plan text into the documented structured execution_plan.
Additionally, the parameter description says “DISTRIBUTED (default)”. With current code, default is Trino’s LOGICAL plan unless a format is provided. Align the description after deciding on code behavior. I can prepare a doc update patch once you decide.
internal/mcp/handlers.go (2)
197-236
: Minor validation hardening: reject empty query strings.The handler checks type but not emptiness. Empty/whitespace-only queries will produce avoidable errors downstream.
Add a trim/emptiness check after extracting query:
- If empty, return a tool error “query parameter must not be empty”.
I can provide a small patch (will require adding strings import) if you want it in this PR.
238-282
: Minor validation hardening: reject empty table names.Similarly, validate the required table parameter for emptiness after type assertion to avoid downstream SQL errors.
Add a whitespace trim and ensure non-empty before proceeding. I can send a small patch (will require strings import).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
README.md
(2 hunks)internal/mcp/handlers.go
(2 hunks)internal/trino/client.go
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
internal/trino/client.go
📄 CodeRabbit Inference Engine (CLAUDE.md)
internal/trino/client.go
: The client layer in internal/trino/client.go must manage database connections with pooling, enforce SQL injection protection via read-only query enforcement, handle context-based timeouts for queries, and process/format query results.
The isReadOnlyQuery() function in internal/trino/client.go must allow only SELECT, SHOW, DESCRIBE, EXPLAIN, and WITH (CTEs) queries by default, blocking INSERT, UPDATE, DELETE, CREATE, DROP, and ALTER unless TRINO_ALLOW_WRITE_QUERIES=true is set, in which case a warning must be logged.
The connection pool must be configured with a maximum of 10 open connections, 5 max idle connections, and a 5-minute maximum lifetime.
Files:
internal/trino/client.go
🧠 Learnings (5)
📓 Common learnings
Learnt from: CR
PR: tuannvm/mcp-trino#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-25T23:51:10.585Z
Learning: Applies to internal/handlers/trino_handlers.go : The handler layer in internal/handlers/trino_handlers.go must implement MCP tools with JSON response formatting, parameter validation, error handling, consistent logging, and tool result standardization.
📚 Learning: 2025-07-25T23:51:10.585Z
Learnt from: CR
PR: tuannvm/mcp-trino#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-25T23:51:10.585Z
Learning: Applies to internal/handlers/trino_handlers.go : The handler layer in internal/handlers/trino_handlers.go must implement MCP tools with JSON response formatting, parameter validation, error handling, consistent logging, and tool result standardization.
Applied to files:
internal/mcp/handlers.go
📚 Learning: 2025-07-25T23:51:10.585Z
Learnt from: CR
PR: tuannvm/mcp-trino#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-25T23:51:10.585Z
Learning: Applies to internal/handlers/trino_handlers.go : All MCP tool endpoints (execute_query, list_catalogs, list_schemas, list_tables, get_table_schema) must return JSON-formatted responses and handle parameter validation.
Applied to files:
internal/mcp/handlers.go
📚 Learning: 2025-07-25T23:51:10.585Z
Learnt from: CR
PR: tuannvm/mcp-trino#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-25T23:51:10.585Z
Learning: Applies to internal/handlers/trino_handlers.go : All MCP tool endpoints must handle parameter validation and error handling consistently.
Applied to files:
internal/mcp/handlers.go
📚 Learning: 2025-07-25T23:51:10.585Z
Learnt from: CR
PR: tuannvm/mcp-trino#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-25T23:51:10.585Z
Learning: Applies to internal/handlers/trino_handlers.go : Tool result standardization must be enforced in handler responses.
Applied to files:
internal/mcp/handlers.go
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Build Verification
🔇 Additional comments (2)
README.md (1)
45-45
: Diagram update looks good.Tools list includes the two new entries and remains consistent with the rest of the doc.
internal/mcp/handlers.go (1)
326-331
: I need to inspect theExplainQuery
handler implementation to verify the actual default and acceptedformat
values. Let me run a quick search ininternal/mcp/handlers.go
to see how"format"
is parsed and what defaults are applied.
Signed-off-by: Tommy Nguyen <tuannvm@hotmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
internal/mcp/handlers.go (1)
308-311
: Resolved: Schema-browsing description now matches behavior (single catalog).This addresses the earlier review about “all catalogs” wording. Thanks for fixing.
🧹 Nitpick comments (5)
internal/mcp/handlers.go (5)
197-236
: Validateformat
against allowed values in ExplainQuery.Prevent avoidable round-trips by rejecting invalid plan types early.
Apply this diff inside ExplainQuery to validate
format
:// Extract optional format parameter var format string if formatParam, ok := args["format"].(string); ok { format = formatParam } + // Validate format value (if provided) + if format != "" { + switch format { + case "LOGICAL", "DISTRIBUTED", "VALIDATE", "IO": + // ok + default: + mcpErr := fmt.Errorf("invalid format %q; must be one of LOGICAL, DISTRIBUTED, VALIDATE, IO", format) + return mcp.NewToolResultErrorFromErr(mcpErr.Error(), mcpErr), nil + } + } // Execute the explain query results, err := h.TrinoClient.ExplainQuery(query, format)
228-236
: Optional: Standardize tool responses with a simple envelope.You currently return raw JSON for each tool. For consistency across tools and to make future evolution easier, consider a small envelope like {"data": ...}. This aligns with the “tool result standardization” preference in prior guidance.
Outside this block, you could add:
type toolResponse struct { Data any `json:"data"` }And replace:
- json.MarshalIndent(results, "", " ")
with:- json.MarshalIndent(toolResponse{Data: results}, "", " ")
241-246
: Minor: Factor out repeated argument parsing.The map assertion + error pattern is repeated across handlers. A tiny helper reduces duplication and keeps error messages consistent.
Example helper (place at package level):
func parseArgs(req mcp.CallToolRequest) (map[string]interface{}, error) { args, ok := req.Params.Arguments.(map[string]interface{}) if !ok { return nil, fmt.Errorf("invalid arguments format: got %T", req.Params.Arguments) } return args, nil }Then replace this block with:
args, err := parseArgs(request) if err != nil { return mcp.NewToolResultErrorFromErr(err.Error(), err), nil }
300-304
: Nit: Clarify overlap between execute_query and explain_query.Since a dedicated
explain_query
tool now exists, hint users to prefer it for plan analysis.- mcp.WithDescription("Execute SQL queries on Trino's fast distributed query engine for big data analytics. Run SELECT, SHOW, DESCRIBE, EXPLAIN statements across multiple data sources simultaneously. Perfect for complex analytics, aggregations, joins, and cross-system data exploration on large datasets."), + mcp.WithDescription("Execute SQL queries on Trino's fast distributed query engine for big data analytics. Run SELECT, SHOW, DESCRIBE, EXPLAIN statements across multiple data sources simultaneously. Perfect for complex analytics, aggregations, joins, and cross-system data exploration on large datasets. For plan analysis without execution, prefer the `explain_query` tool."),
314-317
: Align list_tables description with actual scoping behavior.“Browse all available data across the distributed system” over-promises; the handler lists tables for one catalog/schema (with optional defaults).
- mcp.WithDescription("Discover tables and views available for querying in Trino schemas. Essential for finding datasets to analyze. Can scope to specific catalog/schema or browse all available data across the distributed system."), - mcp.WithString("catalog", mcp.Description("Trino catalog name (optional)")), - mcp.WithString("schema", mcp.Description("Schema name within catalog (optional)"))), + mcp.WithDescription("Discover tables and views available for querying in Trino schemas. Essential for finding datasets to analyze. Scope to a specific catalog/schema; if omitted, the server default(s) are used."), + mcp.WithString("catalog", mcp.Description("Trino catalog name (optional; defaults to server configuration if omitted)")), + mcp.WithString("schema", mcp.Description("Schema name within catalog (optional; defaults to server configuration if omitted)"))),
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
internal/mcp/handlers.go
(2 hunks)internal/trino/client.go
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- internal/trino/client.go
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
PR: tuannvm/mcp-trino#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-25T23:51:10.585Z
Learning: Applies to internal/handlers/trino_handlers.go : The handler layer in internal/handlers/trino_handlers.go must implement MCP tools with JSON response formatting, parameter validation, error handling, consistent logging, and tool result standardization.
📚 Learning: 2025-07-25T23:51:10.585Z
Learnt from: CR
PR: tuannvm/mcp-trino#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-25T23:51:10.585Z
Learning: Applies to internal/handlers/trino_handlers.go : The handler layer in internal/handlers/trino_handlers.go must implement MCP tools with JSON response formatting, parameter validation, error handling, consistent logging, and tool result standardization.
Applied to files:
internal/mcp/handlers.go
📚 Learning: 2025-07-25T23:51:10.585Z
Learnt from: CR
PR: tuannvm/mcp-trino#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-25T23:51:10.585Z
Learning: Applies to internal/handlers/trino_handlers.go : All MCP tool endpoints (execute_query, list_catalogs, list_schemas, list_tables, get_table_schema) must return JSON-formatted responses and handle parameter validation.
Applied to files:
internal/mcp/handlers.go
📚 Learning: 2025-07-25T23:51:10.585Z
Learnt from: CR
PR: tuannvm/mcp-trino#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-25T23:51:10.585Z
Learning: Applies to internal/handlers/trino_handlers.go : All MCP tool endpoints must handle parameter validation and error handling consistently.
Applied to files:
internal/mcp/handlers.go
🧬 Code Graph Analysis (1)
internal/mcp/handlers.go (1)
internal/mcp/server.go (1)
createMCPServer
(50-69)
🔇 Additional comments (9)
internal/mcp/handlers.go (9)
259-266
: LGTM: Required table parameter is enforced correctly.Clear validation with an actionable error; consistent with other handlers.
267-276
: LGTM: Client call and error handling look consistent.Logs, wraps, and returns MCP error results in the expected format.
305-305
: LGTM: list_catalogs description is clear and user-friendly.
320-324
: LGTM: get_table_schema parameters and descriptions are precise.
326-331
: LGTM: explain_query tool registration is comprehensive.Parameters and description match the handler; enumeration listed for
format
.
332-337
: LGTM: show_table_stats tool registration is clear and aligned with handler.
220-225
: TrinoClient.ExplainQuery signature verifiedThe
ExplainQuery(query string, format string) ([]map[string]interface{}, error)
method is defined on*Client
ininternal/trino/client.go:289
. No changes needed.
267-272
: ShowTableStats client method confirmed.
TheShowTableStats(catalog, schema, table)
method is implemented ininternal/trino/client.go:306
, with signaturefunc (c *Client) ShowTableStats(catalog, schema, table string) ([]map[string]interface{}, error)This return type is natively JSON-marshalable. No changes needed.
286-298
: OAuth middleware hook correctly implementedVerified that
GetOAuthMiddleware
is defined ininternal/mcp/server.go
and returnsfunc(*server.MCPServer) func(server.ToolHandlerFunc) server.ToolHandlerFuncwhich matches the expected signature. No further changes required.
…ation Signed-off-by: Tommy Nguyen <tuannvm@hotmail.com>
Signed-off-by: Tommy Nguyen <tuannvm@hotmail.com>
Summary by CodeRabbit
New Features
Documentation