generate_image
Create marketing images using AI-powered templates for social media, banners, and web content. Choose prompt-based generation or direct template control with customizable branding, styles, and sizes.
Instructions
Generate a marketing image. Two modes: (1) Prompt mode — provide a text prompt and AI picks the template. (2) Direct mode (recommended) — provide templateId + slots for precise control. Use list_templates to see available templates.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| prompt | No | Text prompt describing the image (used in prompt mode) | |
| template_id | No | Template ID for direct render mode. Use list_templates to see options. | |
| slots | No | Template slot values. Keys are slot names, values are strings. | |
| photo_query | No | 1-3 word search query for background photo (e.g. 'italian restaurant'). Only used with photo templates when no image_url is provided. | |
| image_url | No | URL of your own image to use as background | |
| size | No | Image size: '1080x1080' (Instagram, default), '1200x628' (OG/Twitter), '1080x1920' (Stories/Reels), '1200x1200' (Instagram HD), '1280x720' (YouTube) | |
| style | No | Visual style: modern, playful, corporate, dark, minimal, bold | |
| brand_kit_id | No | ID of a saved brand kit to use for consistent branding | |
| font | No | Google Font name to use (e.g. 'Poppins', 'Playfair Display') | |
| logo_url | No | HTTPS URL of a logo to overlay on the image | |
| logo_position | No | Position of the logo overlay. Default: bottom-right | |
| background | No | Background type: auto (AI decides), photo (force photo search), gradient (no photo) | |
| variants | No | Number of design variants to generate (1-3). Each variant has different colors/layout. |
Implementation Reference
- src/tools/generate-image.ts:6-150 (handler)Main tool handler implementation. Contains registerGenerateImageTool function that registers the 'generate_image' tool with MCP server. Lines 10-81 define the tool registration with input schema (Zod validation). Lines 82-148 contain the async handler function that processes tool requests, calls the API client's generateImage method, and formats the response for both single images and multiple variants.
export function registerGenerateImageTool( server: McpServer, client: RendrKitClient, ): void { server.registerTool( "generate_image", { description: "Generate a marketing image. Two modes: (1) Prompt mode — provide a text prompt and AI picks the template. (2) Direct mode (recommended) — provide templateId + slots for precise control. Use list_templates to see available templates.", inputSchema: { prompt: z .string() .optional() .describe("Text prompt describing the image (used in prompt mode)"), template_id: z .string() .optional() .describe( "Template ID for direct render mode. Use list_templates to see options.", ), slots: z .record(z.string(), z.string()) .optional() .describe( "Template slot values. Keys are slot names, values are strings.", ), photo_query: z .string() .optional() .describe( "1-3 word search query for background photo (e.g. 'italian restaurant'). Only used with photo templates when no image_url is provided.", ), image_url: z .string() .optional() .describe("URL of your own image to use as background"), size: z .enum(["1080x1080", "1200x628", "1080x1920", "1200x1200", "1280x720"]) .optional() .describe( "Image size: '1080x1080' (Instagram, default), '1200x628' (OG/Twitter), '1080x1920' (Stories/Reels), '1200x1200' (Instagram HD), '1280x720' (YouTube)", ), style: z .enum(["modern", "playful", "corporate", "dark", "minimal", "bold"]) .optional() .describe( "Visual style: modern, playful, corporate, dark, minimal, bold", ), brand_kit_id: z .string() .optional() .describe( "ID of a saved brand kit to use for consistent branding", ), font: z .string() .optional() .describe("Google Font name to use (e.g. 'Poppins', 'Playfair Display')"), logo_url: z .string() .optional() .describe("HTTPS URL of a logo to overlay on the image"), logo_position: z .enum(["top-left", "top-right", "bottom-left", "bottom-right"]) .optional() .describe("Position of the logo overlay. Default: bottom-right"), background: z .enum(["auto", "photo", "gradient"]) .optional() .describe("Background type: auto (AI decides), photo (force photo search), gradient (no photo)"), variants: z .number() .optional() .describe("Number of design variants to generate (1-3). Each variant has different colors/layout."), }, }, async ({ prompt, template_id, slots, photo_query, image_url, size, style, brand_kit_id, font, logo_url, logo_position, background, variants }) => { try { const result = await client.generateImage({ prompt, templateId: template_id, slots, photoQuery: photo_query, imageUrl: image_url, size, style, brandKitId: brand_kit_id, font, logoUrl: logo_url, logoPosition: logo_position, background, variants, }); // Variants > 1 returns { images: [...] } instead of a single image if (variants && variants > 1) { const multi = result as unknown as { images: GeneratedImage[] }; const lines = multi.images.map( (img: GeneratedImage, i: number) => `Variant ${i + 1}: ${img.url} (template: ${img.templateId})`, ); return { content: [ { type: "text" as const, text: `Generated ${multi.images.length} variants!\n\n${lines.join("\n")}`, }, ], }; } return { content: [ { type: "text" as const, text: [ `Image generated successfully!`, ``, `URL: ${result.url}`, `ID: ${result.id}`, `Size: ${result.width}x${result.height}`, result.templateId ? `Template: ${result.templateId}` : null, `Style: ${result.style}`, `Prompt: ${result.prompt}`, `Created: ${result.createdAt}`, ].filter(Boolean).join("\n"), }, ], }; } catch (error) { const message = error instanceof Error ? error.message : String(error); return { content: [ { type: "text" as const, text: `Failed to generate image: ${message}`, }, ], isError: true, }; } }, ); } - src/server.ts:18-18 (registration)Tool registration call - registerGenerateImageTool is invoked in createServer function to register the generate_image tool with the MCP server.
registerGenerateImageTool(server, client); - src/types.ts:47-61 (schema)TypeScript interface definition for GenerateImageParams - defines the schema for parameters passed to the generate image API. Includes fields like prompt, templateId, slots, photoQuery, imageUrl, size, style, brandKitId, font, logoUrl, logoPosition, background, and variants.
export interface GenerateImageParams { prompt?: string; size?: string; style?: string; brandKitId?: string; templateId?: string; slots?: Record<string, string>; photoQuery?: string; imageUrl?: string; font?: string; logoUrl?: string; logoPosition?: "top-left" | "top-right" | "bottom-left" | "bottom-right"; background?: "auto" | "photo" | "gradient"; variants?: number; } - src/types.ts:1-12 (schema)TypeScript interface definition for GeneratedImage - defines the response schema from the generate image API. Includes fields: id, url, width, height, prompt, style, mode (optional), templateId (optional), and createdAt.
/** Response from the generate image endpoint */ export interface GeneratedImage { id: string; url: string; width: number; height: number; prompt: string; style: string; mode?: "direct" | "prompt"; templateId?: string; createdAt: string; } - src/api-client.ts:75-91 (helper)API client method that makes the actual HTTP request to generate images. Takes GenerateImageParams, constructs the request body, and POSTs to /api/v1/generate endpoint. Returns GeneratedImage response or throws RendrKitApiError on failure.
async generateImage(params: GenerateImageParams): Promise<GeneratedImage> { const body: Record<string, unknown> = {}; if (params.prompt) body.prompt = params.prompt; if (params.templateId) body.templateId = params.templateId; if (params.slots) body.slots = params.slots; if (params.photoQuery) body.photoQuery = params.photoQuery; if (params.imageUrl) body.imageUrl = params.imageUrl; if (params.size) body.size = params.size; if (params.style) body.style = params.style; if (params.brandKitId) body.brandKitId = params.brandKitId; if (params.font) body.font = params.font; if (params.logoUrl) body.logoUrl = params.logoUrl; if (params.logoPosition) body.logoPosition = params.logoPosition; if (params.background) body.background = params.background; if (params.variants) body.variants = params.variants; return this.request<GeneratedImage>("POST", "/api/v1/generate", body); }