import { z } from "zod"; import { withAuth, getSessionCredentials } from "../../auth/index.js"; import { handleToolError, validateRequired, handleApiResponse } from "../helpers/errorHandler.js"; import { AcaiHttpClient } from "../helpers/acaiHttpClient.js"; import { withAuthParams } from "../helpers/authSchema.js"; import { canAccessTable } from "../helpers/accessControl.js"; export function registerDeleteTableRecordsTool(server) { server.tool( "delete_table_records", "⚠️ DANGEROUS: Delete records from a database table. This is a PERMANENT operation that cannot be undone. Use with extreme caution. You can delete specific records by their 'num' (primary key) or delete all records from a table. Table names are WITHOUT the 'cms_' prefix.", withAuthParams({ tableName: z.string().describe("Name of the table to delete records from (without 'cms_' prefix)"), recordIds: z.array(z.union([z.string(), z.number()])).optional().describe("Array of record 'num' values (primary key) to delete. If not provided, you must set deleteAll to true."), deleteAll: z.boolean().optional().describe("Set to true to delete ALL records from the table. Use with extreme caution."), }), { readOnlyHint: false, destructiveHint: true }, withAuth(async ({ tableName, recordIds, deleteAll = false }, extra) => { try { // Validation: must provide either recordIds or deleteAll const validationError = validateRequired({ tableName }, ['tableName'], 'delete_table_records'); if (validationError) return validationError; // Check table access const accessCheck = canAccessTable(tableName); if (!accessCheck.allowed) { return { content: [{ type: "text", text: JSON.stringify({ success: false, error: accessCheck.error }) }], isError: true }; } if (!recordIds && !deleteAll) { return { content: [{ type: "text", text: "Error: You must provide either 'recordIds' or set 'deleteAll' to true." }], isError: true, }; } if (deleteAll && recordIds) { return { content: [{ type: "text", text: "Error: Cannot specify both 'recordIds' and 'deleteAll'. Choose one." }], isError: true, }; } if (deleteAll) { return { content: [{ type: "text", text: "Error: 'deleteAll' is not currently supported with this method. Please provide 'recordIds'." }], isError: true, }; } // Build delete parameters for CMS API const credentials = await getSessionCredentials(extra.sessionId); // Build SQL where clause for deleting multiple records const whereClause = recordIds.length === 1 ? `num = ${recordIds[0]}` : `num IN (${recordIds.join(',')})`; const payload = { tableName: tableName, where: whereClause, options: {} }; // Send to CMS API via viewer_functions const response = await AcaiHttpClient.postCmsApi( credentials, 'delete', payload, credentials.token, credentials.tokenHash ); // Check for API errors const apiError = handleApiResponse(response.data, 'delete_table_records'); if (apiError) return apiError; return { content: [{ type: "text", text: JSON.stringify({ success: true, message: `${recordIds.length} record(s) deleted from table '${tableName}'`, deletedCount: recordIds.length, tableName: tableName, serverResponse: response.data ? "Response received" : "No response body" }, null, 2) }], }; } catch (error) { return handleToolError(error, 'delete_table_records', { tableName, recordCount: recordIds?.length || 0 }); } }) ); }