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;
    }
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden and does well disclosing behavioral traits: 'REAL-TIME: <1s' (performance), 'polls every 30s until complete' (monitoring behavior), 'Tool waits synchronously' (blocking behavior), and automatic download capabilities. It doesn't mention rate limits, authentication needs, or error handling, but covers most operational aspects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately sized and front-loaded with the core purpose. Every sentence adds value: first states purpose and performance, second explains returns, third covers monitoring/auto-download, fourth specifies requirements, fifth explains alternative tool usage. Minor redundancy exists ('Returns status and download URL when ready' repeats earlier information).

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex tool with 18 parameters and no output schema, the description does well covering operational context: purpose, performance, return values, monitoring behavior, prerequisites, and alternative tool reference. It doesn't explain the relationship between parameters (like how latest interacts with exportId) or error scenarios, but provides sufficient guidance for basic usage given the comprehensive schema coverage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all 18 parameters thoroughly. The description adds minimal parameter semantics beyond the schema - it mentions 'exportId, environment' as required and explains monitor/autoDownload behaviors, but doesn't provide additional context about parameter interactions or usage patterns that aren't already in the schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose with specific verbs and resources: 'Check database export progress' (verb+resource), 'Returns progress percentage, estimated time remaining, and download URL when export completes' (output details), and distinguishes from sibling db_export_download by explicitly mentioning it. It goes beyond the name/title to explain what the tool actually does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance on when to use this tool vs alternatives: 'Use db_export_download() with the URL to retrieve file' specifies the alternative tool for downloading. It also indicates prerequisites: 'Required: exportId, environment' and context for monitoring/auto-download features. This gives clear operational context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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