Skip to main content
Glama
JaxonDigital

Optimizely DXP MCP Server

by JaxonDigital

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

TableJSON Schema
NameRequiredDescriptionDefault
exportIdNoExport ID to check status for (from db_export response)
environmentNoEnvironment where export was created: Production, Preproduction, Integration (required if exportId provided)
latestNoCheck status of latest/most recent export instead of specific exportId
monitorNoEnable continuous monitoring - polls every 30s until export completes
waitBeforeCheckNoWait N seconds before checking status (60-180s). Tool waits synchronously.
autoDownloadNoAutomatically download export if status is complete
downloadPathNoDirectory to save downloaded export
backgroundNoDownload in background vs wait for completion (default: true)
skipConfirmationNoSkip download confirmation prompts
limitNoMax results to return when listing exports (1-100)
offsetNoPagination offset when listing exports
statusNoFilter by export status when listing
formatNoResponse format: concise (minimal fields) or detailed (all fields)detailed
projectNoProject name (default: current project)
projectNameNoAlternative to project parameter
projectIdNoProject UUID (if providing inline credentials)
apiKeyNoAPI key (if providing inline credentials)
apiSecretNoAPI 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}`);
        }
    }
  • 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;
    }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/JaxonDigital/optimizely-dxp-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server