Skip to main content
Glama
JaxonDigital

Optimizely DXP MCP Server

by JaxonDigital

generate_storage_sas_link

Generate temporary Azure Storage access URLs for Optimizely DXP containers. Create time-limited SAS links for read or write operations to share with external tools or scripts.

Instructions

🔗 Generate temporary Shared Access Signature URL for storage container. INSTANT: <1s. Returns time-limited URL for direct Azure Storage access (read or write). Default: 24 hour expiration, read-only. Set retentionHours for custom expiration (1-168 hours). Set writable=true for write access. Use for external tools, scripts, or direct blob access. Required: container, environment. Returns SAS URL string. URL expires after specified retention period.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
environmentYes
containerNameYes
projectNameNo
projectIdNo
permissionsNoRead
expiryHoursNo
apiKeyNo
apiSecretNo

Implementation Reference

  • The primary handler function for the 'generate_storage_sas_link' tool. It validates input, resolves project credentials if needed, defaults environment to Production, calls the core generateStorageSasLink method, and handles structured response formatting.
    static async handleGenerateStorageSasLink(args: StorageArgs): Promise<any> {
        try {
            // Check if this is a self-hosted project
            if (args.isSelfHosted || args.connectionString) {
                return ResponseBuilder.invalidParams('SAS link generation is not available for self-hosted projects. Self-hosted projects already have direct access via the connection string.');
            }
    
            // Validate container name is provided
            if (!args.containerName) {
                return ResponseBuilder.invalidParams('Missing required parameter: containerName');
            }
    
            // Resolve project configuration if credentials not provided
            let resolvedArgs = args;
            if (!args.apiKey || !args.apiSecret || !args.projectId) {
                const resolved = ProjectTools.resolveCredentials(args);
                if (!resolved.success || !resolved.credentials) {
                    return ResponseBuilder.invalidParams('Missing required parameters. Either provide apiKey/apiSecret/projectId or configure a project.');
                }
                resolvedArgs = {
                    ...args,
                    apiKey: resolved.credentials.apiKey || undefined,
                    apiSecret: resolved.credentials.apiSecret || undefined,
                    projectId: resolved.credentials.projectId || undefined,
                    projectName: resolved.project?.name
                };
            }
    
            // Default to Production if no environment specified
            if (!resolvedArgs.environment) {
                resolvedArgs.environment = 'Production';
            }
    
            const result = await this.generateStorageSasLink(resolvedArgs);
    
            // DXP-66: Check if result is structured response with data and message
            if (result && typeof result === 'object' && 'data' in result && 'message' in result) {
                return ResponseBuilder.successWithStructuredData(result.data, result.message);
            }
    
            // Fallback for legacy string responses
            return ResponseBuilder.success(result);
        } catch (error: any) {
            // console.error('Generate SAS link error:', error);
            return ResponseBuilder.internalError('Failed to generate SAS link', error.message);
        }
    }
  • Core implementation logic that extracts parameters, determines permissions, calls DXPRestClient.getContainerSasLink to generate the SAS URL via Optimizely DXP REST API, and formats the result.
    static async generateStorageSasLink(args: StorageArgs): Promise<SasLinkResult | string> {
        // Extract parameters from args
        const apiKey = args.apiKey!;
        const apiSecret = args.apiSecret!;
        const projectId = args.projectId!;
        const { environment, containerName, permissions = 'Read', expiryHours = 24 } = args;
        // Convert expiryHours to validMinutes for display
        const validMinutes = expiryHours * 60;
    
        // console.error(`Generating SAS link for container ${containerName} in ${environment}`);
    
        // DXP-102: Use REST API instead of PowerShell (3-10x faster, no PowerShell dependency)
        try {
            // Determine if writable based on permissions
            const writable = (permissions === 'Write' || permissions === 'Delete');
    
            // Convert hours to retention hours for API
            const retentionHours = Math.ceil(expiryHours);
    
            const result: SasLinkResponse = await DXPRestClient.getContainerSasLink(
                projectId,
                apiKey,
                apiSecret,
                environment!,
                containerName!,
                {
                    retentionHours: retentionHours,
                    writable: writable
                },
                { apiUrl: args.apiUrl } // Support custom API URLs
            );
    
            // Format response
            if (result) {
                return this.formatSasLink(result, containerName!, environment!, permissions, validMinutes);
            }
    
            return ResponseBuilder.addFooter('SAS link generation completed');
    
        } catch (error: any) {
            // Handle REST API errors
            throw new Error(`Failed to generate SAS link for ${containerName}: ${error.message}`);
        }
    }
  • Type definition for input arguments (StorageArgs) used by generate_storage_sas_link, including required fields like containerName, environment, and optional credentials and expiry.
    interface StorageArgs {
        apiKey?: string;
        apiSecret?: string;
        projectId?: string;
        projectName?: string;
        environment?: string;
        containerName?: string;
        permissions?: string;
        expiryHours?: number;
        connectionString?: string;
        isSelfHosted?: boolean;
        apiUrl?: string;
        limit?: number;
        offset?: number;
    }
  • Helper function to format the SAS link response with human-readable message, tips, and structured data including expiry time.
    static formatSasLink(data: SasLinkResponse, containerName: string, environment: string, permissions: string, validMinutes: number): SasLinkResult {
        const { FORMATTING: { STATUS_ICONS } } = Config;
    
        let response = `${STATUS_ICONS.SUCCESS} **Storage SAS Link Generated**\n\n`;
        response += `**Container:** ${containerName}\n`;
        response += `**Environment:** ${environment}\n`;
        response += `**Permissions:** ${permissions}\n`;
        response += `**Valid for:** ${validMinutes} minutes\n\n`;
    
        if (data.sasLink || data.url) {
            response += `${STATUS_ICONS.UNLOCK} **SAS URL:**\n`;
            response += `\`\`\`\n${data.sasLink || data.url}\n\`\`\`\n\n`;
            response += `**Note:** This link expires after ${validMinutes} minutes.\n`;
        }
    
        const tips = [
            'Use this URL to access the storage container',
            'The link includes authentication credentials',
            'Do not share this link publicly'
        ];
    
        response += '\n' + ResponseBuilder.formatTips(tips);
    
        // DXP-66: Return structured data and message
        const structuredData: SasLinkData = {
            containerName: containerName,
            environment: environment,
            permissions: permissions,
            validMinutes: validMinutes,
            expiresAt: new Date(Date.now() + validMinutes * 60000).toISOString(),
            sasUrl: data.sasLink || data.url || null
        };
    
        return {
            data: structuredData,
            message: ResponseBuilder.addFooter(response)
        };
    }

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