Skip to main content
Glama
server.py10.8 kB
""" Seedream MCP服务器主模块 基于 FastMCP 框架实现的图像生成服务,提供文生图、图生图、多图融合、 组图生成与本地图片浏览等工具能力。 """ from __future__ import annotations # 标准库导入 import argparse import os # 第三方库导入 from dotenv import load_dotenv from mcp.server.fastmcp import FastMCP from mcp.types import TextContent # 本地模块导入 from .config import SeedreamConfig, _parse_bool, _parse_int, set_config from .tools import ( BrowseImagesInput, ImageToImageInput, MultiImageFusionInput, SequentialGenerationInput, TextToImageInput, run_browse_images, run_image_to_image, run_multi_image_fusion, run_sequential_generation, run_text_to_image, ) from .utils.errors import SeedreamConfigError, format_error_for_user from .utils.logging import get_logger, setup_logging # ==================== 服务器元数据常量 ==================== # 服务器标识名称 SERVER_NAME = "seedream_mcp" # 服务器版本号 SERVER_VERSION = "1.2.2" # 服务器功能说明 SERVER_INSTRUCTIONS = "Seedream 图像生成工具,支持文生图、图生图、多图融合、组图与图片浏览。" # ==================== 工具注解常量 ==================== # 生成类工具的能力标注 # - readOnlyHint: 非只读操作(生成文件) # - destructiveHint: 非破坏性操作 # - idempotentHint: 非幂等操作(每次生成结果可能不同) # - openWorldHint: 开放世界操作(需要网络请求) GENERATION_TOOL_ANNOTATIONS = { "readOnlyHint": False, "destructiveHint": False, "idempotentHint": False, "openWorldHint": True, } # 浏览类工具的能力标注 # - readOnlyHint: 只读操作(仅读取文件列表) # - destructiveHint: 非破坏性操作 # - idempotentHint: 幂等操作(相同输入得到相同结果) # - openWorldHint: 非开放世界操作(本地文件系统) BROWSE_TOOL_ANNOTATIONS = { "readOnlyHint": True, "destructiveHint": False, "idempotentHint": True, "openWorldHint": False, } # ==================== MCP 服务器实例 ==================== # 初始化 FastMCP 服务器实例 mcp = FastMCP(SERVER_NAME, instructions=SERVER_INSTRUCTIONS) # 初始化模块日志记录器 logger = get_logger(__name__) # ==================== MCP 工具函数定义 ==================== @mcp.tool( name="seedream_text_to_image", annotations={"title": "Seedream 文生图", **GENERATION_TOOL_ANNOTATIONS}, ) async def seedream_text_to_image(params: TextToImageInput) -> list[TextContent]: """ 文生图: 通过给模型提供清晰准确的文字指令,即可快速获得符合描述的高质量单张图片。 """ return await run_text_to_image(params) @mcp.tool( name="seedream_image_to_image", annotations={"title": "Seedream 图生图", **GENERATION_TOOL_ANNOTATIONS}, ) async def seedream_image_to_image(params: ImageToImageInput) -> list[TextContent]: """ 图文生图: 基于已有图片,结合文字指令进行图像编辑,包括图像元素增删、风格转化、材质替换、色调迁移、改变背景/视角/尺寸等。 """ return await run_image_to_image(params) @mcp.tool( name="seedream_multi_image_fusion", annotations={"title": "Seedream 多图融合", **GENERATION_TOOL_ANNOTATIONS}, ) async def seedream_multi_image_fusion(params: MultiImageFusionInput) -> list[TextContent]: """ 多图融合: 根据您输入的文本描述和多张参考图片,融合它们的风格、元素等特征来生成新图像。如衣裤鞋帽与模特图融合成穿搭图,人物与风景融合为人物风景图等。 """ return await run_multi_image_fusion(params) @mcp.tool( name="seedream_sequential_generation", annotations={"title": "Seedream 组图生成", **GENERATION_TOOL_ANNOTATIONS}, ) async def seedream_sequential_generation( params: SequentialGenerationInput, ) -> list[TextContent]: """ 组图输出: 支持通过一张或者多张图片和文字信息,生成漫画分镜、品牌视觉等一组内容关联的图片。 """ return await run_sequential_generation(params) @mcp.tool( name="seedream_browse_images", annotations={"title": "Seedream 图片浏览", **BROWSE_TOOL_ANNOTATIONS}, ) async def seedream_browse_images(params: BrowseImagesInput) -> list[TextContent]: """ 本地图片浏览: 浏览工作目录中的图片文件,便于用户选择参考图或查看已生成内容。 """ return await run_browse_images(params) # ==================== 配置构建函数 ==================== def _build_config_from_args(args: argparse.Namespace) -> SeedreamConfig: """从命令行参数构建服务器配置对象 优先级:命令行参数 > 配置文件环境变量 > 系统环境变量 > 默认值。 Args: args: 解析后的命令行参数对象。 Returns: 构建完成的 SeedreamConfig 配置实例。 Raises: SeedreamConfigError: 缺少必需参数(如 API 密钥)时抛出。 """ # 加载指定的配置文件(如有) if args.config_file: load_dotenv(args.config_file) # 获取 API 密钥(优先使用命令行参数) cli_api_key = args.api_key or os.getenv("ARK_API_KEY") if not cli_api_key: raise SeedreamConfigError("未找到 API 密钥,请使用 --api-key 或设置 ARK_API_KEY 环境变量。") # 模型别名映射,将简短名称映射为完整模型 ID model_map = { "doubao-seedream-4.5": "doubao-seedream-4-5-251128", "doubao-seedream-4.0": "doubao-seedream-4-0-250828", } model_id = model_map.get(args.model, args.model) # 构建配置对象 cfg = SeedreamConfig( api_key=cli_api_key, base_url=args.base_url, model_id=model_id, default_size=args.default_size, default_watermark=bool(args.watermark), timeout=_parse_int(os.getenv("SEEDREAM_TIMEOUT", "60")), api_timeout=_parse_int(os.getenv("SEEDREAM_API_TIMEOUT", "600")), max_retries=_parse_int(os.getenv("SEEDREAM_MAX_RETRIES", "3")), log_level=args.log_level, log_file=os.getenv("LOG_FILE"), auto_save_enabled=_parse_bool(os.getenv("SEEDREAM_AUTO_SAVE_ENABLED", "true")), auto_save_base_dir=os.getenv("SEEDREAM_AUTO_SAVE_BASE_DIR"), auto_save_download_timeout=_parse_int( os.getenv("SEEDREAM_AUTO_SAVE_DOWNLOAD_TIMEOUT", "30") ), auto_save_max_retries=_parse_int(os.getenv("SEEDREAM_AUTO_SAVE_MAX_RETRIES", "3")), auto_save_max_file_size=_parse_int( os.getenv("SEEDREAM_AUTO_SAVE_MAX_FILE_SIZE", str(50 * 1024 * 1024)) ), auto_save_max_concurrent=_parse_int(os.getenv("SEEDREAM_AUTO_SAVE_MAX_CONCURRENT", "5")), auto_save_date_folder=_parse_bool(os.getenv("SEEDREAM_AUTO_SAVE_DATE_FOLDER", "true")), auto_save_cleanup_days=_parse_int(os.getenv("SEEDREAM_AUTO_SAVE_CLEANUP_DAYS", "30")), stream_buffer_max_size=_parse_int( os.getenv("SEEDREAM_STREAM_BUFFER_MAX_SIZE", str(10 * 1024 * 1024)) ), stream_chunk_size=_parse_int(os.getenv("SEEDREAM_STREAM_CHUNK_SIZE", str(1024 * 1024))), ) # 设置全局配置实例 set_config(cfg) return cfg def _build_arg_parser() -> argparse.ArgumentParser: """构建命令行参数解析器 定义所有支持的命令行选项,包括 API 配置、模型选择、日志级别等。 Returns: 配置完成的 ArgumentParser 实例。 """ parser = argparse.ArgumentParser( description="Seedream MCP 服务器 - AI 图像生成工具", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" 示例用法: seedream-mcp --api-key your_key_here seedream-mcp --api-key your_key_here --default-size 4K --log-level DEBUG seedream-mcp --api-key your_key_here --config-file ./config.env """, ) # API 认证配置 parser.add_argument( "--api-key", help="火山引擎 API 密钥(也可通过 ARK_API_KEY 环境变量配置)", ) parser.add_argument( "--config-file", help="可选的 .env 配置文件路径,用于加载额外环境变量", ) # 模型与生成配置 parser.add_argument( "--model", choices=["doubao-seedream-4.5", "doubao-seedream-4.0"], default="doubao-seedream-4.5", help="模型选择(默认 doubao-seedream-4.5)", ) parser.add_argument( "--default-size", choices=["1K", "2K", "4K"], default="2K", help="默认生成尺寸(默认 2K)", ) parser.add_argument( "--watermark", action="store_true", default=False, help="启用默认水印", ) # 日志配置 parser.add_argument( "--log-level", choices=["DEBUG", "INFO", "WARNING", "ERROR"], default="INFO", help="日志级别", ) # 网络配置 parser.add_argument( "--base-url", default="https://ark.cn-beijing.volces.com/api/v3", help="API 基础 URL", ) # 传输层配置 parser.add_argument( "--transport", choices=["stdio", "sse", "streamable-http"], default="stdio", help="MCP 传输方式(默认 stdio)", ) return parser # ==================== 主入口函数 ==================== def cli_main() -> int: """命令行主入口函数 负责参数解析、配置构建、日志初始化与服务器启动。 Returns: 进程退出码: - 0: 正常退出 - 1: 配置错误或运行异常 """ # 解析命令行参数 parser = _build_arg_parser() args = parser.parse_args() # 构建配置对象 try: config = _build_config_from_args(args) except SeedreamConfigError as exc: print(f"配置错误: {exc.message}") return 1 # 初始化日志系统 setup_logging(config.log_level, config.log_file) logger.info( "Seedream MCP 启动: %s (version %s)", SERVER_NAME, SERVER_VERSION, ) # 启动 MCP 服务器 try: mcp.run(transport=args.transport) except KeyboardInterrupt: logger.info("收到中断信号,正在退出。") return 0 except Exception as exc: logger.error("服务器运行异常", exc_info=True) print(f"服务器运行失败: {format_error_for_user(exc)}") return 1 return 0 # ==================== 模块执行入口 ==================== if __name__ == "__main__": raise SystemExit(cli_main())

Implementation Reference

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/tengmmvp/Seedream_MCP'

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