Skip to main content
Glama
nanameru

Gemini 2.5 Flash Image MCP

by nanameru

edit_image

Modify images using text prompts to adjust content, style, or composition while preserving original lighting and visual characteristics.

Instructions

Edit an image using a prompt. Provide one input image via base64 or file path.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
imageYesOne input image
promptYesDescribe the edit; the model matches original style and lighting.
saveToFilePathNoOptional path to save the edited image

Implementation Reference

  • The handler function for the 'edit_image' tool. It takes the prompt, image input, and optional save path, calls the shared Gemini API helper, processes the generated image, optionally saves it to file, and returns a content array with text description, image data, and data URL.
    async (args) => {
      const { prompt, image, saveToFilePath } = args as { prompt: string; image: InlineImageInput; saveToFilePath?: string };
      const results = await callGeminiGenerate({ prompt, images: [image] });
      const first = results[0];
      const savedPath = await maybeSaveImage(first.imageBase64, first.mimeType, saveToFilePath);
      const dataUrl = `data:${first.mimeType};base64,${first.imageBase64}`;
      return {
        content: [
          { type: 'text', text: `Edited image${savedPath ? ` saved to ${savedPath}` : ''}` },
          { type: 'image', mimeType: first.mimeType, data: first.imageBase64 },
          { type: 'text', text: dataUrl },
        ],
      };
    }
  • Zod input schema for the 'edit_image' tool defining parameters: prompt (string), image (object with dataBase64/path/mimeType), and optional saveToFilePath.
      prompt: z.string().describe('Describe the edit; the model matches original style and lighting.'),
      image: z
        .object({
          dataBase64: z.string().optional().describe('Base64 without data URL prefix'),
          path: z.string().optional().describe('Path to the input image file'),
          mimeType: z.string().optional().describe('image/png or image/jpeg'),
        })
        .describe('One input image'),
      saveToFilePath: z.string().optional().describe('Optional path to save the edited image'),
    },
  • src/index.ts:152-180 (registration)
    The mcp.tool call that registers the 'edit_image' tool with its name, description, input schema, and handler function.
    mcp.tool(
      'edit_image',
      'Edit an image using a prompt. Provide one input image via base64 or file path.',
      {
        prompt: z.string().describe('Describe the edit; the model matches original style and lighting.'),
        image: z
          .object({
            dataBase64: z.string().optional().describe('Base64 without data URL prefix'),
            path: z.string().optional().describe('Path to the input image file'),
            mimeType: z.string().optional().describe('image/png or image/jpeg'),
          })
          .describe('One input image'),
        saveToFilePath: z.string().optional().describe('Optional path to save the edited image'),
      },
      async (args) => {
        const { prompt, image, saveToFilePath } = args as { prompt: string; image: InlineImageInput; saveToFilePath?: string };
        const results = await callGeminiGenerate({ prompt, images: [image] });
        const first = results[0];
        const savedPath = await maybeSaveImage(first.imageBase64, first.mimeType, saveToFilePath);
        const dataUrl = `data:${first.mimeType};base64,${first.imageBase64}`;
        return {
          content: [
            { type: 'text', text: `Edited image${savedPath ? ` saved to ${savedPath}` : ''}` },
            { type: 'image', mimeType: first.mimeType, data: first.imageBase64 },
            { type: 'text', text: dataUrl },
          ],
        };
      }
    );
  • Core helper function that handles the API call to Gemini for image editing/generation. Converts inputs to API format, sends POST request, parses response, extracts image data. Used by edit_image and other image tools.
    async function callGeminiGenerate(request: GenerateRequest): Promise<{ imageBase64: string; mimeType: string }[]> {
      const textPart = { text: request.prompt };
      const imageParts = await toInlineDataParts(request.images);
      const parts = [textPart as any, ...imageParts];
    
      const fetchResponse = await fetch(`${GEMINI_ENDPOINT}?key=${encodeURIComponent(GEMINI_API_KEY)}`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          contents: [
            {
              parts,
            },
          ],
        }),
      });
    
      if (!fetchResponse.ok) {
        const text = await fetchResponse.text();
        throw new Error(`Gemini API error ${fetchResponse.status}: ${text}`);
      }
    
      const json = (await fetchResponse.json()) as GeminiGenerateResponse;
      const images: { imageBase64: string; mimeType: string }[] = [];
      const first = json.candidates?.[0]?.content?.parts ?? [];
      for (const part of first) {
        if (part.inlineData?.data) {
          images.push({ imageBase64: part.inlineData.data, mimeType: part.inlineData.mimeType ?? 'image/png' });
        }
      }
    
      if (images.length === 0) {
        // Fallback: if API returns interleaved text etc.
        throw new Error('No image data returned by Gemini API');
      }
    
      return images;
    }
  • Helper function to optionally save the generated/edited image to a file path, determining extension from mimeType if needed.
    async function maybeSaveImage(base64: string, mimeType: string, targetPath?: string): Promise<string | undefined> {
      if (!targetPath) return undefined;
      const { writeFile } = await import('node:fs/promises');
      const { extname } = await import('node:path');
      const extension = extname(targetPath) || (mimeType === 'image/jpeg' ? '.jpg' : '.png');
      const resolved = resolve(targetPath.endsWith(extension) ? targetPath : `${targetPath}${extension}`);
      const buffer = Buffer.from(base64, 'base64');
      await writeFile(resolved, buffer);
      return resolved;
    }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/nanameru/Gemini-2.5-Flash-Image-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server