UNPKG

mcp-image-generator

Version:

ModelScope AI图像生成器的MCP服务器,支持生成web设计占位图片

250 lines (222 loc) 8.09 kB
#!/usr/bin/env node import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; import axios from "axios"; import sharp from "sharp"; import { v4 as uuidv4 } from "uuid"; import fs from "fs/promises"; import path from "path"; import { fileURLToPath } from "url"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); class ImageGeneratorServer { constructor() { this.server = new Server( { name: "image-generator", version: "1.0.0", }, { capabilities: { tools: {}, }, } ); this.setupToolHandlers(); } setupToolHandlers() { // 列出可用工具 this.server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: "generate_image", description: "基于提示词生成AI图片,用于web设计占位图片", inputSchema: { type: "object", properties: { prompt: { type: "string", description: "英文提示词,描述需要生成的图片内容", }, api_key: { type: "string", description: "ModelScope API密钥", }, width: { type: "number", description: "图片宽度(可选,默认1024)", default: 1024, }, height: { type: "number", description: "图片高度(可选,默认1024)", default: 1024, }, filename: { type: "string", description: "保存的文件名(可选,默认自动生成)", }, }, required: ["prompt", "api_key"], }, }, { name: "generate_placeholder_image", description: "为web设计生成占位图片,根据用途自动优化提示词", inputSchema: { type: "object", properties: { purpose: { type: "string", description: "图片用途(如:hero-banner, product-showcase, user-avatar, background等)", }, description: { type: "string", description: "图片描述(中文或英文)", }, api_key: { type: "string", description: "ModelScope API密钥", }, width: { type: "number", description: "图片宽度(可选,默认1024)", default: 1024, }, height: { type: "number", description: "图片高度(可选,默认1024)", default: 1024, }, style: { type: "string", description: "图片风格(如:modern, minimal, corporate, colorful等)", default: "modern", }, }, required: ["purpose", "description", "api_key"], }, }, ], }; }); // 处理工具调用 this.server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; try { switch (name) { case "generate_image": return await this.generateImage(args); case "generate_placeholder_image": return await this.generatePlaceholderImage(args); default: throw new Error(`未知的工具: ${name}`); } } catch (error) { return { content: [ { type: "text", text: `错误: ${error.message}`, }, ], }; } }); } async generateImage(args) { const { prompt, api_key, width = 1024, height = 1024, filename } = args; if (!prompt || !api_key) { throw new Error("prompt和api_key参数是必需的"); } const url = "https://api-inference.modelscope.cn/v1/images/generations"; const payload = { model: "MAILAND/majicflus_v1", // 使用更新的模型 prompt: prompt, }; const headers = { Authorization: `Bearer ${api_key}`, "Content-Type": "application/json", }; try { // 发送图片生成请求 const response = await axios.post(url, payload, { headers }); if (!response.data.images || !response.data.images[0]) { throw new Error("API响应中未找到图片链接"); } const imageUrl = response.data.images[0].url; // 下载图片 const imageResponse = await axios.get(imageUrl, { responseType: 'arraybuffer' }); // 处理图片尺寸 let imageBuffer = Buffer.from(imageResponse.data); if (width !== 1024 || height !== 1024) { imageBuffer = await sharp(imageBuffer) .resize(width, height, { fit: 'cover' }) .toBuffer(); } // 保存图片 const outputFilename = filename || `generated_image_${uuidv4().slice(0, 8)}.jpg`; await fs.writeFile(outputFilename, imageBuffer); return { content: [ { type: "text", text: `✅ 图片生成成功!\n📁 文件名: ${outputFilename}\n📐 尺寸: ${width}x${height}\n🎨 提示词: ${prompt}`, }, ], }; } catch (error) { throw new Error(`图片生成失败: ${error.message}`); } } async generatePlaceholderImage(args) { const { purpose, description, api_key, width = 1024, height = 1024, style = "modern" } = args; // 根据用途和描述生成优化的英文提示词 const optimizedPrompt = this.generateOptimizedPrompt(purpose, description, style); const filename = `${purpose}_placeholder_${uuidv4().slice(0, 8)}.jpg`; return await this.generateImage({ prompt: optimizedPrompt, api_key, width, height, filename, }); } generateOptimizedPrompt(purpose, description, style) { const styleMap = { modern: "clean, modern, minimalist design", minimal: "minimal, simple, clean lines", corporate: "professional, corporate, business style", colorful: "vibrant, colorful, energetic", elegant: "elegant, sophisticated, luxury", casual: "casual, friendly, approachable", }; const purposeMap = { "hero-banner": "hero banner, website header, large format", "product-showcase": "product display, showcase, commercial photography", "user-avatar": "profile picture, avatar, portrait", "background": "background image, texture, pattern", "logo": "logo design, brand identity, symbol", "icon": "icon, symbol, simple graphic", "illustration": "illustration, artwork, creative design", "photo": "photography, realistic, high quality", }; const basePrompt = `${purposeMap[purpose] || purpose}, ${description}, ${styleMap[style] || style}`; return `${basePrompt}, high quality, professional, web design`; } async run() { const transport = new StdioServerTransport(); await this.server.connect(transport); console.error("MCP Image Generator Server 已启动 🚀"); } } // 启动服务器 const server = new ImageGeneratorServer(); server.run().catch(console.error);