import { z } from 'zod'; import { handleSqlResponse, executeSqlWithFallback } from './utils.js'; import type { ToolContext } from './types.js'; // Schema for edge function output const EdgeFunctionSchema = z.object({ id: z.string().uuid(), name: z.string(), slug: z.string(), status: z.string().nullable(), version: z.number().nullable(), created_at: z.string().nullable(), updated_at: z.string().nullable(), }); const ListEdgeFunctionsOutputSchema = z.array(EdgeFunctionSchema); type ListEdgeFunctionsOutput = z.infer; // Input schema (none needed) const ListEdgeFunctionsInputSchema = z.object({}); type ListEdgeFunctionsInput = z.infer; // Static JSON Schema for MCP capabilities const mcpInputSchema = { type: 'object', properties: {}, required: [], }; // Tool definition export const listEdgeFunctionsTool = { name: 'list_edge_functions', description: 'Lists all deployed Supabase Edge Functions. Returns empty array if edge functions are not available or none are deployed.', inputSchema: ListEdgeFunctionsInputSchema, mcpInputSchema: mcpInputSchema, outputSchema: ListEdgeFunctionsOutputSchema, execute: async (input: ListEdgeFunctionsInput, context: ToolContext): Promise => { const client = context.selfhostedClient; // First check if supabase_functions schema exists const checkSchemaSql = ` SELECT EXISTS ( SELECT 1 FROM pg_catalog.pg_namespace WHERE nspname = 'supabase_functions' ) AS exists `; const schemaCheckResult = await executeSqlWithFallback(client, checkSchemaSql, true); // Handle the schema check result if (Array.isArray(schemaCheckResult) && schemaCheckResult.length > 0) { const exists = schemaCheckResult[0]?.exists; if (!exists) { context.log('supabase_functions schema not found - Edge Functions may not be available in this installation', 'info'); return []; } } else { context.log('Could not verify supabase_functions schema', 'warn'); return []; } // Check if the functions table exists const checkTableSql = ` SELECT EXISTS ( SELECT 1 FROM pg_catalog.pg_tables WHERE schemaname = 'supabase_functions' AND tablename = 'functions' ) AS exists `; const tableCheckResult = await executeSqlWithFallback(client, checkTableSql, true); if (Array.isArray(tableCheckResult) && tableCheckResult.length > 0) { const exists = tableCheckResult[0]?.exists; if (!exists) { context.log('supabase_functions.functions table not found', 'info'); return []; } } else { context.log('Could not verify functions table', 'warn'); return []; } // Query edge functions const listEdgeFunctionsSql = ` SELECT id, name, slug, status, version, created_at::text, updated_at::text FROM supabase_functions.functions ORDER BY name `; const result = await executeSqlWithFallback(client, listEdgeFunctionsSql, true); return handleSqlResponse(result, ListEdgeFunctionsOutputSchema); }, };