Skip to content

Commit 80b3287

Browse files
committed
feat: add MCP elicitation for apply_migration tool
- Implemented user confirmation dialog for apply_migration using MCP elicitation protocol - Added graceful fallback for clients that don't support elicitation - Tests pass with fallback behavior in test environment - Maintains backwards compatibility with all MCP clients
1 parent d319653 commit 80b3287

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

packages/mcp-server-supabase/src/server.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ export function createSupabaseMcpServer(options: SupabaseMcpServerOptions) {
144144
database,
145145
projectId,
146146
readOnly,
147+
server,
147148
})
148149
);
149150
}

packages/mcp-server-supabase/src/tools/database-operation-tools.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { source } from 'common-tags';
2+
import type { Server } from '@modelcontextprotocol/sdk/server/index.js';
23
import { z } from 'zod';
34
import { listExtensionsSql, listTablesSql } from '../pg-meta/index.js';
45
import {
@@ -14,12 +15,14 @@ export type DatabaseOperationToolsOptions = {
1415
database: DatabaseOperations;
1516
projectId?: string;
1617
readOnly?: boolean;
18+
server?: Server;
1719
};
1820

1921
export function getDatabaseTools({
2022
database,
2123
projectId,
2224
readOnly,
25+
server,
2326
}: DatabaseOperationToolsOptions) {
2427
const project_id = projectId;
2528

@@ -215,6 +218,47 @@ export function getDatabaseTools({
215218
throw new Error('Cannot apply migration in read-only mode.');
216219
}
217220

221+
// Try to request user confirmation via elicitation
222+
if (server) {
223+
try {
224+
const result = (await server.request(
225+
{
226+
method: 'elicitation/create',
227+
params: {
228+
message: `You are about to apply migration "${name}" to project ${project_id}. This will modify your database schema.\n\nPlease review the SQL:\n\n${query}\n\nDo you want to proceed?`,
229+
requestedSchema: {
230+
type: 'object',
231+
properties: {
232+
confirm: {
233+
type: 'boolean',
234+
title: 'Confirm Migration',
235+
description: 'I have reviewed the SQL and approve this migration',
236+
},
237+
},
238+
required: ['confirm'],
239+
},
240+
},
241+
},
242+
// @ts-ignore - elicitation types might not be available
243+
{ elicitation: true }
244+
)) as {
245+
action: 'accept' | 'decline' | 'cancel';
246+
content?: { confirm?: boolean };
247+
};
248+
249+
// User declined or cancelled
250+
if (result.action !== 'accept' || !result.content?.confirm) {
251+
throw new Error('Migration cancelled by user');
252+
}
253+
} catch (error) {
254+
// If elicitation fails (client doesn't support it), proceed without confirmation
255+
// This maintains backwards compatibility
256+
console.warn(
257+
'Elicitation not supported by client, proceeding with migration without confirmation'
258+
);
259+
}
260+
}
261+
218262
await database.applyMigration(project_id, {
219263
name,
220264
query,

0 commit comments

Comments
 (0)