UNPKG

doubao-i2i-generator-mcp

Version:

MCP Server for generating images using Doubao Seedream 3.0 i2i (image-to-image) model

136 lines (121 loc) 4.29 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 { spawn } from 'child_process'; // 创建MCP服务器 const server = new Server({ name: 'doubao-i2i-generator', version: '1.0.0', }); // 列出可用工具 server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: 'generate_i2i_image', description: '使用豆包Seedream-3 i2i模型,根据文字提示和输入图片生成新图片', inputSchema: { type: 'object', properties: { model: { type: 'string', description: '模型ID', default: 'doubao-seededit-3-0-i2i-250628' }, prompt: { type: 'string', description: '文字提示词,描述想要生成的图片效果' }, image: { type: 'string', description: '输入图片的URL地址' }, response_format: { type: 'string', description: '输出格式:url 或 b64_json', default: 'url' }, size: { type: 'string', description: '图像尺寸', default: 'adaptive' }, seed: { type: 'number', description: '随机种子,用于控制生成结果的一致性', default: 21 }, guidance_scale: { type: 'number', description: '引导强度,控制生成图片与提示词的匹配程度', default: 5.5 }, watermark: { type: 'boolean', description: '是否添加水印', default: true } }, required: ['prompt', 'image'] } } ] }; }); // 处理工具调用 server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; try { let result; switch (name) { case 'generate_i2i_image': result = await generateI2IImage(args); break; default: result = `未知工具: ${name}`; } return { content: [{ type: 'text', text: typeof result === 'string' ? result : JSON.stringify(result) }] }; } catch (error) { return { content: [ { type: 'text', text: `执行错误: ${error.message}` } ] }; } }); // i2i图片生成工具:根据文字提示和输入图片生成新图片 async function generateI2IImage({ model = 'doubao-seededit-3-0-i2i-250628', prompt, image, response_format = 'url', size = 'adaptive', seed = 21, guidance_scale = 5.5, watermark = true }) { const apiKey = process.env.ARK_API_KEY; if (!apiKey) { throw new Error('请设置 ARK_API_KEY'); } const baseUrl = (process.env.ARK_BASE_URL || 'https://ark.cn-beijing.volces.com/api/v3').replace(/\/+$/,''); const payload = { model, prompt, image, response_format, size, seed, guidance_scale, watermark }; return new Promise((resolve, reject) => { const hasFullEndpoint = /\/images\/generations$/.test(baseUrl); const endpoint = hasFullEndpoint ? baseUrl : `${baseUrl}/images/generations`; const args = [ '-sS', '-X', 'POST', endpoint, '-H', 'Content-Type: application/json', '-H', `Authorization: Bearer ${apiKey}`, '-d', JSON.stringify(payload) ]; const proc = spawn('curl', args, { stdio: ['ignore', 'pipe', 'pipe'] }); let stdout = ''; let stderr = ''; proc.stdout.on('data', (d) => { stdout += d.toString(); }); proc.stderr.on('data', (d) => { stderr += d.toString(); }); proc.on('close', (code) => { if (code !== 0) { return reject(new Error(`curl 执行失败,退出码 ${code}, 错误: ${stderr || '无'}`)); } try { const json = JSON.parse(stdout); resolve(json); } catch (e) { reject(new Error(`解析响应失败: ${e.message}; 原始输出: ${stdout}`)); } }); proc.on('error', (err) => reject(new Error(`启动curl失败: ${err.message}`))); }); } // 启动服务器 async function main() { const transport = new StdioServerTransport(); await server.connect(transport); console.error('Doubao I2I Image Generator MCP Server started'); } main().catch(console.error);