feat(mcp)!: confirm destructive SQL via elicitation and rename costConfirmation option - #408
Draft
barryroodt wants to merge 5 commits into
Draft
feat(mcp)!: confirm destructive SQL via elicitation and rename costConfirmation option#408barryroodt wants to merge 5 commits into
barryroodt wants to merge 5 commits into
Conversation
…tion option Extract the duplicated requestState decode/tool/args/decline/cancel/drift block from create_project and create_branch into checkConfirmationState in tools/confirmation.ts (renamed from cost-confirmation.ts), validate the decoded state with zod safeParse, and rename the server option costConfirmation -> confirmation ahead of non-cost confirmations. BREAKING CHANGE: `createSupabaseMcpServer` option `costConfirmation` is now `confirmation`.
Port Studio's regex-based destructive SQL check (DROP, DELETE, TRUNCATE, ALTER TABLE ... DROP COLUMN incl. EXECUTE-string variants, and UPDATE without WHERE) with comment stripping into tools/destructive-sql.ts, along with the Studio test cases that pin its false-positive and false-negative contract. No new dependencies.
When the `confirmation` option enables them and the client declares form elicitation, execute_sql and apply_migration detect destructive SQL (DROP, DELETE, TRUNCATE, ALTER TABLE ... DROP COLUMN, UPDATE without WHERE, ported from Studio) and require an accepted action-only elicitation, bound by a signed requestState to the project and a hash of the query, before running. Read-only servers, capability-free clients and non-destructive SQL are unchanged.
Coverage Report for CI Build 33888451258Coverage increased (+0.5%) to 97.074%Details
Uncovered Changes
Coverage RegressionsNo coverage regressions found. Coverage Stats
💛 - Coveralls |
Brings in #411 (ctx-aware tools(), hidden get_cost/confirm_cost and confirm_cost_id omission for form-capable clients) and the 0.12.0 release. Conflicts resolved so #411's per-request tool shaping runs under the renamed `confirmation` option; #408's tests migrated from setupFormCapable to setupModern with explicit FORM_CAPABLE capabilities.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What kind of change does this PR introduce?
Feature + breaking change: confirm destructive SQL through elicitation and rename
costConfirmationtoconfirmation.What is the current behavior?
execute_sqlandapply_migrationrun without confirmation. Cost confirmation forcreate_projectandcreate_branchuses duplicated state handling under thecostConfirmationserver option. Since #411, form-capable clients no longer seeget_cost/confirm_costandcreate_*dropsconfirm_cost_idfor them.What is the new behavior?
When enabled, form-capable clients receive an action-only
confirm_destructiveprompt before destructive SQL (DROP, DELETE, TRUNCATE, ALTER TABLE ... DROP COLUMN, UPDATE without WHERE) runs:apply_migrationends withApply the migration to project <ref>?instead. The signedrequestStatebinds the project and query hash, plus the migration name forapply_migration.Accept runs once from the signed state. Decline and cancel run nothing, changed SQL fails, and non-elicit responses re-prompt. Non-destructive SQL, read-only servers, stdio, and clients without per-request form elicitation keep their current behavior.
BREAKING:
createSupabaseMcpServerrenamescostConfirmationtoconfirmation.enabledToolsnow acceptscreate_project,create_branch,execute_sql, andapply_migration. The #411 behavior for form-capable clients (legacy cost tools hidden,confirm_cost_idomitted) is unchanged under the new name.Platform (#37717, #37722, #37898, AI-1164) adopts the published 0.12.0 with
costConfirmationfirst. Once this lands, it takes a second package bump with the one-word rename. This keeps the cost elicitation ship date independent from this PR.The existing cost flows now share
checkConfirmationState, including zod validation for decoded state. Their behavior stays unchanged.How to Review
Server option and shared helper
packages/mcp-server-supabase/src/server.tspackages/mcp-server-supabase/src/tools/confirmation.tspackages/mcp-server-supabase/src/tools/account-tools.tspackages/mcp-server-supabase/src/tools/branching-tools.tsSQL tool flow and detector
packages/mcp-server-supabase/src/tools/database-operation-tools.tspackages/mcp-server-supabase/src/tools/destructive-sql.tsTests
packages/mcp-server-supabase/src/server.test.tspackages/mcp-server-supabase/src/tools/confirmation.test.tspackages/mcp-server-supabase/src/tools/destructive-sql.test.tsReview questions
costConfirmationtoconfirmationrename cover the full public option surface?apply_migrationexecute only from the signed state after acceptance?Verification
pnpm --filter @supabase/mcp-server-supabase test src/server.test.ts -t "confirmation via elicitation"(32 passed)src/server.test.ts(154 passed)pnpm --filter @supabase/mcp-server-supabase test src/tools/confirmation.test.ts src/tools/destructive-sql.test.ts(20 passed)pnpm --filter @supabase/mcp-server-supabase build(passed)pnpm test:packed-platform-consumer(3 assertions passed)pnpm exec biome ci .(passed)Additional context
A follow-up PR will cover unconditional confirmation for
delete_branch,reset_branch,merge_branch, andrebase_branch. Hosted enablement stays in platform, where the SQL tools must be added toenabledTools.Confirmations remain reusable within the
requestStateTTL, carrying over the known limit from #391.The detector and its cases come from Studio's SQL editor warning. It keeps the same known blind spots for nested block comments and fully dynamic SQL, with zero new dependencies.
Merged with
mainat145be89(#411 and the 0.12.0 release) inf0e5131.AI-assisted; human review required.