Skip to main content
Glama

gemini_image_tool

Generate new images or edit existing ones using AI prompts within the ToolBox MCP Server environment.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
operationYesgenerate_image: Generate new image, edit_image: Edit existing image
promptYesPrompt for image generation/editing
inputImageNoImage path (required for edit_image)
outputDirYesOutput directory path
fileNameNoOutput file name templateimage-${year}_${month}_${day}_${hour}_${minute}_${second}.png
temperatureNoTemperature of the model
topPNoTop P of the model
topKNoTop K of the model
maxOutputTokensNoMaximum number of output tokens

Implementation Reference

  • Main handler function implementing Gemini image generation and editing. Uses GoogleGenerativeAI to process prompts, handles image input for editing, generates filename with timestamp, saves output image, and returns success/error messages.
    export default async function (request: any) {
      try {
        const { operation, prompt, inputImage, outputDir, fileName = "image-${year}_${month}_${day}_${hour}_${minute}_${second}.png", temperature = 1, topP = 0.95, topK = 40, maxOutputTokens = 8192 } = request.params.arguments;
    
        // API Key validation
        const apiKey = process.env.GEMINI_API_KEY;
        if (!apiKey) {
          throw new Error("GEMINI_API_KEY 环境变量未设置");
        }
    
        // Path validation
        if (!path.isAbsolute(outputDir)) {
          throw new Error(`路径必须是绝对路径(示例:${path.join(path.parse(process.cwd()).root, "my_images")})`);
        }
    
        const genAI = new GoogleGenerativeAI(apiKey);
    
        // Output directory creation
        try {
          fs.mkdirSync(outputDir, { recursive: true });
        } catch (err) {
          throw new Error(`无法创建目录 ${outputDir}: ${err instanceof Error ? err.message : String(err)}`);
        }
    
        // Filename processing
        const now = new Date();
        const year = now.getFullYear();
        const month = String(now.getMonth() + 1).padStart(2, '0');
        const day = String(now.getDate()).padStart(2, '0');
        const hour = String(now.getHours()).padStart(2, '0');
        const minute = String(now.getMinutes()).padStart(2, '0');
        const second = String(now.getSeconds()).padStart(2, '0');
        const finalFileName = fileName
          .replace("${year}", year.toString())
          .replace("${month}", month)
          .replace("${day}", day)
          .replace("${hour}", hour)
          .replace("${minute}", minute)
          .replace("${second}", second);
        const imagePath = path.join(outputDir, finalFileName);
    
        const model = genAI.getGenerativeModel({
          model: "gemini-2.0-flash-exp-image-generation",
          generationConfig: {
            // @ts-ignore
            responseModalities: ['Text', 'Image'],
            temperature: temperature,
            topP: topP,
            topK: topK,
            maxOutputTokens: maxOutputTokens
          },
        });
    
        let contents;
    
        if (operation === "generate_image") {
          contents = prompt;
        } else if (operation === "edit_image") {
          if (!inputImage) {
            throw new Error("编辑图片操作需要提供 inputImage 参数");
          }
    
          const imageBuffer = fs.readFileSync(inputImage);
          const base64Image = imageBuffer.toString("base64");
    
          contents = [
            { text: prompt },
            {
              inlineData: {
                mimeType: "image/png",
                data: base64Image,
              },
            },
          ];
        } else {
          throw new Error("不支持的操作类型: " + operation);
        }
    
        const response = await model.generateContent(contents);
    
        for (const part of response.response.candidates[0].content.parts) {
          if (part.inlineData) {
            const imageData = part.inlineData.data;
            const buffer = Buffer.from(imageData, "base64");
            fs.writeFileSync(imagePath, buffer);
          }
        }
    
        return {
          content: [
            {
              type: "text",
              text: "Image saved to " + imagePath,
            },
          ],
        };
      } catch (error: any) {
        console.error("Error generating content:", error);
        return {
          content: [
            {
              type: "text",
              text: `Error: ${error instanceof Error ? error.message : String(error)}`,
            },
          ],
          isError: true,
        };
      }
    }
  • Input schema defining parameters for the gemini_image_tool, including operation type, prompt, optional input image, output directory, and generation config options.
    export const schema = {
      name: "gemini_image_tool",
      description: "Generate or edit images with Gemini",
      type: "object",
      properties: {
        operation: {
          type: "string",
          enum: ["generate_image", "edit_image"],
          description: "generate_image: Generate new image, edit_image: Edit existing image",
        },
        prompt: {
          type: "string",
          description: "Prompt for image generation/editing",
        },
        inputImage: {
          type: "string",
          description: "Image path (required for edit_image)",
        },
        outputDir: {
          type: "string",
          description: "Output directory path",
        },
        fileName: {
          type: "string",
          default: "image-${year}_${month}_${day}_${hour}_${minute}_${second}.png",
          description: "Output file name template",
        },
        temperature: {
          type: "number",
          description: "Temperature of the model",
          minimum: 0,
          maximum: 1,
          default: 1
        },
        topP: {
          type: "number",
          description: "Top P of the model",
          minimum: 0,
          maximum: 1,
          default: 0.95
        },
        topK: {
          type: "number",
          description: "Top K of the model",
          default: 40
        },
        maxOutputTokens: {
          type: "number",
          description: "Maximum number of output tokens",
          default: 8192
        }
      },
      required: ["operation", "prompt", "outputDir"],
    };
  • Dynamic tool registration in loadTools(): scans tools directory, imports each tool file (e.g., gemini_image_tool.ts derives name 'gemini_image_tool'), registers schema and wrapped default handler in global tools/handlers maps.
    for (const file of toolFiles) {
      const toolPath = path.join(toolsDir, file);
      try {
        // 如果是重新加载,清除模块缓存
        if (reload) clearModuleCache(toolPath);
    
        // 导入模块,重新加载时添加时间戳防止缓存
        const importPath = 'file://' + toolPath + (reload ? `?update=${Date.now()}` : '');
        const { default: tool, schema, destroy } = await import(importPath);
        const toolName = path.parse(toolPath).name;
    
        // 注册工具
        tools.push({
          name: toolName,
          description: tool.description,
          inputSchema: schema,
          destroy: destroy
        });
    
        // 注册处理函数
        handlers[toolName] = async (request: ToolRequest) => { return await tool(request); };
      } catch (error) {
  • Cleanup function called during tool reload/unload to release resources.
    export async function destroy() {
      // Release resources, stop timers, disconnect, etc.
      console.log("Destroy gemini_image_tool");
    }

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/xiaoguomeiyitian/ToolBox'

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