db_export_status
Monitor database export progress in Optimizely DXP environments. Track completion percentage, estimated time remaining, and retrieve download URLs when exports finish.
Instructions
š Check database export progress. REAL-TIME: <1s. Returns progress percentage, estimated time remaining, and download URL when export completes. Set monitor=true to poll every 30s until complete. Set autoDownload=true to automatically download when ready. Required: exportId, environment. Returns status and download URL when ready. Use db_export_download() with the URL to retrieve file.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| exportId | No | Export ID to check status for (from db_export response) | |
| environment | No | Environment where export was created: Production, Preproduction, Integration (required if exportId provided) | |
| latest | No | Check status of latest/most recent export instead of specific exportId | |
| monitor | No | Enable continuous monitoring - polls every 30s until export completes | |
| waitBeforeCheck | No | Wait N seconds before checking status (60-180s). Tool waits synchronously. | |
| autoDownload | No | Automatically download export if status is complete | |
| downloadPath | No | Directory to save downloaded export | |
| background | No | Download in background vs wait for completion (default: true) | |
| skipConfirmation | No | Skip download confirmation prompts | |
| limit | No | Max results to return when listing exports (1-100) | |
| offset | No | Pagination offset when listing exports | |
| status | No | Filter by export status when listing | |
| format | No | Response format: concise (minimal fields) or detailed (all fields) | detailed |
| project | No | Project name (default: current project) | |
| projectName | No | Alternative to project parameter | |
| projectId | No | Project UUID (if providing inline credentials) | |
| apiKey | No | API key (if providing inline credentials) | |
| apiSecret | No | API secret (if providing inline credentials) |
Implementation Reference
- Primary handler for 'db_export_status' tool. Validates parameters, handles waitBeforeCheck, calls internal status check, adds monitoring/auto-download logic, and structures response.static async handleCheckExportStatus(args: CheckExportStatusArgs): Promise<any> { if (!args.apiKey || !args.apiSecret || !args.projectId) { return ResponseBuilder.invalidParams('Missing required parameters: apiKey, apiSecret, projectId'); } // DXP-81: Support new 'database' parameter const databaseName = args.database || args.databaseName; // If waitBeforeCheck is specified, implement transparent wait-then-check pattern if (args.waitBeforeCheck && args.waitBeforeCheck > 0) { const waitMinutes = Math.floor(args.waitBeforeCheck / 60); const waitSeconds = args.waitBeforeCheck % 60; const waitDisplay = waitMinutes > 0 ? `${waitMinutes} minute${waitMinutes > 1 ? 's' : ''}${waitSeconds > 0 ? ` ${waitSeconds} second${waitSeconds > 1 ? 's' : ''}` : ''}` : `${waitSeconds} second${waitSeconds > 1 ? 's' : ''}`; OutputLogger.info(`ā³ Waiting ${waitDisplay} before checking export status...`); await new Promise(resolve => setTimeout(resolve, args.waitBeforeCheck! * 1000)); OutputLogger.success(`ā Wait complete. Checking export status now...`); } try { const result = await this.internalCheckExportStatus(args); // Check if result is structured response if (result && typeof result === 'object' && 'data' in result && 'message' in result) { // If monitor mode is enabled and export is still in progress, add monitoring instructions if (args.monitor && result.data && result.data.status) { const monitoringInstructions = this.generateMonitoringInstructions( result.data.exportId || args.exportId || 'unknown', result.data.status, args ); result.message = result.message + '\\n\\n' + monitoringInstructions; } // If autoDownload is enabled and export is complete with download URL if (args.autoDownload && result.data && result.data.status === 'Succeeded' && result.data.downloadUrl) { // DXP-184: Use background download to avoid MCP timeout OutputLogger.info('š Auto-download enabled. Starting background download...'); const downloadId = await this.startBackgroundDatabaseDownload( result.data.downloadUrl, args.downloadPath, args.projectName, result.data.environment || args.environment, result.data.databaseName || databaseName ); const fileSize = await this.getRemoteFileSize(result.data.downloadUrl).catch(() => 0); const estimatedTime = this.estimateDownloadTime(fileSize); const downloadMessage = `\n\nš„ **Background Download Started**\n` + `⢠Download ID: \`${downloadId}\`\n` + `⢠Size: ${this.formatBytes(fileSize)}\n` + `⢠Estimated Time: ${estimatedTime}\n\n` + `**Monitor Progress:**\n` + `Use \`download_list()\` to check status.\n` + `Use \`download_status({ downloadId: "${downloadId}", monitor: true })\` for live updates.`; // Append download info to message result.message = result.message + downloadMessage; } return ResponseBuilder.successWithStructuredData(result.data, result.message); } return ResponseBuilder.success(result); } catch (error: any) { console.error('Check export status error:', error); return ResponseBuilder.internalError('Failed to check export status', error.message); } }
- Type definition for input parameters of the db_export_status tool, including optional fields for authentication, export identification, monitoring, and pagination.interface CheckExportStatusArgs { apiKey?: string; apiSecret?: string; projectId?: string; projectName?: string; environment?: string; exportId?: string; databaseName?: string; database?: string; latest?: boolean; monitor?: boolean; autoDownload?: boolean; downloadPath?: string; waitBeforeCheck?: number; incremental?: boolean; limit?: number; offset?: number; status?: string; format?: 'concise' | 'detailed'; }
- Core internal handler performing the actual API call to retrieve database export status, parses response, emits resource events, and formats output.static async internalCheckExportStatus(args: CheckExportStatusArgs): Promise<StatusResult> { const databaseName = args.database || args.databaseName || 'epicms'; let exportId = args.exportId; const projectConfig: ProjectConfig = { name: args.projectName || 'Unknown', projectId: args.projectId!, apiKey: args.apiKey!, apiSecret: args.apiSecret! }; // DXP-76-2: List mode - when limit/offset is specified, list all exports if ((args.limit !== undefined || args.offset !== undefined) && !exportId && !args.latest) { return await this.listAllExports(args, projectConfig, databaseName); } // If 'latest' is specified or no exportId provided, try to get from saved state if (args.latest || !exportId) { const savedState = await this.loadCurrentExportState(); if (savedState && savedState.exportId) { exportId = savedState.exportId; OutputLogger.info(`Using latest export ID: ${exportId}`); } else { throw new Error('No export ID specified and no saved export state found. Please provide exportId or start a new export.'); } } try { // Check export status via REST API (DXP-101: No PowerShell) const result = await DXPRestClient.getDatabaseExportStatus( projectConfig.projectId, projectConfig.apiKey!, projectConfig.apiSecret!, args.environment || 'Production', databaseName, exportId! ); const parsedStatus = this.parseExportStatus(result); // DXP-155: Emit export events based on status try { if (parsedStatus.status === 'InProgress') { ExportResourceHandler.emitInProgress(exportId!, { status: parsedStatus.status, percentComplete: parsedStatus.percentComplete || 0 }); } else if (parsedStatus.status === 'Succeeded') { ExportResourceHandler.emitSucceeded(exportId!, { downloadUrl: parsedStatus.downloadUrl, environment: args.environment || 'Production', databaseName }); } else if (parsedStatus.status === 'Failed') { ExportResourceHandler.emitFailed(exportId!, { error: (parsedStatus as any).errorMessage || 'Export failed', environment: args.environment || 'Production', databaseName }); } } catch (eventError: any) { console.error(`Failed to emit export event: ${eventError.message}`); // Don't fail the operation if event emission fails } // Update saved state if we have one const savedState = await this.loadCurrentExportState(); if (savedState && savedState.exportId === exportId) { savedState.status = parsedStatus.status; if (parsedStatus.downloadUrl) { savedState.downloadUrl = parsedStatus.downloadUrl; } if (parsedStatus.status === 'Succeeded' || parsedStatus.status === 'Failed') { savedState.completedAt = new Date().toISOString(); } await this.saveCurrentExportState(savedState); } let message = `Export Status: ${parsedStatus.status}\\n`; message += `Export ID: ${exportId}\\n`; if (parsedStatus.percentComplete !== undefined) { message += `Progress: ${parsedStatus.percentComplete}%\\n`; } if (parsedStatus.status === 'Succeeded' && parsedStatus.downloadUrl) { message += `\\nā Export completed successfully!\\n`; message += `Download URL available (valid for 24 hours)\\n\\n`; message += `Use download_database_export to download the backup.`; } else if (parsedStatus.status === 'Failed') { message += `\\nā Export failed. Check DXP portal for details.`; } else { message += `\\nā³ Export in progress. Check again in 30 seconds.`; } return { data: { status: parsedStatus.status, exportId: exportId!, downloadUrl: parsedStatus.downloadUrl, environment: args.environment || 'Production', databaseName, percentComplete: parsedStatus.percentComplete }, message }; } catch (error: any) { throw new Error(`Failed to check export status: ${error.message}`); } }
- lib/utils/tool-availability-matrix.ts:205-209 (registration)Tool registration/availability definition in the central tool matrix, specifying hosting restrictions, category, and description for db_export_status.'db_export_status': { hostingTypes: ['dxp-paas'], category: 'Database', description: 'Check export status with optional monitoring and download', restrictedMessage: 'Database export status is only available for DXP PaaS hosting.'
- Helper functions that emit export progress/success events tagged with operation 'db_export_status' for resource updates and notifications.static emitInProgress(exportId: string, details: ExportDetails = {}): DXPEvent { const emitter = getGlobalEmitter(); const event = createEvent( EVENT_TYPES.EXPORT_IN_PROGRESS, exportId, { exportId, status: 'InProgress', progress: details.progress || 50, ...details }, { operation: 'db_export_status', user: 'system' } ); emitter.emitEvent(event); return event; }