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.
152 lines (151 loc) • 5.99 kB
JavaScript
import axios from 'axios';
import { createWriteStream } from 'fs';
import { MinimaxAuthError, MinimaxRequestError } from '../exceptions/index.js';
import * as fs from 'fs';
import * as path from 'path';
import { RESOURCE_MODE_URL } from '../const/index.js';
export class MiniMaxAPI {
config;
baseURL;
session;
constructor(config) {
this.config = config;
this.baseURL = config.apiHost || 'https://api.minimax.chat';
this.session = axios.create({
headers: {
'Authorization': `Bearer ${this.config.apiKey}`,
'MM-API-Source': 'Minimax-MCP-JS'
}
});
}
// Get current resource mode
getResourceMode() {
return this.config.resourceMode || RESOURCE_MODE_URL;
}
getHeaders(hasFiles = false) {
const headers = {
'Authorization': `Bearer ${this.config.apiKey}`,
};
// Set Content-Type based on whether files are being uploaded
if (!hasFiles) {
headers['Content-Type'] = 'application/json';
}
return headers;
}
async makeRequest(endpoint, data, method = 'POST') {
const url = `${this.baseURL}${endpoint}`;
const hasFiles = !!data.files;
const config = {
method,
url,
headers: this.getHeaders(hasFiles),
};
if (method.toUpperCase() === 'GET') {
config.params = data;
}
else {
// Handle file uploads
if (hasFiles) {
// Use FormData for file uploads
const formData = new FormData();
const files = data.files;
delete data.files;
// Add other data to FormData
for (const [key, value] of Object.entries(data)) {
if (value !== undefined) {
formData.append(key, String(value));
}
}
// Add files
for (const [fieldName, fileInfo] of Object.entries(files)) {
const filePath = fileInfo.path;
if (filePath && fs.existsSync(filePath)) {
const fileName = path.basename(filePath);
const fileBuffer = fs.readFileSync(filePath);
const fileBlob = new Blob([fileBuffer]);
formData.append(fieldName, fileBlob, fileName);
}
}
config.data = formData;
}
else {
config.data = data;
}
}
try {
const response = await this.session.request(config);
// Check for error codes in response data
const baseResp = response.data?.base_resp;
if (baseResp && baseResp.status_code !== 0) {
// Throw different exceptions based on error code
if (baseResp.status_code === 1004) {
throw new MinimaxAuthError(`API Error: ${baseResp.status_msg}, Please check your API key and API host. ` +
`Trace ID: ${response.headers['trace-id']}`);
}
else {
throw new MinimaxRequestError(`API Error: ${baseResp.status_msg} ` +
`Trace ID: ${response.headers['trace-id']}`);
}
}
return response.data;
}
catch (error) {
if (error instanceof MinimaxAuthError || error instanceof MinimaxRequestError) {
throw error;
}
if (axios.isAxiosError(error)) {
const axiosError = error;
if (axiosError.response) {
throw new MinimaxRequestError(`Request failed (${axiosError.response.status}): ${axiosError.response.statusText}. ` +
`Response content: ${JSON.stringify(axiosError.response.data)}`);
}
else if (axiosError.request) {
throw new MinimaxRequestError(`Request sent but no response received, possibly a network issue: ${axiosError.message}`);
}
else {
throw new MinimaxRequestError(`Request error: ${axiosError.message}`);
}
}
throw new MinimaxRequestError(`Unknown error: ${String(error)}`);
}
}
async downloadFile(url, outputPath) {
try {
// Ensure directory exists
const dir = path.dirname(outputPath);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
const response = await axios({
method: 'GET',
url,
responseType: 'stream',
headers: this.getHeaders(),
});
const writer = createWriteStream(outputPath);
response.data.pipe(writer);
return new Promise((resolve, reject) => {
writer.on('finish', resolve);
writer.on('error', reject);
});
}
catch (error) {
if (axios.isAxiosError(error)) {
const axiosError = error;
const errorMessage = axiosError.response?.data &&
typeof axiosError.response.data === 'object' &&
'message' in axiosError.response.data
? axiosError.response.data.message
: axiosError.message;
throw new MinimaxRequestError(`File download failed: ${errorMessage}`);
}
throw new MinimaxRequestError(`File download failed: ${String(error)}`);
}
}
async get(endpoint, params = {}) {
return this.makeRequest(endpoint, params, 'GET');
}
async post(endpoint, data = {}) {
return this.makeRequest(endpoint, data, 'POST');
}
}