UNPKG

imagegen-mcp-server

Version:

MCP server for AI image generation with OpenAI DALL-E, Google Imagen, Gemini, and Flux via Replicate

121 lines (120 loc) 4.85 kB
#!/usr/bin/env node import "dotenv/config"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { generateImageOpenAI } from "./providers/openai.js"; import { generateImageGoogle } from "./providers/google.js"; import { generateImageGemini } from "./providers/gemini.js"; import { generateImageReplicate } from "./providers/replicate.js"; import { z } from "zod"; const server = new McpServer({ name: "imagegen-mcp-server", version: "0.1.0", }); server.registerTool("image.generate.openai", { description: "Generate an image using OpenAI (default model gpt-image-1). Returns a saved file path and optional base64.", inputSchema: { prompt: z.string(), negativePrompt: z.string().optional(), width: z.number().int().positive().optional(), height: z.number().int().positive().optional(), size: z.string().optional(), format: z.enum(["png", "jpeg", "jpg", "webp"]).optional(), seed: z.number().int().optional(), quality: z.enum(["standard", "hd"]).optional(), style: z.string().optional(), background: z.enum(["transparent", "solid"]).optional(), model: z.string().optional(), returnBase64: z.boolean().optional(), filenameHint: z.string().optional(), }, }, async (args) => { const r = await generateImageOpenAI(args); const parts = []; parts.push({ type: "text", text: `provider=openai model=${r.model ?? ""} saved=${r.path}`.trim(), }); if (r.base64) parts.push({ type: "image", data: r.base64, mimeType: r.mimeType }); return { content: parts }; }); server.registerTool("image.generate.google", { description: "Generate an image using Google (e.g., Imagen 3). Requires GOOGLE_API_KEY and GOOGLE_IMAGEN_ENDPOINT. Returns a saved file path and optional base64.", inputSchema: { prompt: z.string(), negativePrompt: z.string().optional(), width: z.number().int().positive().optional(), height: z.number().int().positive().optional(), size: z.string().optional(), format: z.enum(["png", "jpeg", "jpg", "webp"]).optional(), seed: z.number().int().optional(), quality: z.string().optional(), style: z.string().optional(), background: z.enum(["transparent", "solid"]).optional(), model: z.string().optional(), returnBase64: z.boolean().optional(), filenameHint: z.string().optional(), }, }, async (args) => { const r = await generateImageGoogle(args); const parts = []; parts.push({ type: "text", text: `provider=google model=${r.model ?? ""} saved=${r.path}`.trim(), }); if (r.base64) parts.push({ type: "image", data: r.base64, mimeType: r.mimeType }); return { content: parts }; }); server.registerTool("image.generate.gemini", { description: "Generate an image using Google Gemini via @google/genai (default gemini-2.5-flash-image-preview). Requires GOOGLE_API_KEY.", inputSchema: { prompt: z.string(), model: z.string().optional(), returnBase64: z.boolean().optional(), filenameHint: z.string().optional(), }, }, async (args) => { const r = await generateImageGemini(args); const parts = []; parts.push({ type: "text", text: `provider=google(gemini) model=${r.model ?? ""} saved=${r.path}`.trim(), }); if (r.base64) parts.push({ type: "image", data: r.base64, mimeType: r.mimeType }); return { content: parts }; }); server.registerTool("image.generate.replicate", { description: "Generate an image using Replicate models: Flux 1.1 Pro (default), Qwen Image, or SeedDream-4. Requires REPLICATE_API_TOKEN.", inputSchema: { prompt: z.string(), model: z.string().optional(), width: z.number().int().positive().optional(), height: z.number().int().positive().optional(), size: z.string().optional(), format: z.enum(["png", "jpeg", "jpg", "webp"]).optional(), seed: z.number().int().optional(), returnBase64: z.boolean().optional(), filenameHint: z.string().optional(), }, }, async (args) => { const r = await generateImageReplicate(args); const parts = []; parts.push({ type: "text", text: `provider=replicate model=${r.model ?? ""} saved=${r.path}`.trim(), }); if (r.base64) parts.push({ type: "image", data: r.base64, mimeType: r.mimeType }); return { content: parts }; }); async function main() { const transport = new StdioServerTransport(); await server.connect(transport); } main().catch((err) => { console.error("Fatal error starting server:", err); process.exit(1); });