feat: Native MCP support over HTTP#977
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
✅ Files skipped from review due to trivial changes (2)
📝 WalkthroughWalkthroughThis PR adds a read-only MCP endpoint at ChangesMCP Endpoint Implementation
Controller Test Additions
Cursor Rule Files
Repository Housekeeping
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
controllers/mcp.go (2)
346-348: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winLog errors from
describeToolDescriptioninstead of silently swallowing them.When
describeToolDescriptionfails for a table, the error is silently ignored withcontinue. This could hide real database issues or permission problems, making the tool list incomplete without any indication of why.🔍 Proposed fix: log at debug level
desc, err := h.describeToolDescription(r, defaultDB, schema, table) if err != nil { + slog.Debug("mcp: skipping tool for table", "schema", schema, "table", table, "error", err) continue }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@controllers/mcp.go` around lines 346 - 348, The error from describeToolDescription is being swallowed by the continue in the tool enumeration flow, which can hide real failures. Update the logic around describeToolDescription in the MCP tool listing path to log the returned err at debug level before continuing, so failures are observable while preserving the existing fallback behavior. Use the surrounding tool-building code in controllers/mcp.go and the describeToolDescription call site as the anchor for the fix.
25-25: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRemove or document the unused
builderfield.
builderis set inNewMCPHandler(line 36) but never referenced anywhere inmcp.go. Either remove it or add a comment explaining its intended future use.♻️ Proposed fix: remove the field
type MCPHandler struct { catalog adapters.CatalogQuerier - builder adapters.RequestQueryBuilder executor adapters.QueryExecutor db adapters.DatabaseRegistry singleDB bool pgDB string }And in the constructor:
func NewMCPHandler(deps Deps) *MCPHandler { return &MCPHandler{ catalog: deps.Catalog, - builder: deps.Builder, executor: deps.Executor, db: deps.DB, singleDB: deps.SingleDB, pgDB: deps.PGDatabase, } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@controllers/mcp.go` at line 25, The MCP handler currently carries an unused builder field that is assigned in NewMCPHandler but never referenced anywhere in mcp.go. Remove the builder field from the handler struct and update NewMCPHandler to stop wiring it in; if it must stay for future use, add a brief comment near the MCPHandler definition explaining its purpose, but the preferred fix is to delete the dead field and constructor assignment.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@controllers/mcp.go`:
- Around line 346-348: The error from describeToolDescription is being swallowed
by the continue in the tool enumeration flow, which can hide real failures.
Update the logic around describeToolDescription in the MCP tool listing path to
log the returned err at debug level before continuing, so failures are
observable while preserving the existing fallback behavior. Use the surrounding
tool-building code in controllers/mcp.go and the describeToolDescription call
site as the anchor for the fix.
- Line 25: The MCP handler currently carries an unused builder field that is
assigned in NewMCPHandler but never referenced anywhere in mcp.go. Remove the
builder field from the handler struct and update NewMCPHandler to stop wiring it
in; if it must stay for future use, add a brief comment near the MCPHandler
definition explaining its purpose, but the preferred fix is to delete the dead
field and constructor assignment.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 817d772f-edb0-4fc9-b066-75b641d6fa97
📒 Files selected for processing (11)
README.mdcontrollers/auth_test.gocontrollers/catalog_test.gocontrollers/crud_test.gocontrollers/deps.gocontrollers/deps_test.gocontrollers/mcp.gocontrollers/mcp_test.gointegration/controllers/mcp_test.gointegration/router/routes_test.gorouter/router.go
There was a problem hiding this comment.
🧹 Nitpick comments (1)
integration/router/routes_test.go (1)
16-26: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider verifying response body content for the POST initialize path.
The
whereparameter ("MCPInitialize") is just a label inDoRequest— no body content is actually asserted since no variadicexpectedBodystrings are passed. The test only confirms HTTP 200. For theinitializeJSON-RPC call, asserting that the response body contains expected fields (e.g.,"serverInfo","capabilities") would strengthen coverage and catch regressions in the response shape.♻️ Optional: add body content assertions
func TestMCPRoute(t *testing.T) { base := helpers.ServerURL(t) testutils.DoRequest(t, base+"/_mcp", nil, "GET", http.StatusOK, "MCPDiscovery") payload := map[string]any{ "jsonrpc": "2.0", "id": 1, "method": "initialize", } - testutils.DoRequest(t, base+"/_mcp", payload, "POST", http.StatusOK, "MCPInitialize") + testutils.DoRequest(t, base+"/_mcp", payload, "POST", http.StatusOK, "MCPInitialize", "serverInfo", "capabilities") }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@integration/router/routes_test.go` around lines 16 - 26, Update TestMCPRoute so the POST initialize request actually asserts response body content instead of only relying on the DoRequest label "MCPInitialize"; use the existing testutils.DoRequest call site to add expectedBody checks for key JSON-RPC response fields such as serverInfo and capabilities, ensuring the initialize path validates the returned payload shape.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@integration/router/routes_test.go`:
- Around line 16-26: Update TestMCPRoute so the POST initialize request actually
asserts response body content instead of only relying on the DoRequest label
"MCPInitialize"; use the existing testutils.DoRequest call site to add
expectedBody checks for key JSON-RPC response fields such as serverInfo and
capabilities, ensuring the initialize path validates the returned payload shape.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 772ed604-5167-433c-9375-e16b4a63d0ca
📒 Files selected for processing (2)
integration/controllers/mcp_test.gointegration/router/routes_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
- integration/controllers/mcp_test.go
There was a problem hiding this comment.
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)
controllers/mcp.go (1)
359-379: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winRestrict
describe_tableto permitted columns.describeColumnsreturns every column fromShowTableCtx, so callers can inspect table metadata even whenlist_tables/select_tablewould hide the table or yield no readable fields. ReuseselectableColumnshere and reject empty results.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@controllers/mcp.go` around lines 359 - 379, The describeTable handler is exposing all columns via describeColumns without enforcing the same column अनुमति checks used elsewhere. Update describeTable to filter the result through selectableColumns for the resolved database/schema/table, and reject the request when no selectable columns remain; keep the validation flow in MCPHandler.describeTable and reuse the existing access-control helpers so the returned metadata only includes permitted columns.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@controllers/mcp.go`:
- Around line 469-513: `MCPHandler.tools` is recomputing table permissions and
columns twice per table during discovery: once indirectly through
`tableRows`/`filterAccessibleTables` and again via `selectableColumns` when
building each tool schema. Update the discovery flow so column metadata is
computed only once per table and reused for both filtering and schema
generation, either by having `filterAccessibleTables` return the columns with
the rows or by making `tools()` work from raw rows and call `selectableColumns`
a single time per table. Keep the fix localized to `tools`, `tableRows`, and
`selectableColumns` so discovery no longer repeats the same DB checks on every
request.
- Around line 310-344: In listSchemas on MCPHandler, the current len(schemas) ==
0 check conflates “no schemas exist” with “permissions filtered everything out,”
causing a schema-name leak. Update the filtering logic to branch on whether
h.perms is set (matching filterAccessibleTables) rather than the size of the map
returned by accessibleSchemas, and only fall back to showing all rows when there
is truly no permission filtering in effect.
---
Outside diff comments:
In `@controllers/mcp.go`:
- Around line 359-379: The describeTable handler is exposing all columns via
describeColumns without enforcing the same column अनुमति checks used elsewhere.
Update describeTable to filter the result through selectableColumns for the
resolved database/schema/table, and reject the request when no selectable
columns remain; keep the validation flow in MCPHandler.describeTable and reuse
the existing access-control helpers so the returned metadata only includes
permitted columns.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: f593eeff-ff5c-4ada-896c-e2147cb09ab7
📒 Files selected for processing (12)
README.mdadapters/database_registry.goadapters/mock/mock.goadapters/mockgen/adapter.goadapters/mockgen/database_registry.goadapters/postgres/postgres.gocontrollers/crud_test.gocontrollers/mcp.gocontrollers/mcp_test.gointegration/controllers/mcp_test.gointegration/router/routes_test.gorouter/router.go
✅ Files skipped from review due to trivial changes (3)
- adapters/mockgen/adapter.go
- adapters/mockgen/database_registry.go
- README.md
🚧 Files skipped from review as they are similar to previous changes (3)
- integration/router/routes_test.go
- integration/controllers/mcp_test.go
- controllers/crud_test.go
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
.cursor/rules/agentic-loop.mdc (1)
83-90: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAlign the adapter-test command with the canonical validation path.
This direct
go testinvocation drops the repo-standard-race,-count=1, and coverage flags thatmake test-unitalready applies. Either point this section atmake test-unitor mirror those flags here so race regressions inadapters/postgresdon’t slip through.🔧 Suggested replacement
-```sh -go test -timeout 30s -parallel 8 ./adapters/postgres/... -``` +```sh +make test-unit +# or, if you need a focused run: +go test -timeout 30s -race -count=1 -tags prest_test_hooks -parallel 8 ./adapters/postgres/... +```🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.cursor/rules/agentic-loop.mdc around lines 83 - 90, The Postgres adapter test command in the agentic-loop rules is bypassing the repo’s canonical validation flags, so update the guidance to use make test-unit or match its behavior in the adapters/postgres test example. Keep the reference anchored around the Postgres adapter unit tests section and the go test invocation, and ensure the command includes the standard race, count, and test-hook flags used by the main unit-test path so regressions are caught consistently.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.cursor/rules/agentic-loop.mdc:
- Around line 49-50: Narrow the resilience policy in the config guidance so it
does not imply a blanket safe default/zero for all settings; the current wording
around unmarshalKeyOrZero, ensure*Path, and ensureJWTConfig should distinguish
non-security config from security-sensitive inputs. Update the Config row in
agentic-loop.mdc to keep warn-and-continue only for non-sensitive values, and
explicitly fail closed or require hard errors for auth, ACL, JWT, secret, and
DB-credential settings.
---
Nitpick comments:
In @.cursor/rules/agentic-loop.mdc:
- Around line 83-90: The Postgres adapter test command in the agentic-loop rules
is bypassing the repo’s canonical validation flags, so update the guidance to
use make test-unit or match its behavior in the adapters/postgres test example.
Keep the reference anchored around the Postgres adapter unit tests section and
the go test invocation, and ensure the command includes the standard race,
count, and test-hook flags used by the main unit-test path so regressions are
caught consistently.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: cfdc5b4c-646d-4c5e-a68d-200f78ea795d
📒 Files selected for processing (1)
.cursor/rules/agentic-loop.mdc
- Updated .gitignore to ignore all output files with the .out extension. - Clarified resilience policy in agentic-loop guidelines to specify that non-sensitive configurations should log warnings and continue startup, while sensitive configurations should fail closed.
- Introduced a new document outlining the safety protocols for AI interactions with git commits, emphasizing that commits must be executed by humans only. - Defined clear boundaries for AI capabilities, including inspection commands and drafting commit messages, while prohibiting direct execution of git commands. - Established a structured approach for suggesting commits, ensuring compliance with repository commit message styles and safety protocols.
- Updated the agentic-loop configuration guidelines to clarify the handling of non-sensitive and sensitive settings during startup. - Specified that non-sensitive configurations should only log warnings and continue, while sensitive configurations must fail closed to maintain security integrity.
Merging this branch changes the coverage (2 decrease, 1 increase)
Coverage by fileChanged files (no unit tests)
Please note that the "Total", "Covered", and "Missed" counts above refer to code statements instead of lines of code. The value in brackets refers to the test coverage of that file in the old version of the code. Changed unit test files
|
|
ref #959 |
Summary by CodeRabbit
Summary
/_mcpsupporting JSON-RPCinitialize,tools/list, andtools/call, including schema-aware per-table select tools./_mcpusage, supported tools/methods, safety guarantees, and error/auth expectations.