Token导航 LogoToken导航TokenDH.com
Open Pic MCP logo
设计创作stdio官方级别未说明来源级核验

Open Pic MCP

MCP Server

openPic-mcp 是一个基于 MCP 协议的图像能力服务器,为 AI 编程助手提供图片理解、比较、生成和编辑功能。

工具数

6

提示词数

0

GitHub Stars

1

资源数

0
图像处理GoClaudeClaude DesktopClaudeCursor

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

作者 / 组织

AoManoh

提供方

AoManoh

最后核验

2026/5/17 20:21

运行时

Docker

快速接入

先看主来源和安装命令,再打开仓库或文档;下面只保留这个条目的关键接入事实。

命令预览

docker run -it --rm \

详细介绍

openPic-mcp

openPic-mcp 是一个基于 MCP (Model Context Protocol) 协议的图像能力服务器,为 AI 编程助手提供图片理解、图片比较、图片生成和图片编辑能力。它支持任何 OpenAI-Compatible 的图像 API 服务。

⚠️ 当前版本说明:当前主路径是 stdio 传输,可使用本地编译后的可执行文件,也可通过 go run github.com/AoManoh/openPic-mcp/cmd/vision-mcp@master 在线拉取源码并在本机运行。uvx / npx 包装入口和远端 Streamable HTTP 服务仍属于后续规划。

功能特性

  • MCP 协议兼容:实现 MCP 协议规范,支持 stdio 传输
  • OpenAI-Compatible:支持任何兼容 OpenAI 图像能力接口的服务
  • 多种图片输入:支持 Base64 编码、Data URI、HTTP/HTTPS URL、本地文件路径
  • 多种图片格式:支持 JPEG、PNG、WebP、GIF、BMP、TIFF、ICO、HEIC、AVIF、SVG 格式
  • 图像比较:支持 2-4 张图片的智能比较分析
  • 图片生成与编辑:支持通过 OpenAI-Compatible /images/generations/images/edits 路由生成或编辑图片

快速开始

前置条件

  • Go 1.23 或更高版本(本地构建)
  • OpenAI API 密钥或兼容服务的访问凭证

本地运行

  1. 克隆项目
git clone https://github.com/AoManoh/openPic-mcp.git
cd openPic-mcp
  1. 配置环境变量
cp .env.example .env
# 编辑 .env 文件,填写实际配置
  1. 构建并运行
go build -o openPic-mcp ./cmd/vision-mcp
./openPic-mcp

在线拉取运行(Go)

如果本机已安装 Go 1.23 或更高版本,可以不手动克隆仓库,直接在 MCP 客户端中使用 go run 拉取并运行:

{
  "mcpServers": {
    "openPic-mcp": {
      "command": "go",
      "args": [
        "run",
        "github.com/AoManoh/openPic-mcp/cmd/vision-mcp@master"
      ],
      "env": {
        "OPENPIC_API_BASE_URL": "https://your-server.com/v1",
        "OPENPIC_API_KEY": "your-api-key",
        "OPENPIC_VISION_MODEL": "your-vision-model-name",
        "OPENPIC_IMAGE_MODEL": "your-image-model-name",
        "OPENPIC_TIMEOUT": "5m"
      }
    }
  }
}

国内网络环境下,首次运行需要下载 Go 模块和依赖,可临时在 MCP 配置的 env 中增加 Go 代理加速:

{
  "env": {
    "GOPROXY": "https://goproxy.cn,direct",
    "GOSUMDB": "sum.golang.google.cn"
  }
}

GOPROXY 能加速公开 Go 模块下载;GOSUMDB 使用 Go checksum database 的国内可访问镜像。该方式仍然需要本机安装 Go,并且首次启动会在本机下载依赖和编译,速度取决于网络和机器性能。

Docker 运行

⚠️ 注意:当前版本仅支持 stdio 传输,Docker 部署暂时无法直接用于 MCP 服务配置。Docker 相关文件是为后续支持 HTTP 传输(Streamable HTTP)预留的,届时将支持端口暴露和远程调用。当前阶段请使用本地运行方式。

Docker 命令参考(开发测试用)

  1. 配置环境变量
cp .env.example .env
# 编辑 .env 文件,填写实际配置
  1. 使用 Docker Compose 启动
docker-compose up -d --build
  1. 查看日志
docker-compose logs -f
  1. 停止服务
docker-compose down

直接使用 Docker

docker build -t openpic-mcp:latest .

docker run -it --rm \
  -e OPENPIC_API_BASE_URL=https://api.openai.com/v1 \
  -e OPENPIC_API_KEY=your-api-key \
  -e OPENPIC_VISION_MODEL=gpt-5.5 \
  -e OPENPIC_IMAGE_MODEL=gpt-image-2 \
  openpic-mcp:latest

配置说明

所有配置通过环境变量设置。可以创建 .env 文件或直接设置环境变量。新配置优先使用 OPENPIC_*,并兼容旧的 VISION_*

环境变量必填默认值说明
OPENPIC_API_BASE_URL-OpenAI-Compatible API 基础 URL,兼容 VISION_API_BASE_URL
OPENPIC_API_KEY-API 密钥,兼容 VISION_API_KEY
OPENPIC_VISION_MODEL-视觉理解模型,兼容 VISION_MODEL
OPENPIC_IMAGE_MODEL使用 generate_imageedit_image 时必填-图片生成或编辑模型
OPENPIC_TIMEOUT5mAPI 请求超时时间,兼容 VISION_TIMEOUT
OPENPIC_LOG_LEVELinfo日志级别,兼容 VISION_LOG_LEVEL
OPENPIC_OUTPUT_DIR空(使用 os.TempDir()/openpic-mcp/generate_image / edit_image 默认落盘目录,必须为绝对路径;可被工具入参 output_dir 覆盖
OPENPIC_FILENAME_PREFIX空(使用工具上下文 generate / edit默认文件名前缀,仅允许 [A-Za-z0-9._-]、最长 32 字符、不能以 . 开头;可被工具入参 filename_prefix 覆盖
OPENPIC_MAX_INLINE_PAYLOAD_BYTES1048576(1 MiB)内联 base64 payload 字节上限。b64_json 模式下超阈直接拒绝;file_path 模式下追加警告。设置 0 / 负值会回退到默认
OPENPIC_OVERWRITEfalse落盘文件命名冲突时的策略:false 追加 -2/-3 等后缀,true 覆盖同名文件;可被工具入参 overwrite 覆盖
OPENPIC_MAX_CONCURRENT_REQUESTS16同时执行的 tools/call 上限;硬上限 100;0/负值/解析失败回退默认;超过上限自动 clamp
OPENPIC_REQUEST_QUEUE_SIZE64tools/call 等待 worker 的有界队列长度;硬上限 10000;同上的 clamp/回退规则。队列满时 recv loop 同步回退处理(绝不丢请求)
OPENPIC_REQUEST_TIMEOUT0s(不限)单个 tools/call 的最大执行时间。0s 表示不超时;图片生成可能需要 1-4 分钟,缺省值正是为了不误杀
OPENPIC_SHUTDOWN_TIMEOUT30s收到 SIGINT / SIGTERM 后等待 in-flight tools/call 完成的预算;超时则 engineCancel 强制收尾。必须 > 0
OPENPIC_LOG_FORMATtexttextjson。所有日志一律写 stderr,stdout 仅承载 MCP JSON-RPC 帧
OPENPIC_TASK_STORE_ENABLEDtrue异步任务工具集总开关。falsesubmit_image_task / get_task_result / list_tasks / cancel_task 不注册,且不构造 store/dispatcher
OPENPIC_TASK_DISK_PERSISTtrue是否把任务 manifest 落盘到 /tasks/true → DiskStore(启动期 fail-fast 校验目录可写);false → MemoryStore,重启即丢
OPENPIC_TASK_MAX_QUEUED256store 中 queued 状态任务上限;硬上限 10000;满则 submit 返回 ErrQueueFull
OPENPIC_TASK_MAX_RETAINED1024终态任务保留窗口;硬上限 100000;超过时按 finished_at 升序淘汰最旧
OPENPIC_TASK_TTL24h终态保留时间(Go duration)。GC 按此清理过期任务;非法/零/负值在 Load 直接报错
注意OPENPIC_TIMEOUT / VISION_TIMEOUT 必须使用 Go 的 duration 格式,例如:30s(30秒)、2m(2分钟)、5m(5分钟)。纯数字如 120 会导致解析错误。部分图片生成或编辑模型单次推理可能需要 1-4 分钟,不建议将该值设置得过低。 服务器并发与生命周期相关的 5 项变量同样使用 Go duration(*_TIMEOUT)和正整数(*_REQUESTS*_QUEUE_SIZE)格式。详见下方 服务器并发与生命周期 章节。

配置示例

OpenAI(截至 2026-04-29,以 OpenAI API 实际可用为准):

OPENPIC_API_BASE_URL=https://api.openai.com/v1
OPENPIC_API_KEY=your-openai-api-key
# 视觉模型可选:
#   - gpt-5.5(2026-04-23 旗舰,推荐默认)、gpt-5.5-pro(高精度)
#   - gpt-5.4 / gpt-5.4-pro(平衡)
#   - gpt-5.4-mini / gpt-5.4-nano(轻量、高并发、低成本)
#   - gpt-5 / gpt-5.2(旧版 snapshot 回退)
OPENPIC_VISION_MODEL=gpt-5.5
# 图像模型可选:gpt-image-2(2026-04-21 旗舰、原生 4K、思考模式)、gpt-image-1.5 / gpt-image-1(前代回退)
OPENPIC_IMAGE_MODEL=gpt-image-2

Azure OpenAI(部署名称由订阅决定,下方仅示意;Azure 上的 GPT-5.5 / gpt-image-2 可能比 OpenAI 直连晚到货):

OPENPIC_API_BASE_URL=https://your-resource.openai.azure.com/openai/deployments/your-deployment
OPENPIC_API_KEY=your-azure-api-key
# 视觉模型用 Azure 上对应的部署名(通常映射到 gpt-5.5 / gpt-5.4-mini)
OPENPIC_VISION_MODEL=your-vision-deployment-name
# 图像模型用 Azure 上对应的部署名(通常映射到 gpt-image-2 / gpt-image-1.5)
OPENPIC_IMAGE_MODEL=your-image-deployment-name

自托管服务:

OPENPIC_API_BASE_URL=https://your-server.com/v1
OPENPIC_API_KEY=your-api-key
OPENPIC_VISION_MODEL=your-vision-model-name
OPENPIC_IMAGE_MODEL=your-image-model-name

MCP 配置示例

当前支持两种 stdio 使用方式:

  • 使用本地编译后的可执行文件路径。
  • 使用 go run github.com/AoManoh/openPic-mcp/cmd/vision-mcp@master 在线拉取并在本机运行。

uvx / npx 形式尚未提供包装入口,因此当前不能直接使用 uvx --from git+... openpic-mcp。如需完全免 Go 环境,需要后续提供预编译二进制下载器或独立包管理器入口。

Claude Desktop

在 Claude Desktop 配置文件中添加:

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json Windows: %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "openPic-mcp": {
      "command": "/path/to/openPic-mcp",
      "args": [],
      "env": {
        "OPENPIC_API_BASE_URL": "https://api.openai.com/v1",
        "OPENPIC_API_KEY": "your-api-key",
        "OPENPIC_VISION_MODEL": "gpt-5.5",
        "OPENPIC_IMAGE_MODEL": "gpt-image-2",
        "OPENPIC_TIMEOUT": "5m"
      }
    }
  }
}

Cursor

在 Cursor MCP 配置中添加:

macOS: ~/.cursor/mcp.json Windows: %USERPROFILE%\.cursor\mcp.json

{
  "mcpServers": {
    "openPic-mcp": {
      "command": "D:\\path\\to\\openPic-mcp.exe",
      "args": [],
      "env": {
        "OPENPIC_API_BASE_URL": "https://api.openai.com/v1",
        "OPENPIC_API_KEY": "your-api-key",
        "OPENPIC_VISION_MODEL": "gpt-5.5",
        "OPENPIC_IMAGE_MODEL": "gpt-image-2",
        "OPENPIC_TIMEOUT": "5m"
      }
    }
  }
}
重要args 字段必须显式指定(即使为空数组 []),否则 MCP 客户端可能无法正确启动服务。

服务器并发与生命周期(C4/C5 引入)

openPic-mcp 内置了一个用 Go 写的 MCP 服务器引擎(internal/server.Server),负责调度所有 JSON-RPC 消息、并发执行 tools/call、传递取消信号和优雅停机。它就在 cmd/vision-mcp/main.go 里被直接装配,用户不需要额外服务。

调度模型

┌──────────────────────────────────────────────────────────────────┐
│                      MCP Client (stdio peer)                      │
└────────────────────────────┬─────────────────────────────────────┘
                             │ JSON-RPC frames
                             ▼
                ┌────────────────────────────┐
                │ internal/transport/Stdio   │  stdout 仅协议帧
                └─────────────┬──────────────┘
                              │
                              ▼
                ┌────────────────────────────┐
                │ recv loop (单 goroutine)    │  解析 envelope
                └─────────┬──────────────────┘
                          │
        ┌─────────────────┼──────────────────────────────┐
        │                 │                              │
        ▼                 ▼                              ▼
 非 tools/call      tools/call → workQueue          notifications/cancelled
 同步执行            (有界,cap=64)                   命中 CancelRegistry,
 (initialize/list)        │                          直接中断 in-flight ctx
                          │
              ┌───────────┴───────────┐
              ▼                       ▼
        worker pool (16 workers)  队列满 → recv loop 同步回退执行
              │
              ▼
   protocol.MCPHandler.HandleMessage(ctx, raw)
              │
              ▼
            tools.*

要点:

  • tools/call 走 worker pool,同时最多并发 OPENPIC_MAX_CONCURRENT_REQUESTS 个;超过队列容量时由 recv loop 同步回退处理,永远不会丢请求。
  • initialize / tools/list / notifications/* 等轻量消息保持在 recv loop 同步派发,避免无谓的并发开销。
  • notifications/cancelled 通过 protocol.CancellationRegistry 直达对应 in-flight tools/call 的 ctx,工具应在所有 HTTP / IO 调用上传播 ctx,让取消立即生效。

调优开关

维度变量默认值调优建议
并发 worker 数OPENPIC_MAX_CONCURRENT_REQUESTS16上游账户并发额度紧张时降低;本机算力富余、上游放得开时提高(最大 100)
排队 bufferOPENPIC_REQUEST_QUEUE_SIZE64客户端瞬时高并发但希望尽量异步处理时调大(最大 10000);不希望累积时调小
单请求预算OPENPIC_REQUEST_TIMEOUT0s(不限)0s 是为了不误杀图片生成;如需为 tools/call 设硬超时,建议 ≥ 90s
优雅停机预算OPENPIC_SHUTDOWN_TIMEOUT30s工具长耗时(图片生成)建议拉长到 60s120s;日志/CI 场景缩到 5s10s 也可
日志格式OPENPIC_LOG_FORMATtext接 ELK/Loki 等日志栈选 json;本地终端调试选 text

优雅停机

收到 SIGINT / SIGTERM,引擎按以下顺序收尾:

  1. recv loop 退出,停止接收新请求。
  2. 关闭 worker queue,workers 排空已入队的 tools/call
  3. inflight WaitGroup 等待所有 in-flight 完成;超过 OPENPIC_SHUTDOWN_TIMEOUT 触发 engineCancel,让 ctx-aware 工具立即返回错误。
  4. in-flight 全部排空之后再关闭 stdio 连接,保证响应不会被截断。

可观测性

引擎统一通过 *slog.Logger 写 stderr,关键事件包括:

  • server.boot / server.started / server.stopped:生命周期边界。
  • req.received / req.dispatched / req.completed / req.cancelled:每条请求一个完整链路。
  • req.queue_full_fallback:队列满触发了同步回退;持续出现说明并发不足。
  • req.panic:handler panic 已被引擎捕获(不会拖垮 worker),需关注。
  • server.shutdown_timeout_exceeded / server.shutdown_force_abandon:停机预算被打穿,建议拉长 OPENPIC_SHUTDOWN_TIMEOUT 或排查长耗时工具。
重要:所有日志一律走 stderr。如果你看到日志混进 MCP 客户端的 JSON-RPC 通道,绝大概率是 OPENPIC_LOG_FORMAT 之外的代码路径误用了 fmt.Println 等写 stdout 的 API,请在仓库内 grep 修复后再上线。

异步任务模型(C8 引入)

为支持长耗时图片生成(90 秒 ~ 4 分钟),项目在不破坏现有同步工具的前提下,新增了一套异步 submit/get 工具集。AI 客户端可立即拿到 task_id 不阻塞会话,再按需轮询结果。

架构

client tools/call(submit_image_task)
        │
        ▼
┌────────────────────────────────────┐
│  internal/taskstore                │
│  ├─ MemoryStore (in-RAM canonical) │
│  └─ DiskStore  (RAM + JSON文件)    │── $OPENPIC_OUTPUT_DIR/tasks/.json
└────────────────────────────────────┘
        │ store.Submit (queued)
        ▼
┌────────────────────────────────────┐
│  internal/tools.Dispatcher         │
│  ├─ 独立 worker pool(与 sync MCP   │
│  │   的 worker pool 完全解耦)      │
│  ├─ buffered queue(≥ MaxQueued)   │
│  └─ 双登记 cancel(store + 自有 map)│
└────────────────────────────────────┘
        │ Transition queued → running
        │ 调底层 generate_image / edit_image handler closure
        │ Transition running → completed / failed / cancelled / abandoned
        ▼
client tools/call(get_task_result with wait=30s) → 终态 + Result.FilePath
关键决策:异步任务的 worker pool 不复用 server 引擎的同步 worker pool。同步 tools/listdescribe_image 等毫秒级请求绝不能被 90 秒级图片生成挤占槽位。两个 pool 独立调度,但共享 OPENPIC_MAX_CONCURRENT_REQUESTS 作为容量基线。

状态机

                    ┌──────► cancelled (cancel_task on queued)
                    │
queued ──► running ─┼──► completed
                    ├──► failed
                    ├──► cancelled (cancel_task on running)
                    └──► abandoned (shutdown / restart 残留)

queued ──► failed     (dispatcher queue full / 内部错误)
queued ──► abandoned  (shutdown 时尚未派发)

非法迁移返回 ErrIllegalTransition,状态机原子化于 sync.RWMutex 写锁下执行。

4 个工具

工具入参返回用途
submit_image_taskkind (generate_image/edit_image) + params(与同步工具同 schema){task_id, state, submitted_at}立即返回,不阻塞会话
get_task_resulttask_id + 可选 wait(Go duration,严格 ≤ 5m,超出硬报错完整 Task(状态+结果+错误+时间戳)wait=0s 立即快照;wait>0 long-poll 至终态或超时;超过 5m 的预算请通过重新轮询拼接
list_tasks可选 states[] / kinds[] / since (RFC3339) / all{tasks, count}默认仅本进程任务;all=true 包含其他 PID 残留。响应体量上限:未过滤时受 OPENPIC_TASK_MAX_RETAINED 约束(默认 1024 → ~1.3 MB,硬上限 100000 → ~10 MB);MCP stdio 不流式,建议高任务量场景下用 since / states 过滤分桶
cancel_tasktask_id + 可选 hint取消后的 Task跨 PID 拒绝;终态任务返回当前快照不变

调用示例

// 1. 提交一个生图任务,立即拿到 task_id
{
  "jsonrpc":"2.0","id":1,"method":"tools/call",
  "params":{
    "name":"submit_image_task",
    "arguments":{
      "kind":"generate_image",
      "params":{"prompt":"a cat","size":"1024x1024","response_format":"file_path"}
    }
  }
}
// → {"task_id":"tsk_28341_2026...","state":"queued","submitted_at":"..."}

// 2. 轮询(long-poll,最多 30 秒)
{
  "jsonrpc":"2.0","id":2,"method":"tools/call",
  "params":{
    "name":"get_task_result",
    "arguments":{"task_id":"tsk_28341_2026...","wait":"30s"}
  }
}
// → 终态 Task:state=completed, result.file_path=...

// 3. 列出最近 1 小时的所有 running 任务
{
  "jsonrpc":"2.0","id":3,"method":"tools/call",
  "params":{
    "name":"list_tasks",
    "arguments":{"states":["running"],"since":"2026-04-29T10:00:00Z"}
  }
}

持久化与重启行为

  • OPENPIC_TASK_DISK_PERSIST=true(默认):每次状态迁移和淘汰都通过 temp + fsync + rename 原子写盘到 /tasks/.json
  • 启动时扫描该目录,把 queued / running 状态的任务自动转 abandoned(hint=process_restart),让重启前正在跑的任务有确定结果,调用方决定是否重新提交。
  • 跨 PID 隔离:list_tasks 默认只返回本进程任务;cancel_task 跨 PID 拒绝,避免误改他人任务。
  • OPENPIC_TASK_DISK_PERSIST=false:纯内存模式,重启即丢,适合无写盘权限的容器或 ephemeral 环境。

优雅停机

shutdown 时引擎按以下顺序协同:

  1. recv loop 退出 → 不再接受新 MCP 请求。
  2. dispatcher.AbandonRunning("shutdown") —— 把所有 running 任务标 abandoned,取消其 ctx;任务 worker 通过 ctx.Done 立即返回。
  3. 关闭 sync MCP work queue → 排空已入队 tools/call
  4. 等待 inflight WaitGroup(最长 OPENPIC_SHUTDOWN_TIMEOUT)。
  5. 关闭 transport。
  6. main 调 dispatcher.Close() 等任务 worker 全部退出。
  7. taskStore.Close() 标记关闭。

任务持久化让客户端在下次启动后还能 get_task_result 看到 state=abandoned,避免悬挂。

上游链路与取消语义

cancel_task 在 MCP 层是确定性的:调用成功后,本进程的 dispatcher 立即把任务状态置为 cancelled、关闭其 ctx、释放 worker 槽。同步工具 (describe_image / compare_images / generate_image / edit_image) 全部使用 http.NewRequestWithContext(ctx, …),因此 ctx 取消会立刻关闭与上游 (OPENPIC_API_BASE_URL) 的 TCP 连接。

"取消是否会节省上游配额"取决于上游服务的实现,本项目不做承诺:

上游形态收到客户端断连后是否会取消上游计算 / 配额
OpenAI 官方 /v1/images/*OpenAI 官方未公开声明 client-disconnect 是否会回滚配额;保守假设:不会
OpenAI-Compatible 网关(如 sub2api)网关本身有内部 retry / failover;客户端断连不一定传播到上游 OpenAI 调用。许多代理实现会等待上游响应后再决定是否计费。
OAuth 凭证池代理(如 CLIProxyAPI)代理收到客户端断连后行为依赖具体实现;外部观察不到的副作用是常态。

结论与建议:

  • cancel_task 看作"在 MCP 这一层立刻释放本地资源(worker 槽 / 内存 / store 配额)"的工具,而不是一个节流上游配额的工具。
  • 如果担心上游计费,第一选择仍然是避免发起昂贵请求(通过 list_image_capabilities 查看模型边界、或本地参数校验 fail-fast),其次才是 cancel_task
  • 上游 safety filter 触发亦不在 cancel_task 的语义内:实测同一 edit_image prompt 在同步路径会被上游改写为通用占位水印(单次失败即返回,无法本地重试),切换到 submit_image_task 异步路径后一次过(约 3 分钟 wall time)。当观察到上游 safety 改写或 502/503 抖动较多时,将 submit_image_task 列为首选路径——服务端持久化与 get_task_result(wait=…) 让客户端可以无副作用地等待并重排队,而同步路径每一次失败都会消耗一次 tools/call 预算。

长耗时调用的超时与上游异常

实测:在 gpt-image-2 路径上,sub2api 的 /v1/images/edits 单次延迟普遍在 70-220 秒;当上游 503 触发 failover 时整体延迟还会叠加。某些复合 prompt(例如 panoramic 2048×2048)可能超过 5 分钟。

现象责任层治理位置
上游网关 (Client.Timeout exceeded while awaiting headers)上游服务 / 网络调高 OPENPIC_TIMEOUT(注意:这是 HTTP client 超时,不是 OPENPIC_REQUEST_TIMEOUT 的 MCP 工具调用预算)
tools/callOPENPIC_REQUEST_TIMEOUT 触发取消本服务(设计)调高 OPENPIC_REQUEST_TIMEOUT,或用异步 submit_image_task + get_task_result(wait="5m") 解耦客户端等待
上游已完成但客户端已断连上游服务MCP 层无法补救;用异步任务模型可以救一次——任务状态在服务端持久化,客户端重连后用 get_task_result(task_id) 仍能取到最终结果

最佳实践:对所有可能 > 30 秒的图像请求,使用 submit_image_task 而非同步 generate_image。这样即便客户端因 IDE 重启 / 网络抖动 / 5 分钟 long-poll 上限断开,也能在重连后通过 task_id 拿回结果。

API/工具说明

describe_image

分析并描述图片内容。

参数:

参数类型必填说明
imagestring图片数据,支持 Base64 编码、Data URI、HTTP/HTTPS URL 或本地文件路径
promptstring自定义分析提示词,不提供则使用默认提示词
detail_levelstring描述详细程度:briefnormal(默认)、detailed

示例请求:

{
  "name": "describe_image",
  "arguments": {
    "image": "https://example.com/image.jpg",
    "prompt": "描述这张图片中的主要内容",
    "detail_level": "detailed"
  }
}

本地文件路径示例:

{
  "name": "describe_image",
  "arguments": {
    "image": "/path/to/local/image.jpg",
    "detail_level": "normal"
  }
}

示例响应:

{
  "content": [
    {
      "type": "text",
      "text": "这张图片展示了..."
    }
  ]
}

compare_images

比较多张图片,分析它们的相似点和差异。

参数:

参数类型必填说明
imagesarray图片数组(2-4张),每个元素支持 Base64、URL 或本地文件路径
promptstring自定义比较提示词,不提供则使用默认提示词
detail_levelstring比较详细程度:briefnormal(默认)、detailed

示例请求:

{
  "name": "compare_images",
  "arguments": {
    "images": [
      "https://example.com/image1.jpg",
      "https://example.com/image2.jpg"
    ],
    "prompt": "比较这两张图片的主要差异",
    "detail_level": "detailed"
  }
}

本地文件比较示例:

{
  "name": "compare_images",
  "arguments": {
    "images": [
      "/path/to/image1.png",
      "/path/to/image2.png",
      "/path/to/image3.png"
    ]
  }
}

示例响应:

{
  "content": [
    {
      "type": "text",
      "text": "这些图片的比较结果:\n\n相似点:...\n\n差异点:..."
    }
  ]
}

generate_image

根据文本提示词生成图片。该工具调用 OpenAI-Compatible /images/generations 路由,需要配置 OPENPIC_IMAGE_MODEL

参数:

参数类型必填说明
promptstring图片生成提示词
sizestring输出尺寸,默认 1024x1024;支持 1024x10241024x15361536x10242048x2048
qualitystring输出质量,实际取值取决于服务支持情况
response_formatstring响应格式:file_pathurlb64_json,默认 file_path;仅显式选择 b64_json 时返回内联 Base64;若上游在 url 模式返回 Data URI,服务端会自动落盘并返回 file_path
nnumber生成图片数量,当前仅支持 1
output_dirstring单次调用的落盘目录,绝对路径,无 .. 段;覆盖 OPENPIC_OUTPUT_DIRresponse_format=b64_json 时被忽略
filename_prefixstring单次调用的文件名前缀;规则同 OPENPIC_FILENAME_PREFIX;覆盖部署级默认
overwriteboolean单次调用的覆盖策略;覆盖 OPENPIC_OVERWRITE

示例请求:

{
  "name": "generate_image",
  "arguments": {
    "prompt": "一只橘猫坐在窗边,电影感光影",
    "size": "1024x1024",
    "response_format": "file_path",
    "output_dir": "/var/lib/openpic-mcp/images",
    "filename_prefix": "demo",
    "n": 1
  }
}

示例响应:

{
  "content": [
    {
      "type": "text",
      "text": "{\n  \"images\": [\n    {\n      \"file_path\": \"/var/lib/openpic-mcp/images/demo-20260429-022045-3f8a91b2.png\",\n      \"format\": \"png\"\n    }\n  ],\n  \"created\": 1234567890,\n  \"requested\": {\n    \"prompt\": \"一只橘猫坐在窗边,电影感光影\",\n    \"size\": \"1024x1024\",\n    \"response_format\": \"file_path\",\n    \"n\": 1,\n    \"output_dir\": \"/var/lib/openpic-mcp/images\",\n    \"filename_prefix\": \"demo\"\n  },\n  \"applied\": {\n    \"size\": \"1024x1024\",\n    \"n\": 1,\n    \"response_format\": \"file_path\",\n    \"output_dir\": \"/var/lib/openpic-mcp/images\",\n    \"filename_prefix\": \"demo\",\n    \"overwrite\": false\n  },\n  \"files\": [\n    {\n      \"index\": 0,\n      \"path\": \"/var/lib/openpic-mcp/images/demo-20260429-022045-3f8a91b2.png\",\n      \"size_bytes\": 70,\n      \"format\": \"png\"\n    }\n  ]\n}"
    }
  ]
}

edit_image

根据输入图片、文本提示词和可选 mask 编辑图片。该工具调用 OpenAI-Compatible /images/edits 路由,需要配置 OPENPIC_IMAGE_MODEL

参数:

参数类型必填说明
imagestring待编辑图片,支持本地文件路径、HTTP/HTTPS URL、Data URI 或原始 Base64
promptstring图片编辑提示词
maskstring可选 mask 图片,支持本地文件路径、HTTP/HTTPS URL、Data URI 或原始 Base64
sizestring输出尺寸,默认 1024x1024;支持 1024x10241024x15361536x10242048x2048
qualitystring输出质量,实际取值取决于服务支持情况
response_formatstring响应格式:file_pathurlb64_json,默认 file_path;仅显式选择 b64_json 时返回内联 Base64;若上游在 url 模式返回 Data URI,服务端会自动落盘并返回 file_path
nnumber编辑结果数量,当前仅支持 1
output_dirstring单次调用的落盘目录,绝对路径,无 .. 段;覆盖 OPENPIC_OUTPUT_DIRresponse_format=b64_json 时被忽略
filename_prefixstring单次调用的文件名前缀;规则同 OPENPIC_FILENAME_PREFIX;覆盖部署级默认
overwriteboolean单次调用的覆盖策略;覆盖 OPENPIC_OVERWRITE

示例请求:

{
  "name": "edit_image",
  "arguments": {
    "image": "/path/to/input.png",
    "prompt": "给这只猫添加一顶红色帽子",
    "size": "1024x1024",
    "response_format": "file_path",
    "output_dir": "/var/lib/openpic-mcp/images",
    "n": 1
  }
}

示例响应:

{
  "content": [
    {
      "type": "text",
      "text": "{\n  \"images\": [\n    {\n      \"file_path\": \"/var/lib/openpic-mcp/images/edit-20260429-022146-8c11e2af.png\",\n      \"format\": \"png\"\n    }\n  ],\n  \"created\": 1234567890,\n  \"requested\": {\n    \"prompt\": \"给这只猫添加一顶红色帽子\",\n    \"size\": \"1024x1024\",\n    \"response_format\": \"file_path\",\n    \"n\": 1,\n    \"output_dir\": \"/var/lib/openpic-mcp/images\"\n  },\n  \"applied\": {\n    \"size\": \"1024x1024\",\n    \"n\": 1,\n    \"response_format\": \"file_path\",\n    \"output_dir\": \"/var/lib/openpic-mcp/images\",\n    \"filename_prefix\": \"edit\",\n    \"overwrite\": false\n  },\n  \"files\": [\n    {\n      \"index\": 0,\n      \"path\": \"/var/lib/openpic-mcp/images/edit-20260429-022146-8c11e2af.png\",\n      \"size_bytes\": 70,\n      \"format\": \"png\"\n    }\n  ]\n}"
    }
  ]
}

图片生成与编辑兼容性说明

以下说明仅适用于 generate_imageedit_image,对 describe_image / compare_images 不生效。

response_format 语义

response_format纯 MCP 客户端侧的交付方式

  • file_path(默认):openPic-mcp 把上游返回的 base64 字节落到本地临时文件,客户端只看到 file_path,避免在 MCP 消息中传输大段 base64。
  • b64_json:openPic-mcp 在响应中保留 base64 字段,适用于客户端需要直接拿到字节的场景。
  • url:等同于 file_path,仅在上游返回的是真正可访问的 URL(非 data URI)时才保留为 URL。GPT image 等模型默认只返回 base64,因此通常会被 openPic-mcp 落盘为 file_path

无论入参选哪一种,openPic-mcp 都不会把 response_format 转发给上游 API。社区已确认 GPT image models 在 images/edits 上传该字段会触发与“模型不支持”混淆的错误,因此 server 内部一律省略。

sizeaspect_ratio

size 默认仅信任 OpenAI 官方 enum:1024x10241024x15361536x10242048x2048 仅在部分 OpenAI-Compatible 代理上可用,原生 OpenAI 不一定支持。

为了避免直接面对像素值,可以使用 aspect_ratio

  • 1:11024x1024
  • 4:31536x1024
  • 3:41024x1536
  • 16:91536x1024(最近的横向预设)
  • 9:161024x1536(最近的纵向预设)
  • auto → 留空 size,由上游决定

sizeaspect_ratio 同时给出时,size 优先

output_format

output_format 用于控制上游生成图片的编码格式(png / jpeg / webp),openPic-mcp 会原样转发到上游。该字段是可选的,留空则使用上游默认(通常为 png)。

声明 vs 实际output_format 是 advisory 字段,openPic-mcp 无法强制兑现。社区已确认部分 OpenAI-Compatible 实现会静默吞掉 output_format: - OpenAI 官方 gpt-image-1/v1/images/edits 端点对 output_format=webp 直接返回 400 "Supported values are: 'png' and 'jpeg'"。 - 多个第三方代理(如 sub2api)会返回成功响应但实际内容仍为 PNG。 为此 openPic-mcp 会在每张返回图片上做 magic bytes 检测,并通过两条额外字段告诉调用方真实情况: - images[i].format:实际检测到的格式(png / jpeg / webp 等),文件扩展名也按这个值打。 - warnings[]:当请求的 output_format 与检测格式不一致时附加的提示(例如 images[0]: requested output_format="webp" but upstream returned "png"; saved as .png)。 调用 list_image_capabilities 可拿到 output_format_enforcement: "advisory"output_format_notes 完整披露。

输出路径策略(P1)

generate_image / edit_imageresponse_format=file_path(默认)或 url 模式下会把上游字节落到本地磁盘。落盘行为遵循下列优先级:

  1. 单次调用入参 output_dir / filename_prefix / overwrite
  2. 部署级环境变量 OPENPIC_OUTPUT_DIR / OPENPIC_FILENAME_PREFIX / OPENPIC_OVERWRITE
  3. 默认值:os.TempDir()/openpic-mcp/、工具上下文 generate / edit、不覆盖。

文件名模板为 -YYYYMMDD-HHMMSS-.,其中:

  • ` 来自 magic-byte 检测出的真实格式(png / jpeg / webp / ...),与 output_format` 是否兑现解耦。
  • ` 是 4 字节随机数的十六进制;overwrite=false 模式同名冲突时追加 -2 / -3` 直到唯一。

output_dir 必须是绝对路径且不含 .. 段,否则在到达上游前直接返回错误。filename_prefix 限制在 [A-Za-z0-9._-]、最长 32 字符且不能以 . 开头。

结构化结果合同(P1)

generate_image / edit_image 的响应在保留 images / created / warnings 兼容字段之外,新增以下结构化字段,便于 MCP 客户端区分"调用方传入"与"服务端实际生效":

  • requested:调用方实际传入的关键参数(prompt / size / aspect_ratio / quality / output_format / response_format / n / output_dir / filename_prefix / overwrite)。未传字段用 omitempty 省略。
  • applied:发往上游的参数(size / quality / output_format / n)以及最终生效的交付参数(response_format / output_dir / filename_prefix / overwrite)。
  • files[]:每张落盘文件的 index / path / size_bytes / formatresponse_format=b64_json 时该字段被省略。
  • usage:仅在上游响应里携带 usage 时透传 input_tokens / output_tokens / total_tokens,缺字段以 omitempty 省略。openPic-mcp 不会伪造任何 token 数。

内联 payload 字节预算(P1)

OPENPIC_MAX_INLINE_PAYLOAD_BYTES 默认 1048576(1 MiB)。

  • response_format=b64_json 模式下若解码后超阈:直接返回 isError 工具结果,提示改用 file_path 或下调 quality / size不会静默切换交付方式
  • response_format=file_path / url 模式下若超阈:照常落盘,但响应里会附加一条 warnings[],便于调用方主动调参或扩大预算。
  • 设置为 0 或负值会被忽略,回退到默认,避免误关 guard。

502 / upstream_error 误读指南

OpenAI-Compatible 图像上游可能把多种失败都包装为 502 upstream_error。常见情况包括:

  1. 上游服务临时不可用,可稍后重试。
  2. 请求参数与目标模型不兼容,例如不支持的 sizeresponse_format 或模型路由。
  3. 图像编辑端点对输入图片本身触发内容审核,但上游没有返回明确的 moderation 错误。

如果同一张图片在多个无害 prompt 下反复 edit 失败、而其他图片同时可以 edit 成功,可能是上游 image moderation 触发。客户端无法可靠区分该情况,建议停止重试并更换输入图片。openPic-mcp 不会自动重试 502/503/504,避免在不可恢复场景下扩大错误面。

图片生成与编辑耗时

图片生成和编辑请求会等待上游 OpenAI-Compatible 服务完成推理后再返回。部分模型(例如高质量图片生成模型)单次 1K 图片可能需要约 1-2 分钟,2K 图片可能需要约 2-4 分钟。建议将 OPENPIC_TIMEOUT 保持为默认 5m 或按实际服务耗时调大,避免服务端在上游仍在推理时提前超时。

支持的图片格式

  • JPEG (.jpg, .jpeg, .jpe, .jfif)
  • PNG (.png)
  • WebP (.webp)
  • GIF (.gif)
  • BMP (.bmp, .dib)
  • TIFF (.tif, .tiff)
  • ICO (.ico)
  • HEIC/HEIF (.heic, .heif)
  • AVIF (.avif)
  • SVG (.svg, .svgz)
注意:实际支持情况取决于您使用的 Vision API 服务。部分格式(如 HEIC、AVIF、SVG)可能不被所有 API 支持。

图片输入方式

  1. Base64 编码:直接传入 Base64 编码的图片数据
  2. Data URIdata:image/jpeg;base64,/9j/4AAQ...
  3. HTTP/HTTPS URLhttps://example.com/image.jpg
  4. 本地文件路径/path/to/local/image.jpgC:\path\to\image.png(Windows)
注意:本地文件路径支持绝对路径和相对路径。系统会自动检测文件的 MIME 类型。

开发指南

项目结构

openPic-mcp/
├── cmd/vision-mcp/          # 主程序入口
│   ├── main.go
│   └── main_test.go
├── internal/
│   ├── config/              # 配置管理 + slog Logger 构造器
│   ├── errors/              # 错误定义
│   ├── image/               # 图片处理(本地文件、MIME检测)
│   ├── protocol/            # 协议层(JSON-RPC、MCP、CancellationRegistry)
│   ├── provider/            # Provider 层
│   │   └── openai/          # OpenAI-Compatible Provider
│   ├── retry/               # 重试机制
│   ├── server/              # MCP 服务器引擎(worker pool / 队列 / 优雅停机)
│   ├── service/tool/        # 工具管理器
│   ├── tools/               # 工具实现
│   │   ├── describe.go      # describe_image 工具
│   │   ├── compare.go       # compare_images 工具
│   │   ├── generate.go      # generate_image 工具
│   │   └── edit.go          # edit_image 工具
│   └── transport/           # 传输层(stdio)
├── pkg/types/               # 公共类型定义
├── .env.example             # 环境变量示例
├── Dockerfile               # Docker 构建文件(预留)
├── docker-compose.yml       # Docker Compose 配置(预留)
├── go.mod                   # Go 模块定义
└── README.md                # 项目文档

构建

# 构建可执行文件
go build -o openPic-mcp ./cmd/vision-mcp

# 构建 Docker 镜像
docker build -t openpic-mcp:latest .

测试

# 运行所有测试
go test ./...

# 运行测试并显示详细输出
go test -v ./...

# 运行测试并生成覆盖率报告
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out -o coverage.html

代码格式化

# 格式化代码
go fmt ./...

# 检查代码格式
gofmt -d .

代码检查

# 运行 go vet
go vet ./...

路线图

v1.0(当前版本)

  • ✅ MCP 协议核心实现(stdio 传输)
  • ✅ OpenAI-Compatible Vision API 支持
  • ✅ describe_image、compare_images、generate_image 和 edit_image 工具
  • ✅ 本地文件路径支持
  • ✅ 多格式图片支持(10种格式)

v1.x(规划中)

  • 🔲 图片压缩功能(已设计,待实现)
  • 🔲 HTTP/SSE 传输支持
  • 🔲 Docker 容器化部署(依赖 HTTP 传输)
  • 🔲 发布到 npm,支持 npx 方式调用
  • 🔲 更多 Vision 工具(UI 分析、代码提取等)

v2.0(远期规划)

  • 🔲 托管服务,用户无需部署即可使用
  • 🔲 多 Provider 支持(Anthropic、Google 等)

许可证

MIT License

Copyright (c) 2024

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

目录标签

目录标签

图像处理GoClaude本地部署MCP协议AI编程助手图片生成图片编辑

支持客户端

Claude DesktopClaudeCursor

接入字段

传输方式(transport,传输协议)

stdio

鉴权方式(authType,认证方式)

oauth

运行时(runtime,运行环境)

Docker

工具数量(toolCount,工具数)

6

资源数量(resourceCount,资源数)

0

提示词数量(promptCount,提示词数)

0

权限和风险

stdiooauth部署方式未说明

接入前请确认传输方式、认证方式和部署位置,并根据实际工具能力限制访问范围。

安装前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

来源信息

继续浏览同类 MCP