UNPKG

minimax-mcp-js

Version:

Official MiniMax Model Context Protocol (MCP) JavaScript implementation that provides seamless integration with MiniMax's powerful AI capabilities including image generation, video generation, text-to-speech, and voice cloning APIs.

263 lines (262 loc) 8.84 kB
import { BaseService } from './index.js'; import { TTSAPI } from '../api/tts.js'; import { ImageAPI } from '../api/image.js'; import { VideoAPI } from '../api/video.js'; import { VoiceCloneAPI } from '../api/voice-clone.js'; import { VoiceAPI } from '../api/voice.js'; import { MusicAPI } from '../api/music.js'; import { VoiceDesignAPI } from '../api/voice-design.js'; import { RESOURCE_MODE_URL } from '../const/index.js'; /** * Media service, handles all media-related operations */ export class MediaService extends BaseService { ttsApi; imageApi; videoApi; voiceCloneApi; voiceApi; musicApi; voiceDesignApi; /** * Create media service instance * @param api API instance */ constructor(api) { super(api, 'media-service'); this.ttsApi = new TTSAPI(api); this.imageApi = new ImageAPI(api); this.videoApi = new VideoAPI(api); this.voiceCloneApi = new VoiceCloneAPI(api); this.voiceApi = new VoiceAPI(api); this.musicApi = new MusicAPI(api); this.voiceDesignApi = new VoiceDesignAPI(api); this.config = {}; // Initialize as empty object, will be set in initialize } /** * Initialize service * @param config Configuration */ async initialize(config) { await super.initialize(config); // Any media service specific initialization logic } /** * Update API instance * @param api New API instance */ updateApi(api) { super.updateApi(api); this.ttsApi = new TTSAPI(api); this.imageApi = new ImageAPI(api); this.videoApi = new VideoAPI(api); this.voiceCloneApi = new VoiceCloneAPI(api); this.voiceApi = new VoiceAPI(api); this.musicApi = new MusicAPI(api); this.voiceDesignApi = new VoiceDesignAPI(api); } /** * Generate speech * @param params Speech generation parameters * @returns Generation result (URL or file path) */ async generateSpeech(params) { this.checkInitialized(); try { return await this.ttsApi.generateSpeech(params); } catch (error) { // console.error(`[${new Date().toISOString()}] Failed to generate speech:`, error); throw this.wrapError('Failed to generate speech', error); } } /** * List available voices * @param params Voice listing parameters * @returns Voice list results */ async listVoices(params) { this.checkInitialized(); try { return await this.voiceApi.listVoices(params); } catch (error) { // console.error(`[${new Date().toISOString()}] Failed to get voice list:`, error); throw this.wrapError('Failed to get voice list', error); } } /** * Clone voice * @param params Voice cloning parameters * @returns Cloning result */ async cloneVoice(params) { this.checkInitialized(); try { return await this.voiceCloneApi.cloneVoice(params); } catch (error) { // console.error(`[${new Date().toISOString()}] Failed to clone voice:`, error); throw this.wrapError('Failed to clone voice', error); } } /** * Generate image * @param params Image generation parameters * @returns Generation results (URL array or file path array) */ async generateImage(params) { this.checkInitialized(); try { // Auto-generate output filename if not provided if (!params.outputFile) { const promptPrefix = params.prompt.substring(0, 20).replace(/[^\w]/g, '_'); params.outputFile = `image_${promptPrefix}_${Date.now()}`; } const outputFiles = await this.imageApi.generateImage(params); return outputFiles; } catch (error) { // console.error(`[${new Date().toISOString()}] Failed to generate image:`, error); throw this.wrapError('Failed to generate image', error); } } /** * Generate video * @param params Video generation parameters * @returns Generation result (URL or file path) */ async generateVideo(params) { this.checkInitialized(); try { // Auto-generate output filename if not provided if (!params.outputFile) { const promptPrefix = params.prompt.substring(0, 20).replace(/[^\w]/g, '_'); params.outputFile = `video_${promptPrefix}_${Date.now()}`; } const result = await this.videoApi.generateVideo(params); if (params.async_mode) { return { content: [ { type: 'text', text: `Success. Video generation task submitted: Task ID: ${result.task_id}. Please use \`query_video_generation\` tool to check the status of the task and get the result.`, }, ], }; } else if (this.config.resourceMode === RESOURCE_MODE_URL) { return { content: [ { type: 'text', text: `Success. Video URL: ${result.video_url}`, }, ], }; } else { return { content: [ { type: 'text', text: `Success. Video saved as: ${result.video_path}`, }, ], }; } } catch (error) { // console.error(`[${new Date().toISOString()}] Failed to generate video:`, error); throw this.wrapError('Failed to generate video', error); } } /** * Query video generation * @param params Video generation query parameters * @returns Query result */ async queryVideoGeneration(params) { this.checkInitialized(); try { const result = await this.videoApi.queryVideoGeneration(params); if (result.status === 'Success') { if (this.config.resourceMode === RESOURCE_MODE_URL) { return { content: [ { type: 'text', text: `Success. Video URL: ${result.video_url}`, }, ], }; } else { return { content: [ { type: 'text', text: `Success. Video saved as: ${result.video_path}`, }, ], }; } } else { return { content: [ { type: 'text', text: `Video generation task is still processing: Task ID: ${params.taskId}.`, }, ], }; } } catch (error) { throw this.wrapError('Failed to query video generation status', error); } } /** * Generate music * @param params Music generation parameters * @returns Generation result (file path) */ async generateMusic(params) { this.checkInitialized(); try { return await this.musicApi.generateMusic(params); } catch (error) { throw this.wrapError('Failed to generate music', error); } } /** * Design voice * @param params Voice design parameters * @returns Design result (voice ID and file path) */ async designVoice(params) { this.checkInitialized(); try { return await this.voiceDesignApi.voiceDesign(params); } catch (error) { throw this.wrapError('Failed to design voice', error); } } /** * Wrap error message * @param message Error message prefix * @param error Original error * @returns Wrapped error */ wrapError(message, error) { if (error instanceof Error) { const wrappedError = new Error(`${message}: ${error.message}`); wrappedError.stack = error.stack; return wrappedError; } return new Error(`${message}: ${String(error)}`); } }