advanced35 minspecial

Chef's Special: AI Image Generation Server

An advanced MCP server that generates images using AI APIs. Learn to handle binary data, manage API keys, and return image content from MCP tools.


title: "Chef's Special: AI Image Generation Server" description: "An advanced MCP server that generates images using AI APIs. Learn to handle binary data, manage API keys, and return image content from MCP tools." order: 6 category: "special" level: "advanced" duration: "35 min" date: "2026-04-01" tags:

  • tools
  • resources
  • ai
  • images keywords:
  • mcp image generation
  • ai image mcp server
  • mcp-framework advanced
  • image generation tool

What You Get

A Chef's Special MCP server that integrates with AI image generation APIs. This template shows advanced patterns: handling binary data, managing API keys, caching generated images as resources, and building a multi-step tool pipeline.

Tools included:

  • generate_image — generate an image from a text prompt
  • list_generated — list all previously generated images

Resources included:

  • images://gallery — browse all generated images in the current session

Quick Start

npx mcp-framework create ai-image-server
cd ai-image-server

The Image Generation Tool

Create src/tools/GenerateImageTool.ts:

import { MCPTool } from "mcp-framework";
import { z } from "zod";
import fs from "fs/promises";
import path from "path";

const GenerateInput = z.object({
  prompt: z.string().describe("Text description of the image to generate"),
  size: z
    .enum(["256x256", "512x512", "1024x1024"])
    .default("512x512")
    .describe("Image dimensions"),
  style: z
    .enum(["natural", "vivid"])
    .default("vivid")
    .describe("Image style"),
});

// In-memory store for session images
const generatedImages: {
  id: string;
  prompt: string;
  path: string;
  timestamp: string;
}[] = [];

class GenerateImageTool extends MCPTool<typeof GenerateInput> {
  name = "generate_image";
  description = "Generate an image from a text prompt using an AI API";
  schema = { input: GenerateInput };

  async execute(input: z.infer<typeof GenerateInput>) {
    const apiKey = process.env.IMAGE_API_KEY;
    if (!apiKey) {
      throw new Error(
        "IMAGE_API_KEY environment variable is required. " +
        "Set it in your Claude Desktop MCP config."
      );
    }

    // Call image generation API
    const res = await fetch("https://api.openai.com/v1/images/generations", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${apiKey}`,
      },
      body: JSON.stringify({
        model: "dall-e-3",
        prompt: input.prompt,
        n: 1,
        size: input.size,
        style: input.style,
        response_format: "b64_json",
      }),
    });

    if (!res.ok) {
      const err = await res.json();
      throw new Error(`Image API error: ${err.error?.message || res.status}`);
    }

    const data = await res.json();
    const imageData = data.data[0].b64_json;

    // Save to disk
    const outputDir = process.env.OUTPUT_DIR || "./generated";
    await fs.mkdir(outputDir, { recursive: true });

    const id = `img_${Date.now()}`;
    const filePath = path.join(outputDir, `${id}.png`);
    await fs.writeFile(filePath, Buffer.from(imageData, "base64"));

    const record = {
      id,
      prompt: input.prompt,
      path: filePath,
      timestamp: new Date().toISOString(),
    };
    generatedImages.push(record);

    return {
      id,
      path: filePath,
      prompt: input.prompt,
      size: input.size,
      message: "Image generated successfully",
    };
  }
}

export default GenerateImageTool;
export { generatedImages };

The List Generated Tool

Create src/tools/ListGeneratedTool.ts:

import { MCPTool } from "mcp-framework";
import { z } from "zod";
import { generatedImages } from "./GenerateImageTool";

class ListGeneratedTool extends MCPTool<typeof z.ZodObject<{}>> {
  name = "list_generated";
  description = "List all images generated in the current session";
  schema = { input: z.object({}) };

  async execute() {
    return {
      count: generatedImages.length,
      images: generatedImages.map((img) => ({
        id: img.id,
        prompt: img.prompt,
        path: img.path,
        timestamp: img.timestamp,
      })),
    };
  }
}

export default ListGeneratedTool;

Configuration

{
  "mcpServers": {
    "ai-image": {
      "command": "node",
      "args": ["./dist/index.js"],
      "env": {
        "IMAGE_API_KEY": "sk-your-api-key",
        "OUTPUT_DIR": "/path/to/save/images"
      }
    }
  }
}

Advanced Patterns Demonstrated

  1. API key management — required env vars with clear error messages
  2. Binary data handling — base64 decode and file system writes
  3. Session state — in-memory store for generated images
  4. Multi-step pipelines — API call, decode, save, index
  5. Configurable output — environment variable for output directory

What You Learn

  • Working with binary/image data in MCP tools
  • Secure API key management patterns
  • File system operations from MCP servers
  • Session-scoped state management
  • Building tools that produce artifacts

Next Up

Ready for the ultimate challenge? Try the Full Developer Tools Suite or learn to ship with the Docker-Ready Template.


Built with mcp-framework (3.3M+ downloads) by @QuantGeekDev. Validated by Anthropic.