Skip to main content
Glama
JaxonDigital

Optimizely DXP MCP Server

by JaxonDigital

list_monitors

View active deployment monitors to track status, identify IDs for management, and monitor update counts in Optimizely DXP environments.

Instructions

📡 List active background monitors tracking deployments. REAL-TIME: <1s. Shows all monitors polling deployment status, including monitor IDs, associated deployment IDs, current status, and update count. Use to discover active monitors for stop_monitoring() or update_monitoring_interval() calls. No parameters. Returns array of active monitor details.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • The handler function that implements the 'list_monitors' tool logic. It reads active monitors from DatabaseSimpleTools.backgroundMonitors and formats a Markdown response with status and available commands.
    static async listMonitors(_params: MonitoringParams = {}): Promise<any> {
        try {
            // Check for active database export monitors
            const DatabaseSimpleTools = require('./database-simple-tools');
            const activeMonitors: Map<string, BackgroundMonitor> = DatabaseSimpleTools.backgroundMonitors;
    
            const response: string[] = [];
            response.push('## 📡 Deployment Monitoring Status\n');
    
            if (activeMonitors && activeMonitors.size > 0) {
                response.push(`**Active Monitors:** ${activeMonitors.size} background monitor(s) running`);
                for (const [exportId, monitor] of activeMonitors) {
                    const runtime = Math.round((Date.now() - monitor.startTime) / 60000);
                    // Show 13 chars to get past first dash (e.g., "c88fa98f-9d3c...")
                    response.push(`• Database Export: ${exportId.substring(0, 13)}... (${monitor.environment}/${monitor.databaseName}) - ${runtime}m`);
                }
            } else {
                response.push('**Active Monitors:** Currently no background monitors running');
            }
            response.push('**Monitoring Features:**');
            response.push('• Real-time deployment tracking');
            response.push('• Progress monitoring with ETA calculation');
            response.push('• Automatic completion detection');
            response.push('• Background monitoring support\n');
    
            response.push('**Available Commands:**');
            response.push('• `update_monitoring_interval` - Change monitoring frequency');
            response.push('• `stop_monitoring` - Stop active monitors');
            response.push('• `get_monitoring_stats` - View detailed statistics\n');
    
            response.push('💡 **Tip:** Monitoring is automatically started when using deployment tools');
    
            return ResponseBuilder.success(
                response.join('\n')
            );
    
        } catch (error: any) {
            return ErrorHandler.handleError(error, { operation: 'list_monitors' });
        }
    }
  • Static Map storing active background monitors (exportId -> BackgroundMonitor), which is accessed by listMonitors handler.
    static backgroundMonitors = new Map<string, BackgroundMonitor>();
  • Helper function that starts and manages background monitoring for database exports, populating the backgroundMonitors map used by list_monitors.
    static startBackgroundMonitoring(
        exportId: string,
        projectConfig: ProjectConfig,
        environment: string,
        databaseName: string,
        downloadPath?: string
    ): void {
        // Check if already monitoring this export
        if (this.backgroundMonitors.has(exportId)) {
            OutputLogger.info(`Already monitoring export ${exportId}`);
            return;
        }
    
        const monitorData: MonitorData = {
            exportId,
            projectConfig,
            environment,
            databaseName,
            downloadPath,
            startedAt: new Date().toISOString(),
            pollCount: 0
        };
    
        const emitter = new EventEmitter() as BackgroundMonitor;
        emitter.exportId = exportId;
        emitter.data = monitorData;
    
        this.backgroundMonitors.set(exportId, emitter);
    
        // Start monitoring loop
        const pollInterval = 30000; // 30 seconds
        const maxDuration = 45; // 45 minutes
    
        const monitorLoop = async (): Promise<void> => {
            try {
                monitorData.pollCount++;
                const elapsedMinutes = Math.floor((Date.now() - new Date(monitorData.startedAt).getTime()) / 60000);
    
                const result = await DXPRestClient.getDatabaseExportStatus(
                    projectConfig.projectId,
                    projectConfig.apiKey!,
                    projectConfig.apiSecret!,
                    environment,
                    monitorData.databaseName,
                    exportId
                );
    
                const parsedStatus = this.parseExportStatus(result);
                monitorData.lastStatus = parsedStatus.status;
    
                (emitter as any).emit('progress', {
                    status: parsedStatus.status,
                    pollCount: monitorData.pollCount,
                    elapsedMinutes
                });
    
                if (parsedStatus.status === 'Succeeded') {
                    (emitter as any).emit('complete', {
                        exportId,
                        downloadUrl: parsedStatus.downloadUrl,
                        environment,
                        databaseName
                    });
    
                    if (emitter.intervalId) {
                        clearInterval(emitter.intervalId);
                    }
                    this.backgroundMonitors.delete(exportId);
    
                    // If autoDownload was requested, trigger background download
                    // DXP-184 FIX: Use background download to avoid blocking background monitor thread
                    if (monitorData.autoDownload && parsedStatus.downloadUrl) {
                        this.startBackgroundDatabaseDownload(
                            parsedStatus.downloadUrl,
                            downloadPath,
                            projectConfig.name,
                            environment,
                            databaseName
                        ).then(downloadId => {
                            OutputLogger.success(`✅ Auto-download started (background). Download ID: ${downloadId}`);
                        }).catch(error => {
                            OutputLogger.error(`Auto-download failed: ${error.message}`);
                        });
                    }
                } else if (parsedStatus.status === 'Failed') {
                    (emitter as any).emit('failed', { exportId, error: 'Export failed' });
                    if (emitter.intervalId) {
                        clearInterval(emitter.intervalId);
                    }
                    this.backgroundMonitors.delete(exportId);
                } else if (elapsedMinutes >= maxDuration) {
                    (emitter as any).emit('timeout', { exportId, elapsedMinutes });
                    if (emitter.intervalId) {
                        clearInterval(emitter.intervalId);
                    }
                    this.backgroundMonitors.delete(exportId);
                }
            } catch (error: any) {
                (emitter as any).emit('error', { exportId, error: error.message });
            }
        };
    
        // Start polling
        emitter.intervalId = setInterval(monitorLoop, pollInterval);
        monitorLoop(); // Immediate first check
    
        OutputLogger.info(`Started background monitoring for export ${exportId}`);
    }
  • Tool listed in availability matrix as available for all hosting types in 'Monitoring' category.
    'list_monitors': {
        hostingTypes: ['dxp-paas', 'dxp-saas', 'self-hosted', 'unknown'],
        category: 'Monitoring',
        description: 'List active monitors'
    },
Behavior4/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It effectively describes key traits: it's a read operation (implied by 'List'), specifies real-time performance ('REAL-TIME: <1s'), and clarifies the return format ('Returns array of active monitor details'). However, it doesn't mention potential limitations like rate limits or authentication needs, leaving some gaps for a tool with no annotation coverage.

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

Conciseness5/5

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

The description is highly concise and well-structured: it starts with an emoji for visual clarity, states the purpose upfront, includes performance details, lists what it shows, provides usage guidance, notes the lack of parameters, and specifies the return type—all in three efficient sentences with no wasted words.

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?

Given the tool's simplicity (0 parameters, no output schema, no annotations), the description is nearly complete: it covers purpose, behavior, usage, and output. However, without annotations or an output schema, it could benefit from more detail on the exact structure of the returned array (e.g., field examples or data types) to fully guide the agent.

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

Parameters4/5

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

The input schema has 0 parameters with 100% coverage, so the baseline is 4. The description adds value by explicitly stating 'No parameters,' which reinforces the schema and prevents confusion, though it doesn't need to explain any parameters beyond that.

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 verb ('List') and resource ('active background monitors tracking deployments'), distinguishing it from siblings like 'list_deployments' or 'get_monitoring_stats' by specifying it shows monitor details including IDs, deployment IDs, status, and update count. It explicitly identifies the scope as real-time active monitors, not historical or aggregated data.

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: 'Use to discover active monitors for stop_monitoring() or update_monitoring_interval() calls.' It directly names alternative tools for related actions, helping the agent choose correctly based on the goal of finding monitors to stop or update.

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