execute_script
Execute multi-statement SQL scripts against databases to run sequential queries and return results in JSON or CSV format.
Instructions
Execute a multi-statement SQL script against a database. All statements are executed in sequence.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| connection_string | No | Database connection URL or configured connection name (e.g., "oracle" for USQL_ORACLE) | |
| output_format | No | Output format for results (default: json) | |
| script | Yes | Multi-line SQL script with one or more SQL statements separated by semicolons | |
| timeout_ms | No | Optional timeout in milliseconds for this call (overrides defaults). Use null for unlimited. |
Implementation Reference
- src/tools/execute-script.ts:50-156 (handler)Core implementation of the execute_script tool handler. Validates input, resolves database connection, checks for destructive operations, executes the SQL script via usql with timeout and format options, parses errors, and returns raw output.async function _handleExecuteScript(input: ExecuteScriptInput): Promise<RawOutput> { const outputFormat = input.output_format || "json"; logger.debug("[execute-script] Handling request", { connectionStringInput: input.connection_string, scriptLength: input.script?.length || 0, statementCount: input.script?.split(";").filter((s) => s.trim()).length || 0, outputFormat, }); let resolvedConnectionString: string | undefined; try { if (!input.script || typeof input.script !== "string") { throw createUsqlError("InvalidInput", "script is required and must be a string"); } // Resolve connection string try { resolvedConnectionString = resolveConnectionStringOrDefault(input.connection_string); } catch (error) { throw createUsqlError("InvalidConnection", `Failed to resolve connection: ${String(error)}`); } if (!validateConnectionString(resolvedConnectionString)) { throw createUsqlError( "InvalidConnection", `Invalid connection string format: ${resolvedConnectionString}` ); } // Validate script contains SQL const trimmedScript = input.script.trim(); if (!trimmedScript) { throw createUsqlError("InvalidInput", "script cannot be empty"); } // Check for potentially dangerous operations (basic check) const upperScript = trimmedScript.toUpperCase(); const hasDropTable = upperScript.includes("DROP TABLE"); const hasDropDatabase = upperScript.includes("DROP DATABASE"); if (hasDropTable || hasDropDatabase) { logger.warn("[execute-script] Potentially destructive script detected", { hasDropTable, hasDropDatabase, }); // We still allow it but log the warning for audit purposes } // Execute script const timeoutOverride = input.timeout_ms === null ? undefined : typeof input.timeout_ms === "number" && Number.isFinite(input.timeout_ms) ? input.timeout_ms : undefined; const timeout = timeoutOverride ?? getQueryTimeout(); logger.debug("[execute-script] Executing script with timeout", { timeout, outputFormat }); const result = await executeUsqlQuery(resolvedConnectionString, trimmedScript, { timeout, format: outputFormat, }); logger.debug("[execute-script] Script executed", { exitCode: result.exitCode, stdoutLength: result.stdout.length, stderrLength: result.stderr.length, }); // Check for errors if (result.exitCode !== 0 && result.stderr) { const errorMessage = parseUsqlError(result.stderr); throw createUsqlError("ScriptExecutionError", errorMessage, { exitCode: result.exitCode, scriptLength: input.script.length, }); } logger.debug("[execute-script] Script completed successfully", { outputFormat, contentLength: result.stdout.length, }); return { format: outputFormat as "json" | "csv", content: result.stdout, }; } catch (error) { const connectionForError = resolvedConnectionString ?? input.connection_string; const mcpError = formatMcpError( error, connectionForError || input.script ? { connectionString: connectionForError, scriptLength: input.script?.length, } : undefined ); logger.error("[execute-script] Error executing script", error); throw mcpError; } } export const handleExecuteScript = withBackgroundSupport("execute_script", _handleExecuteScript);
- src/tools/execute-script.ts:17-48 (schema)JSON schema definition for the execute_script tool input, specifying parameters like connection_string, script (required), output_format, and timeout_ms.export const executeScriptSchema: Tool = { name: "execute_script", description: "Execute a multi-statement SQL script against a database. All statements are executed in sequence. Uses default connection if none specified.", inputSchema: { type: "object", properties: { connection_string: { type: "string", description: '(Optional) Database connection URL or configured connection name. If omitted, uses the default connection from USQL_DEFAULT_CONNECTION (e.g., "oracle" for USQL_ORACLE). Use get_server_info to discover available connections.', }, script: { type: "string", description: "Multi-line SQL script with one or more SQL statements separated by semicolons", }, output_format: { type: "string", enum: ["json", "csv"], description: "Output format for results (default: json)", }, timeout_ms: { type: ["number", "null"], description: "Optional timeout in milliseconds for this call (overrides defaults). Use null for unlimited.", minimum: 1, }, }, required: ["script"], }, };
- src/index.ts:37-46 (registration)Registration of the executeScriptSchema in the server's list of available tools.private tools = [ executeQuerySchema, listDatabasesSchema, listTablesSchema, describeTableSchema, executeScriptSchema, getJobStatusSchema, getServerInfoSchema, cancelJobSchema, ];
- src/index.ts:195-196 (registration)Dispatch to the execute_script handler in the main tool execution switch statement.case "execute_script": return await handleExecuteScript(input as Parameters<typeof handleExecuteScript>[0]);
- src/types/index.ts:39-44 (schema)TypeScript interface defining the input shape for execute_script, used in the handler function signature.export interface ExecuteScriptInput { connection_string?: string; script: string; output_format?: "json" | "csv"; timeout_ms?: number | null; }