Python 创建一个基于 Gemini 模型的图片生成 MCP Server,并将其集成到支持 MCP 的客户端

Python 创建一个基于 Gemini 模型的图片生成 MCP Server,并将其集成到支持 MCP 的客户端

📝 教程:创建图片生成 MCP Server

本教程将引导您完成从项目初始化、代码编写到客户端集成的全过程。

1. 项目初始化与依赖安装

文章推荐使用 uv 作为 Python 项目管理工具,它能高效地管理虚拟环境和依赖。

# 1. 创建项目目录并进入
uv init gemini-image-mcp-server
cd gemini-image-mcp-server

# 2. 创建并激活虚拟环境 (Windows PowerShell)
uv venv
.venv\Scripts\activate

# 3. 安装核心依赖
# mcp[cli]:包含 MCP 服务器库和调试工具
# httpx:一个强大的 HTTP 客户端
uv add mcp[cli] httpx

# 4. 安装 Google Gemini 官方 SDK
uv add google-genai

# 5. 创建服务器主文件
new-item server.py

2. 编写 MCP Server 核心代码

server.py 中编写以下代码,实现一个通过 Gemini 模型生成图片的工具。

from typing import Any
from mcp.server.fastmcp import FastMCP
from google import genai
from google.genai import types
from io import BytesIO
import os
import uuid
from PIL import Image
import sys

# 初始化 FastMCP 服务器,名称将显示在客户端
mcp = FastMCP("gemini-image-mcp-server")

def generate_image_from_gemini(prompt: str) -> str:
    """核心函数:调用 Gemini API 生成图片并保存到本地"""
    api_key = os.getenv('GEMINI_API_KEY') # 从环境变量读取 API 密钥
    if not api_key:
        return "错误:未设置 GEMINI_API_KEY 环境变量"
    
    client = genai.Client(api_key=api_key)
    
    # 使用支持图像生成的 Gemini 模型
    response = client.models.generate_content(
        model="gemini-2.0-flash-exp-image-generation",
        contents=prompt,
        config=types.GenerateContentConfig(
            response_modalities=['Text', 'Image'] # 指示模型可以返回文本或图像
        )
    )

    for part in response.candidates[0].content.parts:
        # 如果返回的是文本(如模型描述),将其打印到标准错误,避免干扰 MCP 通信
        if part.text is not None:
            sys.stderr.write(part.text + '\n')
        # 如果返回的是图像数据
        elif part.inline_data is not None:
            # 将二进制数据转换为图像
            image = Image.open(BytesIO(part.inline_data.data))
            
            # 创建保存图像的目录
            save_dir = 'generated-images'
            if not os.path.exists(save_dir):
                os.makedirs(save_dir)
            
            # 生成唯一文件名并保存
            unique_filename = f"{save_dir}/{uuid.uuid4()}.png"
            image.save(unique_filename)
            # 返回图像的绝对路径
            return os.path.abspath(unique_filename)
    
    # 如果没有找到图像数据,返回错误信息
    return "未找到有效的图像数据。"

@mcp.tool()
async def generate_image(prompt: str) -> str:
    """通过文本描述生成图像,并返回保存路径。
    
    Args:
        prompt: 用于生成图像的文本描述。
    """
    path = generate_image_from_gemini(prompt)
    return path

if __name__ == "__main__":
    # 通过标准输入/输出运行 MCP 服务器
    # 注意:任何 print() 输出到标准输出的内容都会破坏协议通信
    mcp.run(transport='stdio')

代码关键点说明:

  • @mcp.tool():这个装饰器将 generate_image 函数暴露为一个 MCP 工具 (Tool)。客户端(如 AI 助手)可以发现并调用它。
  • transport='stdio':服务器通过标准输入(stdin)接收请求,并通过标准输出(stdout)返回响应。因此,代码中不能使用 print 向 stdout 输出任何调试信息,否则会破坏协议。文章中使用 sys.stderr.write 将文本输出到标准错误,这是安全的做法。
  • API 密钥:通过环境变量 GEMINI_API_KEY 获取,这是一种安全的实践,避免将密钥硬编码在代码中。

3. 集成到 MCP 客户端(以 Roo Code 为例)

要将您刚创建的服务器集成到支持 MCP 的客户端,需要在客户端的 MCP 配置文件中添加服务器信息。

  1. 在 VSCode 中打开 Roo Code 扩展。
  2. 点击顶部的 MCP Servers
  3. 选择 Edit MCP Settings
  4. 在打开的配置文件中,添加一个新的服务器配置:
{
  "mcpServers": {
    "gemini-image-mcp-server": {
      "command": "uv",
      "args": [
        "--directory",
        "D:\\你的实际路径\\gemini-image-mcp-server", // 替换为你的项目绝对路径
        "run",
        "server.py"
      ],
      "env": {
        "GEMINI_API_KEY": "你的Gemini_API密钥" // 替换为你的实际 API Key
      }
    }
  }
}

配置说明:

  • commandargs:使用 uv 命令在指定目录下运行 server.py 脚本。uv run 会自动使用项目虚拟环境。
  • env:在此处设置环境变量 GEMINI_API_KEY,服务器启动时会自动读取。这是比在系统全局设置更推荐的方式。
  • 路径修改务必args 中的 --directory 路径替换为您项目的绝对路径

保存配置文件并重启 VSCode(或 Roo Code),您应该在 MCP Servers 列表中看到 gemini-image-mcp-server 状态为已连接。

4. 验证与使用

在 Roo Code 的对话窗口中,尝试输入一个与图像生成相关的指令,例如:

请生成一张科技感十足的未来城市封面图。

Roo Code 的 AI 会理解您的意图,并自动调用您配置的 generate_image 工具。您会在界面中看到类似以下的提示:

我将使用 gemini-image-mcp-server 中的 generate_image 工具来生成图像。

工具执行成功后,Roo Code 会返回图像的保存路径。您可以在文件系统中找到生成的图片。文章中还演示了如何进一步指示 AI 移动或重命名图片,展示了 MCP 工具与 AI 能力结合后的强大扩展性。

💡 核心要点与扩展思考

  1. 安全与标准错误输出:务必使用 sys.stderr.write 输出任何调试或文本信息,保持标准输出(stdout)仅用于 MCP 协议通信。
  2. 环境变量管理:通过客户端配置文件(如 env 字段)或系统环境变量来管理 API 密钥等敏感信息,切勿硬编码。
  3. 扩展可能性:您可以将任何现有的 Python 脚本、API 调用或自动化任务,通过 @mcp.tool() 封装成 MCP 工具。这意味着,您曾经编写的许多“自动化工作”,都可以低成本地转变为 AI 可以自主调用的“技能”,从而真正实现“动动嘴就把活干了”的愿景。

希望这份教程对您有所帮助。如果您在实践中有任何新的想法或遇到了问题,随时可以继续交流。

暂无评论