Skip to main content
Glama

Minimax MCP Tools

by PsychArch
image-service.ts5.88 kB
import { MinimaxBaseClient } from '../core/base-client.js'; import { API_CONFIG, DEFAULTS, MODELS, CONSTRAINTS, type ImageModel } from '../config/constants.js'; import { FileHandler } from '../utils/file-handler.js'; import { ErrorHandler } from '../utils/error-handler.js'; import { type ImageGenerationParams } from '../config/schemas.js'; interface ImageGenerationPayload { model: string; prompt: string; n: number; prompt_optimizer: boolean; response_format: string; width?: number; height?: number; aspect_ratio?: string; seed?: number; subject_reference?: Array<{ type: string; image_file: string; }>; style?: { style_type: string; style_weight: number; }; } interface ImageGenerationResponse { data?: { image_urls?: string[]; image_base64?: string[]; }; } interface ImageGenerationResult { files: string[]; count: number; model: string; prompt: string; warnings?: string[]; } export class ImageGenerationService extends MinimaxBaseClient { constructor(options: { baseURL?: string; timeout?: number } = {}) { super(options); } async generateImage(params: ImageGenerationParams): Promise<ImageGenerationResult> { try { // Build API payload (MCP handles validation) const payload = this.buildPayload(params); // Make API request const response = await this.post(API_CONFIG.ENDPOINTS.IMAGE_GENERATION, payload) as ImageGenerationResponse; // Process response return await this.processImageResponse(response, params); } catch (error: any) { const processedError = ErrorHandler.handleAPIError(error); ErrorHandler.logError(processedError, { service: 'image', params }); // Throw the error so task manager can properly mark it as failed throw processedError; } } private buildPayload(params: ImageGenerationParams): ImageGenerationPayload { const imageDefaults = DEFAULTS.IMAGE as any; // Choose model based on whether style is provided const model = params.style ? 'image-01-live' : 'image-01'; const payload: ImageGenerationPayload = { model: model, prompt: params.prompt, n: 1, prompt_optimizer: true, // Always optimize prompts response_format: 'url' // Always use URL since we save to file }; // Handle sizing parameters (conflict-free approach) if (params.customSize) { payload.width = params.customSize.width; payload.height = params.customSize.height; } else { payload.aspect_ratio = params.aspectRatio || imageDefaults.aspectRatio; } // Add optional parameters if (params.seed !== undefined) { payload.seed = params.seed; } // Model-specific parameter handling if (model === 'image-01') { // Add subject reference for image-01 model // MCP Server Bridge: Convert user-friendly file path to API format if (params.subjectReference) { // TODO: Convert file path/URL to base64 or ensure URL is accessible // For now, pass through assuming it's already in correct format payload.subject_reference = [{ type: 'character', image_file: params.subjectReference }]; } } else if (model === 'image-01-live') { // Add style settings for image-01-live model if (params.style) { payload.style = { style_type: params.style.style_type, style_weight: params.style.style_weight || 0.8 }; } } return payload; } private async processImageResponse(response: ImageGenerationResponse, params: ImageGenerationParams): Promise<ImageGenerationResult> { // Handle both URL and base64 responses const imageUrls = response.data?.image_urls || []; const imageBase64 = response.data?.image_base64 || []; if (!imageUrls.length && !imageBase64.length) { throw new Error('No images generated in API response'); } // Download and save images const savedFiles: string[] = []; const errors: string[] = []; const imageSources = imageUrls.length ? imageUrls : imageBase64; for (let i = 0; i < imageSources.length; i++) { try { const filename = FileHandler.generateUniqueFilename(params.outputFile, i, imageSources.length); if (imageBase64.length && !imageUrls.length) { // Save base64 image await FileHandler.saveBase64Image(imageBase64[i]!, filename); } else { // Download from URL await FileHandler.downloadFile(imageSources[i]!, filename); } savedFiles.push(filename); } catch (error: any) { errors.push(`Image ${i + 1}: ${error.message}`); } } if (savedFiles.length === 0) { throw new Error(`Failed to save any images: ${errors.join('; ')}`); } // Use the actual model that was used const modelUsed = params.style ? 'image-01-live' : 'image-01'; const result: ImageGenerationResult = { files: savedFiles, count: savedFiles.length, model: modelUsed, prompt: params.prompt }; if (errors.length > 0) { result.warnings = errors; } return result; } // Utility methods async validateSubjectReference(reference: string): Promise<string | null> { if (!reference) return null; try { return await FileHandler.convertToBase64(reference); } catch (error: any) { throw new Error(`Invalid subject reference: ${error.message}`); } } getSupportedModels(): string[] { return Object.keys(MODELS.IMAGE); } getSupportedAspectRatios(): readonly string[] { return CONSTRAINTS.IMAGE.ASPECT_RATIOS; } getModelInfo(modelName: string): { name: string; description: string } | null { return MODELS.IMAGE[modelName as ImageModel] || null; } }

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/PsychArch/minimax-mcp-tools'

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