mcpField
M
media-gen-mcp

media-gen-mcp

本地服务
github.com/strato-space媒体与设计939 周前更新

关于 media-gen-mcp

media-gen-mcp 是一个 TypeScript MCP 服务,可通过 OpenAI 和 Google GenAI 生成及编辑图像、生成视频,也能从网址或本地文件获取媒体和文档,并按 MCP 客户端需要组织输出。

主要功能

  1. 01使用 OpenAI 模型生成和编辑图像
  2. 02创建和管理 Sora 视频任务
  3. 03生成 Veo 视频并获取结果
  4. 04从网址或文件获取并压缩图像
  5. 05以 MCP 资源形式返回媒体和文档

适用场景

  1. 01根据文本提示创建或修改图像
  2. 02创建、混剪或查看 Sora 视频任务
  3. 03生成 Veo 视频并下载完成的视频
  4. 04为 MCP 客户端载入并优化图像文件

MCP 相关

向 MCP 客户端提供图像、视频和文件获取工具。媒体可作为内联内容或资源链接返回,并支持结构化结果和 MCP 错误处理。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"strato-space-media-gen": {
"command": "npx",
"args": [
"-y",
"@strato-space/media-gen-mcp"
],
"env": {
"OPENAI_API_KEY": "<OPENAI_API_KEY>",
"GEMINI_API_KEY": "<GEMINI_API_KEY>",
"GOOGLE_API_KEY": "<GOOGLE_API_KEY>",
"GOOGLE_GENAI_USE_VERTEXAI": "<GOOGLE_GENAI_USE_VERTEXAI>",
"GOOGLE_CLOUD_PROJECT": "<GOOGLE_CLOUD_PROJECT>",
"GOOGLE_CLOUD_LOCATION": "<GOOGLE_CLOUD_LOCATION>",
"AZURE_OPENAI_API_KEY": "<AZURE_OPENAI_API_KEY>",
"AZURE_OPENAI_ENDPOINT": "<AZURE_OPENAI_ENDPOINT>",
"OPENAI_API_VERSION": "<OPENAI_API_VERSION>",
"AZURE_OPENAI_DEPLOYMENT": "<AZURE_OPENAI_DEPLOYMENT>",
"MEDIA_GEN_DIRS": "<MEDIA_GEN_DIRS>",
"MEDIA_GEN_URLS": "<MEDIA_GEN_URLS>",
"MEDIA_GEN_MCP_URL_PREFIXES": "<MEDIA_GEN_MCP_URL_PREFIXES>",
"MEDIA_GEN_MCP_TEST_SAMPLE_DIR": "<MEDIA_GEN_MCP_TEST_SAMPLE_DIR>"
}
}
}
}
启动命令npx -y @strato-space/media-gen-mcp
需要配置的环境变量
OPENAI_API_KEY密钥OpenAI API key (required for OpenAI image/video tools).
GEMINI_API_KEY密钥Gemini API key (alternative to GOOGLE_API_KEY).
GOOGLE_API_KEY密钥Google GenAI API key for Veo video tools.
GOOGLE_GENAI_USE_VERTEXAISet to true to use Vertex AI for Google GenAI.
GOOGLE_CLOUD_PROJECTGCP project id for Vertex AI.
GOOGLE_CLOUD_LOCATIONGCP region for Vertex AI (e.g. us-central1).
AZURE_OPENAI_API_KEY密钥Azure OpenAI API key (optional).
AZURE_OPENAI_ENDPOINTAzure OpenAI endpoint hostname.
OPENAI_API_VERSIONAzure OpenAI API version.
AZURE_OPENAI_DEPLOYMENTAzure OpenAI deployment name.
MEDIA_GEN_DIRSComma-separated output directories for media files.
MEDIA_GEN_URLSComma-separated URL prefixes allowed for fetch tools.
MEDIA_GEN_MCP_URL_PREFIXESPublic URL prefixes for mapping local output files.
MEDIA_GEN_MCP_TEST_SAMPLE_DIRPath to sample images for the test-images tool.

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@strato-space/media-gen-mcp1.0.4

工具

13

收录的工具列表 · 更新于 2 周前

参数类型必填说明
ninteger否
sizeenum否1024x1024 | 1536x1024 | 1024x1536 | auto
userstring否
modelenum否gpt-image-1.5 | gpt-image-1
promptstring是
qualityenum否auto | high | medium | low
backgroundenum否transparent | opaque | auto
moderationenum否auto | low
tool_resultenum否控制 content[] 的形态:'resource_link'(默认)会生成 ResourceLink 项,'image' 会生成 base64 ImageContent 块。resource_link | image
output_formatenum否png | jpeg | webp
response_formatenum否控制 structuredContent 的形态:'url'(默认)会生成 data[].url,'b64_json' 会生成 data[].b64_json。url | b64_json
output_compressioninteger否

详细介绍

media-gen-mcp

media-gen-mcp MCP SDK OpenAI SDK mcp-proxy fast-mcp 许可证 GitHub 星标 构建状态


Media Gen MCP 是一个采用 严格 TypeScript 编写的模型上下文协议(MCP)服务,适用于 OpenAI Images(gpt-image-1.5、gpt-image-1)、OpenAI Videos(Sora)和 Google GenAI Videos(Veo):生成和编辑图像、创建和混剪视频任务,并通过 URL 或磁盘获取媒体;支持智能选择 resource_link 或内嵌 image 输出,以及可选的 sharp 处理。专注于生产环境(完整严格类型检查、ESLint 和 Vitest CI)。兼容 fast-agent、Claude Desktop、ChatGPT、Cursor、VS Code、Windsurf 及任何兼容 MCP 的客户端。

**设计原则:**规范优先、类型安全的图像工具——严格遵循 OpenAI Images API 和 MCP 规范,使用完全静态的 TypeScript 类型,并灵活选择结果位置和响应格式,以适配不同客户端。

  • 生成图像:使用 OpenAI 的 gpt-image-1.5 模型,根据文本提示词生成图像(兼容 gpt-image-1,并计划在未来版本中支持 DALL·E)。
  • 编辑图像(局部重绘、扩图、合成):一次可处理 1 到 16 张图像,并提供高级提示词控制。
  • 生成视频:通过 OpenAI Videos(sora-2、sora-2-pro)创建、混剪、列出、检索和删除任务,并下载素材。
  • 生成视频:通过 Google GenAI(Veo)生成视频,支持轮询操作状态并优先下载文件。
  • 获取并压缩图像:从 HTTP(S) URL 或本地文件路径获取图像,并智能优化大小和质量。
  • 获取文档:从 HTTP(S) URL 或本地文件路径获取文档,并返回 resource_link/resource 输出。
  • 调试 MCP 输出格式:使用 test-images 工具,模拟生产环境中的结果位置(content、structuredContent、toplevel)。
  • 集成支持:fast-agent、Windsurf、Claude Desktop、Cursor、VS Code 以及任何兼容 MCP 的客户端。

✨ 功能

  • 严格支持 MCP 规范
    工具输出是最新 MCP 架构中的一等 CallToolResult 对象,包括: content 项(text、image、resource_link、resource)、可选的 structuredContent、可选的顶层 files,以及失败时使用的 isError 标志。

  • 全面支持 gpt-image-1.5 和 sora-2/sora-2-pro 参数(生成与编辑)

    • openai-images-generate 对应 OpenAI Images create API,适用于 gpt-image-1.5(以及 gpt-image-1)(background、moderation、size、quality、output_format、output_compression、n、user 等)。
    • openai-images-edit 对应 OpenAI Images createEdit API,适用于 gpt-image-1.5(以及 gpt-image-1)(image、mask、n、quality、size、user)。
  • OpenAI 视频(Sora)任务工具(创建 / 混剪 / 列出 / 检索 / 删除 / 内容)

  • Google GenAI(Veo)操作与下载(生成 / 检索操作 / 检索内容)

  • 从 URL 或文件获取并处理图像
    fetch-images 工具从 HTTP(S) URL 或本地文件路径加载图像,并支持由用户控制的可选压缩(默认禁用)。支持并行处理最多 20 张图像。

  • 从 URL 或文件获取视频
    fetch-videos 工具列出本地视频,或将远程视频 URL 下载到磁盘,并返回 MCP resource_link(默认)或嵌入式 resource 块(通过 tool_result)。

  • 从 URL 或文件获取文档
    fetch-document 工具下载远程文件或复用本地路径,并返回 MCP resource_link(默认)或嵌入式 resource 块(通过 tool_result)。

  • 混合和编辑最多 16 张图像
    openai-images-edit 接受单个字符串或包含 1–16 个文件路径 / base64 字符串的数组作为 image,符合 GPT Image 模型(gpt-image-1.5、gpt-image-1)的图像编辑规范。

  • 智能图像压缩
    内置基于 sharp 的压缩功能——通过迭代降低质量和尺寸,使图像符合 MCP 载荷限制,同时保持视觉质量。

  • 通过 resource_link 实现资源感知型文件输出

    • 当响应总大小超过安全阈值时,自动从内联 base64 切换为 file。
    • 输出文件会写入磁盘,文件名格式为 output_<time_t>_media-gen__<tool>_<id>.<ext>(图像/文档使用生成的 UUID;视频使用 OpenAI video_id),并根据 tool_result 通过 content[] 提供给 MCP 客户端(图像使用 resource_link/image,视频/文档下载使用 resource_link/resource)。
  • 内置测试图像工具,便于调试 MCP 客户端
    test-images 会从配置的目录读取示例图像,并使用与生产工具相同的结果构建逻辑返回图像。使用 tool_result 和 response_format 参数,测试不同 MCP 客户端如何处理 content[] 和 structuredContent。

  • 结构化 MCP 错误处理
    所有工具错误(验证、OpenAI API 故障、I/O)都会作为 MCP 错误返回,其中包含 isError: true 和 content: [{ type: "text", text: <error message> }],便于在 MCP 客户端中解析和显示故障。


🚀 安装

git clone https://github.com/strato-space/media-gen-mcp.git
cd media-gen-mcp

npm install
npm run build

构建模式:

  • npm run build – 严格的 TypeScript 构建,启用所有严格标志,包括 skipLibCheck: false。通过 .tsbuildinfo 进行增量构建(预热缓存后约需 2-3 秒)。
  • npm run esbuild – 通过 esbuild 快速打包(不进行类型检查,适合快速迭代)。
开发模式(无需构建)

适用于开发,或因内存限制导致 TypeScript 编译失败的情况:

npm run dev  # Uses tsx to run TypeScript directly
质量检查
npm run lint        # ESLint with typescript-eslint
npm run typecheck   # Strict tsc --noEmit
npm run test        # Unit tests (vitest)
npm run test:watch  # Watch mode for TDD
npm run ci          # lint + typecheck + test
单元测试

项目使用 vitest 进行单元测试。测试位于 test/ 中。

覆盖的模块:

模块测试数说明
compression12图像格式检测、缓冲区处理、文件 I/O
helpers31URL/路径验证、输出解析、结果放置、资源链接
env19配置解析、环境变量验证、默认值
logger10结构化日志 + 截断安全性
pricing5Sora 价格估算辅助函数
schemas69所有工具的 Zod schema 验证、类型推断
fetch-images(集成)3端到端 MCP 工具调用行为
fetch-videos(集成)3端到端 MCP 工具调用行为

测试类别:

  • compression — isCompressionAvailable、detectImageFormat、processBufferWithCompression、readAndProcessImage
  • helpers — isHttpUrl、isAbsolutePath、isBase64Image、ensureDirectoryWritable、resolveOutputPath、getResultPlacement、buildResourceLinks
  • env — MEDIA_GEN_* / MEDIA_GEN_MCP_* 设置的配置加载和验证
  • logger — 截断和错误格式化行为
  • schemas — openai-images-*、openai-videos-*、fetch-images、fetch-videos、test-images 输入的验证,以及边界测试(提示词长度、图像数量限制、路径验证)
npm run test
# ✓ test/compression.test.ts (12 tests)
# ✓ test/helpers.test.ts (31 tests)
# ✓ test/env.test.ts (19 tests)
# ✓ test/logger.test.ts (10 tests)
# ✓ test/pricing.test.ts (5 tests)
# ✓ test/schemas.test.ts (69 tests)
# ✓ test/fetch-images.integration.test.ts (3 tests)
# ✓ test/fetch-videos.integration.test.ts (3 tests)
# Tests: 152 passed
通过 npx 直接运行(无需本地克隆)

你也可以使用 npx 直接从远程仓库运行服务:

npx -y github:strato-space/media-gen-mcp --env-file /path/to/media-gen.env

--env-file 参数用于告知服务要加载哪个 env 文件(例如,当你将机密信息保存在克隆目录之外时)。该文件应包含 OPENAI_API_KEY、可选的 Azure 变量,以及任何 MEDIA_GEN_MCP_* 设置。

secrets.yaml(可选)

你可以将 API 密钥(以及可选的 Google Vertex AI 设置)保存在 secrets.yaml 文件中(兼容 fast-agent secrets 模板):

openai:
  api_key: <your-api-key-here>
anthropic:
  api_key: <your-api-key-here>
google:
  api_key: <your-api-key-here>
  vertex_ai:
    enabled: true
    project_id: your-gcp-project-id
    location: europe-west4

media-gen-mcp 会从当前工作目录(或通过 --secrets-file /path/to/secrets.yaml 指定的位置)加载 secrets.yaml,并将其应用到环境变量;secrets.yaml 中的值会覆盖 env,且 <your-api-key-here> 占位符会被忽略。


⚡ 快速开始(fast-agent 和 Windsurf)

fast-agent

在 fast-agent 中,MCP 服务配置在 fastagent.config.yaml 的 mcp.servers 部分(参见 fast-agent 文档)。

要通过 npx 从 GitHub 添加 media-gen-mcp 作为 MCP 服务:

# fastagent.config.yaml

mcp:
  servers:
    # your existing servers (e.g. fetch, filesystem, huggingface, ...)
    media-gen-mcp:
      command: "npx"
      args: ["-y", "github:strato-space/media-gen-mcp", "--env-file", "/path/to/media-gen.env"]

将 OPENAI_API_KEY 和其他设置写入 media-gen.env(参见本仓库中的 .env.sample)。

Windsurf

使用以下 JSON 格式添加一个通过 npx 从 GitHub 运行 media-gen-mcp 的 MCP 服务(类似于 Claude Desktop / VS Code):

{
  "mcpServers": {
    "media-gen-mcp": {
      "command": "npx",
      "args": ["-y", "github:strato-space/media-gen-mcp", "--env-file", "/path/to/media-gen.env"]
    }
  }
}

🔑 配置

添加到你的 MCP 客户端配置中(fast-agent、Windsurf、Claude Desktop、Cursor、VS Code):

{
  "mcpServers": {
    "media-gen-mcp": {
      "command": "npx",
      "args": ["-y", "github:strato-space/media-gen-mcp"],
      "env": { "OPENAI_API_KEY": "sk-..." }
    }
  }
}

也支持 Azure 部署:

{
  "mcpServers": {
    "media-gen-mcp": {
      "command": "npx",
      "args": ["-y", "github:strato-space/media-gen-mcp"],
      "env": {
        // "AZURE_OPENAI_API_KEY": "sk-...",
        // "AZURE_OPENAI_ENDPOINT": "my.endpoint.com",
        "OPENAI_API_VERSION": "2024-12-01-preview"
      }
    }
  }
}

环境变量:

  • 在运行 node dist/index.js 的进程环境中设置 OPENAI_API_KEY(以及可选的 AZURE_OPENAI_API_KEY、AZURE_OPENAI_ENDPOINT、OPENAI_API_VERSION)(shell、systemd unit、Docker env 等)。
  • 如果存在本地 .env 文件,服务会选择性地从其工作目录加载该文件(不会覆盖已设置的环境变量)。
  • 启动服务时也可以传入 --env-file /path/to/env(包括通过 npx 启动);该文件会在工具运行前通过 dotenv 加载,同样不会覆盖已设置的环境变量。
日志记录和 base64 截断

为避免大量图像负载淹没日志,内置日志记录器会对传递给 log.debug/info/warn/error 的结构化 data 应用仅用于日志的清理:

  • 将已配置的字符串字段(例如 b64_json、base64、字符串形式的 data、image_url)截断为简短预览;预览长度由 LOG_TRUNCATE_DATA_MAX 控制(默认值:64 个字符)。默认键列表 在 src/lib/logger.ts 中定义为 LOG_SANITIZE_KEYS,并可通过 MEDIA_GEN_MCP_LOG_SANITIZE_KEYS(以逗号分隔的字段名称列表)覆盖。
  • 清理操作仅应用于日志序列化;返回给 MCP 客户端的工具结果不会被修改。

通过环境变量控制:

  • MEDIA_GEN_MCP_LOG_SANITIZE_IMAGES(默认值:true)
    • 1、true、yes、on – 启用截断(默认行为)。
    • 0、false、no、off – 禁用截断并记录完整负载。

字段列表和限制通过 src/lib/logger.ts 中的 LOG_SANITIZE_KEYS 和 LOG_TRUNCATE_DATA_MAX 配置。

安全性和本地文件访问
  • 允许的目录:所有工具都仅限访问与 MEDIA_GEN_DIRS 匹配的路径。如果未设置,默认为 /tmp/media-gen-mcp(Windows 上为 %TEMP%/media-gen-mcp)。
  • 测试样例:MEDIA_GEN_MCP_TEST_SAMPLE_DIR 会将一个目录添加到允许列表,并启用 test-images 工具。
  • 本地读取:fetch-images 和 fetch-document 接受文件路径(绝对路径或相对路径)。相对路径会以第一个 MEDIA_GEN_DIRS 条目为基准解析,并且仍须匹配允许的模式。
  • 远程读取:HTTP(S) 获取会根据 MEDIA_GEN_URLS 模式进行筛选。为空 = 全部允许。
  • 写入:openai-images-generate、openai-images-edit、fetch-images、fetch-videos 和 fetch-document 会在 MEDIA_GEN_DIRS 的第一个条目下写入。test-images 只读,不会创建新文件。
Glob 模式

MEDIA_GEN_DIRS 和 MEDIA_GEN_URLS 都支持 glob 通配符:

模式匹配内容示例
*任意单个片段(不含 /)/home/*/media/ 匹配 /home/user1/media/
**任意数量的片段/data/**/images/ 匹配 /data/a/b/images/

URL 示例:

MEDIA_GEN_URLS=https://*.cdn.example.com/,https://storage.example.com/**/assets/

路径示例:

MEDIA_GEN_DIRS=/home/*/media-gen/output/,/data/**/images/

⚠️ 警告:没有分隔符的尾随通配符(例如 /home/user/* 或 https://cdn.com/**)会开放整个子树,并在启动时触发控制台警告。

建议的缓解措施
  1. 使用专用 OS 用户运行,并仅授予其访问允许目录的权限。
  2. 将允许列表保持在最小范围。避免在主目录或系统路径中使用 *。
  3. 对远程获取使用明确的 MEDIA_GEN_URLS 前缀。
  4. 通过 OS ACL 或备份监控允许的目录。
工具结果参数:tool_result 和 response_format

图像工具(openai-images-*、fetch-images、test-images)支持两个参数,用于控制 MCP 工具结果的结构:

参数可选值默认值描述
tool_resultresource_link、imageresource_link控制 content[] 的结构
response_formaturl、path、b64_jsonurl控制 structuredContent 的结构(OpenAI ImagesResponse 格式)

视频/文档下载工具(下载时的 openai-videos-create/openai-videos-remix、openai-videos-retrieve-content、下载时的 google-videos-generate、google-videos-retrieve-content、fetch-videos、fetch-document)支持:

参数可选值默认值描述
tool_resultresource_link、resourceresource_link控制 content[] 的结构

Google 视频工具(google-videos-*)也支持:

参数可选值默认值描述
response_formaturl、b64_jsonurl控制 structuredContent.response.generatedVideos[].video 的结构(uri 或 videoBytes)
tool_result — 控制 content[]
  • 图像(openai-images-*、fetch-images、test-images)
    • resource_link(默认):输出带有 file:// 或 https:// URI 的 ResourceLink 项
    • image:输出 base64 ImageContent 块
  • 视频(下载视频数据的工具)
    • resource_link(默认):输出带有 file:// 或 https:// URI 的 ResourceLink 项
    • resource:输出包含 base64 resource.blob 的 EmbeddedResource 块
  • 文档(fetch-document)
    • resource_link(默认):输出带有 file:// 或 https:// URI 的 ResourceLink 项
    • resource:输出包含 base64 resource.blob 的 EmbeddedResource 块
response_format — 控制 structuredContent

对于 OpenAI 图像,structuredContent 始终包含一个符合 OpenAI ImagesResponse 格式的对象:

{
  "created": 1234567890,
  "data": [
    { "url": "https://..." } // or { "path": "/abs/path.png" } / { "b64_json": "..." } depending on response_format
  ]
}
  • url(默认):data[].url 包含文件 URL
  • path:data[].path 包含本地文件系统路径
  • b64_json:data[].b64_json 包含 base64 编码的图像数据

对于 Google 视频,response_format 控制 structuredContent.response.generatedVideos[].video 优先采用:

  • url(默认):video.uri(并移除 video.videoBytes)
  • b64_json:video.videoBytes(并移除 video.uri)
向后兼容性(MCP 5.2.6)

根据 MCP 规范 5.2.6,content[] 中也会包含一个带有序列化 JSON 的 TextContent 块(data[] 始终使用 URL),以兼容不支持 structuredContent 的客户端。

工具结果结构示例:

{
  "content": [
    // ResourceLink or ImageContent based on tool_result
    { "type": "resource_link", "uri": "https://...", "name": "image.png", "mimeType": "image/png" },
    // Serialized JSON for backward compatibility (MCP 5.2.6)
    { "type": "text", "text": "{ \"created\": 1234567890, \"data\": [{ \"url\": \"https://...\" }] }" }
  ],
  "structuredContent": {
    "created": 1234567890,
    "data": [{ "url": "https://..." }]
  }
}

ChatGPT MCP 客户端行为(chatgpt.com,截至 2025-12-01):

  • ChatGPT 目前优先使用 structuredContent,忽略 content[] 中的图像数据。
  • 对于 ChatGPT,请使用 response_format: "url",并将第一个 MEDIA_GEN_MCP_URL_PREFIXES 条目配置为公开的 HTTPS 前缀(例如 MEDIA_GEN_MCP_URL_PREFIXES=https://media-gen.example.com/media)。

对于 Anthropic 客户端(Claude Desktop 等),默认配置即可正常使用。

通过 mcp-proxy(SSE)进行网络访问

如需通过网络访问 SSE,可使用 mcp-proxy 或其同类工具,将 media-gen-mcp 接入前端。此设置已通过 TypeScript SSE 代理实现 punkpeye/mcp-proxy 进行测试。

例如,可以使用一行命令:

mcp-proxy --host=0.0.0.0 --port=99 --server=sse --sseEndpoint=/ --shell 'npx -y github:strato-space/media-gen-mcp --env-file /path/to/media-gen.env'

在生产环境中,通常会通过 systemd 模板单元来配置此项,并从 EnvironmentFile= 加载 PORT/SHELL_CMD(参见 server/mcp/[email protected] 风格的设置)。


🛠 工具签名

openai-images-generate

参数(输入架构):

  • prompt(字符串,必填)
    • 描述所需图像的文本提示词。
    • 最大长度:32,000 个字符。
  • background("transparent" | "opaque" | "auto",可选)
    • 背景处理模式。
    • 如果 background 为 "transparent",则 output_format 必须为 "png" 或 "webp"。
  • model("gpt-image-1.5" | "gpt-image-1",可选,默认值:"gpt-image-1.5")
  • moderation("auto" | "low",可选)
    • 内容审核行为,会传递给 Images API。
  • n(整数,可选)
    • 要生成的图像数量。
    • 最小值:1,最大值:10。
  • output_compression(整数,可选)
    • 压缩级别(0–100)。
    • 仅在 output_format 为 "jpeg" 或 "webp" 时应用。
  • output_format("png" | "jpeg" | "webp",可选)
    • 输出图像格式。
    • 如果省略,服务端会将输出视为 PNG 语义。
  • quality("auto" | "high" | "medium" | "low",默认值:"high")
  • size("1024x1024" | "1536x1024" | "1024x1536" | "auto",默认值:"1024x1536")
  • user(字符串,可选)
    • 转发给 OpenAI 用于监控的用户标识符。
  • response_format("url" | "path" | "b64_json",默认值:"url")
    • 响应格式(与 OpenAI Images API 对齐):
      • "url":基于文件/URL 的输出(resource_link 项、image_url 字段,以及 api 放置方式中的 data[].url)。
      • "path":data[].path 中的本地文件系统路径(用于本地 skill 工作流)。
      • "b64_json":内联 base64 图像数据(图像内容,以及 api 放置方式中的 data[].b64_json)。
    • tool_result("resource_link" | "image",默认值:"resource_link")
      • 控制 content[] 的结构:
        • "resource_link" 会输出 ResourceLink 项(基于文件/URL)
        • "image" 会输出 base64 ImageContent 块

行为说明:

  • 服务端默认使用 OpenAI gpt-image-1.5(设置 model: "gpt-image-1" 可使用旧版行为)。
  • 如果所有 base64 图像的总大小超过配置的负载阈值(默认约为 50MB,通过 MCP_MAX_CONTENT_BYTES 配置),服务端会自动将实际输出模式切换为基于文件/URL 的模式,并将图像保存到 MEDIA_GEN_DIRS 的首个条目(默认值:/tmp/media-gen-mcp)。
  • 即使明确请求 response_format: "b64_json",服务端仍会将文件写入磁盘(用于静态托管、缓存或后续复用)。工具结果中是否会暴露文件路径/URL,取决于 MEDIA_GEN_MCP_RESULT_PLACEMENT 和单次调用的 result_placement(见下文)。

输出(MCP CallToolResult,当放置方式包含 "content" 时):

  • 当实际 output 模式为 "base64" 时:
    • content 是一个数组,可能包含:
      • 图像项:
        • { type: "image", data: <base64 字符串>, mimeType: <"image/png" | "image/jpeg" | "image/webp"> }
      • 可选的文本项,包含 Images API 返回的修订后提示词(适用于支持此功能的模型,例如 DALL·E 3):
        • { type: "text", text: <revised_prompt 字符串> }
  • 当实际 output 模式为 "file" 时:
    • content 中每个文件对应一个 resource_link 项,另加包含修订后提示词的相同可选 text 项:
      • { type: "resource_link", uri: "file:///absolute-path-1.png", name: "absolute-path-1.png", mimeType: <图像 mime 类型> }
    • 对于 gpt-image-1.5 和 gpt-image-1,还会附加一行定价估算(基于 structuredContent.usage),而 structuredContent.pricing 则包含完整的定价明细。

当 result_placement 包含 "api" 时,openai-images-generate 会改为返回一个类似 OpenAI Images API 的对象,不包含 MCP 封装:

{
  "created": 1764599500,
  "data": [
    { "b64_json": "..." } // or { "url": "https://.../media/file.png" } when output: "file"
  ],
  "background": "opaque",
  "output_format": "png",
  "size": "1024x1024",
  "quality": "high"
}
openai-images-edit

参数(输入架构):

  • image(字符串或字符串数组,必需)
    • 单个图像文件的绝对路径(.png、.jpg、.jpeg、.webp), base64 编码的图像字符串(可选用 data:image/...;base64,... URL), 或指向可公开访问图像的 HTTP(S) URL, 或包含 1–16 个此类字符串的数组(用于多图像编辑)。
    • 提供 HTTP(S) URL 时,服务端会获取图像并将其转换为 base64,然后发送给 OpenAI。
  • prompt(字符串,必需)
    • 对所需编辑效果的文字描述。
    • 最大长度:32,000 个字符。
  • mask(字符串,可选)
    • 蒙版图像的绝对路径、base64 字符串或 HTTP(S) URL(PNG < 4MB,尺寸与源图像相同)。透明区域表示要编辑的区域。
  • model("gpt-image-1.5" | "gpt-image-1",可选,默认值:"gpt-image-1.5")
  • n(整数,可选)
    • 要生成的图像数量。
    • 最小值:1,最大值:10。
  • quality("auto" | "high" | "medium" | "low",默认值:"high")
  • size("1024x1024" | "1536x1024" | "1024x1536" | "auto",默认值:"1024x1536")
  • user(字符串,可选)
    • 转发给 OpenAI 用于监控的用户标识符。
  • response_format("url" | "path" | "b64_json",默认值:"url")
    • 响应格式(与 OpenAI Images API 一致):
      • "url":基于文件/URL 的输出(resource_link 项、image_url 字段,以及 api placement 中的 data[].url)。
      • "path":data[].path 中的本地文件系统路径(用于本地 skill 工作流)。
      • "b64_json":内联 base64 图像数据(图像内容,以及 api placement 中的 data[].b64_json)。
  • tool_result("resource_link" | "image",默认值:"resource_link")
    • 控制 content[] 的形态:
      • "resource_link" 输出 ResourceLink 项(基于文件/URL)
      • "image" 输出 base64 ImageContent 块

行为说明:

  • 服务端接受绝对路径、base64/data URL 或 HTTP(S) URL 形式的 image 和 mask。
  • 提供 HTTP(S) URL 时,服务端会获取图像,并在调用 OpenAI 前将其转换为 base64 data URL。
  • 编辑操作输出图像时,服务端始终采用 PNG 语义(mime 类型为 image/png)。

输出(MCP CallToolResult):

  • 有效的 output 模式为 "base64" 时:
    • content 是一个数组,可能包含:
      • 图像项:
        • { type: "image", data: <base64 string>, mimeType: "image/png" }
      • 可选的文本项,其中包含修订后的提示词(底层模型返回时):
        • { type: "text", text: <revised_prompt string> }
  • 有效的 output 模式为 "file" 时:
    • content 包含每个文件对应的一个 resource_link 项,以及相同的可选文本项,其中包含修订后的提示词:
      • { type: "resource_link", uri: "file:///absolute-path-1.png", name: "absolute-path-1.png", mimeType: "image/png" }
    • 对于 gpt-image-1.5 和 gpt-image-1,还会额外包含一行定价估算(基于 structuredContent.usage),而 structuredContent.pricing 则包含完整的定价明细。

当 result_placement 包含 "api" 时,openai-images-edit 遵循与 openai-images-generate 相同的原始 API 格式(顶层字段 created、data[]、background、output_format、size、quality;base64 输出使用 b64_json,文件输出使用 url)。

错误处理(两种工具均适用):

  • 工具处理程序内部发生错误(校验、OpenAI API 失败、I/O 等)时,服务端会返回标记为错误的 CallToolResult:
    • isError: true
    • content: [{ type: "text", text: <error message string> }]
  • 错误消息文本直接取自底层异常消息,服务端不会添加额外说明;完整详情会记录到服务端控制台。
openai-videos-create

使用 OpenAI Videos API(videos.create)创建视频生成任务。

参数(输入架构):

  • prompt(字符串,必填)— 描述视频的文本提示词(最多 32K 个字符)。
  • input_reference(字符串,可选)— 可选的图像参考(HTTP(S) URL、base64/数据 URL 或文件路径)。
  • input_reference_fit("match" | "cover" | "contain" | "stretch",默认值:"contain")
    • 如何将 input_reference 调整到请求的视频 size:
      • match:要求尺寸完全相同(不匹配时立即失败)
      • cover:调整尺寸并居中裁剪以填满
      • contain:调整尺寸并填充边框以适配(默认值)
      • stretch:拉伸调整尺寸,可能导致变形
  • input_reference_background("blur" | "black" | "white" | "#RRGGBB" | "#RRGGBBAA",默认值:"blur")
    • 当 input_reference_fit="contain" 时使用的填充背景。
  • model("sora-2" | "sora-2-pro",默认值:"sora-2-pro")
  • seconds("4" | "8" | "12",可选)
  • size("720x1280" | "1280x720" | "1024x1792" | "1792x1024",可选)
    • 1024x1792 和 1792x1024 需要使用 sora-2-pro。
    • 如果省略 input_reference 和 size,则使用 API 默认值。
  • wait_for_completion(布尔值,默认值:true)
    • 为 true 时,服务会轮询 openai-videos-retrieve,直到状态为 completed 或 failed(或超时),然后下载资源。
  • timeout_ms(整数,默认值:900000)
  • poll_interval_ms(整数,默认值:2000)
  • download_variants(字符串[],默认值:["video"])
    • 允许的值:"video" | "thumbnail" | "spritesheet"。
  • tool_result("resource_link" | "resource",默认值:"resource_link")
    • 控制下载资源的 content[] 结构:
      • "resource_link" 会输出 ResourceLink 项(基于文件/URL)
      • "resource" 会输出带有 base64 resource.blob 的 EmbeddedResource 块

输出(MCP CallToolResult):

  • structuredContent:OpenAI Video 对象(任务元数据;当 wait_for_completion=true 时为最终状态)。
  • content:包含 resource_link(默认)或下载资源的嵌入式 resource 块(按需提供),以及带有 JSON 的文本块。
    • 包含摘要 JSON 块:{ "video_id": "...", "pricing": { "currency": "USD", "model": "...", "size": "...", "seconds": 4, "price": 0.1, "cost": 0.4 } | null }(等待时则为:{ "video_id": "...", "assets": [...], "pricing": ... })。
openai-videos-remix

基于现有 video_id 创建混剪任务(videos.remix)。

参数(输入架构):

  • video_id(字符串,必填)
  • prompt(字符串,必填)
  • wait_for_completion、timeout_ms、poll_interval_ms、download_variants、tool_result — 与 openai-videos-create 的语义相同(默认等待值为 true)。
openai-videos-list

列出视频任务(videos.list)。

参数(输入架构):

  • after(字符串,可选)— 游标(视频 ID),用于列出其后的任务。
  • limit(整数,可选)
  • order("asc" | "desc",可选)

输出:

  • structuredContent:OpenAI 列表响应结构 { data, has_more, last_id }。
  • content:包含序列化 JSON 的文本块。
openai-videos-retrieve

获取任务状态(videos.retrieve)。

  • video_id(字符串,必填)
openai-videos-delete

删除视频任务(videos.delete)。

  • video_id(字符串,必填)
openai-videos-retrieve-content

获取已完成任务的资源(videos.downloadContent,REST GET /videos/{video_id}/content),将其写入允许的 MEDIA_GEN_DIRS 下,并返回 MCP resource_link(默认)或嵌入式 resource 块(通过 tool_result 指定)。

参数(输入架构):

  • video_id(字符串,必填)
  • variant("video" | "thumbnail" | "spritesheet",默认值:"video")
  • tool_result("resource_link" | "resource",默认值:"resource_link")

输出(MCP CallToolResult):

  • structuredContent:OpenAI Video 对象。
  • content:包含 resource_link(或嵌入式 resource)、摘要 JSON 块 { video_id, variant, uri, pricing },以及完整的视频 JSON。
google-videos-generate

使用 Google GenAI SDK(@google/genai)的 ai.models.generateVideos 创建 Google 视频生成操作。

参数(输入架构):

  • prompt(字符串,可选)
  • input_reference(字符串,可选)——图像转视频输入(HTTP(S) URL、base64/数据 URL,或 MEDIA_GEN_DIRS 下的文件路径)
  • input_reference_mime_type(字符串,可选)——覆盖 input_reference 的 MIME 类型(必须为 image/*)
  • input_video_reference(字符串,可选)——视频扩展输入(HTTP(S) URL 或 MEDIA_GEN_DIRS 下的文件路径;不能与 input_reference 同时使用)
  • model(字符串,默认值:"veo-3.1-generate-001")
  • number_of_videos(整数,默认值:1)
  • aspect_ratio("16:9" | "9:16",可选)
  • duration_seconds(整数,可选)
    • Veo 2 模型:5–8 秒(默认值:8)
    • Veo 3 模型:4、6 或 8 秒(默认值:8)
    • 使用 referenceImages 时:8 秒
  • person_generation("DONT_ALLOW" | "ALLOW_ADULT" | "ALLOW_ALL",可选)
  • wait_for_completion(布尔值,默认值:true)
  • timeout_ms(整数,默认值:900000)
  • poll_interval_ms(整数,默认值:10000)
  • download_when_done(布尔值,可选;等待时默认值为 true)
  • tool_result("resource_link" | "resource",默认值:"resource_link")
    • 控制下载生成视频时 content[] 的形状。
  • response_format("url" | "b64_json",默认值:"url")
    • 控制 structuredContent.response.generatedVideos[].video 字段:
      • "url" 优先使用 video.uri(并移除 video.videoBytes)
      • "b64_json" 优先使用 video.videoBytes(并移除 video.uri)

要求:

  • Gemini Developer API:设置 GEMINI_API_KEY(或 GOOGLE_API_KEY),或在 secrets.yaml 中设置 google.api_key。
  • Vertex AI:设置 GOOGLE_GENAI_USE_VERTEXAI=true、GOOGLE_CLOUD_PROJECT 和 GOOGLE_CLOUD_LOCATION(或在 secrets.yaml 中设置 google.vertex_ai.*)。

输出:

  • structuredContent:Google 操作对象(包含 name、done,以及可用时的 response.generatedVideos[])。
  • content:状态文本、可选的 .mp4 resource_link(默认)或嵌入式 resource 块(下载后),以及用于兼容性的 JSON 文本块。
google-videos-retrieve-operation

检索/轮询现有的 Google 视频操作(ai.operations.getVideosOperation)。

  • operation_name(字符串,必填)
  • response_format("url" | "b64_json",默认值:"url")

输出:

  • structuredContent:Google 操作对象。
  • content:JSON 文本块,包含简短摘要和完整操作。
google-videos-retrieve-content

下载已完成操作的 .mp4 内容,并以文件优先的 MCP resource_link(默认)或嵌入式 resource 块(通过 tool_result)返回。

  • operation_name(字符串,必填)
  • index(整数,默认值:0)——选择 response.generatedVideos[index]
  • tool_result("resource_link" | "resource",默认值:"resource_link")
  • response_format("url" | "b64_json",默认值:"url")

推荐工作流:

  1. 调用 google-videos-generate 并设置 wait_for_completion=true(默认值)以获取已完成的操作并下载视频;只有在需要立即获取操作 ID 时才设为 false。
  2. 轮询 google-videos-retrieve-operation,直到 done=true。
  3. 调用 google-videos-retrieve-content 下载 .mp4 并接收 resource_link(或嵌入式 resource)。
fetch-images

从 URL 或本地文件路径获取并处理图像,可选择压缩。

参数(输入架构):

  • sources(string[],可选)
    • 图像来源数组:HTTP(S) URL 或文件路径(绝对路径,或相对于第一个 MEDIA_GEN_DIRS 条目的路径)。
    • 最少:1 张,最多:20 张图像。
    • 不能与 ids 和 n 同时使用。
  • ids(string[],可选)
    • 图像 ID 数组,用于在主 MEDIA_GEN_DIRS[0] 目录下按本地文件名匹配获取图像。
    • ID 必须安全(仅限 [A-Za-z0-9_-];不能包含 ..、*、?、斜杠)。
    • 匹配文件名中包含 _{id}_ 或 _{id}. 的文件(支持单张输出和 _1.png 等多张输出后缀)。
    • 使用 ids 时不支持 compression 和 file(不会创建新文件)。
    • 不能与 sources 和 n 同时使用。
  • n(integer,可选)
    • 设置后,返回主 MEDIA_GEN_DIRS[0] 目录中最后的 N 个图像文件。
    • 文件按修改时间排序(最近修改的排在最前面)。
    • 不能与 sources 和 ids 同时使用。
  • compression(object,可选)
    • max_size(integer,可选):最大尺寸,单位为像素。超过此尺寸的图像将被调整大小。
    • max_bytes(integer,可选):目标最大文件大小,单位为字节。默认值:819200(800KB)。
    • quality(integer,可选):JPEG/WebP 质量,范围为 1-100。默认值:85。
    • format("jpeg" | "png" | "webp",可选):输出格式。默认值:jpeg。
  • response_format("url" | "path" | "b64_json",默认值:"url")
    • 响应格式:基于文件/URL(url)、本地路径(path)或内嵌的 base64(b64_json)。
  • tool_result("resource_link" | "image",默认值:"resource_link")
    • 控制 content[] 的结构:
      • "resource_link" 会输出 ResourceLink 项(基于文件/URL)
      • "image" 会输出 base64 ImageContent 块
  • file(string,可选)
    • 输出文件的基础路径。如果有多张图像,会添加索引后缀。

行为说明:

  • 图像会并行处理,以最大限度提高吞吐量。
  • 只有提供 compression 选项时才会进行压缩。
  • 启用压缩后,会使用 sharp 迭代降低质量/尺寸。
  • 部分成功:如果部分来源处理失败,仍会返回成功处理的图像,并在响应中列出错误。
  • 提供 n 时,只有在 MEDIA_GEN_MCP_ALLOW_FETCH_LAST_N_IMAGES 环境变量设置为 true 时才会生效。否则,调用会因验证错误而失败。
  • 有时,MCP 客户端(例如 ChargeGPT)可能会因超时而不等待 media-gen-mcp 的响应。在需要快速获取最新 openai-images-generate / openai-images-edit 输出的创作环境中,可以使用带 n 参数的 fetch-images。当 MEDIA_GEN_MCP_ALLOW_FETCH_LAST_N_IMAGES=true 环境变量设置后,即使原始生成或编辑操作在 MCP 客户端一侧超时,fetch-images 也会返回 MEDIA_GEN_DIRS[0] 中最后的 N 个文件。
fetch-videos

从 HTTP(S) URL 或本地文件路径获取视频。

参数(输入架构):

  • sources(string[],可选)
    • 视频源数组:HTTP(S) URL 或文件路径(绝对路径,或相对于第一个 MEDIA_GEN_DIRS 条目的路径)。
    • 最少:1 个,最多:20 个视频。
    • 不能与 ids 和 n 同时使用。
  • ids(string[],可选)
    • 视频 ID 数组,根据主 MEDIA_GEN_DIRS[0] 目录下的本地文件名匹配来获取视频。
    • ID 必须安全(仅允许 [A-Za-z0-9_-];不能包含 ..、*、? 或斜杠)。
    • 匹配文件名中包含 _{id}_ 或 _{id}. 的文件(支持单个输出,以及 _thumbnail.webp 等多资源后缀)。
    • 使用 ids 时不支持 file(不会下载;返回现有文件)。
    • 不能与 sources 和 n 同时使用。
  • n(integer,可选)
    • 设置后,返回主 MEDIA_GEN_DIRS[0] 目录中最新的 N 个视频文件。
    • 文件按修改时间排序(最近修改的排在最前面)。
    • 不能与 sources 和 ids 同时使用。
  • tool_result("resource_link" | "resource",默认值:"resource_link")
    • 控制 content[] 的结构:
      • "resource_link" 会生成 ResourceLink 项(基于文件或 URL)
      • "resource" 会生成 EmbeddedResource 块,其中包含 base64 格式的 resource.blob
  • file(string,可选)
    • 输出文件的基础路径(从 URL 下载时使用)。如果下载多个视频,会添加索引后缀。

输出:

  • content:每个已解析的视频对应一个 resource_link(默认)或内嵌的 resource 块,此外还可能包含一个错误摘要文本块。
  • structuredContent:{ data: [{ source, uri, file, mimeType, name, downloaded }], errors?: string[] }。

行为说明:

  • 仅当 URL 与 MEDIA_GEN_URLS 匹配时(如果已设置),才允许下载 URL。
  • 如果提供了 n,仅当环境变量 MEDIA_GEN_MCP_ALLOW_FETCH_LAST_N_VIDEOS 设置为 true 时才会生效。否则,调用会因验证错误而失败。
fetch-document

从 HTTP(S) URL 或本地文件路径获取文档。

参数(输入架构):

  • sources(string[])
    • 文档源数组:HTTP(S) URL 或文件路径(绝对路径,或相对于第一个 MEDIA_GEN_DIRS 条目的路径)。
    • 最少:1 个,最多:20 个文档。
  • tool_result("resource_link" | "resource",默认值:"resource_link")
    • 控制 content[] 的结构:
      • "resource_link" 会生成 ResourceLink 项(基于文件或 URL)
      • "resource" 会生成 EmbeddedResource 块,其中包含 base64 格式的 resource.blob
  • file(string,可选)
    • 输出文件的基础路径(从 URL 下载时使用)。如果下载多个文档,会添加索引后缀。

输出:

  • content:每个已解析的文档对应一个 resource_link(默认)或内嵌的 resource 块,此外还可能包含一个错误摘要文本块。
  • structuredContent:{ data: [{ source, uri, file, mimeType, name, downloaded }], errors?: string[] }。

行为说明:

  • 仅当 URL 与 MEDIA_GEN_URLS 匹配时(如果已设置),才允许下载 URL。
  • 本地路径会根据 MEDIA_GEN_DIRS 进行验证,也可以用 file:// URL 提供。
  • 如果省略 file,默认文件名格式为 output_<time_t>_media-gen__fetch-document_<uuid>.<ext>。
test-images

用于测试 MCP 结果放置方式的调试工具,不会调用 OpenAI API。

仅当设置了 MEDIA_GEN_MCP_TEST_SAMPLE_DIR 时启用。该工具会从此目录读取现有图像,不会创建新文件。

参数(输入架构):

  • response_format("url" | "path" | "b64_json",默认值:"url")
  • result_placement("content" | "api" | "structured" | "toplevel" 或这些值组成的数组,可选)
    • 为本次调用覆盖 MEDIA_GEN_MCP_RESULT_PLACEMENT。
  • compression(对象,可选)
    • 与 fetch-images 使用相同的逻辑调优参数,但键采用 camelCase:
  • tool_result("resource_link" | "image",默认值:"resource_link")
    • 控制 content[] 的结构:
      • "resource_link" 会生成 ResourceLink 项(基于文件/URL)
      • "image" 会生成 base64 ImageContent 块
      • maxSize(整数,可选):最大像素尺寸。
      • maxBytes(整数,可选):目标最大文件大小,单位为字节。
      • quality(整数,可选):JPEG/WebP 质量,范围为 1–100。
      • format("jpeg" | "png" | "webp",可选):输出格式。

行为说明:

  • 从示例目录读取最多 10 张图像(不排序——按文件系统顺序)。

  • 使用与 openai-images-generate 和 openai-images-edit 相同的结果构建逻辑(包括 result_placement 覆盖项)。

  • 当 output == "base64" 且提供了 compression 时,会读取示例文件并使用 sharp 在内存中压缩;不会修改磁盘上的原始文件。

  • 可用于测试不同 MCP 客户端如何处理各种结果结构。

  • 当 result_placement 包含 "api" 时,该工具会返回模拟 OpenAI Images API 风格的对象:

    • 顶层:created、data[]、background、output_format、size、quality。
    • 对于 response_format: "b64_json",每个 data[i] 都包含 b64_json。
    • 对于 response_format: "path",每个 data[i] 都包含 path。
    • 对于 response_format: "url",每个 data[i] 都包含 url,而非 b64_json。
test-images 的调试 CLI 辅助脚本

本地调试时,有两个辅助脚本可直接调用 test-images:

  • npm run test-images – 使用 debug/debug-call.ts,并打印 MCP SDK 客户端看到的已验证 CallToolResult。用法:

    npm run test-images -- [placement] [--response_format url|path|b64_json]
    # examples:
    # npm run test-images -- structured --response_format b64_json
    # npm run test-images -- structured --response_format path
    # npm run test-images -- structured --response_format url
    
  • npm run test-images:raw – 使用 debug/debug-call-raw.ts,并打印原始 JSON-RPC result(底层的 CallToolResult,不含额外包装)。CLI 标志与上面相同。

两个脚本都会截断较大的字段,以便阅读:

  • image_url → 前 80 个字符,然后是 ...(N chars);
  • b64_json 和 data(当其为 base64 字符串时)→ 前 25 个字符,然后是 ...(N chars)。

🧩 版本策略

语义化版本(SemVer)

此软件包遵循 SemVer:MAJOR.MINOR.PATCH(x.y.z)。

  • MAJOR — 破坏性变更(工具名称、输入架构、输出结构)。
  • MINOR — 新增工具或向后兼容的扩展(新的可选参数、响应中的新字段)。
  • PATCH — 错误修复和内部重构,不会有意改变行为。

自 1.0.0 起,本项目遵循标准 SemVer 规则:破坏性变更会提升 MAJOR 版本(npm 的 ^1.0.0 允许 1.x,但不允许 2.0.0)。

依赖策略

本仓库旨在与当前稳定版本保持紧密同步:

  • MCP SDK:以最新稳定版 @modelcontextprotocol/sdk 和 schema 为目标。
  • OpenAI SDK:定期更新到最新稳定版 openai 包。
  • Zod:使用 Zod 4.x 系列(当前为 ^4.1.3)。本项目之前使用 Zod 3.x,与 MCP TypeScript SDK 类型定义组合时,将 .shape 传入 inputSchema 会触发大量 TypeScript 错误,尤其是 TS2589("type instantiation is excessively deep and possibly infinite")和 TS2322(schema shape not assignable to AnySchema | ZodRawShapeCompat)。我们持续关注上游讨论 modelcontextprotocol/typescript-sdk#494 以及相关的 Zod 类型改进 colinhacks/zod#5222,并让技术栈保持在能够可靠通过完整严格模式编译的组合上。
  • 工具链(Node.js、TypeScript 等):使用近期的 LTS 版/当前版本开发和测试,并配有专用的 tsconfig-strict.json,用于启用所有严格 TypeScript 检查(strict、noUnusedLocals、noUnusedParameters、exactOptionalPropertyTypes、noUncheckedIndexedAccess、noPropertyAccessFromIndexSignature 等)。

如果你的环境有需要,可以固定或降级 Node.js、TypeScript、OpenAI SDK、Zod 或技术栈中的其他组件,但请注意:

  • 我们主要针对最新技术栈进行测试和调整;
  • 仅在较旧运行时/SDK 版本上复现的问题,我们可能更难调查和支持;
  • 上游兼容性首先根据最新 MCP 规范和 OpenAI Images API 进行验证。

本项目有意保持一定的前瞻性:它会跟进 MCP 和 OpenAI 工具中出现的新功能(尤其是通过 MCP 提供稳健的多模态/图像支持,以及 ChatGPT UI 中的相关支持)。参考资料部分列出了一份关于 ChatGPT 中 MCP 图像渲染的详细真实案例错误报告和分析,作为案例研究。

如果你需要长期稳定的技术栈,请在自己的分支中固定确切版本,并在你的环境中仔细验证。


🧩 类型化工具回调

所有工具处理程序都使用通过 z.input<typeof schema> 从 Zod schema 派生的强类型回调参数:

// Schema definition
const openaiImagesGenerateBaseSchema = z.object({
  prompt: z.string().max(32000),
  background: z.enum(["transparent", "opaque", "auto"]).optional(),
  // ... more fields
});

// Type alias
type OpenAIImagesGenerateArgs = z.input<typeof openaiImagesGenerateBaseSchema>;

// Strictly typed callback
server.registerTool(
  "openai-images-generate",
  { inputSchema: openaiImagesGenerateBaseSchema.shape, ... },
  async (args: OpenAIImagesGenerateArgs, _extra: unknown) => {
    const validated = openaiImagesGenerateSchema.parse(args);
    // ... handler logic
  },
);

此模式提供:

  • 静态类型安全 — IDE 自动补全,并对所有输入字段进行编译时检查。
  • 运行时验证 — Zod .parse() 会确保所有输入在处理前均符合 schema。
  • MCP SDK 兼容性 — inputSchema: schema.shape 提供用于工具注册的 JSON Schema。

所有工具(openai-images-*、openai-videos-*、fetch-images、fetch-videos、fetch-document、test-images)都遵循此模式。


🧩 工具注解

此 MCP 服务公开了以下带注解提示的工具:

工具readOnlyHintdestructiveHintidempotentHintopenWorldHint
openai-images-generatetruefalsefalsetrue
openai-images-edittruefalsefalsetrue
openai-videos-createtruefalsefalsetrue
openai-videos-remixtruefalsefalsetrue
openai-videos-listtruefalsefalsetrue
openai-videos-retrievetruefalsefalsetrue
openai-videos-deletetruefalsefalsetrue
openai-videos-retrieve-contenttruefalsefalsetrue
fetch-imagestruefalsefalsefalse
fetch-videostruefalsefalsefalse
fetch-documenttruefalsefalsefalse
test-imagestruefalsefalsefalse

这些提示有助于 MCP 客户端了解,这些工具:

  • 可能会调用外部 API 或读取外部资源(开放世界),
  • 不会修改现有项目文件或用户数据;它们只会在配置的输出目录中创建新的媒体文件(图片/视频/文档),
  • 即使输入相同,每次调用也可能产生不同的输出。

由于大多数工具的 readOnlyHint 都设为 true,MCP 平台(包括 chatgpt.com)可以将此服务视为逻辑上只读,通常不会显示“此工具可以修改你的文件”警告。


📁 项目结构

media-gen-mcp/
├── src/
│   ├── index.ts              # MCP server entry point
│   └── lib/
│       ├── compression.ts    # Image compression (sharp)
│       ├── env.ts            # Env parsing + allowlists (+ glob support)
│       ├── helpers.ts        # URL/path validation, result building
│       ├── logger.ts         # Structured logging + truncation helpers
│       └── schemas.ts        # Zod schemas for all tools
├── test/
│   ├── compression.test.ts             # 12 tests
│   ├── env.test.ts                     # 19 tests
│   ├── fetch-images.integration.test.ts# 2 tests
│   ├── fetch-videos.integration.test.ts# 2 tests
│   ├── helpers.test.ts                 # 31 tests
│   ├── logger.test.ts                  # 10 tests
│   └── schemas.test.ts                 # 64 tests
├── debug/                    # Local debug helpers (MCP client scripts)
├── plan/                     # Design notes / plans
├── dist/                     # Compiled output
├── tsconfig.json
├── vitest.config.ts
├── package.json
├── CHANGELOG.md
├── README.md
└── AGENTS.md

📝 许可证

MIT


🩺 故障排除

  • 确保你的 OPENAI_API_KEY 有效且具有图像 API 访问权限。
  • 你必须拥有已验证的 OpenAI 组织。验证后,图像 API 访问权限可能需要 15–20 分钟才能激活。
  • 文件路径[可选参数]必须是绝对路径。
    • Unix/macOS/Linux:以 / 开头(例如,/path/to/image.png)
    • Windows:盘符后跟 :(例如,C:/path/to/image.png 或 C:\path\to\image.png)
  • 对于文件输出,请确保目标目录可写。
  • 如果看到与文件类型有关的错误,请检查图像文件的扩展名和格式。

🙏 灵感

本服务最初受到 SureScaleAI/openai-gpt-image-mcp 的启发,但现在已是一个独立实现,专注于紧密遵循官方规范:

  • 与 OpenAI Images API 保持一致——openai-images-generate 和 openai-images-edit 的参数与 images.create / gpt-image-1.5 一致: prompt、n、size、quality、background、output_format、 output_compression、user,以及 response_format(url / b64_json), 其语义与 OpenAI Images API 相同。
  • 与 MCP 工具结果保持一致(image + resource_link)——当 result_placement = "content" 时,服务遵循 MCP 5.2 工具结果 章节 (5.2.2 图像内容, 5.2.4 资源链接) 并输出强类型的 content[] 条目:
    • 对于 response_format = "b64_json",输出 { "type": "image", "data": "<base64>", "mimeType": "image/png" };
    • 对于基于文件/URL 的输出,输出 { "type": "resource_link", "uri": "file:///..." | "https://...", "name": "...", "mimeType": "image/..." }。
  • 原始 OpenAI 风格 API 输出——当 result_placement = "api" 时,工具 结果本身就是一个 OpenAI Images 风格的对象: { created, data: [...], background, output_format, size, quality, usage? }, 其中每个 data[] 条目包含 b64_json(当 response_format = "b64_json" 时)或 url(当 response_format = "url" 时)。此模式下不会添加 MCP 包装字段(content、structuredContent、files、urls)。

简而言之,这个库:

  • 当 result_placement = "api" 且 response_format = "url" | "b64_json" 时, 在参数和结果结构上遵循 OpenAI Images API;并且
  • 当 result_placement = "content" 时,在工具结果内容块(image、 resource_link、text)上遵循 MCP 规范。
常见客户端的推荐预设
  • 默认模式 / Claude Desktop / 严格遵循 MCP 规范的客户端
    对于严格遵循 MCP 规范的客户端,推荐且自然的配置是:

    • result_placement = content
    • response_format = b64_json

    在此模式下,服务会返回:

    • content[],其中包含 type: "image"(base64 图像数据)和 type: "resource_link"(文件/URL 链接),符合 MCP 第 5.2 节(图像 内容和资源链接)。此输出非常适合与 Claude Desktop 及任何完整实现 2025‑11‑25 规范的客户端直接集成。
  • chatgpt.com Developer Mode
    若要将此服务作为 MCP 后端接入 ChatGPT Developer Mode,最实用的配置是 尽可能贴近 OpenAI Images API 的配置:

    • result_placement = api
    • response_format = url

    在此模式下,工具结果与 images.create / gpt-image-1.5 的格式 一致(包括 data[].url),这让预期使用 OpenAI 架构的后端和库更容易 处理结果。

    但是,即使采用这种原生 OpenAI 格式,chatgpt.com 客户端目前仍无法 渲染图像。以下报告对此行为作了详细说明:
    https://github.com/strato-space/report/issues/1


⚠️ 局限性与大型文件处理

  • 可配置的负载保护: 默认情况下,此服务会为内联 content 使用约 50MB(52,428,800 字节)的预算,以适应常见 MCP 客户端的限制。你可以通过设置 MCP_MAX_CONTENT_BYTES 环境变量来提高(或降低)此阈值。
  • 自动切换为文件输出: 如果图像的 base64 总大小超过配置的阈值,工具会自动将图像保存到磁盘,并通过 resource_link 返回文件路径,而不是内联 base64。这有助于避免客户端出现“负载过大”错误,同时仍能提供完整分辨率的图像。
  • 默认文件位置: 如果未指定 file 路径,输出会以 output_<time_t>_media-gen__<tool>_<id>.<ext> 这样的名称保存在 MEDIA_GEN_DIRS[0] 下(默认:/tmp/media-gen-mcp)。
  • 环境变量:
    • MEDIA_GEN_DIRS:设置此变量以控制输出文件的保存位置。示例:export MEDIA_GEN_DIRS=/your/desired/dir。如果直接从该目录提供文件服务,此目录可以与公共静态文件目录相同。
    • MEDIA_GEN_MCP_URL_PREFIXES:可选的、以逗号分隔的 HTTPS 前缀,按位置与 MEDIA_GEN_DIRS 条目对应。设置后,服务会构建公共 URL,格式为 <prefix>/<relative_path_inside_root>,并与文件路径一同返回(例如通过 resource_link URI,以及 response_format: "url" 时的 structuredContent.data[].url)。示例:export MEDIA_GEN_MCP_URL_PREFIXES=https://media-gen.example.com/media,https://media-gen.example.com/samples
    • 最佳实践: 对于大型图像或生产环境中的图像,始终使用文件输出,并确保客户端已配置为处理文件路径。配置 MEDIA_GEN_DIRS,并可选配置 MEDIA_GEN_MCP_URL_PREFIXES,通过公共 Web 服务(例如 nginx)提供图像。

🌐 通过 HTTPS 提供生成的文件

如果你希望 ChatGPT(或任何 MCP 客户端)在文件路径旁一并提供可公开访问的 URL:

  1. 通过 HTTPS 公开你的图像目录。例如,使用 nginx:

    server {
        # listen 443 ssl http2;
        # server_name <server_name>;
    
        # ssl_certificate     <path>;
        # ssl_certificate_key <path>;
    
        location /media/ {
            alias /home/username/media-gen-mcp/media/;
            autoindex off;
            expires 7d;
            add_header Cache-Control "public, immutable";
        }
    }
    
  2. 确保 MEDIA_GEN_DIRS 中的第一项指向同一目录(例如 MEDIA_GEN_DIRS=/home/username/media-gen-mcp/media/,或者在项目根目录运行时使用 MEDIA_GEN_DIRS=media/)。

  3. 设置 MEDIA_GEN_MCP_URL_PREFIXES=https://media-gen.example.com/media,使服务在顶层 urls、resource_link URI 和 image_url 字段中返回相应的 HTTPS URL(对于 response_format: "url")。

现在,openai-images-generate 和 openai-images-edit 在 base64 和 文件响应模式下都会附带 files + urls,使客户端可以引用本地文件系统路径或公共 HTTPS 链接。这在 ChatGPT 尚无法内联渲染 MCP 图像块时尤其有用。


📚 参考资料


🙏 致谢

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。