mcp-image-generator
Version:
ModelScope AI图像生成器的MCP服务器,支持生成web设计占位图片
250 lines (222 loc) • 8.09 kB
JavaScript
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);